串口通讯是嵌入式系统中最常用的通讯方式。
STM32的串口接收普通的方式是在串口读数据寄存器非空RXNE中断(Read data register not empty)中1个字节1个字节的接收串口数据,一帧数据的接收完成可以使用结束帧判断,也可以使用定时器计时当定时器溢出时认为一帧数据已经接收完成(一帧数据中各byte的时间间隔很短<1mS,因此可以将定时器设置为3mS溢出,在RXNE中断中清0定时器,若产生定时器溢出中断表明已经3mS没有接收到数据了,判定已结束一帧数据接收)。
如上方式每一个字节的接收都会触发RXNE中断进行接收字节的保存,因此若一直接收数据会占用较多的CPU时间,从而影响其它业务程序的执行。比较好的方式是使用DMA+串口空闲中断实现数据的接收,STM32只需要进一次中断即可。直接存储器存取(DMA)是用来提供在外设和存储器之间或者存储器和存储器之间的高速数据传输。无须CPU干预,数据可以通过DMA快速地移动,从而可以节省CPU的资源来做其他操作。
工具准备:
STM32CubeMX(Verison5.6.1)
KEIL5(uVision V5.26.2.0)
正点原子潘多拉IOT开发板(芯片型号:STM32L475VET6,也可以使用其它STM32芯片)
设计需求:
- LED状态指示灯指示系统运行状态(正常为闪烁)
- 可实现串口DMA数据接收,并将接收到的数据原封不动的返回
硬件配置:
- 使用板载的绿色LED灯作为系统运行状态指示灯,硬件引脚为PE8
- 使用潘多拉IOT开发板开发板的USART1,硬件引脚为PA9(TX),PA10(RX)
USART1配置如下:
波特率:128000bps
数据位:8
校验位:无
停止位:1
<Part 1 工程生成>
1、打开STM32CubeMX后选择Start My Project from MCU
2、根据芯片型号创建工程
3、选择系统时钟源为外部晶振(可自由配置)
这里需要解释的是选择外部高速时钟HSE时有2个时钟源选项。其中Crystal/Ceramic Resonator表示使用晶振/陶瓷振荡器,Bypass Clock Sourc表示使用旁路时钟源,即不使用晶振,外部直接供给一个可靠的时钟源。
4、配置程序的调试方式,一般选JTAG或SWD(根据自己项目的调试方式选就可以)
5、配置系统时钟频率,最终配置系统时钟频率为80MHz
6、配置USART1基本信息
7、配置USART1 DMA接收
需要配置的模式为USART1接收DMA,方向从外设到内存(即将USART1接收到的数据搬运到用户定义的内存空间中),数据宽度为1Byte,DMA的优先级设置为High,模式为Normal即搬运完用户指定的字节数后停止DMA工作,Circle循环模式则在搬运完成后又从头开始搬运,因此循环接收时会覆盖掉用户定义的内存空间中保存的之前接收到的数据。
8、设置USART1中断优先级
NVIC在此处默认为4bit为抢占优先级,0bit为从优先级,即不支持配置从优先级,抢占优先级的配置范围为0~15(0优先级为最高,此处将串口中断优先级设置为3,也算是优先级比较高了)
9、配置系统运行指示灯PE8的管脚信息
配置系统运行指示灯的意义在于,可以直观的观察到程序是否正常运行。这里需要注意的是,在GPIO端口被配置为输出时,其弱上拉和弱下拉电阻是不可用的。
10、配置工程生成相关配置
<Part 2 工程修改>
需要修改的文件有如下几个:
main.c
usart.c
usart.h
stm32l4xx_it.c
main.c中修改部分如下红框所示: