S32K FTM(FlexTimer module)详解
1. 簡介
FTM(FlexTimer)是由一個簡單的定時器——HCS08 定時器 PWM(TPM)模塊建立而來的,在飛思卡爾 8bit 微控制器上已經使用多年。Flextimer模塊應用領域包括馬達控制,照明控制和電源等。
FTM是一個2到8通道定時器,支持輸入捕獲,輸出比較,pwm信號發生和正交解碼功能。
2. Features
-
FTM source clock is selectable
-
可選的FTM時鐘源
-
Source clock can be the FTM input clock, the fixed frequency clock, or an external clock.
-
時鐘源可以是FTM輸入時鐘/固定頻率時鐘/外部時鐘。
-
Fixed frequency clock is an additional clock input to allow the selection of an on chip clock source other than the FTM input clock.
-
固定頻率時鐘允許使用片上其他時鐘源作為時鐘輸入補充。
-
Selecting external clock connects FTM clock to a chip level input pin therefore allowing to synchronize the FTM counter with an off chip clock source
-
選擇外部時鐘即連接FTM時鐘到外部管腳,允許使用外部時鐘同步FTM計數器。
-
-
Prescaler divide-by 1, 2, 4, 8, 16, 32, 64, or 128.
-
預分頻支持1,2,4,8,16,32,64,128。
-
16-bit counter
-
16bit計數器。
-
It can be a free-running counter or a counter with initial and final value.
-
自由運行計數器或擁有初始值和終止值的計數器。
-
The counting can be up or up-down.
-
可以遞增或遞減。
-
-
Each channel can be configured for input capture, output compare, or edge-aligned PWM mode.
-
每個通道可以配置為輸入捕獲、輸出比較或邊沿對齊PWM模式。
-
In Input Capture mode:
-
輸入捕獲模式下:
-
The capture can occur on rising edges, falling edges or both edges.
-
可以是上升沿、下降沿或邊沿捕獲。
-
An input filter can be selected for some channels. One unique prescaler is available for all filters.
-
一些通道可以選擇輸入濾波器,所有的濾波器可選一個唯一的分頻器。
-
-
In Output Compare mode the output signal can be set, cleared, or toggled on match.
-
在輸出比較模式,輸出信號在匹配觸發時可以置位,復位,或翻轉。
-
All channels can be configured for center-aligned PWM mode
-
所有的通道可以配置為中心對齊PWM模式。
-
Each pair of channels can be combined to generate a PWM signal with independent control of both edges of PWM signal.
-
每一對通道可以組合生成一個PWM信號,對PWM信號兩個邊沿進行獨立控制。
-
The FTM channels can operate as pairs with equal outputs, pairs with complementary outputs, or independent channels with independent outputs
-
FTM通道可以成對相同輸出,成對輸出互補,或各通道獨立輸出。
-
The deadtime insertion is available for each complementary pair.
-
每個互補輸出可以設置死區。
-
Generation of match triggers.
-
匹配觸發發生器(生成匹配觸發器??????)
-
Software control of PWM outputs.
-
軟件可控的PWM輸出。
-
The polarity of each channel is configurable
-
所有通道極性可配。
-
Up to 4 fault inputs for global fault control.
-
最多支持4個故障輸入作為全局故障控制。
-
The generation of an interrupt per channel
-
每個通道可產生中斷。
-
The generation of an interrupt when the counter overflows
-
計數器溢出中斷。
-
The generation of an interrupt when the fault condition is detected.
-
故障條件觸發中斷。
-
The generation of an interrupt when a register reload point occurs.
-
寄存器重新加載點觸發中斷。
-
Synchronized loading of write buffered FTM registers.
-
FTM寫緩沖寄存器同步加載。
-
Half cycle and Full cycle register reload capacity.
-
半周期/全周期寄存器重載能力。
-
Write protection for critical registers
-
關鍵寄存器寫保護。
-
Backwards compatible with TPM.
-
向后兼容TPM。
-
Testing of input capture mode.
-
輸入捕獲模式測試。
-
Direct access to input pin states.
-
輸入引腳狀態直接訪問。
-
Dual edge capture for pulse and period width measurement.
-
用于脈沖寬度和周期測量的雙邊沿捕獲模式。
-
Quadrature decoder with input filters, relative position counting, and interrupt on position count or capture of position count on external event.
-
帶有輸入濾波器的正交譯碼器,相對位置計數,位置計數中斷或位置計數捕獲。
-
The FTM channels can be selected to generate a trigger pulse on channel output instead of a PWM.
-
可以選擇FTM通道來產生通道輸出的觸發脈沖,而不是PWM。
-
Dithering capability to simulate fine edge control for both PWM period or PWM duty cycle.
-
抖動功能可模擬PWM周期或PWM占空比的精細邊沿控制。
3. S32K144 FTM結構框圖
?
Flextimer模塊圖,左上角為Flextimer基準時鐘信號,默認狀態為無時鐘選擇,即Flextimer計數器關閉。
右上角為時鐘分頻控制,可以控制Flextimer計數時鐘頻率。框圖中包括中斷控制,模式選擇,故障信號檢測以及輸出信號。
Flextimer工作模式包括:輸入捕獲,輸出比較,PWM波形輸出,正交解碼器。
FTM模塊的核心是一個16bit計數器,該計數器的時鐘源可以選擇,如果我們選擇由FTM來實現PWM,輸入捕捉,或者輸出比較,定時中斷,脈寬測量等功能,則一般選擇system clock。如果我們選擇由FTM實現對外部脈沖的計數,也可選擇外部時鐘,如果是外部編解碼器輸入的AB相脈沖,用于電機正反轉測速,則可以使用PHA和PHB輸入,由計數器自動加減計數。
每個FTM模塊擁有一個FTM Couter計數器,所有通道共用同一計數器。
-
CNTIN - 初始值
-
MOD - 結束值
三種計數方式
-
遞增計數。
-
先加后減,循環往復。
-
正交解碼模式下自動遞增或遞減。
4. 功能描述
4.1 時鐘源
-
FTM時鐘
-
固定頻率時鐘
-
外部時鐘
4.2 分頻
支持1、2、4、8、16、32、64、128分頻。
4.3 計數器
16bit計數器
-
向上遞增模式,主要用于EPWM。
-
CNTIN定義計數開始值,MOD定義技術終止值。FTM使能后會加載CNTIN值,累加計數直到達到MOD終止值。之后會重新裝載CNTIN計數開始值。當計數值重新加載CNTIN值時,TOF(計數器溢出標志位)置位。
-
-
向上遞增再向下遞減循環模式,主要用于CPWM模式。
-
CNTIN定義計數開始值,MOD定義技術終止值。FTM使能后會加載CNTIN值,累加計數直到達到MOD終止值,之后計數器將遞減計數值直到計數值為CNTIN。之后會重復遞增遞減計數的過程。
-
-
正交解碼模式,根據AB相序增減計數。
4.4 通道模式
下表顯示了通道的模式選擇
??
每個通道都可以配置成輸入捕獲,輸出比較或者邊沿對齊PWM波輸出。
輸入捕獲可以配置捕獲方式:上升沿、下降沿或者雙沿捕獲。
一些通道可以配置輸入信號濾波。
輸出比較模式下,輸出信號可以配置為輸出高或低或者每次匹配翻轉。
所有通道都可以配置成PWM中心對齊輸出。
每對通道均可以結合輸出PWM波。
每對通道可以配置相同輸出,相反(互補)輸出或者作為獨立通道。
每對互補通道可以提供死區插入功能。
4.5 FTM操作模式
4.5.1 邊沿對齊PWM(EPWM)模式
在邊沿對齊PWM模式下, FTM計數器從FTM_CNTIN值向上計數到FTM_MOD值。當FTM計數器從MOD值變為CNTIN值時,所有FTM通道的信號都在邊緣對齊。 當QUADEN = 0, DECAPEN = 0, MCOMBINE = 0, COMBINE = 0, CPWMS = 0和MSnB =1時,選擇邊沿對齊PWM模式。 邊沿對齊PWM周期由MOD – CNTIN + 0x0001決定,脈沖寬度(或占空比)由 CnV – CNTIN or MOD – CNTIN – CnV決定,具體取決于控制位 ELSnB:ELSnA。
在中,示波器通道CH1, CH2, CH3和 CH4 分別代表FTM模塊的FTM_CH0,FTM_CH1, FTM_CH2和 FTM_CH3。第一個通道對(FTM_CH0/FTM_CH1)和第二 個通道對(FTM_CH2/FTM_CH3)在互補模式下工作,分別具有50%和25%的占空比。 第二個通道對(FTM_CH2/FTM_CH3)演示了邊緣對齊。
4.5.2 中心對齊PWM(CPWM)模式
在中心對齊PWM模式下, FTM計數器從FTM_CNTIN向上計數到FTM_MOD,然后從FTM_MOD向下計數到FTM_CTNIN。所有FTM通道的信號在FTM計數器達到FTM_MOD值的點對齊。當 QUADEN = 0, DECAPEN = 0, MCOMBINE = 0, COMBINE = 0和CPWMS = 1時,選擇中心對齊PWM模式。
中心對齊PWM的占空比確定為 2 × (CnV - CNTIN)。周期確定為 2 × (MOD - CNTIN)。
?
圖中,示波器通道CH1、 CH2、 CH3和CH4分別代表FTM模塊的FTM_CH0、FTM_CH1、 FTM_CH2和FTM_CH3。第一個通道對(FTM_CH0/FTM_CH1)和第二 個通道對(FTM_CH2/FTM_CH3)在互補模式下工作, 分別具有50%和25%的占空比。 第二個通道對(FTM_CH2/FTM_CH3)演示了中心對齊。
4.5.3 互補模式和死區時間插入
FTM模式支持互補模式。如果通過FTM_COMBINE寄存器中的COMP位啟用互補模式,則輸出信號僅由偶數FTM通道生成。奇數輸出信號由互補邏輯生成,作為偶數FTM通道的補碼。 對于FTM的每個通道對,是否輸出互補信號是可以單獨配置的。
?為避免短路,死區時間必須插入互補信號中。死區插入由死區邏輯提供,遵循互補邏輯。該功能可以通過FTMxCOMBINEm寄存器中的DTEN位使能。死區邏輯將每個上升沿延遲一段時間,該時間由FTM_DEADTIME寄存器設置。死區時間由兩部分組成,前兩個最高有效位DTPS[1:0]定義系統時鐘的預分頻器。位DTVAL[5:0]使用預分頻時鐘定義占空比值。 互補模式和死區插入應用于邊沿對齊PWM和中心對齊PWM模式,如前幾節所述。
4.5.4 組合模式
組合模式提供了更高的靈活性,因為PWM通道( n)輸出是通過組合偶數通道( n)和相鄰的奇數通道(n+1)產生的。這意味著偶數和奇數通道必須在互補模式下工作。
組合模式僅允許使用遞增計數器、非對稱PWM或相移PWM來生成EPWM和CPWM。相移PWM通常用于移相全橋轉換器和電機控制應用,其中三相定子電流由采樣電阻得到。有關更多詳細信息,請參閱使用Kinetis KEA128的三相 BLDC電機無傳感器控制參考設計(文檔DRM151)。
當QUADEN = 0, DECAPEN = 0, MCOMBINE = 0, COMBINE = 1和CPWMS = 0時,選擇組合模式。
要生成具有高真脈沖的相移PWM,請將控制位設置為ELSnB:ELSnA = 1: 0。
void Phase_Shifted_PWM()
{/* Enable clock for FTM1 */PCC->PCCn[PCC_FLEXTMR1_INDEX] = PCC_PCCn_PCS(6) | PCC_PCCn_CGC_MASK;/* Enable clock for PORTB */PCC->PCCn[PCC_PORTB_INDEX] = PCC_PCCn_CGC_MASK;/* Enable clock for PORTD */PCC->PCCn[PCC_PORTD_INDEX] = PCC_PCCn_CGC_MASK;PORTB->PCR[2] = PORT_PCR_MUX(2); // Set PTB2 for FTM1 – Channel0 PORTB->PCR[3] = PORT_PCR_MUX(2); // Set PTB3 for FTM1 – Channel1 PORTD->PCR[8] = PORT_PCR_MUX(6); // Set PTD8 for FTM1 – Channel4 PORTD->PCR[9] = PORT_PCR_MUX(6); // Set PTd9 for FTM1 –Channel5/* Enable combine, complementary mode and dead-time for channel pair CH0/CH1 and CH4/CH5 */FTM1->COMBINE = FTM_COMBINE_COMBINE0_MASK | FTM_COMBINE_COMP0_MASK | FTM_COMBINE_DTEN0_MASK | FTM_COMBINE_COMBINE2_MASK | FTM_COMBINE_COMP2_MASK | FTM_COMBINE_DTEN2_MASK;FTM1->CONTROLS[0].CnSC=FTM_CnSC_ELSB_MASK; // Select high-true pulses FTM1->CONTROLS[1].CnSC=FTM_CnSC_ELSB_MASK; // Select high-true pulsesFTM1->CONTROLS[4].CnSC=FTM_CnSC_ELSB_MASK; // Select high-true pulses FTM1->CONTROLS[5].CnSC=FTM_CnSC_ELSB_MASK; // Select high-truepulses/* Set Modulo (10kHz PWM frequency @112MHz system clock) */FTM1->MOD = FTM_MOD_MOD(11200-1); // Set moduloFTM1->CONTROLS[0].CnV=FTM_CnV_VAL(2800); // Set channel ValueFTM1->CONTROLS[1].CnV=FTM_CnV_VAL(8400); // Set channel Value FTM1->CONTROLS[4].CnV=FTM_CnV_VAL(5600); // Set channel ValueFTM1->CONTROLS[5].CnV=FTM_CnV_VAL(11200); // Set channel Value FTM1->CNT = 0; ?// Counter reset/* Insert DeadTime (1us) */FTM1->DEADTIME = FTM_DEADTIME_DTPS(3) | FTM_DEADTIME_DTVAL(7);FTM1->SC|=FTM_SC_CLKS(1)|FTM_SC_PWMEN0_MASK | FTM_SC_PWMEN1_MASK | FTM_SC_PWMEN4_MASK | FTM_SC_PWMEN5_MASK; // Select clock and enable PWM
}
圖中,示波器通道 CH1、 CH2、 CH3和CH4分別代表FTM1模塊通道FTM1_CH0、FTM1_CH1、 FTM_CH4和FTM_CH5。第一個通道對( FTM_CH0/FTM_CH1)和第二個通道對( FTM_CH4/FTM_CH5)都在互補模式下工作,占空比為50%。第二個通道對(FTM_CH4/FTM_CH5)與第一個通道對(FTM_CH0/FTM_CH1)相移90°。
圖中還顯示了PWM生成的靈活性,因為50%的占空比可以根據特定的應用要求進行 邊沿對齊、中心對齊或各種偏移。
4.5.4B 改進組合模式
改進的組合PWM模式是為了生成周期不變但是占空比會變得PWM。通道n和n+1結合生成PWM信號,通常通道n匹配邊沿是固定的,通道n+1匹配邊沿可以被修改。
一般使用多個通道時,配置每個通道n的匹配邊沿帶有固定偏移的輸出,這樣在產生照明PWM控制信號時是有用的,當需要的邊緣不與其他對一致,以幫助消除噪聲產生。
4.5.5 單邊輸入捕獲模式
FTM 捕獲模式主要用于測量信號的脈沖寬度或周期。 FTM 捕獲模式的另一個選擇是檢測外部信號的上升/下降沿并產生中斷以通知外部事件出現。 FTM 捕獲模式也用于BLDC電機控制應用,其中霍爾傳感器用于檢測轉子位置并計算轉子速度,從而可以穩定速度環。 霍爾傳感器連接到獨立的FTM (FTM_CHx) 的通道。然后, FTM 可以檢測霍爾傳感器信號的下降沿和上升沿并生成捕獲中斷。在捕獲中斷程序中, PWM 信號的占空比會根據霍爾傳感器邏輯進行更新。 當 DECAPEN = 0、 MCOMBINE = 0、 COMBINE = 0、 CPWMS = 0、 MSnB:MSnA =0:0 且 ELSnB:ELSnA ≠ 0:0 時,選擇單邊沿捕獲模式。 要測量信號的脈沖寬度或周期,請選擇FTM模塊 FTM_CHx 的輸入通道,并通過控制位 ELSnB:ELSnA 選擇邊沿觸發。當通道輸入上出現所選邊沿時, FTM計數器的當前值將被存儲到 CnV 寄存器中并產生通道中斷(如果 CH(n)IE = 1)。在例程中斷中,將 CnV 寄存器的值保存到一個變量中,并將當前值與前一個中斷例程中保存的值進行區分。如果所選捕獲模式在上升沿 (ELSnB:ELSnA= 0:1) 或下降沿 (ELSnB:ELSnA= 1:0) 觸發,則差值等于信號周期。如果所選的捕獲模式在兩個邊沿都觸發 (ELSnB:ELSnA = 1:1),則差值等于被測信號的脈沖寬度。
此示例顯示FTM0的輸入捕獲模式,該模式測量通過FTM0_CH0通道的輸入信號的時間周期。
在圖 5中,示波器通道CH0表示輸入到FTM0_CH0通道的測試信號。 每次出現上升沿,都會產生捕獲中斷,并在中斷程序中計算信號周期。
4.5.6 雙邊捕獲模式
雙邊沿捕獲模式使用兩個 FTM 通道,可以測量信號的正極或負極脈沖寬度。在此模式下,信號必須通過偶數 FTM 通道輸入,而忽略奇數通道。
DECAPEN = 1 時選擇雙邊沿捕獲模式。 FTM 的雙邊沿捕獲模式可以工作在一次性捕獲模式或連續捕獲模式。 MS(n)A = 0 時選擇一次性捕獲模式。如果使能 DECAP 位,則捕獲邊沿。對于每次新的測量,必須清除 CH(n)F 和 CH(n+1)F,并且必須再次設置 DECAP位。 MS(n)A = 1 時選擇連續捕獲模式。在這種模式下,如果 DECAP 位被設置,則邊沿被連續捕獲。對于每次新的測量,都需要清除 CH(n)F 和 CH(n+1)F 位。
要測量被測信號的正極脈寬(無論是單次模式還是連續模式),通道(n)必須配置為捕獲上升沿( ELS( n) B: ELS( n) A = 1:0) 和通道 (n+1) 必須配置為捕獲下降沿(ELS(n+1)B:ELS(n+1)A = 0:1)。當檢測到被測信號的第二個下降沿時, CH(n+1)F 置位,DECAP 位清零,并產生中斷(如果 CH(n+1)IE=1)。在中斷程序中,將C(n+1)V和C(n)V寄存器中保存的值相減,確定被測信號的正極脈寬,并清除CH(n+1)F 位。
如 果 應 用 需 要 測 量 信 號 的 負 極 性 脈 寬 , 則 通 道 (n) 必 須 配 置 為 捕 獲 下 降 沿(ELS(n)B:ELS(n)A = 0:1)和通道(n) +1) 必須配置為捕獲上升沿 (ELS(n+1)B:ELS(n+1)A =1:0)。 要確定被測信號周期,通道 (n) 和通道 (n+1) 必須在相同的邊沿上敏感。
此示例顯示了 FTM0 模塊的雙邊沿捕獲模式,該模式用于確定兩個輸入信號的正脈沖度。
圖中顯示了通過 FTM0_CH0 和 FTM0_CH2 通道輸入 FTM0 模塊的兩個測量信號。它們的正極性脈沖寬度為 17.8 μs 和 50 μs。
4.5.7 輸出比較模式
輸出比較模式下,FTM可以產生位置、極性、持續時長和周期可編程的時間脈沖。當計數器值匹配CnV寄存器的值,通道n輸出可以被設置、清除或翻轉。
當一個通道被配置為翻轉模式,通道輸出前一個值會保持,直到下一個比較事件發生。
4.5.8 捕獲測試模式
捕獲測試模式允許對CnV寄存器、FTM計數器以及FTM計數器與CnV寄存器之間的對接邏輯進行測試。
該模式下,所有通道必須配置為輸入捕獲模式,FTM計數器必須配置為向上遞增。
當捕獲測試模式被啟用(CAPTEST = 1)時,FTM計數器被凍結,任何對CNT寄存器的寫入都直接更新FTM計數器;見下圖。
在寫入后,所有CnV寄存器都將寫入的值更新為CNT寄存器,并設置CHF位。因此,根據FTM計數器的配置,它的下一個值將被更新。它的下一個值取決于CNTIN、MOD和寫入FTM計數器的值。
4.5.9 DMA
支持CHF通過DMA傳輸
4.6 其他特性
4.6.1 屏蔽、反相和軟件控制功能
屏蔽和軟件控制功能強制 FTM 通道的輸出處于非活動/需要狀態,保持通道輸出的恒定邏輯。 這些 FTM 功能可以通過軟件打開/關閉電源設備。反相功能翻轉 FTM 通道對的信號。 屏蔽功能用于 BLDC 電機控制應用。三相 BLDC 電機通常由配備六個 MOSFET 或六個 IGB(絕緣柵雙極晶體管)的三相功率逆變器供電。 BLDC 電機常用的控制技術是 6 步換向法。在這種控制技術中,兩相通電,第三相斷開。因此,必須關閉相應逆變器支路的兩個功率器件。 FTM 模塊的屏蔽特性可以在這個應用程序中實現來實現這樣的功能。 每個FTM 通道在FTM_OUTMASK 寄存器中有一個對應的位。對 OUTMASK 寄存器的任何寫操作只是將值鎖存到其寫緩沖區中。
當FTM時鐘被禁用(在FTM_SYNC[SYNCHOM]=0時在FTM輸入時鐘的每個上升沿)或著在軟件或硬件同步更新FTM_SYNCONF 寄存器中的 SWOM 位或 HWOM 位時候,FTM 通道的輸出邏輯可以在寫入 FTM_OUTMASK 寄存器后立即更新(參見Section 4.3,“Updating FTM registers”)。 當 FTM_CHx 通道被屏蔽時,根據 FTM_POL 寄存器中使能的位來控制輸出邏輯保持高/低。
軟件控制功能通過設置或清除 FTM_SWOCTRL 寄存器中的 CHxOC 位來強制 FTM 通道的輸出為軟件定義的值。如果 CHxOC 位清零, FTM 通道的輸出仍由 PWM 或其他源驅動。如果CHxOC 位被置位,相應的 FTM 通道的輸出受軟件影響。 FTM_SWOCTRL 寄存器中的 CHxOCV 位控制各個 FTM 通道的邏輯。當 CHxOCV = 1 時, FTM_CHx 通道的輸出為1,否則為 0。
反相功能通常用于直流電機控制應用。直流電機由 H 橋供電,一個通道對(FTM_CH0/CH1) 連接到一個分支,而另一對通道 (FTM_CH2/CH3) 連接到另一個分支。兩個通道對都在互補模式下工作。此類應用要求對角線功率器件同時開啟/關閉,這意味著 FTM_CH0 和FTM_CH3 必須具有相同的時序。為了保證這樣的條件, FTM_CH1 和 FTM_CH3 必須工作在反相模式。 FTM_INVCTRL 寄存器中的 INVmEN 位使能相應通道對的反相。從寫入緩沖區的值更新FTM_INVCTRL 寄存器的值與更新FTM_OUTMASK 寄存器值的方式相同。
4.6.2 故障控制功能
FTM 模塊的故障控制在電機控制應用中發揮著重要作用,因為它提供了在關鍵時刻保護功率設備以及整個電力驅動系統的機會,當出現過溫、過壓、 或發生過電流。在這種情況下,故障信號可以通過傳感器或特殊電路產生。一旦在 FTM 故障引腳的輸入端檢測到故障信號,故障控制就能夠停止所有 PWM 通道。接收到故障信號后可以產生中斷以減輕故障損失。
所有 FTM 中斷源(故障中斷、 FTM 計數器溢出和重裝載中斷、通道比較事件中斷和捕獲中斷)共享相同的中斷向量號。當出現故障信號時, FTM 通道的輸出被禁用并保持在FTM_POL 寄存器中定義的安全邏輯電平。例如,如果 POL0 = 1并且存在故障,則FTM_CH0 被禁用并強制為高電平。相反,如果 POL0 = 0 并且存在故障,則 FTM_CH0 被禁用,但被強制為低電平。
FTM 有多個通道。然而, FTM 不能通過特定的故障信號來禁用特定的通道。故障信號是由所有進入的故障信號OR 運算的結果。 FTM 通道是否可以被故障信號禁用取決于FTM_COMBINE 寄存器中的 FAULTENx 位。由此產生的故障信號可以禁用所有 FTM 通道或僅禁用偶數通道 (FTM_CH0/CH2/CH4/CH6),這取決于 FTM_MODE 寄存器中的FAULTM 位字段 。
PWM 通 道 的 輸 出 恢 復 有 兩 種 方 式 : FAULTM[1:0]=11 設 置 的 自 動 故 障 清 除 和FAULTM[1:0]=0:1或1:0時的手動故障清除。從下一個PWM周期中的安全狀態恢復PWM信號,在選擇自動故障清除模式時,無需任何軟件干預。要在手動清除模式下恢復 PWM 信號,必須清除 FTM_MODE 寄存器中的 FAULTF 位,然后在下一個 PWM 周期使能 PWM。
在以下代碼示例中,啟動了兩個 FTM 模塊以演示故障控制功能。 FTM0 配置為中心對齊 PWM模式, FTM1 用于生成故障信號,該信號通過故障引腳 FTM0_FLT0 從外部影響FTM0 通道的輸出。
在圖中,示波器通道 CH1、 CH2 和 CH3 分別代表 FTM0 模塊通道 FTM0_CH0、FTM0_CH1 和 FTM0_CH2。 FTM0_CH0 和 FTM0_CH1 工作在互補和組合模式,與FTM0_CH2 和 FTM0_CH3 相同。通道 CH4 顯示外部故障信號(由 FTM1 產生),其頻率為 FTM0 頻率的十分之一。 當在 FTM0_FLT0 故障輸入引腳上檢測到上升沿時,所有 FTM0通道都被強制為安全(低)邏輯。 圖 11 還顯示,當故障輸入信號為 0 時,所有 FTM0 通道都在下一個計數器周期恢復。
4.6.3 更新FTM寄存器
在電機控制或開關電源應用中,施加在負載上的電壓必須由 PWM 占空比控制。 PWM占空比可以通過在 FTM_CnV 和 FTM_CNTIN 寄存器中設置適當的值來控制。某些應用還需要更改 PWM 的周期。該周期由 FTM_MOD 寄存器中的值控制。
FTM_CnV、 FTM_CNTIN 和 FTM_MOD 是雙緩沖寄存器,這意味著對這些寄存器的寫入只是將它們的值鎖存到它們的寫入緩沖區中。 FTM 模塊的雙緩沖寄存器有通道 (n) 值(FTM_CnV) 、 計 數 器 初 始 值 (FTM_CNTIN) 、 模 數 (FTM_MOD) 、 半 周 期 寄 存 器(FTM_HCR)、輸出掩碼 (OUTMASK)、軟件輸出控制 (SWOCTRL ) 和反相控制寄存器(INVCTRL)。然后可以根據選擇的更新方案用它們的緩沖值更新雙緩沖寄存器。 S32K 器件上的當前實現更新寄存器方法有使用半周期或全周期重載策略、軟件或硬件 PWM 同步,或者直接禁用緩沖器。下表總結了所有雙緩沖寄存器及其更新方法:
更新雙緩沖FTM寄存器
| Update technique | Double-buffered FTM registers | Note |
|---|---|---|
| Initialization stage CLKS[1:0] = 0:0 | CnV, CNTIN, MOD, HCR | The registers are loaded immediately. |
| TPM compatibility CLKS[1:0] ≠ 0:0, FTMEN = 0 | CnV, CNTIN, MOD, HCR | The CNTIN register is loaded immediately and the CnV, MOD, and HCR registers at the end of the FTM counter period. The CnV register is loaded immediately in the output compare mode. |
| Software synchronization CLKS[1:0] ≠ 0:0, FTMEN=1, SYNCMODE = 1 | CnV, CNTIN, MOD, HCR (SWWRBUF = 1) | The registers are updated by the software trigger-enabling SWSYNC bit. If SWRSTCNT = 1, the software trigger resets the FTM counter reset. |
| .. | SWOCTRL (SWOC = 1, SWSOC = 1) | The registers are updated by the software trigger-enabling SWSYNC bit. |
| .. | OUTMASK (SYNCHOM = 1, SWOM = 1) | .. |
| .. | INVCTRL (INVC = 1, SWINVC = 1) | .. |
| Hardware synchronization CLKS[1:0] ≠ 0:0, FTMEN=1, SYNCMODE = 1 | CnV, CNTIN, MOD, HCR (HWWRBUF = 1) | The registers are updated when TRIGn = 1 and the hardware trigger is detected at the trigger (n) input signal. If HWTRIGMODE = 1, the hardware trigger clears the TRIGn bit. |
| .. | SWOCTRL (SWOC = 1, HWSOC = 1) | .. |
| .. | OUTMASK (SYNCHOM = 1, HWOM = 1) | .. |
| .. | INVCTRL (INVC = 1, HWINVC = 1) | .. |
| Half and full cycle reload strategy CLKS[1:0] ≠ 0:0, FTMEN=1, | CnV, CNTIN, MOD, HCR | In the up-counting mode, the synchronization points are when the FTM counter changes from MOD to CNTIN, enable CNTMIN, or CNTMAX bit. For the up/down-counting mode, see Table below. |
向上/向下計數模式下的重新加載機會
| FTM_SYNC bits | Reload opportunities selected |
|---|---|
| CNTMIN = 0 and CNTMAX = 0 | When the counter turns from up to down (compatibility mode). |
| CNTMIN = 1 and CNTMAX = 0 | When the counter turns from down to up. |
| CNTMIN = 0 and CNTMAX = 1 | When the counter turns from up to down. |
| CNTMIN = 1 and CNTMAX = 1 | When the counter turns from down to up and when the counter turns from up to down. |
(1)在初始化階段更新FTM寄存器
(2)半周期和全周期重裝策略
(3)通過軟件觸發更新FTM寄存器--軟件同步
(4)通過硬件觸發更新FTM寄存器--硬件同步
4.6.4 全局時基(GTB)
芯片上有多個FTM,但多個FTM模塊是獨立的。如果應用需要的 PWM 通道多于一個FTM 所能提供的通道數,則可以使用多個 FTM 模塊,但它們必須同步。兩個(或多個)FTM 模塊的同步意味著它們的計數器在任何時刻都具有相同的值。
S32K 設備提供了 GTB 機制來同步多個 FTM。 GTB 是由主 FTM 生成的同步信號,它啟動所有使用的 FTM 的計數器。使用 GTB 功能時必須滿足這兩個條件:每個 FTM 必須具有相同的時鐘源,并且每個 FTM 必須同時啟動。
要使能 GTB 功能,請對每個參與的 FTM 模塊執行以下步驟:
-
停止FTM計數器(將00b寫入SC[CLKS])。
-
將FTM編程為預期配置。 FTM 計數器模式必須在所有參與模塊中保持一致。
-
向CONF[GTBEEN]寫入1,同時向CONF[GTBEOUT]寫入0。
-
在 SC[CLKS] 中選擇預期的 FTM 計數器時鐘源。 所有參與模塊的時鐘源必須一致。
-
重置FTM計數器(向CNT寄存器寫入一些值)。
以下示例顯示了FTM0 和 FTM2 的同步。兩個 PWM 的占空比都調整為非常低的值,以更好地展示 GTB 機制的功能。
在圖 16 和圖 17 中,示波器通道 CH1、 CH2、 CH3 和 CH4 分別代表 FTM0 和 FTM2模塊的通道 FTM0_CH0、 FTM0_CH1、 FTM2_CH0 和 FTM2_CH1。 FTM0_CH0 和FTM0_CH1 工作在互補模式,與 FTM2_CH0 和 FTM2_CH1 相同。調整示波器的時基,以便在示波器顯示屏上可以清楚地看到通道 FTM0 和 FTM2 的 1% 占空比。如果全局時基未激活,則所使用的 FTM 的加減計數器不會完全對齊,它們的通道信號也不會對齊(參見圖16)。通過將 GTB 功能應用于 FTM 模塊來處理此類問題(參見圖 17)。 注意 GTB 功能不提供 FTM 計數器的連續同步,這意味著 FTM 計數器可能會在 FTM 操作期間失去同步。 GTB 功能僅允許 FTM 計數器啟動時同步 。
4.6.5 ADC由FTM和PDB模塊觸發
在電機控制應用以及開關電源應用中,有必要測量 PWM 信號中心的電流。功率器件在這個瞬間沒有切換,因此分流電阻上檢測到的壓降是穩定的。
S32K 設備的所有四個 FTM 模塊都有多達八個通道。六個通道通常足以生成控制常用三相電機所需的 PWM 信號。 FTM 模塊的其余兩個通道隨后可用于控制 ADC 轉換的時間點。
FTM 模塊的觸發信號可以在 FTM_EXTTRIG 寄存器中選擇。所有 FTM 通道均可用于觸發 ADC 模塊。例如,如果在 FTM_EXTTRIG 寄存器中設置 CH0,則 FTM 計數器計數,直到達到寫入 C0V 寄存器中的值。此時, CH0 產生一個信號,在每個 FTM 計數器周期觸發 ADC 模塊。如果 FTM_EXTTRIG 寄存器中的 INITTRIG 位被設置,則每次 FTM 計數器達到 CNTIN 寄存器的值時都會產生觸發信號。
ADC 模塊的默認和建議硬件觸發方案是通過可編程延遲塊 (PDB)。 S32K配備了兩個成對工作的 ADC 模塊和兩個 PDB 模塊。這意味著 PDB0 與 ADC0 鏈接, PDB1 與 ADC1 鏈接。每個 PDB 模塊都可以由軟件或硬件觸發。 FTM 模塊是可以通過 TRGMUX 寄存器TRGMUX_PDB0 和 TRGMUX_PDB1 選擇的觸發源之一。
要在中心對齊 PWM模式下 并通過 FTM0 到 PDB0 觸發 ADC0,請執行以下步驟:
-
初始化FTM0模塊為中心對齊PWM模式并使能FTM0_EXTTRIG寄存器中的 INITTRIGEN 位產生ADC0模塊的硬件觸發信號。
-
通過向TRGMUX_PDB0寄存器中的SEL0位域寫入0x16,配置TRGMUX模塊由 FTM0通過PDB0模塊觸發ADC0。
-
通過將適當的值寫入 PDB0_MOD 和 PDB0_CH0DLY0 寄存器,延遲 PDB0 模塊的 FTM0 初始化觸發,以在 PWM 周期的中心觸發 ADC0。
-
初始化ADC0模塊,使能ADC0_SC2寄存器中的ADTRG位,由FTM0模塊觸發 ADC0。 以下代碼示例演示了 FTM0、 PDB0 和 ADC0 模塊的配置,其中 FTM0 用于生成中心對齊 PWM信號并通過 PDB0 模塊觸發 ADC0。
在圖中,示波器通道 CH1 和 CH2 分別代表 FTM0 通道 FTM0_CH0 和 FTM0_CH1。通道對 FTM0_CH0/FTM0_CH1 工作在互補模式,與通道對 FTM0_CH2/FTM0_CH3 相同。示波器通道 CH3 和 CH4 演示了 FTM0、 PDB0 和 ADC0 模塊之間的互連。通道 CH3 表示每次 FTM0 計數器達到 CNTIN 寄存器的值時 PDB0 中斷程序中讓PTD2 引腳翻轉,每次ADC0 轉換完成(COCO = 1)時,通道 CH4 顯示 ADC0 中斷程序中讓 PTD3 引腳翻轉。FTM0 觸發信號由 PDB0 模塊延遲,以便 ADC0 轉換發生在 PWM 信號的中心。
4.6.6 精細控制
FTM實現了一個分數延遲,以實現對產生的PWM信號的精細分辨率控制。抖動可用于需要一個單位以上的FTM計數器分辨率的應用程序。
支持兩種抖動方式:PWM周期抖動和邊沿抖動。
4.6.6.1 PWM周期抖動
5. FTM的寄存器
5.1 寄存器特性
-
寄存器具有buffer,寫入后并不能立即更新。
-
系統設置載入點(load point),配合軟硬件觸發來從緩沖器更新寄存器的值。
-
很多寄存器具有寫保護功能。
5.2 寄存器
5.2.1 狀態和控制寄存器(FTMx_SC)
-
TOF
-
TOIE
-
CPWMS
-
CLKS
-
PS
5.2.2 計數器(FTMx_CNT)
向該寄存器寫入任何值將會使該寄存器回到初始設定值。
BDM模式下,FTM計數器被凍結。
5.2.3 模數寄存器(FTMx_MOD)
5.2.4 通道n狀態及控制寄存器(FTMx_CnSC)
每個通道都有一個CnSC寄存器。該寄存器中包含通道中斷標志位、中斷使能控制位、通道設置以及引腳功能設置。
-
CHF
-
CHIE
-
MSB/MSA
-
ELSB/ELSA
-
DMA
-
提前提到的 DECAPEN/COMBINE
5.2.5 通道n計數值寄存器(FTMx_CnV)
每個通道有一個CnV寄存器。
輸入捕獲模式下
當捕捉到設置的邊沿時,此時FTM計數器的值自動保存到CnV寄存器中,該值可用于反映捕捉事件發生的時刻。
輸出模式下
Cnv寄存器保存輸出匹配值,該值用于和FTM計數器的值進行比較,當相等時,則比較成功。
在輸入捕捉、捕捉測試和雙邊沿捕捉模式下,任何對該寄存器的寫入操作都無效。在輸出模式下,寫入該寄存器的值會先鎖存到緩沖器內,何時更新寄存器更新設置有關。
5.2.6 計數器初始值寄存器(FTMx_CNTIN)
該寄存器保存FTM計數器的初始值。
5.2.7 捕捉和比較狀態寄存器(FTMx_STATUS)
該寄存器中包含了每個通道的FTMx_CSC寄存器中的CHnF位的拷貝,以方便編程。這樣一次就可以讀出一個FTM模塊的所有通道的標志位。
5.2.8 特性模式選擇寄存器(FTMx_MODE)
該寄存器主要設置錯誤中斷、錯誤控制、捕捉測試模式、PWM同步、寫保護、通道輸出初始化、FTM增強特性使能。這些控制和所有通道都有關。
-
FAULTIE:錯誤中斷使能。
-
FAULTM:定義錯誤控制模式。
-
CAPTEST:捕捉測試使能。
-
PWMSYNC:PWM同步模式,即如何將某些寄存器的值從Buffer中更新的一種機制。
-
WPDIS:寫保護禁止,與WPEN相反。
-
INIT:通道輸出初始化。
-
FTMEN:FTM使能。
5.2.9 同步寄存器(FTMx_SYNC)
該寄存器用于設置PWM同步。一個同步事件能夠執行MOD,CV,OUTMASK寄存器的同步,即使用緩沖器中的值更新這幾個寄存器,這是FTM計數器也可以重新初始化。當FTMEN=1時,該寄存器必須合理設置。
-
SWSYNC:PWM同步軟件觸發。
-
TRIG2:PWM同步硬件觸發器2。使能硬件觸發器2觸發PWM同步,觸發器2輸入引腳上出現上升沿時硬件觸發。
-
TRIG1:PWM同步硬件觸發器1。使能硬件觸發器2觸發PWM同步,觸發器1輸入引腳上出現上升沿時硬件觸發。
-
TRIG0:PWM同步硬件觸發器0。使能硬件觸發器2觸發PWM同步,觸發器0輸入引腳上出現上升沿時硬件觸發。
-
SYNCHOM:輸出屏蔽同步,選擇OUTMASK寄存器是否從緩沖器里更新。
-
RENINT:FTM計數器重新初始化。
-
CNTMAX:最大載入點使能,當觸發事件發生后,知道FTM計數器達到某一個值時,這一時刻才會發生更新寄存器值的同步,這一時刻就是載入點。
當該位為1時,當FTM計數器達到最大值時,即MOD值,這一時刻將作為一個同步的載入點。
-
CNTMIN:最小裝載點使能。當該位為1時,當FTM計數器達到最小值時,即CNTIN值,這一時刻將作為一個同步的載入點。
5.2.10 通道輸出初始狀態(FTMx_OUTINIT)
-
CHxOI:通道x輸出初始值。
5.2.11 輸出屏蔽寄存器(FTMx_OUTMASK)
-
CHxOM:通道x輸出屏蔽
5.2.12 通道聯合功能寄存器(FTMx_COMBINE)
該寄存器包含:錯誤控制、同步、死區插入、雙邊沿捕捉模式、補償、雙通道聯合等功能。該寄存器在使用雙通道聯合功能時,主要是非對稱PWM輸出,雙通道互補輸出,雙邊沿捕捉等功能時需要合理設置。
-
FAULTENn:使能通道2n和2n+1的錯誤控制。
-
SYNCENn:使能寄存器C(2n)V和C(2n+1)V的PWM同步,即這兩個寄存器能否被觸發事件觸發更新。
-
DTENn:死區使能。
-
DECAPn:雙邊沿捕獲。(何為通道的雙邊沿)
-
COMPn:使能通道2n和2n+1的互補模式,即兩個通道波形相反。
-
COBINEn:通道2n和2n+1聯合設置。只有COMBINEn=1,才可使用上面那些位設置的功能。
5.2.13 死區插入控制寄存器(FTMx_DEADTIME)
該寄存器設置死區時間分頻系數和死區值。所有的FTM通道都使用這個時鐘分頻和死區值。
-
DTPS:分頻設置。死區時間的定時也是由對BusClock計數實現的,DTPS對BusClock分頻的設置。
-
DTVAL:DTVAL設置對DTPS分頻后的時鐘計數值以確定死區插入的時間。死區插入的時間=DTPS x DTVAL x 總線時鐘周期。
5.2.14 通道極性寄存器(FTMx_POL)
當各通道處于非活動狀態,給寄存器設置各通道非活動狀態下的值。
5.2.15 輸入捕捉濾波控制寄存器(FTMx_FILTER)
該寄存器設置輸入通道的濾波值,通道4、5、6、7無輸入濾波器。
濾波模式一般只在輸入捕捉時使用,當啟用濾波功能時,如果輸入端發生變化,則濾波器內部的5bit計數器開始累加計數,一旦溢出,輸入端變化才提交給邊沿檢測器。如果計數過程中,輸入端再次發生相反變化,則計數器會被復位并重新開始計數,這樣一些比過濾時間短的脈沖則會被視為干擾且不會提交給邊沿計數器,只有濾波模塊計數期間保持穩定的信號才會提交給邊沿計數器。
5.2.16 正交解碼控制和狀態寄存器(FTMx_QDCTRL)
正交解碼一般用于正反向脈沖計數,由旋轉編碼器輸入A相和B相脈沖,由FTM模塊根據相位自動增加或減少。在電機正反轉測速時非常有用。
-
PHAFLTREN:A相輸入濾波使能設置。
-
PHBFLTREN:B相輸入濾波使能設置。
-
PHAPOL:A相輸入極性選擇。
-
PHBPOL:B相輸入極性選擇。
-
QUADMODE:正交解碼模式。
-
QUADIR:正交解碼模式下的FTM計數方向狀態位,查詢該位可獲知當前計數方向。
-
TOFDIR:正交解碼模式下FTM計數器溢出方向。在溢出時,查詢該位可獲知溢出方向。
-
QUADEN:正交編解碼模式使能位。
5.2.17 設置寄存器(FTMx_CONF)
-
GTBEOUT:全局時間基準輸出,使能全局時間基準信號給其他FTM。
-
GTBEEN:全局時間基準使能,設置FTM使用一個其它FTM模塊產生的外部的全局時間基準。
-
BDMMODE:選擇FTM在BDM模式下的行為。
-
NUMOF:設置計數器溢出次數和TOF標志置位次數的比值,NUMTOF=n,每溢出n+1次,TOF置位一次。
5.2.18 同步設置寄存器(FTMx_SYNCONF)
該寄存器主要設置軟件觸發和硬件觸發對于某些寄存器的影響。
5.2.19 FTM反相設置寄存器(FTMx_INVCTRL)
該寄存器中的各位設置通道2n和通道2n+1顛倒使用,即n通道成為n+1通道的輸出,n+1通道輸出n通道的輸出。可用于控制電機正反轉切換。該功能在雙通道聯合互補輸出時可用。
-
INVnEN:通道2n和通道2n+1切換輸出使能。
5.2.20 FTM軟件輸出控制寄存器(FTMx_SWOCTRL)
該寄存器設置各通道強制輸出高電平或低電平。
-
CHnOS=1時對于通道n強制輸出:
-
CHnOCV=0,當強制輸出時,輸出低電平;
-
CHnOCV=1,當強制輸出時,輸出高電平。
5.2.21 FTMPWM裝載寄存器(FTMx_PWMLOAD)
使能PWM的自動載入功能,當FTM計數計到MOD設定值并變化到下一個值或該通道設置為輸出比較且比較成功時,MOD、CNTIN、C(n)V、C(n+1)V載入緩沖器中的值。
-
LDOK:載入使能。
-
CHnSEL:載入時是否包括通道n
6. Demo
6.0 外設引腳配置示例
/* Generate array of configured pin structures */
pin_settings_config_t g_pin_mux_InitConfigArr_ftm_pwm1[NUM_OF_CONFIGURED_PINS_FTM_PWM1] = {{.base ? ? ? ? ? ?= PORTA,.pinPortIdx ? ? ?= 22U,.pullConfig ? ? ?= PORT_INTERNAL_PULL_NOT_ENABLED,.driveSelect ? ? = PORT_STRENGTH_DISABLED,.mux ? ? ? ? ? ? = PORT_MUX_ALT2,.hysteresisSelect = PORT_HYSTERESYS_DISABLED,.gpioBase ? ? ? ?= NULL,.direction ? ? ? = GPIO_UNSPECIFIED_DIRECTION,.initValue ? ? ? = 0,.intConfig ? ? ? = PORT_INT_DISABLED,.clearIntFlag ? ?= false,.debounceEnable ?= false,},{.base ? ? ? ? ? ?= PORTA,.pinPortIdx ? ? ?= 21U,.pullConfig ? ? ?= PORT_INTERNAL_PULL_NOT_ENABLED,.driveSelect ? ? = PORT_STRENGTH_DISABLED,.mux ? ? ? ? ? ? = PORT_MUX_ALT2,.hysteresisSelect = PORT_HYSTERESYS_DISABLED,.gpioBase ? ? ? ?= NULL,.direction ? ? ? = GPIO_UNSPECIFIED_DIRECTION,.initValue ? ? ? = 0,.intConfig ? ? ? = PORT_INT_DISABLED,.clearIntFlag ? ?= false,.debounceEnable ?= false,},{.base ? ? ? ? ? ?= PORTA,.pinPortIdx ? ? ?= 3U,.pullConfig ? ? ?= PORT_INTERNAL_PULL_NOT_ENABLED,.driveSelect ? ? = PORT_STRENGTH_DISABLED,.mux ? ? ? ? ? ? = PORT_MUX_ALT2,.hysteresisSelect = PORT_HYSTERESYS_DISABLED,.gpioBase ? ? ? ?= NULL,.direction ? ? ? = GPIO_UNSPECIFIED_DIRECTION,.initValue ? ? ? = 0,.intConfig ? ? ? = PORT_INT_DISABLED,.clearIntFlag ? ?= false,.debounceEnable ?= false,},{.base ? ? ? ? ? ?= PORTA,.pinPortIdx ? ? ?= 2U,.pullConfig ? ? ?= PORT_INTERNAL_PULL_NOT_ENABLED,.driveSelect ? ? = PORT_STRENGTH_DISABLED,.mux ? ? ? ? ? ? = PORT_MUX_ALT2,.hysteresisSelect = PORT_HYSTERESYS_DISABLED,.gpioBase ? ? ? ?= NULL,.direction ? ? ? = GPIO_UNSPECIFIED_DIRECTION,.initValue ? ? ? = 0,.intConfig ? ? ? = PORT_INT_DISABLED,.clearIntFlag ? ?= false,.debounceEnable ?= false,},{.base ? ? ? ? ? ?= PORTB,.pinPortIdx ? ? ?= 0U,.pullConfig ? ? ?= PORT_INTERNAL_PULL_NOT_ENABLED,.driveSelect ? ? = PORT_STRENGTH_DISABLED,.mux ? ? ? ? ? ? = PORT_MUX_ALT2,.hysteresisSelect = PORT_HYSTERESYS_DISABLED,.gpioBase ? ? ? ?= NULL,.direction ? ? ? = GPIO_UNSPECIFIED_DIRECTION,.initValue ? ? ? = 0,.intConfig ? ? ? = PORT_INT_DISABLED,.clearIntFlag ? ?= false,.debounceEnable ?= false,},{.base ? ? ? ? ? ?= PORTA,.pinPortIdx ? ? ?= 31U,.pullConfig ? ? ?= PORT_INTERNAL_PULL_NOT_ENABLED,.driveSelect ? ? = PORT_STRENGTH_DISABLED,.mux ? ? ? ? ? ? = PORT_MUX_ALT2,.hysteresisSelect = PORT_HYSTERESYS_DISABLED,.gpioBase ? ? ? ?= NULL,.direction ? ? ? = GPIO_UNSPECIFIED_DIRECTION,.initValue ? ? ? = 0,.intConfig ? ? ? = PORT_INT_DISABLED,.clearIntFlag ? ?= false,.debounceEnable ?= false,},{.base ? ? ? ? ? ?= PORTA,.pinPortIdx ? ? ?= 30U,.pullConfig ? ? ?= PORT_INTERNAL_PULL_NOT_ENABLED,.driveSelect ? ? = PORT_STRENGTH_DISABLED,.mux ? ? ? ? ? ? = PORT_MUX_ALT2,.hysteresisSelect = PORT_HYSTERESYS_DISABLED,.gpioBase ? ? ? ?= NULL,.direction ? ? ? = GPIO_UNSPECIFIED_DIRECTION,.initValue ? ? ? = 0,.intConfig ? ? ? = PORT_INT_DISABLED,.clearIntFlag ? ?= false,.debounceEnable ?= false,},{.base ? ? ? ? ? ?= PORTA,.pinPortIdx ? ? ?= 23U,.pullConfig ? ? ?= PORT_INTERNAL_PULL_NOT_ENABLED,.driveSelect ? ? = PORT_STRENGTH_DISABLED,.mux ? ? ? ? ? ? = PORT_MUX_ALT2,.hysteresisSelect = PORT_HYSTERESYS_DISABLED,.gpioBase ? ? ? ?= NULL,.direction ? ? ? = GPIO_UNSPECIFIED_DIRECTION,.initValue ? ? ? = 0,.intConfig ? ? ? = PORT_INT_DISABLED,.clearIntFlag ? ?= false,.debounceEnable ?= false,},{.base ? ? ? ? ? ?= PORTA,.pinPortIdx ? ? ?= 14U,.pullConfig ? ? ?= PORT_INTERNAL_PULL_NOT_ENABLED,.driveSelect ? ? = PORT_STRENGTH_DISABLED,.mux ? ? ? ? ? ? = PORT_MUX_ALT2,.hysteresisSelect = PORT_HYSTERESYS_DISABLED,.gpioBase ? ? ? ?= NULL,.direction ? ? ? = GPIO_UNSPECIFIED_DIRECTION,.initValue ? ? ? = 0,.intConfig ? ? ? = PORT_INT_DISABLED,.clearIntFlag ? ?= false,.debounceEnable ?= false,},{.base ? ? ? ? ? ?= PORTA,.pinPortIdx ? ? ?= 13U,.pullConfig ? ? ?= PORT_INTERNAL_PULL_NOT_ENABLED,.driveSelect ? ? = PORT_STRENGTH_DISABLED,.mux ? ? ? ? ? ? = PORT_MUX_ALT2,.hysteresisSelect = PORT_HYSTERESYS_DISABLED,.gpioBase ? ? ? ?= NULL,.direction ? ? ? = GPIO_UNSPECIFIED_DIRECTION,.initValue ? ? ? = 0,.intConfig ? ? ? = PORT_INT_DISABLED,.clearIntFlag ? ?= false,.debounceEnable ?= false,},{.base ? ? ? ? ? ?= PORTA,.pinPortIdx ? ? ?= 18U,.pullConfig ? ? ?= PORT_INTERNAL_PULL_NOT_ENABLED,.driveSelect ? ? = PORT_STRENGTH_DISABLED,.mux ? ? ? ? ? ? = PORT_MUX_ALT2,.hysteresisSelect = PORT_HYSTERESYS_DISABLED,.gpioBase ? ? ? ?= NULL,.direction ? ? ? = GPIO_UNSPECIFIED_DIRECTION,.initValue ? ? ? = 0,.intConfig ? ? ? = PORT_INT_DISABLED,.clearIntFlag ? ?= false,.debounceEnable ?= false,},{.base ? ? ? ? ? ?= PORTA,.pinPortIdx ? ? ?= 16U,.pullConfig ? ? ?= PORT_INTERNAL_PULL_NOT_ENABLED,.driveSelect ? ? = PORT_STRENGTH_DISABLED,.mux ? ? ? ? ? ? = PORT_MUX_ALT2,.hysteresisSelect = PORT_HYSTERESYS_DISABLED,.gpioBase ? ? ? ?= NULL,.direction ? ? ? = GPIO_UNSPECIFIED_DIRECTION,.initValue ? ? ? = 0,.intConfig ? ? ? = PORT_INT_DISABLED,.clearIntFlag ? ?= false,.debounceEnable ?= false,},{.base ? ? ? ? ? ?= PORTA,.pinPortIdx ? ? ?= 28U,.pullConfig ? ? ?= PORT_INTERNAL_PULL_NOT_ENABLED,.driveSelect ? ? = PORT_STRENGTH_DISABLED,.mux ? ? ? ? ? ? = PORT_MUX_ALT2,.hysteresisSelect = PORT_HYSTERESYS_DISABLED,.gpioBase ? ? ? ?= NULL,.direction ? ? ? = GPIO_UNSPECIFIED_DIRECTION,.initValue ? ? ? = 0,.intConfig ? ? ? = PORT_INT_DISABLED,.clearIntFlag ? ?= false,.debounceEnable ?= false,},{.base ? ? ? ? ? ?= PORTA,.pinPortIdx ? ? ?= 29U,.pullConfig ? ? ?= PORT_INTERNAL_PULL_NOT_ENABLED,.driveSelect ? ? = PORT_STRENGTH_DISABLED,.mux ? ? ? ? ? ? = PORT_MUX_ALT2,.hysteresisSelect = PORT_HYSTERESYS_DISABLED,.gpioBase ? ? ? ?= NULL,.direction ? ? ? = GPIO_UNSPECIFIED_DIRECTION,.initValue ? ? ? = 0,.intConfig ? ? ? = PORT_INT_DISABLED,.clearIntFlag ? ?= false,.debounceEnable ?= false,},
};
/******************************************************************************************************** EOF
*******************************************************************************************************/
6.1 EPWM
/*** @page misra_violations MISRA-C:2012 violations** @section [global]* Violates MISRA 2012 Advisory Rule 8.7, External variable could be made static.* The external variables will be used in other source files in application code.**/
?
/* Global configuration of flexTimer_pwm_1 InitConfig */
ftm_user_config_t flexTimer_pwm_1_InitConfig_pwm =
{{true, /* Software trigger state */false, /* Hardware trigger 1 state */false, /* Hardware trigger 2 state */false, /* Hardware trigger 3 state */false, /* Max loading point state */false, /* Min loading point state */FTM_PWM_SYNC, /* Update mode for INVCTRL register */FTM_PWM_SYNC, /* Update mode for SWOCTRL register */FTM_PWM_SYNC, /* Update mode for OUTMASK register */FTM_PWM_SYNC, /* Update mode for CNTIN register */true, /* Automatic clear of the trigger*/FTM_UPDATE_NOW, /* Synchronization point */},FTM_MODE_EDGE_ALIGNED_PWM, /* Mode of operation for FTM */FTM_CLOCK_DIVID_BY_1, /* FTM clock prescaler */FTM_CLOCK_SOURCE_SYSTEMCLK, ? /* FTM clock source */FTM_BDM_MODE_11, /* FTM debug mode */false, ? ?/* Interrupt state */false ? ? /* Initialization trigger */
};
?
/* PWM configuration for flexTimer_pwm_1 */
ftm_pwm_param_t flexTimer_pwm_1_PwmConfig_pwm =
{1U, /* Number of independent PWM channels */0U, /* Number of combined PWM channels */FTM_MODE_EDGE_ALIGNED_PWM, /* PWM mode */0U, /* Dead time value */FTM_DEADTIME_DIVID_BY_1, /* Dead time prescale */1000U, /* PWM frequency */flexTimer_pwm_1_IndependentChannelsConfig_pwm, /* The independent PWM channels configuration structure */NULL, /* Combined PWM channels configuration structure */&flexTimer_pwm_1_FaultConfig /* PWM fault configuration structure */
};
?
/*!\brief The FTMTestEdgePwm function for the project.\details The startup initialization sequence is the following:* - startup asm routine* - FTMTestEdgePwm()
*/
int FTMTestEdgePwm(void)
{/* Write your local variable definition here */ftm_state_t ftmStateStruct;uint16_t dutyCycle = flexTimer_pwm_1_IndependentChannelsConfig_pwm[0].uDutyCyclePercent;
?/* Initialize pins */PINS_DRV_Init(NUM_OF_CONFIGURED_PINS_FTM_PWM1, g_pin_mux_InitConfigArr_ftm_pwm1);
?/* Initialize FTM instance */FTM_DRV_Init(INST_FLEXTIMER_PWM_1, &flexTimer_pwm_1_InitConfig_pwm, &ftmStateStruct);
?/* Initialize FTM PWM */FTM_DRV_InitPwm(INST_FLEXTIMER_PWM_1, &flexTimer_pwm_1_PwmConfig_pwm);
?/* Infinite loop */for ( ;; ){dutyCycle += 50;if (dutyCycle >= 0x8000U){dutyCycle = 1U;}FTM_DRV_UpdatePwmChannel(INST_FLEXTIMER_PWM_1,flexTimer_pwm_1_IndependentChannelsConfig_pwm[0].hwChannelId,FTM_PWM_UPDATE_IN_DUTY_CYCLE, dutyCycle,0U,true);OS_DelayMs(5);}
?return exit_code;
}
6.2 CPWM
/*!\brief The FTMTestCenterPwm function for the project.\details The startup initialization sequence is the following:* - startup asm routine* - FTMTestCenterPwm()
*/
int FTMTestCenterPwm(void)
{/* Write your local variable definition here */ftm_state_t ftmStateStruct;uint16_t dutyCycle = flexTimer_pwm_1_IndependentChannelsConfig_pwm[0].uDutyCyclePercent;
?/* Initialize pins */PINS_DRV_Init(NUM_OF_CONFIGURED_PINS_FTM_PWM1, g_pin_mux_InitConfigArr_ftm_pwm1);
?flexTimer_pwm_1_PwmConfig_pwm.mode = FTM_MODE_CEN_ALIGNED_PWM;
?/* Initialize FTM instance */FTM_DRV_Init(INST_FLEXTIMER_PWM_1, &flexTimer_pwm_1_InitConfig_pwm, &ftmStateStruct);
?/* Initialize FTM PWM */FTM_DRV_InitPwm(INST_FLEXTIMER_PWM_1, &flexTimer_pwm_1_PwmConfig_pwm);
?/* Infinite loop */for ( ;; ){dutyCycle += 50;if (dutyCycle >= 0x8000U){dutyCycle = 1U;}FTM_DRV_UpdatePwmChannel(INST_FLEXTIMER_PWM_1,flexTimer_pwm_1_IndependentChannelsConfig_pwm[0].hwChannelId,FTM_PWM_UPDATE_IN_DUTY_CYCLE, dutyCycle,0U,true);OS_DelayMs(5);}return exit_code;
}
6.3 Input Capture
/* Global configuration of flexTimer_ic_1 InitConfig */
ftm_user_config_t flexTimer_ic_1_InitConfig =
{{true, ? ?/* Software trigger state */false, ?/* Hardware trigger 1 state */false, ?/* Hardware trigger 2 state */false, ?/* Hardware trigger 3 state */false, /* Max loading point state */false, /* Min loading point state */FTM_SYSTEM_CLOCK, /* Update mode for INVCTRL register */FTM_SYSTEM_CLOCK, /* Update mode for SWOCTRL register */FTM_SYSTEM_CLOCK, /* Update mode for OUTMASK register */FTM_SYSTEM_CLOCK, /* Update mode for CNTIN register */false, /* Automatic clear of the trigger */FTM_UPDATE_NOW, /* Synchronization point */},FTM_MODE_INPUT_CAPTURE, /* Mode of operation for FTM */FTM_CLOCK_DIVID_BY_1, /* FTM clock prescaler */FTM_CLOCK_SOURCE_SYSTEMCLK, ? /* FTM clock source */FTM_BDM_MODE_11, /* FTM debug mode */false, ? ?/* Interrupt state */false ? ? /* Initialization trigger */
};
?
?
/* Input capture configuration for flexTimer_ic_1 */
ftm_input_param_t flexTimer_ic_1_InputCaptureConfig =
{1U, /* Number of channel configurations */65535U, /* Maximum count value */flexTimer_ic_1_InputCaptureChannelConfig /* Channels configuration*/
};
?
/*!\brief The ftm_signal_measure_entry function for the project.\details The startup initialization sequence is the following:* - startup asm routine
*/
int FTMTestCapture(void)
{ftm_state_t ftm1StateStruct;ftm_state_t ftm2StateStruct;/* Variables used to store PWM frequency,* input capture measurement value*/uint16_t inputCaptureMeas = 0U;uint32_t frequency;
?bool conversionComplete = false;/* Buffer for string processing */char txBuff[255];
?/* Initialize pins* ? - ? See PinSettings component for more info*/PINS_DRV_Init(NUM_OF_CONFIGURED_PINS_FTM_SG0, g_pin_mux_InitConfigArr_ftm_sg0);PINS_DRV_Init(NUM_OF_CONFIGURED_PINS_FTM_SG1, g_pin_mux_InitConfigArr_ftm_sg1);
?/* Initialize FTM instances, PWM and Input capture* - ? See ftm component for more details*/FTM_DRV_Init(INST_FLEXTIMER_IC_1, &flexTimer_ic_1_InitConfig, &ftm1StateStruct);FTM_DRV_Init(INST_FLEXTIMER_PWM_1, &flexTimer_pwm_1_InitConfig, &ftm2StateStruct);
?/* Setup input capture */FTM_DRV_InitInputCapture(INST_FLEXTIMER_IC_1, &flexTimer_ic_1_InputCaptureConfig);
?/* Start PWM */FTM_DRV_InitPwm(INST_FLEXTIMER_PWM_1, &flexTimer_pwm_1_PwmConfig);
?/* Get the FTM frequency to calculate* the frequency of the measured signal.*/frequency = FTM_DRV_GetFrequency(INST_FLEXTIMER_IC_1);
?/* Send the hello message */log_info("This example will show you how to use FTM's signal measurement feature.\r\n""To achieve that we will generate a modifiable frequency PWM and read it with Input Capture.\r\n");
?/* Infinite loop* - ? Wait for user input* - ? Measure and calculate the signal frequency* - ? Send original and measured freq via LPUART* - ? Modify the PWM frequency*/for ( ;; ){//log_info("Press any key to initiate a new conversion...\r\n");OS_DelayS(5);/* Wait for user input *///LPUART_DRV_ReceiveDataBlocking(INST_LPUART_1, (uint8_t *)&txBuff, 1U, 1 << 31U);conversionComplete = false;
?while (conversionComplete == false){/* Wait a number of cycles for the PWM to reach stability */delayCycles(0x7FFFFU);
?/* Get the latest value */inputCaptureMeas = FTM_DRV_GetInputCaptureMeasurement(INST_FLEXTIMER_IC_1, 0U);/* Calculate the signal frequency using recorded data*/inputCaptureMeas = frequency / (inputCaptureMeas);
?/* Stop PWM */FTM_DRV_DeinitPwm(INST_FLEXTIMER_PWM_1);
?/* Convert the integer to char array and send it*/sprintf(txBuff, "PWM frequency:%6lu, Measured frequency:%6u [Hz]\r\n",flexTimer_pwm_1_PwmConfig.uFrequencyHZ, inputCaptureMeas);log_info("%s\n", txBuff);
?/* Increase frequency */if (flexTimer_pwm_1_PwmConfig.uFrequencyHZ < 3000U){flexTimer_pwm_1_PwmConfig.uFrequencyHZ += 100U;}else{flexTimer_pwm_1_PwmConfig.uFrequencyHZ = 1000U;conversionComplete = true;}
?/* Restart PWM with new settings */FTM_DRV_InitPwm(INST_FLEXTIMER_PWM_1, &flexTimer_pwm_1_PwmConfig);}}
?return exit_code;
}
6.4 中斷
/*!\brief The ftm_periodic_interrupt function for the project.\details The startup initialization sequence is the following:* - startup asm routine* - FTMTestInterrupt()
*/
int FTMTestInterrupt(void)
{/* Write your local variable definition here */ftm_state_t state;
?/* Initialize pins */PINS_DRV_Init(NUM_OF_CONFIGURED_PINS_INT0, g_pin_mux_InitConfigArr_int0);
?/* Initialize FTM */FTM_DRV_Init(INST_FLEXTIMER_MC_1, &flexTimer_mc_1_InitConfig_0, &state);
?/* Initialize counter */FTM_DRV_InitCounter(INST_FLEXTIMER_MC_1, &flexTimer_mc_1_TimerConfig_0);
?/* Start Counter */FTM_DRV_CounterStart(INST_FLEXTIMER_MC_1);
?/* Loop */for (;;){/* Do no thing, just wait for the interrupt */}
?return exit_code;
}
6.5 Combined pwm
/*** @page misra_violations MISRA-C:2012 violations** @section [global]* Violates MISRA 2012 Advisory Rule 8.7, External variable could be made static.* The external variables will be used in other source files in application code.**/
?
/* Global configuration of flexTimer_pwm_1 InitConfig */
ftm_user_config_t flexTimer_pwm_1_InitConfig_cb =
{{true, /* Software trigger state */false, /* Hardware trigger 1 state */false, /* Hardware trigger 2 state */false, /* Hardware trigger 3 state */false, /* Max loading point state */false, /* Min loading point state */FTM_PWM_SYNC, /* Update mode for INVCTRL register */FTM_PWM_SYNC, /* Update mode for SWOCTRL register */FTM_PWM_SYNC, /* Update mode for OUTMASK register */FTM_PWM_SYNC, /* Update mode for CNTIN register */true, /* Automatic clear of the trigger*/FTM_UPDATE_NOW, /* Synchronization point */},FTM_MODE_EDGE_ALIGNED_PWM, /* Mode of operation for FTM */FTM_CLOCK_DIVID_BY_1, /* FTM clock prescaler */FTM_CLOCK_SOURCE_SYSTEMCLK, ? /* FTM clock source */FTM_BDM_MODE_11, /* FTM debug mode */false, ? ?/* Interrupt state */false ? ? /* Initialization trigger */
};
?
/* PWM configuration for flexTimer_pwm_1 */
ftm_pwm_param_t flexTimer_pwm_1_PwmConfig_cb =
{0U, /* Number of independent PWM channels */1U, /* Number of combined PWM channels */FTM_MODE_EDGE_ALIGNED_PWM, /* PWM mode */48U, /* Dead time value */FTM_DEADTIME_DIVID_BY_4, /* Dead time prescale */10000U, /* PWM frequency */NULL, /* The independent PWM channels configuration structure */flexTimer_pwm_1_CombinedChannelsConfig, /* Combined PWM channels configuration structure */&flexTimer_pwm_1_FaultConfig /* PWM fault configuration structure */
};
?
/*!\brief The ftm_combined_pwm function for the project.\details The startup initialization sequence is the following:* - startup asm routine* - ftm_combined_pwm()
*/
int FTMTestCombinedPwm(void)
{/* Write your local variable definition here */ftm_state_t ftmStateStruct;bool increaseDutyCycle = true;uint32_t dutyCycle ?= 0UL;
?/* Initialize pins */PINS_DRV_Init(NUM_OF_CONFIGURED_PINS_FTM_PWM0, g_pin_mux_InitConfigArr_ftm_pwm0);
?/* Initialize FTM */FTM_DRV_Init(INST_FLEXTIMER_PWM_1, &flexTimer_pwm_1_InitConfig_cb, &ftmStateStruct);
?/* Initialize FTM PWM */FTM_DRV_InitPwm(INST_FLEXTIMER_PWM_1, &flexTimer_pwm_1_PwmConfig_cb);
?/* Infinite loop* - ? increment or decrement duty cycleU* - ? Update channel duty cycle* - ? Wait for a number of cycles to make* ? ? the change visible*/for ( ;; ){if (increaseDutyCycle == false){dutyCycle -= 1U;if (dutyCycle < 1U)increaseDutyCycle = true;}else{dutyCycle += 1U;if (dutyCycle > 0x7FFF)increaseDutyCycle = false;}
?/* Update PWM channels */FTM_DRV_UpdatePwmChannel(INST_FLEXTIMER_PWM_1, 0U, FTM_PWM_UPDATE_IN_DUTY_CYCLE, 0UL, dutyCycle, true);delayCycles(0xFFU);}
?return exit_code;
}
6.6 Deadtime PWM
6.7 Fault Control
int FTMTestFaultControl(void)
{/* Write your local variable definition here */ftm_state_t ftmStateStruct;ftm_state_t ftmStateStruct_1;bool increaseDutyCycle = true;uint32_t dutyCycle ?= 0UL;bool result = false;int32_t idx = 0U;
?OS_IoWrite32((void *)0x40080230, 0xffffffff);OS_IoWrite32((void *)0x40080234, 0xffffffff);OS_IoWrite32((void *)0x40080238, 0xffffffff);OS_IoWrite32((void *)0x4008023C, 0xffffffff);OS_IoWrite32((void *)0x40080240, 0xffffffff);OS_IoWrite32((void *)0x40080244, 0xffffffff);OS_IoWrite32((void *)0x400800A8, 0x1);OS_IoWrite32((void *)0x400800B4, 0x1);OS_IoWrite32((void *)0x400800C0, 0x1);OS_IoWrite32((void *)0x400800CC, 0x1);
?/* Initialize pins */PINS_DRV_Init(NUM_OF_CONFIGURED_PINS_FTM_PWM0, g_pin_mux_InitConfigArr_ftm_pwm0);
?/* Initialize FTM */
?//flexTimer_pwm_1_InitConfig_cb.BDMMode = FTM_BDM_MODE_00;FTM_DRV_Init(INST_FLEXTIMER_PWM_1, &flexTimer_pwm_1_InitConfig_cb, &ftmStateStruct);
?//FTM_DRV_EnableInterrupts(INST_FLEXTIMER_PWM_1, FTM_FAULT_INT_ENABLE);
?/* Initialize FTM PWM */flexTimer_pwm_1_PwmConfig_cb.faultConfig->faultMode = FTM_FAULT_CONTROL_AUTO_ALL;flexTimer_pwm_1_PwmConfig_cb.faultConfig->pwmFaultInterrupt = false;FTM_DRV_InitPwm(INST_FLEXTIMER_PWM_1, &flexTimer_pwm_1_PwmConfig_cb);
?/* Infinite loop* - ? increment or decrement duty cycleU* - ? Update channel duty cycle* - ? Wait for a number of cycles to make* ? ? the change visible*/delayCycles(1000U);
?FTM_DRV_Init(INST_FLEXTIMER_PWM_2, &flexTimer_pwm_1_InitConfig_cb, &ftmStateStruct_1);flexTimer_pwm_1_PwmConfig_cb.faultConfig->faultMode = FTM_FAULT_CONTROL_DISABLED;flexTimer_pwm_1_PwmConfig_cb.uFrequencyHZ = flexTimer_pwm_1_PwmConfig_cb.uFrequencyHZ / 10;FTM_DRV_InitPwm(INST_FLEXTIMER_PWM_2, &flexTimer_pwm_1_PwmConfig_cb);
?while (1);
?return result;
}
7. 應用舉例
7.1 步進電機驅動
步進電機控制示意圖,通過FTM模塊控制電機的兩個H橋,比較器可以用作電機線圈過流保護,ADC模塊提供過流檢測參考信號。
7.2 基于霍爾傳感器的BLDC驅動
直流無刷電機控制示意圖,六路FTM通道控制電機的三相線圈,霍爾傳感器提供電機轉速信息(使用一路FTM來測量脈沖周期)。
7.3 ACIM/PMSM電機控制
永磁同步電機控制示意圖,使用六路FTM控制電機三相橋,正交信號提供電機轉速信息(使用FTM正交譯碼功能)
?
總結
以上是生活随笔為你收集整理的S32K FTM(FlexTimer module)详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: sprintf()函数的使用
- 下一篇: UVA - 725 Division-s