STM32产生任意波形的一种实现思路(以产生5k赫兹的方波 STM32F103RCT6,HAL库开发为例)

本文的实现思路为DAC+DMA+TIMER 的方法产生任意波形

基本思路

​ DDS的原理,通过在STM32中,存储一个完整周期的信号波形,并以等间隔时间将波形数据输出,即可得到预期的波形

​ 我们在一个完整周期内取100点,用着100点来描述一个完整的周期信号

​ 1、我们需要$$5KHz*100 = 500KHz $$ 的时间间隔——定时器以$$\frac{1}{500KHz}$$的时间间隔输出单个的波形数据,不断重复即可得到频率为5K赫兹的波形。

​ 2、在长度为100的波形数组中,定义前50个数据为0,后50个数据为1,形成一个完整的单周期方波信号。

​ 3、定时器循环的输出方波数组中的波形数据即可得到的5KHz的方波。

程序流程

STM32产生任意波形的一种实现思路(以产生5k赫兹的方波 STM32F103RCT6,HAL库开发为例)

STM32的TIM、TRGO事件

​ STM32中有三类定时器:高级定时器、通用定时器、基本定时器。三类定时器都可以产生触发事件(TRGO),所以使用任意一种定时器即可,这里以使用基本定时器为例。

STM32产生任意波形的一种实现思路(以产生5k赫兹的方波 STM32F103RCT6,HAL库开发为例)

当定时器发生溢出时,可以通过触发控制器产生TRGO事件。

STM32产生任意波形的一种实现思路(以产生5k赫兹的方波 STM32F103RCT6,HAL库开发为例)

​ 可以看到当定时器发生上溢时,将产生更新事件,在CubeMX中可以配置

STM32产生任意波形的一种实现思路(以产生5k赫兹的方波 STM32F103RCT6,HAL库开发为例)

上文的基本思路里面我们已经知道,定时器需要定时$$\frac{1}{500KHz}$$的时间,TIM6挂接在系统APB1总线,

APB1总线的时钟频率为$$18Mhz$$ ,根据定时器时间计算公式:

\(T(s) = \frac{(ARR+1)*(PSC+1)}{TIM_CLK(Hz)}\)

\(f(Hz) = \frac{TIM_CLK(Hz)}{(ARR+1)*(PSC+1)} = \frac{18MHz}{(5+1)*(5+1)} = 500KHz\)

STM32DAC触发方式下的DMA传输

根据参考手册中

STM32产生任意波形的一种实现思路(以产生5k赫兹的方波 STM32F103RCT6,HAL库开发为例)

可知,当有外部触发DAC转换时,DAC会先产生一个DMA请求,更新DAC_DORx寄存器,更新完成后再进行DA转换

在CubeMX中的设置如下:

DAC触发启动:

STM32产生任意波形的一种实现思路(以产生5k赫兹的方波 STM32F103RCT6,HAL库开发为例)

DAC的DMA配置:

STM32产生任意波形的一种实现思路(以产生5k赫兹的方波 STM32F103RCT6,HAL库开发为例)

主程序的编写

1、构建波形数据:

STM32产生任意波形的一种实现思路(以产生5k赫兹的方波 STM32F103RCT6,HAL库开发为例)

2、在初始化后开启定时器、开始DMA转换:

STM32产生任意波形的一种实现思路(以产生5k赫兹的方波 STM32F103RCT6,HAL库开发为例)

3、切换波形

​ 在这里使用按键KEY0来控制波形的切换,当按键按下产生外部中断,在中断中处理波形

STM32产生任意波形的一种实现思路(以产生5k赫兹的方波 STM32F103RCT6,HAL库开发为例)

总结

​ 不同于以往,我一般使用定时器定时,到时间后,手动执行DA转换,这次使用定时器触发,DMA传输波形数据来完成DA转换。

​ 之前在看B站上,有人通过定时器定时,在定时中断中执行AD转换,获取波形数据,做了一个数字示波器,在比赛中,我尝试使用DMA来控制AD转换,思路是在DMA转换完成的中断中,重启DMA,最后并没有达到效果,今天使用DAC同触发的方式实现了波形,输出,是不是也可以通过同样的思路实现ADC的采集呢?
STM32产生任意波形的一种实现思路(以产生5k赫兹的方波 STM32F103RCT6,HAL库开发为例)

ADC也可以通过触发方式启动,,,,

​ 可见,嵌入式编程是与硬件有关的编程,有时候自己的想法并不一定与硬件的设计思路相吻合,还是要多多学习。

上一篇:Linux开发STM32H7系列教程之二《手动配置H743XIH6工程》


下一篇:[学习笔记]STM32F1串口重定义printf+数据类型的范围(寄存器、标准库、HAL库)