【STM32】串口USART空闲中断+DMA接收不定长数据

今天翻出之前的USART学习总结,  重温STM32 的 USART 接收处理,然后根据使用更新一些资料。 

先上最终代码下载:https://download.csdn.net/download/zhouml_msn/12396522


实验环境

STM32F429IG(魔女开发板) + Keil_5.27 + 寄存器操作

【STM32】串口USART空闲中断+DMA接收不定长数据_第1张图片

实验效果如下

【STM32】串口USART空闲中断+DMA接收不定长数据_第2张图片


USART 的两种接收方式

  • RENE 非空中断,最常用的方式,接收的代码简单,但数据处理时稍麻烦。正点原子的代码中USART接收就是使用这种方式。每个字节中断一次,系统实时性要求较高时得注意, 如无人机等.
  • IDLE 空闲中断 + DMA ,  省资源!!  在接收到数据时,DMA把数据挨个存放到指定缓冲区,当一帧数据接收完成后(发现一个字节时间没收到数据),产生空闲中断,USART的SR寄存器第4位IDLE被置1.

注意注意:空闲中断并不是适合所有情况,如正点原子的LORA模块,115200波特率下接收一字节用了90us,但有900us左右间隔是空白的,这类每个字节间的间隔时间比工作时间还长的、不连续接收(一个紧挨一个),  是不适合使用空闲中断的。


使用时,注意两点:

1. IDLE的中断清理方式.

  • USART的非空中断标志位, 是自动清理的, 你只要读出数据, 标志会就自动被清, 不用自己费心.
  • 但IDLE的中断标志位, 必须通过软件序列清零, 步骤如下: 
  • u32 temp;
  • temp=USART1->SR;
  • temp=USART1->DR;
  • 这两句顺序还不能错, 之前没细心看手册, 调试差点爆血管. 前人不说, 撞墙也想不出来这前因后果!!

2. DMA 设置

  • 使用DMA时, 一般会设置明确的传输数据量, 就是长度是已知道的;  而IDLE 空闲中断 , 最方便的就是接收不定长数据.
  • 所以NDTR(传输数量)要设得比实际数量要大, 注意单位:你的字长, 如200. 大多少没关系.
  • 中断处理时, 要重新设置DMA的NDTR.  另外: DMA是在关闭的时候才能修改!!

代码编写

整个功能分三小部代码进行编写,USART的初始化、DMA的初始化、中断服务函数;

fputc()的重定向就不贴出来了,可下载完整示例代码。

1)USART初始化

  1. 声明缓冲区:  u8 RxTemp[255];     // 比接收的数据字节数大些就成;另外注意避免使用char类型
  2. GPIO 初始化
  3. UART 初始化                                // 使能发送, 使能IDLE
  4. 使能UART接收                             // 这一步已开始工作
  5. 使能中断通道,配置优先级          // 使用了魔女的NVICSet函数,一行代码搞掂

2) DMA初始化

代码中的参数都是比较容易理解的,注意打开STM32的数据手册, 翻查DMA资源表格,确定使用哪个数据流、通道就成。

3)中断服务函数

你可能感兴趣的:(STM32)