本次采用USART1不定长中断接收,来控制板截LED_RED的开与关。
1、串口图形化配置、打开串口全局中断:
2、添加串口重定向:
/* USER CODE BEGIN 1 */
#include "stdio.h"
#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
//#define GETCHAR_PROTOTYPE int __io_getchar(FILE *f)
PUTCHAR_PROTOTYPE
{
HAL_UART_Transmit(&huart1, (uint8_t*)&ch, 1, HAL_MAX_DELAY);
return ch;
}
//GETCHAR_PROTOTYPE
//{
// uint8_t ch = 0;
// HAL_UART_Receive(&huart1, (uint8_t *)&ch, 1, 0xFFFF);
// return ch;
//}
#endif
3、添加串口中断函数,中断函数中,如果接收到数据,更新串口接收数据标志为1,以便其他进程判,并处理数据。
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(huart);
/* NOTE: This function Should not be modified, when the callback is needed,
the HAL_UART_TxCpltCallback could be implemented in the user file
*/
if(rxtx_it_usart.huart == huart)
{
rxtx_it_usart.rx_flage = 1;
}
}
4、添加自定义串口空闲中断回调函数
//自定义空闲中断处理函数
void HAL_UART_IDLE_HANDLER(UART_HandleTypeDef *huart)
{
uint32_t isrflags = READ_REG(huart->Instance->ISR);
if((USART_ISR_IDLE & isrflags) != RESET && ( huart->RxXferCount > 0))
{
printf("idle\r\n");
__HAL_UART_CLEAR_IDLEFLAG(huart);
/* Disable the UART Data Register not empty Interrupt */
__HAL_UART_DISABLE_IT(huart, UART_IT_RXNE);
/* Disable the UART Parity Error Interrupt */
__HAL_UART_DISABLE_IT(huart, UART_IT_PE);
/* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */
__HAL_UART_DISABLE_IT(huart, UART_IT_ERR);
/* Rx process is completed, restore huart->RxState to Ready */
huart1.RxState = HAL_UART_STATE_READY;
HAL_UART_RxCpltCallback(huart);
}else if((USART_ISR_IDLE & isrflags) != RESET && ( huart->RxXferCount == 0 ))
{
__HAL_UART_CLEAR_IDLEFLAG(huart);
}
}
5、添加初始化空闲中断,在main初始化时加载来启用空闲中断的接收。
//初始化空闲中断
void uart1_user_init(void)
{
__HAL_UART_ENABLE_IT(rxtx_it_usart.huart, UART_IT_IDLE);
__HAL_UART_CLEAR_IDLEFLAG(rxtx_it_usart.huart);
HAL_UART_Receive_IT(rxtx_it_usart.huart,rxtx_it_usart.rx_buf,RXBUFFSIZE);
}
6、在main中添加串口接收数,判是串口接收数据标志是否更新,如果有更新,判断符合LED命令,则相应做出LED灯的动作。数据处理后,重置接收标志,清空数据接收缓存。
if(rxtx_it_usart.rx_flage == 1)
{
ret = strstr((char *)rxtx_it_usart.rx_buf,(char *)"LED_RED_ON");
if(0 != ret)
{
printf("LED_ON \r\n");
HAL_GPIO_WritePin(LED_RED_GPIO_Port, LED_RED_Pin, GPIO_PIN_SET);
}
ret = strstr((char *)rxtx_it_usart.rx_buf,(char *)"LED_RED_OFF");
if(ret != 0)
{
printf("LED_OFF \r\n");
HAL_GPIO_WritePin(LED_RED_GPIO_Port, LED_RED_Pin, GPIO_PIN_RESET);
}
rxtx_it_usart.rx_flage = 0;
//回显接收到的数据
// printf("\r\nrcv done:\r\n");
//printf("%s\r\n", rxtx_it_usart.rx_buf);
//重新开始接收20个字节数据
memset(rxtx_it_usart.rx_buf,0,sizeof(rxtx_it_usart.rx_buf));
HAL_UART_Receive_IT(rxtx_it_usart.huart,rxtx_it_usart.rx_buf,RXBUFFSIZE);
}
7、实验效果:
【小结】这次实验实现了,不定长度的串口中断接收,并完成对接收数据的判断,做出相应的LED的控制动作。
|