經常有人想利用STM32定時器輸出一些任意波形來滿足應用需求。比方最近有人在某論壇發帖咨詢想使用STM32芯片的TIM1實現如下4路特征的驅動波形。【下面波形只畫出了兩個周期】
通過觀察不難看出,四路波形是有規律的周期性波形。不過除了/B路外,其它三路不太容易通過定時器PWM輸出模式來簡單實現。
我們知道,對于STM32常規定時器,其比較輸出功能較常用的輸出模式主要是PWM輸出模式和比較輸出切換模式。其中PWM輸出模式是指定時器輸出控制單元根據計數器的值與比較寄存器的值的比較結果來決定輸出電平的高低。而比較輸出切換模式是指定時器輸出控制單元在計數器的值與比較寄存器的值匹配相等時,做輸出電平的切換。即如果發生匹配之前是高電平的,發生匹配時輸出電平切換為低電平。反之亦然。
結合到本案例,對于A路、/A路及B路輸出波形我們就可以考慮使用比較輸出切換模式來實現。
我們這里假設定時器的計數器采用向上計數模式,每記800個時鐘單位為1個計數周期。【向上計數模式,ARR=800-1】
對于A路,當CCR=200和 CCR=700時發生輸出切換,這樣周期性的修改CCR的值,從而實現目前所期望的輸出波形。此時我們可以使用比較事件觸發DMA,通過DMA將下次要用來做比較的數據從內存傳到相應通道的CCR寄存器。
同理,對于/A路,當CCR=300和 CCR=600時發生輸出切換。同樣開啟該通道的比較事件觸發DMA傳輸,實現CCR寄存器的數據循環更新。
同樣,對于B路,參照上面的相同做法。當CCR=100和CCR=400時做輸出切換。
至于最后的/B路,可以跟上面一樣采用比較輸出切換模式。不過,該通道直接使用PWM輸出模式更方便,具體到這里我們可以使用PWM2輸出模式,CCR=500.
下面是基于STM32F4系列芯片的TIM1來實現上述輸出波形的配置及相關用戶代碼介紹。其中,代碼是基于STM32CUBE庫。
一、基于上述分析,使用STM32CubeMx來完成基本的初始化配置。
從上面兩幅圖我們可以看出,TIM1的通道1/2/3都被配置為比較輸出切換模式。通道4被配置PWM2輸出模式。【另外,注意下通道1/2/3三個比較輸出通道的初始比較值。】
前面說了,我們要利用各通道的比較事件觸發DMA做CCR寄存器的數據更新,所以需做基于各個通道比較事件的DMA配置。見下圖,各通道CCR寄存器的數據更新都使用循環模式。
2、準備或編寫用戶應用代碼。
2.1 準備3個數組,對應存放用來動態更新3個比較輸出通道CCR值的數據。數據的擬定請結合上面的介紹和待實現的波形特征。
uint16_t Data1_to_Comp[]={200,700}; //ch1
uint16_t Data2_to_Comp[]={600,300}; //ch2
uint16_t Data3_to_Comp[]={400,100}; //ch3
2.2 關閉通道1/2/3的比較寄存器的預裝功能,即修改CCR的值后立即生效,無須也不需等待更新事件。
__HAL_TIM_DISABLE_OCxPRELOAD(&htim1, TIM_CHANNEL_1);
__HAL_TIM_DISABLE_OCxPRELOAD(&htim1,TIM_CHANNEL_2);
__HAL_TIM_DISABLE_OCxPRELOAD(&htim1, TIM_CHANNEL_3);
2.3 開啟TIM1通道1/2/3的比較輸出功能。
TIM_CCxChannelCmd(TIM1,TIM_CHANNEL_1, TIM_CCx_ENABLE);
TIM_CCxChannelCmd(TIM1,TIM_CHANNEL_2, TIM_CCx_ENABLE);
TIM_CCxChannelCmd(TIM1,TIM_CHANNEL_3, TIM_CCx_ENABLE);
2.4允許相應通道比較事件的DMA請求并開啟相應通道的DMA傳輸功能。
hdma_tim1_ch1.State = HAL_DMA_STATE_READY;
HAL_DMA_Start_IT(&hdma_tim1_ch1,(uint32_t)Data1_to_Comp, (uint32_t)&TIM1->CCR1, 2);
__HAL_TIM_ENABLE_DMA(&htim1, TIM_DMA_CC1);
hdma_tim1_ch2.State= HAL_DMA_STATE_READY;
HAL_DMA_Start_IT(&hdma_tim1_ch2, (uint32_t)Data2_to_Comp, (uint32_t)&TIM1->CCR2,2);
__HAL_TIM_ENABLE_DMA(&htim1, TIM_DMA_CC2);
hdma_tim1_ch3.State= HAL_DMA_STATE_READY;
HAL_DMA_Start_IT(&hdma_tim1_ch3, (uint32_t)Data3_to_Comp,(uint32_t)&TIM1->CCR3, 2)
__HAL_TIM_ENABLE_DMA(&htim1, TIM_DMA_CC3);
2.5 使能TIM1通道4的PWM輸出功能并使能TIM1, 啟動計數器計數。
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_4);
三、結果驗證。
經過上面的準備之后,編譯運行工程代碼即可看到開篇所期望的結果。【下面圖形是我使用MDK環境下的邏輯分析儀所得截圖,供參考】
好,到此上面案例就基本介紹完畢,全部配置及用戶代碼均貼出來了,供有需要的STM32用戶參考。
說實話,要徹底搞明白上述過程并實現它,需要對STM32定時器輸出比較切換模式原理、定時器的部分寄存器的預裝特性、比較事件、DMA傳輸有較為細致和深入的理解。不像使用PWM輸出模式給個CCR的值即可輸出PWM波形那么簡單。
最后補充兩點,上面波形的實現是基于STM32的TIMER1一個定時器來完成的。如果換成別的定時器一個定時器可能實現不了,可能要用到2個定時器。這時往往涉及到定時器的主從同步問題。其中的關鍵點就是要知道如何讓兩個定時器上下級聯并做同步啟動,實現上述輸出也是沒問題的。
還有一點,對于上述波形的實現,如果我們使用STM32的高精度定時器實現起來就會更方便,STM32F334,STM32H7,STM32G4等系列都有高精度定時器。
-
單片機
+關注
關注
6032文章
44525瀏覽量
633261 -
STM32
+關注
關注
2266文章
10876瀏覽量
354929 -
定時器
+關注
關注
23文章
3241瀏覽量
114516
原文標題:STM32定時器比較輸出切換模式之應用實例
文章出處:【微信號:stmcu832,微信公眾號:茶話MCU】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論