引言
最近在一個(gè)支持客戶的項(xiàng)目中,客戶工程師向我提出了一個(gè)需求,希望能實(shí)現(xiàn)使用YTM32微控制器,對(duì)輸出的PWM信號(hào),每30個(gè)周期觸發(fā)一次中斷,用于調(diào)整占空比,這樣便于動(dòng)態(tài)調(diào)整向目標(biāo)的控制量。來活了,開搞。
分析問題
一開始我能想到的實(shí)現(xiàn)方式,是使用軟件直接對(duì)產(chǎn)生PWM信號(hào)的eTMR模塊的Overflow中斷進(jìn)行計(jì)數(shù)。但客戶工程師King提到,需要輸出的PWM信號(hào)頻率可能會(huì)比較高,頻繁進(jìn)出eTMR的中斷會(huì)影響CPU運(yùn)行控制算法的效率,希望能夠通過硬件機(jī)制實(shí)現(xiàn)。
eTMR的調(diào)試模式Modulization
此時(shí),我最初想到的是利用eTMR輸出信號(hào)的調(diào)制模式(Modulization)。調(diào)試模式實(shí)際上是將相互調(diào)制的兩個(gè)輸出信號(hào)進(jìn)行邏輯與,然后再輸出。此時(shí),使用兩路PWM,一路作為載波信號(hào),另一路作為包絡(luò)信號(hào),控制載波信號(hào),可以實(shí)現(xiàn)調(diào)輸出控制信號(hào)占空比的功能(直流電機(jī)控制算法中調(diào)整負(fù)載驅(qū)動(dòng)能力的過程中就用到了類似的思路)
26.4.16 Modulation Implementation The eTMR0 and supports channel outputs modulated by eTMR1 channel 1 output. The eTMR3 supports channel outputs modulated by eTMR2 channel 1 output. Any of the 8 channels of eTMR0 and eTMR3 can be configured to support this modulation function. This function is enabled by configuring CIM_ETMROPT1[ETMR0_CHxOUTSEL] and CIM_ETMROPT1[ETMR3_CHxOUTSEL]. See ETMR0 Output Modulation Select and ETMR3 Output Modulation Select for details.
但King提到,當(dāng)前使用的YTM32B1MD14芯片的四個(gè)eTMR都被他用掉了,沒有額外的eTMR可以專門用來產(chǎn)生載波信號(hào)(或者包絡(luò)信號(hào))。同時(shí),調(diào)制模式是對(duì)時(shí)間進(jìn)行同步控制的,但客戶工程師明確提到,這個(gè)應(yīng)用場(chǎng)景需要對(duì)周期數(shù)量進(jìn)行控制,在PWM周期時(shí)間靈活變化的場(chǎng)景中,控制時(shí)長(zhǎng)和控制數(shù)量是不等價(jià)的。因此,調(diào)制模式不適合解決這個(gè)問題。
FTM的多次重載事件
King還提到,他記得之前他用過的一家友商微控制器平臺(tái)上,就已經(jīng)設(shè)計(jì)了這個(gè)功能。我一看,果不其然,確實(shí)有,對(duì)應(yīng)著FTM模塊的寄存器字段FTM_CONF[LDFQ]
,如圖x所示。
FTM0->CONF = FTM_CONF_LDFQ(30);/ *Allow each 32times reload opportunity interrupt * /
圖x FTM_CONF[LDFQ]字段
通過閱讀手冊(cè)原文,我明確了思路,意識(shí)到在應(yīng)用中的重點(diǎn)可能不是中斷,而是調(diào)整占空比。這時(shí),我想起來YTM32的手冊(cè)里也有類似的關(guān)于Loading Frequency的設(shè)計(jì)。如圖x所示。
圖x eTMR模塊的同步載入機(jī)制
其中大意是,eTMR的一些同計(jì)數(shù)相關(guān)的寄存器,同時(shí)還設(shè)計(jì)了緩沖寄存器(或稱為“影子寄存器”),包括 CHMASK、INIT、MID、MOD、CH_VAL0和CH_VAL1。當(dāng)啟用eTMR后,這些寄存器的值就被鎖定了,只有在特定的時(shí)刻才會(huì)從各自對(duì)應(yīng)的影子寄存器中載入新值。
這其實(shí)也是一些能夠適配高頻率計(jì)數(shù)器的高級(jí)定時(shí)器的標(biāo)配設(shè)計(jì),為了獲取更高的計(jì)數(shù)精度,計(jì)數(shù)的時(shí)鐘源的頻率有時(shí)甚至?xí)哂隍?qū)動(dòng)定時(shí)器外設(shè)數(shù)字部分工作的系統(tǒng)總線時(shí)鐘頻率,此時(shí),通過總線設(shè)置的計(jì)數(shù)器相關(guān)寄存器的值,就需要在合適時(shí)刻,由兩個(gè)時(shí)鐘域同步后,才能生效(由影子寄存器載入到實(shí)際起作用的寄存器中)。
使用這個(gè)功能的意義還在于,留給軟件一些時(shí)間,用于先后完成多個(gè)寄存器的配置,然后在同一個(gè)時(shí)間點(diǎn)上,讓多個(gè)參數(shù)配置同時(shí)生效。在數(shù)字系統(tǒng)設(shè)計(jì)中,也稱之為防止“沖突冒險(xiǎn)”,否則,某些中間狀態(tài)可能會(huì)意外觸發(fā)系統(tǒng)崩潰(例如電機(jī)控制應(yīng)用場(chǎng)景中,在某個(gè)瞬間可能同時(shí)導(dǎo)通H橋的上下兩個(gè)橋臂,以至于燒掉電機(jī)的線圈導(dǎo)線)。
如果從當(dāng)前King描述的單路PWM控制信號(hào)的應(yīng)用場(chǎng)景上看,僅對(duì)單路PWM進(jìn)行控制,不需要多路PWM協(xié)同工作的情況下,實(shí)際沒啥必要啟用這個(gè)緩沖的功能,要求硬件立即載入生效即可,這也是對(duì)軟件最干凈和友好的方式。
從手冊(cè)上的描述來看,eFTM_SYNC[LDFRQ]
是同FTM_CONF[LDFQ]
功能最接近的,八成是他想要的。
終極大招-使用觸發(fā)鏈
然而,我又察覺到了一種潛在的需求,或許King就是想要實(shí)現(xiàn)通過軟件更新PWM占空比的節(jié)奏,因此提到了使用中斷的需求(實(shí)際上經(jīng)過同步多次載入事件的事件確實(shí)也能產(chǎn)生中斷),并且提供的樣例代碼中使用了32次同步,而我們家的eTMR在這里最多僅能配置16次同步?我覺得這事可能還有下文,說不準(zhǔn)還需要超過32次的周期,那時(shí),僅靠eTMR或者FTM自身的設(shè)計(jì),也不能完全搞定了。
如此,我又想出來一個(gè)終極大招。我打算對(duì)PWM信號(hào)同時(shí)對(duì)外發(fā)出的觸發(fā)信號(hào)Trigger進(jìn)行計(jì)數(shù),不過YTM32微控制器系統(tǒng)中沒有專門對(duì)Trigger進(jìn)行計(jì)數(shù)的外設(shè)模塊(我印象中,只有老東家的LPC系列微控制器上的一個(gè)偏門的外設(shè)SCT,為了管理硬件實(shí)現(xiàn)的狀態(tài)機(jī)模型,可以對(duì)Trigger計(jì)數(shù)并作為狀態(tài)轉(zhuǎn)換的一個(gè)判定條件),但幸運(yùn)的是,YTM32中設(shè)計(jì)了一個(gè)基于大循環(huán)和小循環(huán)的DMA控制器,其中大循環(huán)就是對(duì)DMA的觸發(fā)進(jìn)行計(jì)數(shù)的,我可以利用DMA的大循環(huán)計(jì)數(shù)器來實(shí)現(xiàn)對(duì)eTMR的DMA觸發(fā)信號(hào)計(jì)數(shù)。并且DMA的大循環(huán)(觸發(fā)循環(huán))也有重載機(jī)制(自動(dòng)繞圈計(jì)數(shù))和中斷,并且長(zhǎng)度可配置31比特長(zhǎng)度,遠(yuǎn)遠(yuǎn)超出32次的限制,完美符合對(duì)PWM脈沖累計(jì)計(jì)數(shù)可編程的需求。
解決問題
現(xiàn)在,大方向已經(jīng)有了,就是要確定從eTMR的Overflow事件,到DMA的大循環(huán),能不能走出一條通路。這就需要在手冊(cè)里搜集零星的相關(guān)的描述,把所有線索串在一起。
從實(shí)現(xiàn)可能性從大到小,反推整個(gè)觸發(fā)鏈:先要確認(rèn)DMA控制器(DMAMUX)能夠捕獲到來自eTMR的觸發(fā)信號(hào),然后在eTMR中確認(rèn)eTMR的觸發(fā)信號(hào)能否同PWM的一次輸出周期關(guān)聯(lián)起來,最后再查閱如何配置eTMR產(chǎn)生對(duì)應(yīng)的觸發(fā)信號(hào)。這三個(gè)環(huán)節(jié)環(huán)環(huán)相扣,如果連不上,這事可能也就搞不成了。小心翼翼。。。
確認(rèn)DMAMUX中的eTMR相關(guān)觸發(fā)源
在DMA章節(jié)中,查閱關(guān)于DMAMUX的表項(xiàng),它是芯片系統(tǒng)集成過程中列寫的,每款芯片的DMAMUX表項(xiàng)都不一樣,因此需要具體去查。如圖x所示。
圖x DMAMUX中關(guān)于eTMR的觸發(fā)源
看到表中的內(nèi)容,我差一點(diǎn)淚流滿面,這真是誠(chéng)意滿滿啊。這里要注意,此處DMAMUX能捕獲的觸發(fā)信號(hào)不是十分規(guī)整的,eTMR1和eTMR2包含的8個(gè)通道,每個(gè)通道是可以獨(dú)占一個(gè)DMA觸發(fā)通道的,而eTMR0和eTMR3就只能各自定時(shí)器的所有通道共享一個(gè)DMA觸發(fā)通道。在本例中,將使用eTMR0的這個(gè)共享的觸發(fā)通道進(jìn)行說明。為什么選用這個(gè)通道呢?一方面是因?yàn)楠?dú)占觸發(fā)通道的用例更簡(jiǎn)單,另一方面,是因?yàn)榭蛻艄こ處烱ing那邊現(xiàn)在用的就是eTMR0的CH2,如此調(diào)下來的用例可以在他的板子上驗(yàn)證。
OK,這里已經(jīng)確認(rèn)了,DMA是可以接收來自eTMR的觸發(fā)信號(hào)。接下來就要看eTMR是如何產(chǎn)生這個(gè)觸發(fā)信號(hào)了。
eTMR產(chǎn)生觸發(fā)信號(hào)
查閱手冊(cè)中關(guān)于eTMR的章節(jié),在關(guān)于DMA的功能介紹中,有如下內(nèi)容:
26.4.19 DMA All eTMRs support DMA, this function is enabled by setting CH_CTRL[DMAEN]=1. The DMA request is generated when STS[CHxF]=1. The DMA request is cleared by clearing STS[CHxF]. The DMA priority is higher than the interrupt.
這段內(nèi)容是說,通過配置eTMR_CHn_CTRL[DMAEN]=1
,就能啟用產(chǎn)生DMA觸發(fā)的功能,相當(dāng)于是把eTMR到DMAMUX的信號(hào)通路打開了,允許eTMR發(fā)出DMA觸發(fā)信號(hào)(Request)。當(dāng)eTMR通道的計(jì)數(shù)匹配事件產(chǎn)生后,eTMR_STS[CHxF]
標(biāo)志位置1,就會(huì)產(chǎn)生一個(gè)DMA的觸發(fā)(原本也可以產(chǎn)生一個(gè)中斷)。但這個(gè)標(biāo)志位應(yīng)該是需要被清零,才能捕獲到下次觸發(fā)。這里又說DMA的優(yōu)先級(jí)高于中斷,估計(jì)大概率不會(huì)需要通過中斷服務(wù)程序清零了。一種可能的情況是,DMA捕獲到來自外設(shè)的觸發(fā)信號(hào)后,向外設(shè)回發(fā)的應(yīng)答信號(hào),可以用來作為硬件清零CHxF標(biāo)志位的操作。
但進(jìn)一步理解下,這里還要注意,不能直接用eTMR的計(jì)數(shù)器溢出事件觸發(fā),而必須通過一個(gè)通道的事件觸發(fā)。因此為了產(chǎn)生DMA的觸發(fā)信號(hào),還需要再啟用一個(gè)eTMR通道。這個(gè)問題不大,單從具體的應(yīng)用場(chǎng)景看,反正是要產(chǎn)生PWM信號(hào)的,直接用這個(gè)輸出PWM波形的通道觸發(fā)DMA,也是可行的。有一些資深的玩家可能要提問了,那有沒有可能僅用定時(shí)器觸發(fā)DMA呢?比如要使用固定周期的DMA向UART引擎送數(shù),向總線上發(fā)送心跳數(shù)據(jù)包。答案是,沒有。目前在YTM32B1MD微控制器的DMAMUX中,入選的定時(shí)器只有eTMR,(其他例如TMR、LPTMR、pTMR等尚未入選),而使用eTMR則不得不通過一個(gè)eTMR通道才能產(chǎn)生DMA觸發(fā)。但是,YTM32微控制器平臺(tái)上還涉及了另一個(gè)同觸發(fā)相關(guān)的外設(shè)TMU(Trigger Mux Module),其中收納了pTMR,也能發(fā)揮一定的聯(lián)動(dòng)作用)
軟件
編寫本例的軟件工程源代碼,編譯,下載,調(diào)試,可以正常觸發(fā)DMA中斷,說明已經(jīng)搭建起觸發(fā)鏈,按照預(yù)期方式工作。
但在調(diào)試過程中出現(xiàn)一點(diǎn)小插曲。我在樣例工程中設(shè)定eTMR的PWM的頻率是100Hz,指定DMA捕獲到1000次PWM的觸發(fā)信號(hào)后觸發(fā)一次中斷。如代碼所示:
void etmr_init(void)
{
/* setup counter. */
eTMR_CounterInit_Type etmr_init;
etmr_init.ClkSrc = eTMR_CounterClkSrc_BusClk;
etmr_init.ClkFreqHz = CLOCK_FIRC_FREQ_HZ;
etmr_init.StepFreqHz = CLOCK_FIRC_FREQ_HZ / 100000u; /* 100khz. */
etmr_init.InitVal = 0u;
etmr_init.MidVal = 0u;
etmr_init.ModVal = 1000; /* 100 hz for timeout. */
etmr_init.EnableRunningOnDebug = false;
etmr_init.EnableGlobalCountingBase = false;
eTMR_InitCounter(BOARD_ETMR_PORT, &etmr_init);
/* setup channel. */
eTMR_ChannelOutputCompareInit_Type etmr_chn_init;
etmr_chn_init.EnableComplementaryMode = false;
etmr_chn_init.EnableDoubleSwitchMode = false;
etmr_chn_init.InitOutputLogic = eTMR_OutputLogic_Low;
etmr_chn_init.EnableDma = true; /* enable to generate request to trigger the dma. */
etmr_chn_init.OutputCompareEventForVal0 = eTMR_OutputCompareEvent_ToOutputLogic1;
etmr_chn_init.OutputCompareEventForVal1 = eTMR_OutputCompareEvent_ToOutputLogic0;
etmr_chn_init.Val0 = 0;
etmr_chn_init.Val1 = 200;
eTMR_InitChannelOutputCompare(BOARD_ETMR_PORT, BOARD_ETMR_CHN, &etmr_chn_init);
}
void etmr_dma_init(void)
{
/* setup dma. */
dma_init(1000); /* collect pwm triggers for each period. */
/* setup etmr. */
etmr_init();
/* start etmr counter. */
eTMR_StartCounter(BOARD_ETMR_PORT);
}
預(yù)計(jì)觸發(fā)DMA中斷的時(shí)間間隔大約在10s左右,但實(shí)際上,觸發(fā)DMA中斷的周期基本上在5s,頻率差了2倍??如圖x所示。
圖x 測(cè)量DMA的觸發(fā)時(shí)間間隔
再翻了翻手冊(cè),總算是找到root cause了。在手冊(cè)中關(guān)于輸出比較模式的介紹中提到,每個(gè)通道配備的兩個(gè)匹配事件,都可以讓標(biāo)志位CHxF置位,那也就意味著,每個(gè)PWM周期都會(huì)產(chǎn)生兩個(gè)觸發(fā)信號(hào)。這也就解釋了DMA中斷觸發(fā)的周期比預(yù)想中少了一半的情況。如果還想得到預(yù)定時(shí)間長(zhǎng)度的中斷周期,就得把大循環(huán)的長(zhǎng)度設(shè)置為雙倍!
26.4.5 Output Compare Mode When CHx_CTRL[CHMODE]=0x2, the channel x is in output compare mode. In this mode, each channel can set, clear, or toggle the output when the counter reaches the specific value defined by CH_VAL0[VAL0] and CH_VAL1[VAL1]. Configure CH_CTRL[VAL0CMP] and CH_CTRL[VAL1CMP] to select the action of the corresponding channel when the counter reaches the CH_VAL0[VAL0] and CH_VAL1[VAL1]. As shown in Figure eTMR Output Compare. The channel flag (STS[CHxF]) will be set when a compare event occurs.
總結(jié)
本例實(shí)現(xiàn)了一種利用DMA的大循環(huán)(觸發(fā)循環(huán))對(duì)eTMR模塊產(chǎn)生PWM信號(hào)波形進(jìn)行計(jì)數(shù)并產(chǎn)生周期中斷的功能,相對(duì)于硬件IP通過重載同步機(jī)制中設(shè)計(jì)的計(jì)數(shù)方式,本例利用對(duì)DMA觸發(fā)信號(hào)進(jìn)行計(jì)數(shù),可以實(shí)現(xiàn)更多數(shù)量的計(jì)數(shù),并且具有更廣泛的普適性。
文中使用的DMA觸發(fā)計(jì)數(shù)方法,不僅僅可用于對(duì)定時(shí)器觸發(fā)信號(hào)的計(jì)數(shù),還可用于實(shí)現(xiàn)對(duì)DMAMUX能夠捕獲的其他觸發(fā)信號(hào)的計(jì)數(shù)。更進(jìn)一步,如果配合其他的觸發(fā)管理設(shè)備(例如Trigger Mux),形成觸發(fā)鏈,還可以進(jìn)一步擴(kuò)大DMA觸發(fā)計(jì)數(shù)方法的適用范圍。
-
微控制器
+關(guān)注
關(guān)注
48文章
7668瀏覽量
152214 -
寄存器
+關(guān)注
關(guān)注
31文章
5372瀏覽量
121346 -
定時(shí)器
+關(guān)注
關(guān)注
23文章
3256瀏覽量
115481 -
串口中斷
+關(guān)注
關(guān)注
0文章
67瀏覽量
14023 -
PWM信號(hào)
+關(guān)注
關(guān)注
3文章
95瀏覽量
20219
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
TC275 TOM模塊進(jìn)行電機(jī)控制,如何實(shí)現(xiàn)一個(gè)PWM周期兩次更新占空比和周期呢?
STM32L151定時(shí)器上升沿觸發(fā)ADC采樣,為什么每個(gè)PWM周期內(nèi)會(huì)觸發(fā)第二次采樣?
stm32 AD采樣周期如何計(jì)算?
利用定時(shí)器產(chǎn)生PWM波
如何去實(shí)現(xiàn)ADC定時(shí)器觸發(fā)+DMA雙緩沖的設(shè)計(jì)呢
如何利用DMA方式去實(shí)現(xiàn)串口的轉(zhuǎn)發(fā)功能呢
應(yīng)用筆記(三)| 運(yùn)用DMA 功能實(shí)現(xiàn)高級(jí)定時(shí)器和ADC 的同步觸發(fā)采樣
請(qǐng)問如何使用定時(shí)器DMA PWM改變周期?
如何在使用定時(shí)器更新中斷來了解設(shè)備何時(shí)達(dá)到計(jì)數(shù)器周期呢?
如何使用HAL從TIM觸發(fā)DMA?
如何利用DMA功能創(chuàng)建帶有高級(jí)定時(shí)器1的PWM序列?
巧妙利用pwm原理,PWM控制LED實(shí)現(xiàn)呼吸燈
![巧妙<b class='flag-5'>利用</b><b class='flag-5'>pwm</b>原理,<b class='flag-5'>PWM</b>控制LED<b class='flag-5'>實(shí)現(xiàn)</b>呼吸燈](https://file.elecfans.com/web1/M00/C9/E6/o4YBAF-G00mABClJAAAMv8BSldk416.jpg)
在一個(gè)周期內(nèi)實(shí)現(xiàn)PWM到DC的轉(zhuǎn)換
![在一個(gè)<b class='flag-5'>周期</b>內(nèi)<b class='flag-5'>實(shí)現(xiàn)</b><b class='flag-5'>PWM</b>到DC的轉(zhuǎn)換](https://file.elecfans.com/web1/M00/D9/4E/pIYBAF_1ac2Ac0EEAABDkS1IP1s689.png)
評(píng)論