經(jīng)常有人想利用STM32定時器輸出一些任意波形來滿足應(yīng)用需求。比方最近有人在某論壇發(fā)帖咨詢想使用STM32芯片的TIM1實現(xiàn)如下4路特征的驅(qū)動波形?!鞠旅娌ㄐ沃划嫵隽藘蓚€周期】
通過觀察不難看出,四路波形是有規(guī)律的周期性波形。不過除了/B路外,其它三路不太容易通過定時器PWM輸出模式來簡單實現(xiàn)。
我們知道,對于STM32常規(guī)定時器,其比較輸出功能較常用的輸出模式主要是PWM輸出模式和比較輸出切換模式。其中PWM輸出模式是指定時器輸出控制單元根據(jù)計數(shù)器的值與比較寄存器的值的比較結(jié)果來決定輸出電平的高低。而比較輸出切換模式是指定時器輸出控制單元在計數(shù)器的值與比較寄存器的值匹配相等時,做輸出電平的切換。即如果發(fā)生匹配之前是高電平的,發(fā)生匹配時輸出電平切換為低電平。反之亦然。
結(jié)合到本案例,對于A路、/A路及B路輸出波形我們就可以考慮使用比較輸出切換模式來實現(xiàn)。
我們這里假設(shè)定時器的計數(shù)器采用向上計數(shù)模式,每記800個時鐘單位為1個計數(shù)周期?!鞠蛏嫌嫈?shù)模式,ARR=800-1】
對于A路,當(dāng)CCR=200和 CCR=700時發(fā)生輸出切換,這樣周期性的修改CCR的值,從而實現(xiàn)目前所期望的輸出波形。此時我們可以使用比較事件觸發(fā)DMA,通過DMA將下次要用來做比較的數(shù)據(jù)從內(nèi)存?zhèn)鞯较鄳?yīng)通道的CCR寄存器。
同理,對于/A路,當(dāng)CCR=300和 CCR=600時發(fā)生輸出切換。同樣開啟該通道的比較事件觸發(fā)DMA傳輸,實現(xiàn)CCR寄存器的數(shù)據(jù)循環(huán)更新。
同樣,對于B路,參照上面的相同做法。當(dāng)CCR=100和CCR=400時做輸出切換。
至于最后的/B路,可以跟上面一樣采用比較輸出切換模式。不過,該通道直接使用PWM輸出模式更方便,具體到這里我們可以使用PWM2輸出模式,CCR=500.
下面是基于STM32F4系列芯片的TIM1來實現(xiàn)上述輸出波形的配置及相關(guān)用戶代碼介紹。其中,代碼是基于STM32CUBE庫。
一、基于上述分析,使用STM32CubeMx來完成基本的初始化配置。
從上面兩幅圖我們可以看出,TIM1的通道1/2/3都被配置為比較輸出切換模式。通道4被配置PWM2輸出模式?!玖硗猓⒁庀峦ǖ?/2/3三個比較輸出通道的初始比較值?!?/p>
前面說了,我們要利用各通道的比較事件觸發(fā)DMA做CCR寄存器的數(shù)據(jù)更新,所以需做基于各個通道比較事件的DMA配置。見下圖,各通道CCR寄存器的數(shù)據(jù)更新都使用循環(huán)模式。
2、準備或編寫用戶應(yīng)用代碼。
2.1 準備3個數(shù)組,對應(yīng)存放用來動態(tài)更新3個比較輸出通道CCR值的數(shù)據(jù)。數(shù)據(jù)的擬定請結(jié)合上面的介紹和待實現(xiàn)的波形特征。
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 關(guān)閉通道1/2/3的比較寄存器的預(yù)裝功能,即修改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允許相應(yīng)通道比較事件的DMA請求并開啟相應(yīng)通道的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, 啟動計數(shù)器計數(shù)。
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_4);
三、結(jié)果驗證。
經(jīng)過上面的準備之后,編譯運行工程代碼即可看到開篇所期望的結(jié)果?!鞠旅鎴D形是我使用MDK環(huán)境下的邏輯分析儀所得截圖,供參考】
好,到此上面案例就基本介紹完畢,全部配置及用戶代碼均貼出來了,供有需要的STM32用戶參考。
說實話,要徹底搞明白上述過程并實現(xiàn)它,需要對STM32定時器輸出比較切換模式原理、定時器的部分寄存器的預(yù)裝特性、比較事件、DMA傳輸有較為細致和深入的理解。不像使用PWM輸出模式給個CCR的值即可輸出PWM波形那么簡單。
最后補充兩點,上面波形的實現(xiàn)是基于STM32的TIMER1一個定時器來完成的。如果換成別的定時器一個定時器可能實現(xiàn)不了,可能要用到2個定時器。這時往往涉及到定時器的主從同步問題。其中的關(guān)鍵點就是要知道如何讓兩個定時器上下級聯(lián)并做同步啟動,實現(xiàn)上述輸出也是沒問題的。
還有一點,對于上述波形的實現(xiàn),如果我們使用STM32的高精度定時器實現(xiàn)起來就會更方便,STM32F334,STM32H7,STM32G4等系列都有高精度定時器。
-
單片機
+關(guān)注
關(guān)注
6037文章
44558瀏覽量
635408 -
STM32
+關(guān)注
關(guān)注
2270文章
10900瀏覽量
356092 -
定時器
+關(guān)注
關(guān)注
23文章
3248瀏覽量
114833
原文標題:STM32定時器比較輸出切換模式之應(yīng)用實例
文章出處:【微信號:stmcu832,微信公眾號:茶話MCU】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
評論