你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】STM32CubeMX—串口空闲中断+DMA接收

[复制链接]
STMCU小助手 发布时间:2022-5-16 10:35
一、实验说明
实验平台:STM32F103C8T6
实验内容:使用串口一空闲中断结合DMA 完成不定长数据接收

STM32的串口接收数据的方式
1、轮询接收
  所谓轮询,就是在主函数中判断接收完成的标志位。举个不太恰当例子,就比如,此时你正在考试作弊,手机藏在兜里,你的队友再给你发答案,但是你的手机静音,所以你不得不写一会题看一会手机,有的时候答案已经发来了但是你此时在假装写,没有看,导致你没能及时看到答案浪费了时间(仅仅为了举例而已。。。。)。轮询接收数据也是这样。

2、中断接收
  串口接收配置为中断模式,当有数据收到时,进入到串口接收中断中读取数据。继续上面的例子(你为了不浪费时间且及时抄到答案,你把手机开了震动,消息一来立马看,这是就比上面好多了,能够及时发现消息。但是又出了一个问题,你的猪队友,写一个选择给你发一次,不停的震动,完全扰乱了你的节奏)。其实也就是,串口接收数据时,一次接收一个字节,当数据量较大时,显然这样频繁的进入中断,打断主程序,严重影响系统性能。

3、空闲中断接收

  空闲中断接收,当一帧数据接收完成之后,串口会进入到空闲中断中去,然后在空闲中断中处理收到的数据。这种模式对处理不定长数据帧带来很大的便利,我们不必频繁的进入接收中断处理数据,但是弊端也是明显的,由于每次都要接收完一个完整的数据帧后才空闲中断,所以当一帧数据出错时,我们也不得不接收这帧错误的数据。在通讯可靠的场合,使用空闲中断接收模式接收串口数据,将会大大提高系统的性能。

二、实验步骤
1、基础配置

1)、sys中,选好调试方式,例如jtag-4pin。
2)、RCC时钟,晶振选择。
3)、时钟树配置。
4)、中断分组配置。
以上步骤可以参考串口中断实验。

串口中断实验配置
本实验要配置好printf函数便于演示效果

2、串口和DMA配置
1)、串口一配置。

]CXMGGO%(~CVM(]Z)3~HG(Y.png

2)、DMA选择
T(MA7CJTGMUHRZZU~9F.png

71CDS@LW]C_6GUJ7RXXP@XN.png

3)、生成工程代码

IZOO[@GPHC5O@UK9ASY]IDI.png

然后生成代码。
4)、添加代码

3@8(I63`AXKHYAEVQ4QLC30.png

  1. // 这里没有使用中断回调函数,这样写更直接一点。
  2. extern volatile uint8_t rx_len;//接收到的数据长度
  3. extern volatile uint8_t recv_end_flag; //接收完成标志位
  4. extern uint8_t rx_buffer[200]; //数据缓存数组
  5. void USART1_IRQHandler(void)
  6. {
  7.   /* USER CODE BEGIN USART1_IRQn 0 */
  8.     uint32_t tmp_flag = 0;
  9.     uint32_t temp;
  10.     tmp_flag =__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE);
  11.     if((tmp_flag != RESET))
  12.     {
  13.         __HAL_UART_CLEAR_IDLEFLAG(&huart1);
  14.         temp = huart1.Instance->SR;  
  15.         temp = huart1.Instance->DR;
  16.         HAL_UART_DMAStop(&huart1);
  17.         temp  = hdma_usart1_rx.Instance->CNDTR;
  18.         rx_len =  200 - temp;
  19.         recv_end_flag = 1;               
  20.     }
  21.     HAL_UART_IRQHandler(&huart1);        
  22. }
复制代码

如下图,在usart.c 文件中先把变量定义上,同时把支持printf的函数添加上。

  1. //注:**这三个变量 需要在stm32f1xx_it.c和main.c中外部声明**
  2. volatile uint8_t rx_len=0;  //接收到的数据长度
  3. volatile uint8_t recv_end_flag=0;//接收成功标志位
  4. uint8_t rx_buffer[200];//缓存数组
复制代码

ZD3I8)}08`}Y`@Y]W5QGW19.png

10BJGM%V~TYC4W]DN6F1ALW.png

  1.         __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);
  2. HAL_UART_Receive_DMA(&huart1,rx_buffer,200);
复制代码

3_4M~T~TU3DS7MZDRB24~GL.png

  1. int main(void)
  2. {
  3.         HAL_Init();
  4.         SystemClock_Config();
  5.         MX_GPIO_Init();
  6.         MX_DMA_Init();
  7.         MX_USART1_UART_Init();
  8.         /* USER CODE BEGIN WHILE */
  9.         printf("DMA_TEST");
  10.         while (1)
  11.         {
  12.                 if(recv_end_flag ==1)                        
  13.                 {        
  14.                         printf("接收到的数据长度为%d\r\n",rx_len);
  15.                         HAL_UART_Transmit(&huart1,rx_buffer, rx_len,200);
  16.                         for(uint8_t i=0;i<rx_len;i++)
  17.                         {
  18.                                 rx_buffer<i>=0;
  19.                         }
  20.                         printf("\r\n");
  21.                         rx_len=0;
  22.                         recv_end_flag=0;
  23.                 }
  24.                 HAL_UART_Receive_DMA(&huart1,rx_buffer,200);        
  25.                 /* USER CODE END WHILE */
  26.         }
  27. }
  28. </i>
复制代码

3 烧录调试
添加链接描述

2E6(L5`BW[C2NM5)0UHR3PC.png
收藏 评论0 发布时间:2022-5-16 10:35

举报

0个回答
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版