FTM的PWM、輸入捕獲、正交解碼
輸入捕獲初始化完畢后,FTM1就會在PTB0有輸入PWM的時候產生中斷了,接下來看一下其中斷函數是怎么寫的:本文引用地址:http://cqxgywz.com/article/201611/322237.htm
| 01 | voidic_isr(void) |
| 02 | { |
| 03 | uint32cnt; |
| 04 | if(LPLD_FTM_IsCHnF(FTM1,FTM_Ch0)) |
| 05 | { |
| 06 | cnt=LPLD_FTM_GetChVal(FTM1,FTM_Ch0); |
| 07 | Freq1=(g_bus_clock/LPLD_FTM_GetClkDiv(FTM1))/cnt; |
| 08 | LPLD_FTM_ClearCounter(FTM1); |
| 09 | LPLD_FTM_ClearCHnF(FTM1,FTM_Ch0); |
| 10 | } |
| 11 | } |
Line 4:首先調用LPLD_FTM_IsCHnF()函數判斷是不是FTM1的Ch0通道產生的捕獲事件,因為每個FTMx的所有通道中斷都是公用一個中斷函數的,所以為了安全,必須在中斷中判斷是哪個通道產生的中斷。
Line 6:獲得Ch0通道的計數值,并存到臨時變量cnt中。這個值就是C0V小朋友在事件來臨的一瞬間,從CNT那里記錄下來的計數值。
Line 7:用上將講到的頻率計算公式來計算出PWM的頻率。這里LPLD_FTM_GetClkDiv()可以得到我們初始化時設置的計數器分頻系數,g_bus_clock變量是總線頻率的數值,用(g_bus_clock/LPLD_FTM_GetClkDiv(FTM1))就得到了計數器CNT的技術頻率,在除以cnt計數值,得到的就是輸入方波的頻率。
Line 8:用LPLD_FTM_ClearCounter()函數清空CNT小朋友的計數值,以便我們下次中斷獲取的值是從0開始的,方便計算。
Line 9:用LPLD_FTM_ClearCHnF()函數清除Ch0通道的中斷標志。
正交解碼
正交解碼原理
講到正交解碼,其實并沒有什么神秘的,名字聽起來挺高端大氣上檔次的,其實實現起來非常簡單,我覺得反而是FTM模塊中最簡單的功能。首先要清楚正交解碼是干嘛用的,舉個栗子?霍爾編碼器是常用的電機測速傳感器,他不僅可以測速,還可以知道電機的正轉還是反轉,靠的就是他能輸出兩路正交信號,我們可以通過正交信號的相位差來識別出當前電機的轉動方向。因此有了FTM模塊,我們就可以將這兩路正交信號PhA和PhB輸入到FTM的正交輸入通道,通過正交解碼功能,直接讀取脈沖的計數值,這個計數值是有符號的,正數代表正轉,負數則代表反轉。
具體到FTM內部時怎樣工作的,還要提到CNT小朋友,在正交解碼模式下,他不再按照SC給定的規則喊號了,而是根據兩路PhA和PhB正交信號的狀態來計數。你也可以理解為CNT小朋友是一個解碼員,當然具體是增計數還是減計數,不是CNT說了算,FTM內部有一套復雜的機制決定。而且這個正交解碼功能有兩種解碼方法可以選擇,分別是計數和方向編碼、相位A和相位B編碼。他們的解碼方法如下面兩圖所示:
上圖是計數和方向編碼方法,紅框后面的波形是FTM輸入通道PhB的波形,它代表計數方向,籃框后面的波形是FTN輸入通道PhA的波形,它代表計數個數,這是一種編碼方法,當PhB為高電平時,CNT加計數,當PhB低電平時,CNT減計數,計數頻率由PhA決定。從圖中還可以看出,CNTIN小朋友決定從什么數開始計數,MOD小朋友決定計數到什么時候產生溢出中斷。
上圖是相位A和相位B編碼方法,這個是我們常用的正交解碼模式,也是霍爾編碼傳感器兩路波形輸出的方式。從圖中可以看到,當PhA和PhB處于特定的電平和邊沿時,他們的狀態共同決定了CNT是增還是減。具體原則如下:
CNT小朋友增計數時看到的是:
A上升沿,B邏輯低
B上升沿,A邏輯高
B下降沿,A邏輯低
A下降沿,B邏輯高
CNT小朋友減計數時看到的是:
A下降沿,B邏輯低
B下降沿,A邏輯高
B上升沿,A邏輯低
A上升沿,B邏輯高
正交解碼例程講解
要測試正交解碼例程,首先你要準備兩路正交信號,可以用霍爾編碼器的信號直接輸入。打開例程“LPLD_QuadratureDecoder”,看正交解碼初始化函數qd_init()的代碼:
| 1 | ftm_init_struct.FTM_Ftmx=FTM1;//只有FTM1和FTM2有正交解碼功能 |
| 2 | ftm_init_struct.FTM_Mode=FTM_MODE_QD;//正交解碼功能 |
| 3 | ftm_init_struct.FTM_QdMode=QD_MODE_PHAB;//AB相輸入模式 |
| 4 | LPLD_FTM_Init(ftm_init_struct); |
| 5 | LPLD_FTM_QD_Enable(FTM1,PTB0,PTB1); |
Line 2:配置FTM1為正交解碼功能,這里需要注意的是,FTM中只有FTM1和FTM2具有正交解碼輸入通道,FTM0是沒有的。
Line 3:選擇解碼模式為AB相輸入模式解碼QD_MODE_PHAB。
Line 5:使能FTM1的正交解碼物理輸入引腳,調用LPLD_FTM_QD_Enable()函數,第二個參數是PhA相的物理引腳,第三個參數的PhB的。關于此函數的參數的具體范圍,請參考FTM模塊的在線函數手冊(點擊進入)。
正交解碼初始化完畢后,還要初始化定時中斷模塊,因為我們要在固定的間隔時間內獲取計數值才能計算出頻率,所以就務必會用到PIT模塊。pit_init()函數是PIT初始化函數,相信大家都能讀懂,這里我就不重復解釋了。下面直接看PIT的中斷函數代碼:
| 1 | qd_result=LPLD_FTM_GetCounter(FTM1); |
| 2 | LPLD_FTM_ClearCounter(FTM1); |
Line 1:LPLD_FTM_GetCounter()函數可以獲取當前FTM計數器即CNT小朋友的計數值,當然這個值是有符號的,可以正可以是負數。如果是正代表電機在正轉,如果是負,代表電機在反轉。
Line 2:為了下次方便計數,情況CNT的計數值。
當然,本例程只是簡單的獲取計數值,如果你要計算頻率,還用通過你的定時中斷時間進一步計算。
FTM拾遺補缺
PWM死區
PWM死去是在是PWM輸出時,為了使H橋或半H橋的上下管不會因為器件本身的開關速度問題導致同時導通而設置的一個保護時段。這個時間在Kinetis的FTM模塊也是可以設置的,當然在庫函數使用時就更簡單了,你只要在配置PWM輸出時,配置FTM_PwmDeadtimeCfg和FTM_PwmDeadtimeDiv就可以了。這兩個成員變量的取值本文不再贅述,請參考在線函數手冊。
溢出中斷
除了輸入捕獲能產生中斷外,FTM內部也會產生溢出中斷,這是你在使用輸入捕獲或者正交解碼時可能遇到的問題,那么什么是溢出中斷呢,它是當CNT計數器計數到上限時產生的一種中斷。你可以在初始化FTM時配置是否使能該中斷,利用成員變量FTM_ToiEnable。


評論