這里使用STM32G4系列Nucleo開發板演示如下需求的實現過程。
TIMER2使用3個通道的PWM輸出,占空比可能被不時修改。修改的數據通過UART傳輸過來,UART接收的數據通過DMA傳輸到內存。新的數據接收后,基于TIMER更新事件觸發DMA,利用TIMER的更新事件觸發DMA Burst 而一次性用新數據修改3個通道的CCR值以調整PWM輸出。每次新數據的接收允許以產生按鍵動作為準,即每次按鍵動作允許一次數據更新。
這里有兩點要注意,TIM2是32位定時器,3個CCR數據使用32位格式。另外,3個數據的修改基于更新事件一次性修改,不能出現混亂,即不可以某一個時刻3個CCR寄存器的數據不是來自同一批的。為了避免數據混亂這種情況,我這里平常禁止TIMER2的更新事件的產生,只有每次收到新數據后才臨時允許更新事件的產生,并在TIMER觸發的DMA完成中斷里再次禁止更新事件的產生。
使用LPUART從外部接收新數據,選用LPUART主要原因是它的TX/RX剛好跟G4Nucleo開發板的虛擬串口接在一起的,并無其它特別原因。至于按鍵就選用板載按鍵PC13,并開啟了對應的外部中斷。
大致的數據傳輸流程如下圖所示:
關于定時器更新事件的能否產生的控制由TIMER的控制寄存器里的UDIS位決定:
我在代碼里對該位的操作,寫成宏的方式,便于閱讀。
該位默認為0。若該位被軟件置1,定時器的更新事件將不能產生,意味著開啟預裝功能時,影子寄存器內容不能被更新,同時也不能因溢出操作、計數器復位操作而觸發相應中斷或DMA請求 。
測試代碼的里幾個主要的基本操作:
一、響應按鍵事件,啟動UART的DMA接收。
HAL_UART_Receive_DMA(&hlpuart1,(uint8_t*)CCR_rx, 12);
二、基于UART事件的DMA接收完成中斷,允許TIMER更新事件的產生,并啟動基于TIMER更新事件的DMA Burst 傳輸。
Permit_UpdateEvt; //Updated event permitted
HAL_TIM_DMABurst_MultiWriteStart(&htim2,TIM_DMABASE_CCR1,TIM_DMA_UPDATE,(uint32_t*)CCR_rx,TIM_DMABURSTLENGTH_3TRANSFERS,3);
三、基于TIMER事件的DMA完成中斷,禁止更新事件的產生,并基于串口通信提示可以接受下次數據更新。
__HAL_TIM_CLEAR_FLAG(&htim2,TIM_FLAG_UPDATE);
Forbid_UpdateEvt;//update event forbidden
Indicating_CCR_Updated();
再看看基本的CubeMx配置,配置比較簡單。下面是LPUART的配置貼圖。
我開啟LPUART 的DMA接收,其發送功能使用查詢阻塞模式,主要用來輸出一些提示信息。
下面是TIM2的一些基本配置截圖。開啟3個通道的PWM輸出和基于TIMER更新事件的DMA傳輸。
最后,我們來簡單驗證下。下面截圖就是通過串口助手鍵入新數據后TIMER的輸出結果。
整體上,操作流程就是每次按鍵操作提示可以修改占空比了;串口終端鍵入新的3個字的數據,基于UART接收事件的DMA傳輸完成后提示數據收到;基于TIMER事件的DMA完成完成后提示數據更新結束,提示等待下次按鍵動作。
好,今天的分享就到這里,下次再聊。如果有人想要完整的測試工程代碼的話,可以私下留言,只要時間不是過去太久且我這邊有保存的話,都可以分享供參考。
-
內存
+關注
關注
8文章
3019瀏覽量
74003 -
STM32
+關注
關注
2270文章
10895瀏覽量
355739 -
uart
+關注
關注
22文章
1235瀏覽量
101354 -
dma
+關注
關注
3文章
560瀏覽量
100546 -
開發板
+關注
關注
25文章
5032瀏覽量
97372
原文標題:STM32G4 UART+TIMER+DMA應用示例
文章出處:【微信號:stmcu832,微信公眾號:茶話MCU】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論