本文的實現思路為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也可以通過觸發方式啟動,,,,
可見,嵌入式編程是與硬件有關的編程,有時候自己的想法並不一定與硬件的設計思路相吻合,還是要多多學習。
