本次采用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的控制动作。
|