凡亿教育-柚子
凡事用心,一起进步
打开APP
公司名片
凡亿专栏 | 【STM32 cubemx】0006 HAL库开发:uart串口和DMA传输
【STM32 cubemx】0006 HAL库开发:uart串口和DMA传输

stm32这款强大的单片机,有更多的用法可以实现高效的串口收发,本节我们就介绍使用DMA传输串口数据。


先简单介绍一下DMA,DMA全称为:Direct Memory Access,即直接存储器访问。它可以独立地将数据从一个地址空间复制到另外一个地址空间,而不占用CPU的资源。

DMA尤其在高速、大容量的数据传输时特别有用:如果使用中断传输,CPU会在传输数据的一段时间内多次进入中断处理,也会占用很多CPU的时间;而使用DMA,CPU只用作一些初始化操作,之后DMA会自动将数据从一个地址复制到另一个地址,数据量很大时,能减轻很多CPU的工作。


1)cubemx生成代码

首先还是在cubemx中生成代码,选择器件、设置SYS(调试接口)、设置RCC(外部晶振时钟源)。

然后设置串口引脚,选择uart1,异步串口,选完后,已经使用的串口引脚PA9和PA10会变成绿色;然后选择开启串口全局中断(使用DMA时中断一定要打开):

5bd47d1be24f94960d6a28a1bba44a.jpg

然后,设置DMA,在DMA选项卡下面,添加RX和TX,然后将RX的mode改成Circular,

即设置为循环接收:(其他参数,可以选择地址自增、数据宽度等等,这里都默认)

6ed0c42dcb88cf2af394e3c83bdf41.jpg


之后,在时钟选项卡设置主时钟为72M;在project Manager选项卡设置工程名和路径,生成工程代码。


2)HAL库函数的使用

生成的工程中,已经有比较完善的初始化代码。

发送时,可以直接调用HAL_UART_Transmit_DMA函数实现,如下图:

直接使用DMA发送了16个字节的数据,这里我们看一下效果,在发送之后直接设置断点。我们前面讲的中断发送,如果在发送函数之后直接断点停止的话,一般只能发出两个字节的数出来,后面的要等程序跑起来,进中断处理后才能发出来。而DMA发送,可以看到,它是不受断点影响的,即使CPU被断点中断,数据仍然可以都发出来,图中看以看到16个数据都发送完了。

dda01ba6fdc09f22497822c5cc4941.jpg


接收时,可以调用HAL_UART_Receive_DMA函数,如下图:

这里我们可以在断点停止时,用串口调试助手发送20个字节数据,当再次运行时,可以看到rx_data里的数据发生了变化,说明DMA在CPU未运行时也在收数据。

另外,还可以看到,因为设置了循环收16个字节,但是发送了20个字节,所以16个字节之后的4个字节又覆盖了头4个字节:

629257981547d003332d233d173b2f.jpg


3)接收程序改写

HAL库生成的DMA的接收/发送函数,与中断的函数一样,有以下特点:发送时如果上一次的数据还未发完,则本次数据不会发送,仍然继续发送上一次未发完的数据。接收数据要提前设定长度,未达到长度返回,不方便使用。

好在发送的时间点是可以由软件控制的,所以发送时的矛盾并不特别突出。而接收不行,接收时程序并不知道外界什么时候会发数过来,也不知道每次发多少个,所以一般会改写接收的函数,使用空闲中断结合DMA来接收数据,具体做法是:

打开串口的空闲中断;打开DMA接收,接收长度设为一个较大的值,保证不会被填满;当空闲中断产生时,说明一段数据已收完,此时把数据拷贝走,并再次开启DMA接收。

由于每收完一段数据都会产生空闲,在空闲时能产生中断进行处理,所以可以实现不定长度的数据接收。

代码实现如下:

首先添加初始化函数,开启接收中断、空闲中断,打开DMA接收(这里接收数组设置为32字节,一般建议设置大一点,确保不会溢出):

0c1010b561ed841542ce46f54b4979.jpg


在中断服务函数中添加如下:

这部分代码的作用是:检查是否是空闲中断,如果是,则获取已经接收的字节数,并置标志位;然后再次打开接收中断、开启DMA接收。

这里注意一下长度的获取,是用设置的最大长度减去未填充的空间得到的。

423c98bf21f17f3b48cfa924b054e4.jpg


主循环中,只要检测标志位,然后将已收到的数据处理完即可(这里是将数据发回)。

56eb0789fd0935a48cdc1f2cf1f3b2.jpg


运行后用串口调试助手发数和接收,可以看到与预期一致:

fe04bddaad8b742b203fe04837b3dd.jpg

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表凡亿课堂立场。文章及其配图仅供工程师学习之用,如有内容图片侵权或者其他问题,请联系本站作侵删。
相关阅读
进入分区查看更多精彩内容>
精彩评论

暂无评论