STM32F0XX DMA串口发送数据

简介: 最近在接手一个安排的时候,需要修改之前的一些代码的外设接口,然后发现之前有部分关于USART通过DMA收发数据的部分功能,修改移植的时候发现有些需要注意的事项,以及解释的,做一篇小笔记吧,博主使用的单片机是STM32f071。
**前言:**

最近在接手一个安排的时候,需要修改之前的一些代码的外设接口,然后发现之前有部分关于USART通过DMA收发数据的部分功能,修改移植的时候发现有些需要注意的事项,以及解释的,做一篇小笔记吧,博主使用的单片机是STM32f071。


USART有三种模式进行传输:轮询、中断、以及DMA。

轮询模式

CPU不断查询IO设备,如设备有请求则加以处理。例如CPU不断查询串口是否传输完成,如传输超过则返回超时错误。轮询方式会占用CPU处理时间,效率较低。

中断控制方式

当I/O操作完成时,输入输出设备控制器通过中断请求线向处理器发出中断信号,处理器收到中断信号之后,转到中断处理程序,对数据传送工作进行相应的处理。

直接内存存取技术(DMA)方式

所谓直接传送,即在内存与IO设备间传送一个数据块的过程中,不需要CPU的任何中间干涉,只需要CPU在过程开始时向设备发出“传送块数据”的命令,然后通过中断来得知过程是否结束和下次操作是否准备就绪。

· 如果没有多操作过,可以用STM32CubeMX进行快速配置哈,这是之前学习CubeMX时候看到教程,很精简,点击进入链接。

串口的基本配置大家可以看哈野火老哥的教程,很扎实很细致。

首先配置好需要用的usartx:4edc953e2c684bbe819ffa954c899c08.png

时钟配置,开启gpio、usart、dma时钟.4edc953e2c684bbe819ffa954c899c08.png

IO配置为需要的模式.**注意:**f0系类的MCU配置复用功能的时候需要配置GPIOx_AFR寄存器,此在数据手册查询到PD5 PD6引脚默认复用功能引脚便是USART2,所以此处便可以省略配置,但是其他时候大家配置的时候记得进行查询在进行配置.4edc953e2c684bbe819ffa954c899c08.png

数据手册查询位置4edc953e2c684bbe819ffa954c899c08.png

此处为stm32f0开发手册GPIO寄存器配置查询4edc953e2c684bbe819ffa954c899c08.png

usart2外设配置

利用DMA通道发送接收串口时候,收发是分离的。


DMA的发送有几个步骤.

1.在数据发送缓冲区内放好要发送的数据,说明:此数据缓冲区的首地址必须要在DMA初始化的时候写入到DMA配置中去。

2. 将数据缓冲区内要发送的数据字节数赋值给发送DMA通道,(串口发送DMA和串口接收DAM不是同一个DMA通道)

3.开启DMA,一旦开启,则DMA开始发送数据,说明一下:在KEIL调试好的时候,DMA和调试是不同步的,即不管Keil 是什么状态,DMA总是发送数据。

3. 等待发送完成标志位,即下面的终端服务函数中的第3点设置的标志位。或者根据自己的实际情况来定,是否要一直等待这个标志位,也可以通过状态机的方式来循环查询也可以。或者其他方式判断数据发送完成.


DMA的接收步骤

串口接收DMA在初始化的时候就处于开启状态,一直等待数据的到来,在软件上无需做任何事情,只要在初始化配置的时候设置好配置就可以了。

判断数据数据接收完成:

这里判断接收完成是通过串口空闲中断的方式实现,即当串口数据流停止后,就会产生IDLE中断。这个中断里面做如下几件事:

1.关闭串口接收DMA通道,2点原因:1>.防止后面又有数据接收到,产生干扰。2>.便于DMA的重新配置赋值,下面第4点。

2. 清除DMA 所有标志位

3. 从DMA寄存器中获取接收到的数据字节数

4. 重新设置DMA下次要接收的数据字节数,注意,这里是给DMA寄存器重新设置接收的计数值,这个数量只能大于或者等于可能接收的字节数,否则当DMA接收计数器递减到0的时候,又会重载这个计数值,重新循环递减计数,所以接收缓冲区的数据则会被覆盖丢失。

5. 开启DMA通道,等待下一次的数据接收,注意,对DMA的相关寄存器配置写入,如第4条的写入计数值,必须要在关闭DMA的条件进行,否则操作无效。

说明一下,STM32的IDLE的中断在串口无数据接收的情况下,是不会一直产生的,产生的条件是这样的,当清除IDLE标志位后,必须有接收到第一个数据后,才开始触发,一断接收的数据断流,没有接收到数据,即产生IDLE中断。

