1STM32微控制器介绍
STM32系列微控制器是ST公司基于Cortex-M3内核的高集成度的微控制器。它在性能、价格、功耗和实时性方面树立了一个新的标杆,集成了Cortex-M3内核,以及双ADC、多用途的通用时钟TIMx、RTC、I2C、SPI、UART、CAN、DMA、USB等丰富的外设。其功耗在全速72MHz所有模块都打开时也仅仅为36 mA,在低功耗模式下其功耗仅为2μA。
2 DMA和TIMx简介
STM32系列微控制器均含有DMA和通用时钟TIMx模块。其低端型号中仅包含DMA1,支持7个通道;高端型号还包括DMA2,支持5个通道。它的每个通道可任意指定工作模式,如内存到内存、内存到外设或外设到内存等。当涉及到外设时,一般是由外设来触发DMA的一次传输,如串口收到数据的标志位可触发DMA。
DMA的每次传输都分为4个阶段:申请仲裁、地址计算、总线存取和应答。除总线存取阶段,其他3个阶段都只需要一个系统周期,并且不占用总线,可在DMA控制器内部并发地执行。总线存取阶段,每个字(4字节)的传输需要3个系统周期。DMA和CPU工作在交替方式下,不会相互阻塞。DMA各个通道可独立设置优先级,当访问同一资源时高优先级通道先获得资源。
DMA的使用比较简单,每路DMA仅包括4个寄存器,用于指定DMA的工作模式、源地址、目标地址和传输次数。ST公司提供了很好的驱动库,简化了外设的使用,方便阅读和移植。本文采用库函数来展示功能。
其通用时钟是很有特色的外围模块,可实现多种复杂的功能。时钟模块内部主要包含一个计数器和4个通道的比较/捕获寄存器。时钟可工作在捕获或比较模式。在捕获模式下,若有对应的触发信号,计数器的值会保存到比较/捕获寄存器,并触发中断或DMA;在比较模式下,若计数器的值与比较/捕获寄存器的值相等,则对外输出预选设定好的信号,如高电平、低电平或电平反转等。
3 采用DMA+TIMx实现多路方波的产生
采用时钟的4个比较/捕获通道加DMA可以产生出4路不同频率和占空比的方波。这里为简化篇幅,只列出了产生一路方波的代码。基本原理是:将时钟的4个通道设置为反转模式(即计数器与比较捕获寄存器相等时,其对应的CPU引脚电平发生反转),设置计数器为向上计数到0xFFFF的模式;然后预先计算好需要引脚反转的时刻,并使能对应通道的DMA请求。这样,当计数器与比较/捕获寄存器的值相等时,由DMA将下一个需要引脚电平反转的时刻送入到比较/捕获寄存器。
这里将DMA设置为从内存到外设的半字(2个字节)环形传输。开启DMA全满和半满中断,在中断处理函数中不断填充新的时刻值,即可保证产生的波形不间断。假设存放时刻值的缓冲长度为N,则每N/2个点才中断一次,这样CPU就不需要频繁进入中断,执行效率比较高。由此也可以看出,缓冲越大,对中断响应的实时性要求也越低,当然这时中断的处理时间也越长。以下为示例代码:
需要注意的是,比较/捕获寄存器的预加载功能必须禁止掉。我们需要的是写入比较/捕获寄存器的值立即与计数器相比较输出,而无需等待一个更新事件。
4 采用DMA+TIMx实现多路方波的捕获
假设有一个方波需要记录并分析。一种方案是设置CPU引脚在上升沿和下降沿中断,然后在中断中记录该时刻。这种处理方式的实时性和效率会差一些,因为进出中断本身就需要一定的指令周期(Cortex-M3为12+12或6+12个系统周期),而且需要考虑多个中断同时发生的最坏情况,对可检测方波的最大频率有一定的限制。另一种方案是采用轮询的方式不断查询该引脚的状态并记录上升沿和下降沿的时刻,这种方式下系统几乎不能处理其他的任务了。
采用DMA+TIMx的方式来捕获上升沿和下降沿时刻,有利于提高系统的实时性和执行效率。通过TIMx的捕获功能将方波的电平跳变时刻记录在比较/捕获寄存器中,然后DMA将该值自动传输到内存,只有当DMA触发半满或全满事件时CPU才需要进入中断处理数据。通过记录方波的上升沿和下降沿时刻,然后将两个时刻相减,进而就能得到所有低沿和高沿的宽度,最后进行后续的分析处理。这种方式下中断频率仅为方波频率的4/N(N为缓冲区大小)。
图1为TIMx工作在捕获模式下一个通道的示意图。
其中TI1为CPU引脚的输入,经过滤波(新的电平必须保持一定时间才认为有效,以防止高频噪声的干扰)后进入后继的边沿极性选择,最后经过分频作为捕获信号的输入。这里TI2F为相邻通道经过滤波后的信号,也就是说一个引脚的信号可作为TIMx两个通道的输入捕获信号,这样信号只需要接一个CPU引脚就可以触发两个时钟通道了。
将输入方波接到CPU一个引脚上,假设该引脚对应于图上的TI1,设定其在下降沿触发通道1的捕获事件,而其在上升沿触发通道2的捕获事件,事件发生后申请DMA将捕获的比较/捕获寄存器的值保存起来。示例代码如下:
其他部分与第3节中比较输出的代码基本一致。
5 总结
测试中STM32系列微控制器工作在36MHz,可产生出1路最高1.5MHz的方波,可捕获1MHz的方波,而此时CPU的执行几乎不受影响。这里采用DMA来实现方波的产生和捕获,极大地提高了系统的实时性和执行效率,减少了中断次数,节省了宝贵的资源。这种方案也可以用来实现高效的模拟串口。
DMA的传输需要多个系统周期的,例如采用DMA实现内存到内存的搬移,每次传输需要5个系统周期,而内存到外围的一次传输需要2个APB周期+5个AHB周期。这样用上述方法产生的方波最小沿(低沿或高沿)为14个周期(包括比较/捕获寄存器到内部影子寄存器的传输等)。若有更高的需求,应考虑其他的实现方案。另外,若有多个DMA同时工作,应考虑最坏情况下DMA的响应时间,以避免错误发生。