实验目标:

单片机现有3种工作模式:
1.LED控制模式-PC4
2.FAN控制模式-PC6
3.BEEP控制模式-PA15
可以在某一个模式下通过按键KEY1-PC9控制设备:按键按下一次,设备打开,再按下一次,设备关闭(设备管脚输出反向电平);
通过两种方式切换模式:

1.通过串口UART1通信,pc端发送当前模式:LED,FAN,BEE
2.底板用户自定义按键USER-PA12进行模式切换,按键按下一次进入LED,再按一次进入FAN,再按一次进入BEEP,循环切换

梳理:

1.定义enum设置三种模式,定义全局变量unsigned int con_mode = MODE_LED;默认LED模式:

enum 
{
	MODE_LED,	//LED控制模式
	MODE_FAN,	//FAN控制模式
	MODE_BEEP	//BEEP控制模式
};

2.通过STM32CubeMX工具配置UART1接收中断和PA12上升沿检测中断,设置PC4、PC6、PA15为GPIO_OUTPUT:

/*GPIO初始化
*/
void MX_GPIO_Init(void)
{

  GPIO_InitTypeDef GPIO_InitStruct = {0};

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOC_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_4|GPIO_PIN_6, GPIO_PIN_RESET);

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_15, GPIO_PIN_RESET);

  /*Configure GPIO pins : PC4 PC6 */
  GPIO_InitStruct.Pin = GPIO_PIN_4|GPIO_PIN_6;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

  /*Configure GPIO pin : PC9 */
  GPIO_InitStruct.Pin = GPIO_PIN_9;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

  /*Configure GPIO pin : PA12 */
  GPIO_InitStruct.Pin = GPIO_PIN_12;
  GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  /*Configure GPIO pin : PA15 */
  GPIO_InitStruct.Pin = GPIO_PIN_15;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  /* EXTI interrupt init*/
  HAL_NVIC_SetPriority(EXTI12_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(EXTI12_IRQn);

}
/*UART1初始化
*/
void MX_USART1_UART_Init(void)
{

  /* USER CODE BEGIN USART1_Init 0 */

  /* USER CODE END USART1_Init 0 */

  /* USER CODE BEGIN USART1_Init 1 */

  /* USER CODE END USART1_Init 1 */
  huart1.Instance = USART1;
  huart1.Init.BaudRate = 115200;
  huart1.Init.WordLength = UART_WORDLENGTH_8B;
  huart1.Init.StopBits = UART_STOPBITS_1;
  huart1.Init.Parity = UART_PARITY_NONE;
  huart1.Init.Mode = UART_MODE_TX_RX;
  huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart1.Init.OverSampling = UART_OVERSAMPLING_16;
  huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
  huart1.Init.ClockPrescaler = UART_PRESCALER_DIV1;
  huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
  if (HAL_UART_Init(&huart1) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_UARTEx_SetTxFifoThreshold(&huart1, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_UARTEx_SetRxFifoThreshold(&huart1, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_UARTEx_DisableFifoMode(&huart1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN USART1_Init 2 */

  /* USER CODE END USART1_Init 2 */

}

3.设置PC9作为KEY1按键,放在main函数中:

while (1)
  {
		HAL_UART_Receive_IT(&huart1, (uint8_t *)buf, 3);    //使能UART1接收中断
		
		switch(con_mode)
		{
			case MODE_LED:
				if (HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_9)==0)
				{
					HAL_Delay(100);    //软件消抖
					if (HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_9)==0)
					{
						HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_4);    //电平反转
					}
				}
			break;
			case MODE_FAN:
				if (HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_9)==0)
				{
					HAL_Delay(100);
					if (HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_9)==0)
					{
						HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_6);
				
					}
				}
			break;
			case MODE_BEEP:
				if (HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_9)==0)
				{
					HAL_Delay(100);
					if (HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_9)==0)
					{
						HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_15);
					}
				}
			break;
			default:
				break;
		}
	}

4.重定义中断处理函数HAL_GPIO_EXTI_Rising_Callback和HAL_UART_RxCpltCallback(PS:UART1接收中断需要调用HAL_UART_Receive_IT接口,才能正常回调):

char buf[128] = {0};    //串口接收buf,长度为128
unsigned int con_mode = MODE_LED;    //定义当前控制模式,默认LED控制模式

/*重定义fputc函数,输出log到uart1*/
int fputc(int ch, FILE * file)
{
	HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 5);
	return ch;
}
/*重定义UART1中断处理函数*/
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	printf("uartRxCplt_rx_ok %s\n\r", buf);
	if(!strcmp(buf, "LED"))    //比较是否LED
	{
		con_mode = MODE_LED;    //设置模式为LED控制模式
	}
	else if(!strcmp(buf, "FAN"))    //比较是否FAN
	{
		con_mode = MODE_FAN;    //设置模式为FAN控制模式
	}
	else if(!strcmp(buf, "BEE"))    //比较是否BEE
	{
		con_mode = MODE_BEEP;    //设置模式为BEEP控制模式
	}
}

/*重定义GPIO中断处理函数*/
void HAL_GPIO_EXTI_Rising_Callback(uint16_t GPIO_Pin)
{
	
	printf("uartRising_rx_ok\n\r");
	if(GPIO_Pin == GPIO_PIN_12)    //检测到PA12管脚上升沿时,循环切换模式
	{
		if(con_mode == MODE_BEEP)
			con_mode = MODE_LED;
		else
			con_mode++;		
	}
}

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