STM32中采用DMA实现方波的产生和捕获
1 STM32微控制器介绍
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就不需要频繁进入中断,执行效率比较高。由此也可以看出,缓冲越大,对中断响应的实时性要求也越低,当然这时中断的处理时间也越长。以下为示例代码:
需要注意的是,比较/捕获寄存器的预加载功能必须禁止掉。我们需要的是写入比较/捕获寄存器的值立即与计数器相比较输出,而无需等待一个更新事件。
评论