本帖最后由 6552918 于 2023-7-30 22:04 编辑
#申请原创# #技术资源#[url=home.php?mod=space&uid=760190]@21小跑堂 [/url]
原厂例程包里的DMA例程是有错误的,编译提示有个符号是未定义的
按规格书描述修改定义如下后可以编译通过
手动为添加3个DMA请求的定义
使能DMA发送完请求
修改完上述设置,可以在串口助手内看到DMA的发送数据了
虽然功能已经实现,但不具有实际使用意义,我给大家带来具有实际意义的UART+DMA实现双缓冲的使用。
在实现的过程总过程中发现一处笔误
还发现一处严重BUG,配置时使能了空闲中断但空闲中断无法被使能
经过分析发现问题原因是,中断使能寄存器配置配置结构体中IRQEna长度为1个字节
但实际这个寄存器的大小超过了一个字节,导致初始化时bit8丢失,所以,空闲中断无法被使能
需要将IRQEna改为uint16_t才行
接下来看看UART+DMA实现高效收发是如何实现的吧
本例程实现功能如下:
1实现UART0和UART1使用DMA发送数据
2实现UART0和UART1使用DMA接收不定长度数据
3实现UART0和UART1使用DMA接收数据的双缓冲方式
初始化需要实现DMA GPIO UART NVIC等的初始化。先关具体实现都在UART_DMA.c和UART_DMA.h文件内。
DMA初始化配置
UART0 TX使用DMA通道0,UART0 RX使用DMA通道1;
UART1 TX使用DMA通道2,UART0 RX使用DMA通道3;
发送通道在发送数据时才能使能,因此在初始化时是不使能的,这里需要注意一下。
GPIO初始化配置
UART0_RXD P0.15;UART0_TXD P1.0
UART1_RXD P2.8;UART1_TXD P3.9
UART初始化配置
串口中断使用了,空闲中断,用于不定长度数据结尾的判断
DMA请求使用了 收完成DMA请求 和 送缓冲区空 DMA 请求,用于数据收发的DMA请求。
NVIC初始化配置
使用了DMA中断,用于DMA传输完成处理(接收区收满数据情况)
UART0和UART1中断,用于空闲中断处理(接收一帧完成)
DMA中断
通道1是UART0 RX使用
通道3是UART1 RX使用
我们看看DMA中断内的数据接收处理
串口中断
仅处理了空闲中断,用于判断数据帧接收完成。
进入这个中断有3中情况
1接收数据长度不到DMA传输次数时,检测到空闲
2接收数据长度等于DMA传输次数时,检测到空闲
3接收数据长度大于DMA传输次数时,检测到空闲
我们再来看一下,接收数据的处理,
当接收数据长度等于DMA传输次数时,检测到空闲 和 接收数据长度大于DMA传输次数时,检测到空闲,这两种情况是先进入DMA中断再进入串口中断的,数据在DMA中断中就已经拷贝和切换过缓冲区,所以数据不存在丢包和覆盖问题。
开启调试输出后测试效果如下
因为这款MCU的DMA没有DMA半传输中断或硬件双缓存功能,所以实现双缓存只能采用软件方式。
例程源码如下:
Demo29_UART_DMA.zip
(2 MB)
|