串口空闲中断(UART_IT_IDLE):串口接收数据,超过一个字节的时间内没有再接收到数据的时候发生的
好处:与传统的判断'\r','\n'为结束位相比,空闲中断判断串口数据接收完毕准确且迅速
缺点:串口持续不断的发送数据时,无法进入空闲中断。因此需要间隔一个字节以上的时间,间歇式的发送数据。这个缺点在正常使用中,根本不是问题
下面进入主题



在usart.c文件中创建接收数组和处理函数:
- #define USART1_RX_MAX 2148
-
- uint8_t Rxbuf[USART1_RX_MAX];
-
- uint16_t Rxlen=0;
-
- void Usart_Receive_Data(UART_HandleTypeDef *huart)
- {
- if(RESET != __HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE)) //判断是否是空闲中断
- {
- //清除空闲中断标志(否则会一直不断进入中断)
- __HAL_UART_CLEAR_IDLEFLAG(huart);
- //计算接收到的数据量
- Rxlen = (USART1_RX_MAX) - (__HAL_DMA_GET_COUNTER(&hdma_usart1_rx));
- //停止接收
- HAL_UART_DMAStop(huart);
-
- }
- }
这里需要注意添加: HAL_UART_DMAStop(huart);//停止接收
不添加的话,DMA接收不会停止,重新开启DMA接收,RX缓存将不会从0开始接收数据
在stm32f1xx_it.c文件中调用Usart_Receive_Data():
- void USART1_IRQHandler(void)
- {
- /* USER CODE BEGIN USART1_IRQn 0 */
-
- /* USER CODE END USART1_IRQn 0 */
- HAL_UART_IRQHandler(&huart1);
- /* USER CODE BEGIN USART1_IRQn 1 */
- Usart_Receive_Data(&huart1);//调用函数
- /* USER CODE END USART1_IRQn 1 */
- }
在main.c文件中的main()函数中开启空闲中断并启动DMA:
在main()函数中,判断Rxlen大于0,则开始处理串口数据:
- int main(void)
- {
- //初始化
- __HAL_UART_ENABLE_IT(&huart1,UART_IT_IDLE);//开启空闲中断
- HAL_UART_Receive_DMA(&huart1,Rxbuf,USART1_RX_MAX); //启动DMA接收
- while(1)
- {
- if(Rxlen>0){
- //处理串口数据
- //清空串口缓存并Rxlen=0
- memset(Rxbuf,0,USART1_RX_MAX);
- Rxlen=0;
- //重新开启DMA接收
- HAL_UART_Receive_DMA(&huart1,Rxbuf,USART1_RX_MAX); //启动DMA接收
- }
- }
- }