本文的实现思路为DAC+DMA+TIMER 的方法产生任意波形
基本思路
DDS的原理,通过在STM32中,存储一个完整周期的信号波形,并以等间隔时间将波形数据输出,即可得到预期的波形
我们在一个完整周期内取100点,用着100点来描述一个完整的周期信号
1、我们需要$$5KHz*100 = 500KHz $$ 的时间间隔——定时器以$$\frac{1}{500KHz}$$的时间间隔输出单个的波形数据,不断重复即可得到频率为5K赫兹的波形。
2、在长度为100的波形数组中,定义前50个数据为0,后50个数据为1,形成一个完整的单周期方波信号。
3、定时器循环的输出方波数组中的波形数据即可得到的5KHz的方波。
程序流程
STM32的TIM、TRGO事件
STM32中有三类定时器:高级定时器、通用定时器、基本定时器。三类定时器都可以产生触发事件(TRGO),所以使用任意一种定时器即可,这里以使用基本定时器为例。
当定时器发生溢出时,可以通过触发控制器产生TRGO事件。
可以看到当定时器发生上溢时,将产生更新事件,在CubeMX中可以配置
上文的基本思路里面我们已经知道,定时器需要定时$$\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传输
根据参考手册中
可知,当有外部触发DAC转换时,DAC会先产生一个DMA请求,更新DAC_DORx寄存器,更新完成后再进行DA转换
在CubeMX中的设置如下:
DAC触发启动:
DAC的DMA配置:
主程序的编写
1、构建波形数据:
2、在初始化后开启定时器、开始DMA转换:
3、切换波形
在这里使用按键KEY0来控制波形的切换,当按键按下产生外部中断,在中断中处理波形
总结
不同于以往,我一般使用定时器定时,到时间后,手动执行DA转换,这次使用定时器触发,DMA传输波形数据来完成DA转换。
之前在看B站上,有人通过定时器定时,在定时中断中执行AD转换,获取波形数据,做了一个数字示波器,在比赛中,我尝试使用DMA来控制AD转换,思路是在DMA转换完成的中断中,重启DMA,最后并没有达到效果,今天使用DAC同触发的方式实现了波形,输出,是不是也可以通过同样的思路实现ADC的采集呢?
ADC也可以通过触发方式启动,,,,
可见,嵌入式编程是与硬件有关的编程,有时候自己的想法并不一定与硬件的设计思路相吻合,还是要多多学习。