数据手册上写AT32WB415有3个USART和14个通道的2个DMA 但由于WB415采用MCU和蓝牙SOC合封方式,受封装限制导致管脚引出做了牺牲,且有些管脚作为了MCU和蓝牙SOC的内部连接使用,所以,实际可用的串口只有2.5个。
DMA支持固定请求映射和弹性请求映射,可以灵活的接到各种外设上 对MCU熟悉的人都应该清楚,串口常见的应用方式有查询 中断和DMA这几种,从对CPU占用角度看,DMA方式 < 中断方式 <查询方式。 我将介绍一种利用DMA实现双缓冲的高效串口收发方式,这种方式是建立在DMA基础上的,如果没有DMA就没法应用我这种方式了。为了实现双缓冲,我们需要利用DMA的如下特性 我要利用DMA的半传输和传输完成中断实现一次传输的2次相应过程,从而实现双缓冲,但由于DMA传输的次数是要预先设定的,对串口发送来说,还是没问题的,因为要发送的数据长度,你是知道的。但如果要接收不固定长度的数据,想要利用DMA来处理就比较麻烦了。如果遇到这种情况,就要用到串口本身的一种特性了 这里我要利用串口空闲中断弥补DMA不能接收不定长度数据的问题,当接收的数据没有达到触发DMA半传输和传输完成中断时,使用串口空闲中断来结束这帧数据的传输。整个收发方式的思路就是这样了,我们看看代码如何实现吧 由于整个方式都是在中断中实现的,main函数中主要是对DMA和串口的初始化。 以串口2为例,DMA配置如图所示。 将串口2的TX绑定到DMA1的CH1上,由于DMA支持弹性映射,也可以根据需求绑定到其他通道上,DMA发送完成中断这里没有开启,发送完成的处理我放到的串口发送完成中断中处理了,这里可以根据自己的需求修改。 将串口2的RX帮定到了DMA的CH2上,由于DMA支持弹性映射,也可以根据需求绑定到其他通道上。通道4的中断我开启了 半传输中断 和 传输完成中断,这样在大数据传输时就可以实现双缓冲的目的了。 dma_init_struct.memory_base_addr =(uint32_t)uart2_dma_buff.RX_BUFF.rx_buff;//内存地址 在CH2的内存地址设置这,我利用结构体将缓存区分为2个部分,正好与 半传输中断 和 传输完成中断 的数据缓存相对应。 其他具体细节见源码文件。 在配置串口时,先使能相关管脚的时钟和复用功能时钟,并配置相关NVIC中断使能。 串口2 tx配置到PA2上,rx配置到PA3上。 在串口初始化中,要开启 空闲中断 和 发送完中断 空闲中断是用来处理DMA接收无法处理的不定长度数据。发送完中断用于关闭发送。 DMA中断函数用到绑定串口接收的中断,中断内分为 半传输处理 和传输完处理,将DMA接收到内存的数据进行处理 串口中断内分为发送完中断和空闲中断,发送完中断很好理解,就是关闭发送的DMA通道即可。空闲中断是用来处理不满足DMA接收通道的数据,弥补DMA存在的不足。 WB415的USART1 USART2 USART3,都支持DMA, 将USART3使用DMA可以高效的实现与蓝牙SOC的通信。
|