此处文字是摘录别人的文字,大家可以看哈别人的文章,可以更好的学习一哈.附上链接.

虽然其他人写的很详细,但是博主用的使用是DMA移植发送形式,并没有在DMA通道的专用中断函数发送.

MCU中DMA有5个通道的,有7个通道的,博主使用的MCU是七个通道的,我们需要从stm32开发手册进行查询并配置对应的通道,这个很重要,记得,因为其他的配置都很常规,在这里配置的时候需要注意,因为配置一旦出错,就很容易出现hardfault.

串口接收DMA在初始化的时候就处于开启状态,一直等待数据的到来,在软件上无需做任何事情,只要在初始化配置的时候设置好配置就可以了。

判断数据数据接收完成:

这里判断接收完成是通过串口空闲中断的方式实现,即当串口数据流停止后,就会产生IDLE中断。这个中断里面做如下几件事:

关闭串口接收DMA通道,2点原因:1.防止后面又有数据接收到,产生干扰。2.便于DMA的重新配置赋值,下面第4点。

清除DMA 所有标志位

从DMA寄存器中获取接收到的数据字节数

重新设置DMA下次要接收的数据字节数,注意,这里是给DMA寄存器重新设置接收的计数值,这个数量只能大于或者等于可能接收的字节数,否则当DMA接收计数器递减到0的时候,又会重载这个计数值,重新循环递减计数,所以接收缓冲区的数据则会被覆盖丢失。

开启DMA通道,等待下一次的数据接收,注意,对DMA的相关寄存器配置写入,如第4条的写入计数值,必须要在关闭DMA的条件进行,否则操作无效。

说明一下,STM32的IDLE的中断在串口无数据接收的情况下,是不会一直产生的,产生的条件是这样的,当清除IDLE标志位后,必须有接收到第一个数据后,才开始触发,一断接收的数据断流,没有接收到数据,即产生IDLE中断。

4edc953e2c684bbe819ffa954c899c08.png

DMA处查询usart2_通道为ch4,或者可以通过Remap到ch7进行发送数据.4edc953e2c684bbe819ffa954c899c08.png

由于数据发送的时候,尚未发送完成就执行完函数,所以加上发送完成标志完成判断,然后再清除掉标志.

DMA通道配置函数,配置之后就可以使用此函数了.4edc953e2c684bbe819ffa954c899c08.png

主函数调用

4edc953e2c684bbe819ffa954c899c08.png

串口打印显示

但是Remap请慎用,有些MCU是没有此项功能的.博主最早之前就是想用Remap,没有主要此处,所以造成了发送一直显示只能发送第一个byte.4edc953e2c684bbe819ffa954c899c08.png

示范一个错误案例:没有查询是否可以DMA Remap就直接进行Remap

4edc953e2c684bbe819ffa954c899c08.png4edc953e2c684bbe819ffa954c899c08.png4edc953e2c684bbe819ffa954c899c08.png

**结语:**大家写的时候一定多多注意,希望可以帮到大家,写的比较匆忙,好多知识点就不写了,CSDN等等大家都总结的很详细.

目录
相关文章
|
1月前
|
传感器
【STM32】I2C练习,SHT3X温度传感器的数据读取
【STM32】I2C练习,SHT3X温度传感器的数据读取
|
7月前
STM32串口编程基础知识讲解
STM32串口编程基础知识讲解
59 0
|
2月前
|
存储 缓存 芯片
STM32--USART串口
STM32--USART串口
|
2月前
|
Java C语言
STM32使用printf重定向到USART(串口)并打印数据到串口助手
STM32使用printf重定向到USART(串口)并打印数据到串口助手
46 0
|
7月前
|
存储 物联网 芯片
STM32速成笔记(十四)—串口IAP
本文介绍了什么是IAP,IAP有什么作用,如何实现IAP。最后,给出了IAP的实现程序。
122 0
STM32速成笔记(十四)—串口IAP
|
8月前
STM32F0单片机快速入门七 串口(UART)操作从轮询到中断
STM32F0单片机快速入门七 串口(UART)操作从轮询到中断
STM32F0单片机快速入门七 串口(UART)操作从轮询到中断
|
1月前
【STM32】基于HAL库的360度编码器、摇杆代码编写
【STM32】基于HAL库的360度编码器、摇杆代码编写
|
3月前
|
C++ 芯片 编译器
STM32F103标准外设库—— 新建工程与库函数(四)
STM32F103标准外设库—— 新建工程与库函数(四)
51 0
STM32F103标准外设库—— 新建工程与库函数(四)
|
3月前
|
传感器 芯片 内存技术
STM32F103标准外设库——认识STM32(一)
STM32F103标准外设库——认识STM32(一)
114 0
STM32F103标准外设库——认识STM32(一)