蓝桥杯嵌入式竞赛:使用stm32G431RBT6实现串口不定长收发的空闲中断和DMA

目录

1、cubemx配置

(1)串口选择异步模式,波特率9600,打开串口接收中断

(2)打开dma接收、发送请求,选择normal搬运,数据类型设置为字节

2、在初始化中加入以下代码:空闲中断使能、打开DMA发送、接收请求

3、在stm32g4xx_it.c中找到USART1_IRQHandler(void),重写中断服务函数

4、编写空闲中断回调函数

5、主函数while接收


        空闲中断:顾名思义当串口空闲时候触发中断,当串口接收到数据时,数据是以字节为单位进行传送,当最后一字节接收后一段时间(通常很短)没有接收到下一字节数据,就会触发空闲中断。利用空闲中断的这个特性,可以实现串口数据的不定长接收。

1、cubemx配置

(1)串口选择异步模式,波特率9600,打开串口接收中断

(2)打开dma接收、发送请求,选择normal搬运,数据类型设置为字节

2、在初始化中加入以下代码:空闲中断使能、打开DMA发送、接收请求

__HAL_UART_CLEAR_IDLEFLAG(&huart1);   //空闲中断标志位清除
__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE); 	
	
HAL_UART_Receive_DMA(&huart1, (uint8_t *)rx, 20);
HAL_UART_Transmit_DMA(&huart1, (uint8_t *)rx,20);

3、在stm32g4xx_it.c中找到USART1_IRQHandler(void),重写中断服务函数

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 */

	if(__HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE)!=RESET)
	{
		ucTemp=1;
		__HAL_UART_CLEAR_IDLEFLAG(&huart1);
		HAL_UART_DMAStop(&huart1);
		idle_rxcallback(&huart1);
	}
	


  /* USER CODE END USART1_IRQn 1 */
}

        将中断函数中的回调函数HAL_UART_IRQHandler(&huart1)屏蔽掉,检查空闲中断的标志位,若置位则将uc_Temp置1,然后清除空闲中断标志位(若不清除程序会一直卡在中断里,导致其余代码无法执行)。清除标志位之后停止DMA,然后调用idle_rxcallback(&huart1);回调函数。

注意:回调函数是自己编写,什么名字都可以!!!

不要开启其它串口中断,否则程序可能会卡死在串口中断中。

4、编写空闲中断回调函数

void idle_rxcallback(UART_HandleTypeDef *huart)
{
	rx_num=0;
	rx_num=20-__HAL_DMA_GET_COUNTER(&hdma_usart1_rx);   //DMA传输的剩余数据量
	HAL_UART_Receive_DMA(&huart1, (uint8_t *)rx, 20);
	
}

        在空闲中断中打开DMA的接收搬运,此代码中我添加了对接收数据的计数,没有这个需求的也可以不加。

5、主函数while接收

if(ucTemp==1)
{
	ucTemp=0;
	//printf("%s",rx);         //串口回显
			
	strcpy(tx,rx);
	HAL_UART_Transmit_DMA(&huart1, (uint8_t *)tx,20);//串口回显
			
	sprintf(text,"rx_num:%02d",rx_num);
    LCD_DisplayStringLine(Line1, (u8 *)text);
			
    memset(rx,0,sizeof((unsigned char)rx));
    memset(tx,0,sizeof((unsigned char)tx));

 }	

        在主函数中检查uc_Temp标志位,若标志位等于1,则说明空闲中断被触发,一帧串口数据接收完成,可以进行数据处理,处理后,再将标志位置0,等待下一帧数据接收完成。

作者:geandbear

物联沃分享整理
物联沃-IOTWORD物联网 » 蓝桥杯嵌入式竞赛:使用stm32G431RBT6实现串口不定长收发的空闲中断和DMA

发表评论