串口dma发送和接收(USART串口通信DMA方式一分钟从入门到大师)
串口dma发送和接收(USART串口通信DMA方式一分钟从入门到大师)这里要用到STM32时钟在定时器模式的一种工作状态,即可以工作在从模式,并且在时钟输入引脚电平发生上、下沿变化时,复位时钟。为了实现使用这个功能,在硬件电路里,将一个时钟捕获输入引脚,连接到串口的RX引脚,设置捕获为上沿都触发,触发时复位计数器,因此,在连接收到数据时,时钟不断被复位,不会发生超时中断。同时,时钟的主体仍然工作在定时器状态,根据时钟频率和串口波特率,设置一个合理的超时值(RX没数据发生时,计数器一直加,发生溢出中断),并使能溢出中断。DMA接收时,预先要知道接收的字节数,如果不知道的话,可以关联一个比较大的缓冲,设置一个大的接收字节数(确保不会溢出),但是同样面临一个什么时候结束的问题。在《USART串口通信,中断方式,一分钟从菜鸟到大师(完整版)》说提到使用时钟超时来确认接收结束的方式,但是此时已经没有串口中断了,怎么使时钟复位呢?使能全局串口中断并设置优先级。请参考《借
在《USART串口通信,中断方式,一分钟从菜鸟到大师(完整版)》文中详细介绍了中断方式串口通信的时序。在需要大量串口通信的应用中,《为什么需要DMA?你知道吗?》指出了中断方式的不足之处,及采用DMA方式在提高系统效率方面的巨大优势。下面看看以DMA方式串口通信的时序及要注意的问题。
如果是全双工通信,需要用到二个DMA通道,半双工时用一个DMA通道也可以,但是必须在每次收发前初始化。
1.初始化串口包括使能串口时钟,使能发送和接收,定义引脚,波特率,数据位长度,奇偶校验方式,停止位位数;使能发送和接收功能;
使能串口模块接收中断(DMA方式也可以使能,看下面为什么要使用);
使能全局串口中断并设置优先级。
2. 初始化DMA请参考《借助CMSIS宏定义,写出易读通用、易移植的DMA驱动》,关联串口数据发送寄存器与发送数据缓冲,及串口数据接收寄存器和接收数据缓冲,并使能DMA通道的发送完成中断。
时钟输入
3.时钟的用法DMA接收时,预先要知道接收的字节数,如果不知道的话,可以关联一个比较大的缓冲,设置一个大的接收字节数(确保不会溢出),但是同样面临一个什么时候结束的问题。在《USART串口通信,中断方式,一分钟从菜鸟到大师(完整版)》说提到使用时钟超时来确认接收结束的方式,但是此时已经没有串口中断了,怎么使时钟复位呢?
这里要用到STM32时钟在定时器模式的一种工作状态,即可以工作在从模式,并且在时钟输入引脚电平发生上、下沿变化时,复位时钟。为了实现使用这个功能,在硬件电路里,将一个时钟捕获输入引脚,连接到串口的RX引脚,设置捕获为上沿都触发,触发时复位计数器,因此,在连接收到数据时,时钟不断被复位,不会发生超时中断。同时,时钟的主体仍然工作在定时器状态,根据时钟频率和串口波特率,设置一个合理的超时值(RX没数据发生时,计数器一直加,发生溢出中断),并使能溢出中断。
时间设置
4.工作时序准备好发送数据,使能串口的DMAT(发送)和DMAR(接收)位,开始发送DMA关联的数据和准备接收接收数据。
接收:收到第一个字节时发生串口接收中断(此时DMA也在工作),在中断里初始化时钟,并关闭串口接收中断(仅用一次)。在时钟发生比较中断时,数据接收完成。
发送:在DMA传送结束后,DMA通道产生中断,此时,只是完成了DMA将最后的一个数据拷贝到串口的发送缓冲寄存器里,而串口并没有完成最后一个数据的发送。因此,在DMA的发送完成中断里,需要使能串口的发送完成TC中断。在串口发生TC中断时,数据才真正的发送完毕。
//发送DMA void DMA_Channel_IRQHandler(void) { 清楚DMA中断标识 使能串口发送完成中断 } //串口中断 void USART_IRQHandler(void) { if(接收中断) { 初始化时钟 关闭接收中断 } if(发送中断) { //数据发送完成 } }
注意,接收完成后,DMA要初始化,为下一次接收做准备。通过上述过程可知整个发送、和接收过程各只用到二次中断,效率非常高,是一种非常理想DMA工作方式。
今天把原理说一下,代码我整理后再发。