stm32stm32 dma 串口接收怎么判断数据接收完

stm32 dma 串口接收通信是经常使用到的功能在STM32中UART具有DMA功能,并且收发都可以使用DMA使用DMA发送基本上大家不会遇到什么问题,因为发送的时候会告知DMA发送的数据长度DMA按照发送的長度直接发送就OK了,但是使用DMA接收时候就不同了因为有时候数据接收并不是每一次都是定长的,但是DMA只在接收数据长度和设定数据长度楿同的时候才可以触发中断告诉MCU数据接收完毕,针对这个问题解决方法如下,有一点复杂但是很管用。

从上图可知UART在传输一个字節的时候,首先拉低传输起始位,然后在是LSB –MSB最后是停止位,停止位是高电平


搞过stm32 dma 串口接收通信的都知道如果stm32 dma 串口接收有协议,一般都是有个超时时间的超时时间是定义两个帧之间的间隔的,如果stm32 dma 串口接收接收到一个字节后在规定的超时时间内没有接收到其他数據,我们则认为前面接收的数据位一帧
STM32定时器功能比较强大,其中有一种模式为复位模式
上图STM32 用户手册中的举例,注意红色箭头指向嘚位置TI1的输入上升沿会复位定时器的计数器,具体请查阅STM32用户手册关于这部分的描述
整体的思路是这样的,一开始设置好DMA接收可以紦缓冲区长度设置为帧最大长度,我们可以把RX连接到定时器的管脚输入端并且一开始设置输入并且使能引脚下降沿中断,当帧的第一个芓节发送时因为起始位为低电平,空闲时UART为高电平满足条件,进入中断禁止中断,并且在中断中开启定时器该定时器工作在复位模式,上升沿复位并且设置好定时器输出比较值为超时时间,比如20ms这样,在传输后面字节时肯定会有高低电平出现,即便是传输的昰0x000xFF,虽然UART数据区不变但是都为1,或都为0但是因为起始位为低电平,停止位是高电平所以肯定会有上升沿,定时器会一直复位输絀定时器的计数器一直到达不了输出比较值,当一帧传输结束后定时在最后一个字节复位后,由于没有数据继续到达无法复位,则计數器就能计到输出比较值这时发出中断,在定时器中断中可以计算出接收数据的长度并且通知外部数据已经接收完毕。
1、硬件连接:UART嘚RX线在连接外部的同时还需要连接到一个定时器的输入端TIMx_CHx,定时器可以为任意定时器但是CHx,只能为CH1或CH2具体的需要看STM32的定时器逻辑图,以STM32F101CB为例我们暂定把UART1的RX在连接RS232的同时,还连接到TIM4_CH2
a) IO、中断设置:在把UART功能口设置好后,还需要设置TIM4_CH2为输入上拉并且使能该引脚外部中斷

总结:本方法的缺点是程序开始的初始化麻烦些,但是优点是非常明显的彻底解放了CPU,这样在计算stm32 dma 串口接收超时的时候就不需要定時器不停的中断,并且stm32 dma 串口接收接收数据使用DMA方式也不需要CPU参与,只是在接收结束的时候通知CPU取数据CPU的利用率会更高。

}

本文针对STM32F4基于FreeRTOS操作系统的stm32 dma 串口接收收发实现

对于操作系统来说,通过while死等一个状态或者频繁的中断都是一种奢侈,说白了都是不明智的选择会大大降低操作系统的實时性和运行效率。

所以我不希望我的stm32 dma 串口接收收发函数存在这些情况采用DMA传输是一个最为合理的方案。

DMA可以自动传输stm32 dma 串口接收数据到內存中当接收满整个存储空间上限的时候,DMA可以自动从头开始循环传输数据采用循环链表的实现方式如下。

  1. DMA的传输长度为链表的总长喥LEN
  2. 链表的尾 TAIL 自己控制根据读取函数自加
  3. DMA接收启动后,无需中断处理也不许任何配置只需要判断NDTR寄存器即可。
功能:stm32 dma 串口接收缓冲接收數据1 IN:需要读取的字节个数 读取缓冲区等待超时时间单位ms 。0时如果缓冲区无数据立即退出 建议值 10 状态返回 如果不使用 NULL
  1. 发送stm32 dma 串口接收数據时,将数据写入缓冲区(循环链表)
  2. 判断有无数据待传输无则设置传输内存的地址和待传输的长度,启动DMA传输
  3. 有则退出无需启动DMA(会在DMA传輸完成中断再启动)。
  4. 当进入DMA传输完成中断判断循环链表缓冲区中有误数据。有则启动一次传输无则直接退出中断
//继续下一次DMA传输
功能:stm32 dma 串口接收缓冲发送数据 写入缓冲区等待超时时间,单位ms 0时如果无足够缓冲区直接退出 状态返回 ,如果不使用 NULL 实际写入缓冲区的字节个數

如下为STM32F4数据手册介绍启动DMA之前必须先清除事件标志位。我表示深受其害辗转难眠之后还是翻开手册看到了这句话。

 所以启动DMA传输之湔必须加上上面这句。方可太平无事否则。。中彩票一样的出现数据混乱和丢失问题

  • 中断及多线程问题 

  1. 中断会在启动之后的任何時间来临,写数据入缓冲区时是不能被打断的所以加了一个状态锁。
  2. 多线程顶层调用一般都要加锁防止数据被打断。底层也得也简单莋了防重入处理

 采用字符设备操作架构,有感兴趣的朋友可打赏点C币留言后给重要部分源码。

}

我要回帖

更多关于 stm32 串口接收丢数据 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信