現(xiàn)在有如下圖所示的這樣一個需求,希望使用STM32芯片來實現(xiàn)。
橫軸表示時間,縱軸表示電壓【3.3v為限】,不同時刻的電壓輸出不一樣、持續(xù)時間也不盡相同。
此問題源于某高校STM32學習時的習題,這里拿出來一起交流探討下。方法不是唯一的,尤其基于不同STM32系列。這里盡量使用通用、常規(guī)的方法,算是拋磚引玉。
顯然,我們可以考慮使用STM32的DAC加TIMER以及片內(nèi)其它資源加以實現(xiàn)。
對于這個實現(xiàn)我們可以分兩種方式完成,每一種方式同時也體現(xiàn)不同難度。
我們可以考慮下面兩種應(yīng)用情形:
第一種方式:MCU除了做這一件事外,還做點別的,比方做按鍵響應(yīng)、ADC采樣這些,整體上沒有太復雜的功能和要求。【中斷方式】
第二種方式:MCU的主要工作是別的而不再是這個輸出了,要求該輸出自啟動后不再需要CPU的參與,即由相應(yīng)外設(shè)自行完成。【DMA方式】
對于第一種實現(xiàn)方式,我們可以用個TIMER作為時基,每到適當?shù)挠嫊r點就通過TIMER中斷及時修改DAC的輸出值而改變輸出電壓。至于對DAC輸出寄存器賦值,可以直接在定時器中斷里操作,也可以先在定時器中斷里設(shè)置標志位后在主循環(huán)里實現(xiàn)修改,可以靈活決定。顯然,這樣操作也不會影響其它按鍵處理、ADC處理等。該方式的實現(xiàn)就介紹到這里,重點聊聊第二種方式。
對于第二種方式,顯然不能使用中斷,這里就得DMA出場了。因為人家要求該輸出自啟動后不再讓CPU參與。這里有兩個量都是變的,DAC的輸出值在變,不同DAC輸出所持續(xù)的時間也在變。這兩個變量都需要DMA幫忙完成,顯然DAC的輸出需要使用TIMER事件來觸發(fā)DMA,這里使用更新事件比較合理。那么,TIMER自身的數(shù)據(jù)更新又如何實現(xiàn)呢?我們可以考慮使用TIMER的比較事件來觸發(fā)另外的DMA請求以更新自己。
下面我使用STM32F4系列芯片的TIM1及DAC來實現(xiàn)第二種需求。【當然,使用STM32其它系列,比如G4,H5,H7,U5等都可以】
TIM1的更新事件觸發(fā)DMA,修改DAC的輸出寄存器的值以改變輸出。另外,選擇TIM1通道1的比較事件觸發(fā)DMA【哪個通道比較事件不重要,能觸發(fā)DMA即可】,使用TIMER DMA Burst傳輸同時修改TIM1的ARR,RCR,CCR1三個寄存器的值,此處RCR始終用0值。因為這里要修改CCR1的值,RCR夾在ARR和CCR1寄存器中間,做Burst傳輸時RCR必須每次被使用。【這里CCR1的值其實也可以固定不變。我是每次取ARR的中間值作為CCR1的值,不是必須的。主要是考慮到有些應(yīng)用場合可能需要動態(tài)修改CCR值,在此特意拓展下TIMER Burst傳輸?shù)膽?yīng)用介紹。】
下面是關(guān)于TIM1時基參數(shù)的初始配置,其中ARR和CCR1值我是隨便設(shè)定的,算是個過渡值,目的就是產(chǎn)生更新事件和比較事件,之后都會按照代碼中預(yù)定的數(shù)據(jù)運行。
下面是有關(guān)TIM1的基于更新事件和通道1比較事件的DMA配置。
下面截圖是關(guān)于DAC的CubeMx配置,比較簡單,開啟其輸出功能即可。
下面截圖里的數(shù)組DacOutData[10]存放不同時刻DAC輸出所對應(yīng)的數(shù)據(jù)。數(shù)組PulseData3[30]存放10次DMA Burst 傳輸用到的數(shù)據(jù)。顯然這兩個數(shù)組數(shù)據(jù)在使用時間上要匹配,否則輸出波形對不了。
下面是具體的用戶代碼,使用CubeMx進行配置和STM32 HAL庫函數(shù),以源碼形式放在下面,供有需要的參考、使用。
HAL_DMA_Start_IT(&hdma_tim1_up, (uint32_t) DacOutData,
(uint32_t)&hdac.Instance- >DHR12R1, 10);
__HAL_TIM_CLEAR_FLAG(&htim1,TIM_FLAG_UPDATE);
__HAL_TIM_CLEAR_FLAG(&htim1,TIM_DMA_CC1);
HAL_TIM_DMABurst_MultiWriteStart(&htim1, TIM_DMABASE_ARR,
TIM_DMA_CC1,(uint32_t *)PulseData3,
TIM_DMABURSTLENGTH_3TRANSFERS,10*3);
__HAL_TIM_ENABLE_DMA(&htim1, TIM_DMA_UPDATE);
HAL_DAC_Start(&hdac, DAC_CHANNEL_1);
__HAL_TIM_ENABLE(&htim1);
-
mcu
+關(guān)注
關(guān)注
146文章
17135瀏覽量
351031 -
dac
+關(guān)注
關(guān)注
43文章
2291瀏覽量
190989 -
STM32
+關(guān)注
關(guān)注
2270文章
10896瀏覽量
355774
發(fā)布評論請先 登錄
相關(guān)推薦
評論