通常工程的底層代碼搭建好以後,大部分應用程序中用到的PWM功能能夠用如下三個函數表示:ide
* 修改PWM佔空比、周期函數
typedef struct{ Uint16 TBPRD7; Uint16 TBPRD8; Uint16 TBPRD9; Uint16 TBPRD10; Uint16 TBPRD11; Uint16 TBPRD12; Uint16 CmpA7; Uint16 CmpA8; Uint16 CmpA9; Uint16 CmpA10; Uint16 CmpA11; Uint16 CmpA12;} PwmData; void PwmManage(PwmData*data){ EPwm7Regs.TBPRD = data->TBPRD7; EPwm8Regs.TBPRD = data->TBPRD8; EPwm9Regs.TBPRD = data->TBPRD9; EPwm10Regs.TBPRD = data->TBPRD10; EPwm11Regs.TBPRD = data->TBPRD11; EPwm12Regs.TBPRD = data->TBPRD12; EPwm7Regs.CMPA.bit.CMPA = data->CmpA7; EPwm8Regs.CMPA.bit.CMPA = data->CmpA8; EPwm9Regs.CMPA.bit.CMPA = data->CmpA9; EPwm10Regs.CMPA.bit.CMPA = data->CmpA10; EPwm11Regs.CMPA.bit.CMPA = data->CmpA11; EPwm12Regs.CMPA.bit.CMPA = data->CmpA12;}
* 釋放PWM測試
void PwmEnable(void){ EALLOW; EPwm1Regs.TZCLR.bit.OST = 1; EPwm2Regs.TZCLR.bit.OST = 1; EPwm3Regs.TZCLR.bit.OST = 1; EPwm4Regs.TZCLR.bit.OST = 1; EPwm5Regs.TZCLR.bit.OST = 1; EPwm6Regs.TZCLR.bit.OST = 1; EPwm7Regs.TZCLR.bit.OST = 1; EPwm8Regs.TZCLR.bit.OST = 1; EPwm9Regs.TZCLR.bit.OST = 1; EPwm10Regs.TZCLR.bit.OST = 1; EPwm11Regs.TZCLR.bit.OST = 1; EPwm12Regs.TZCLR.bit.OST = 1; EDIS; }
* 閉鎖PWM翻譯
void PwmDisable(void){ EALLOW; EPwm1Regs.TZFRC.bit.OST = 1; EPwm2Regs.TZFRC.bit.OST = 1; EPwm3Regs.TZFRC.bit.OST = 1; EPwm4Regs.TZFRC.bit.OST = 1; EPwm5Regs.TZFRC.bit.OST = 1; EPwm6Regs.TZFRC.bit.OST = 1; EPwm7Regs.TZFRC.bit.OST = 1; EPwm8Regs.TZFRC.bit.OST = 1; EPwm9Regs.TZFRC.bit.OST = 1; EPwm10Regs.TZFRC.bit.OST = 1; EPwm11Regs.TZFRC.bit.OST = 1; EPwm12Regs.TZFRC.bit.OST = 1; EDIS; }
上面代碼中釋放與閉鎖PWM的功能是由軟件TRIP實現的。code
以上三個函數基本在兩電平或者三電平逆變器上用的比較多,除此以外PWM還有不少其餘功能,接下來筆者慢慢列舉。blog
PWM啓動ADC事件
這是一個比較經常使用的功能,基本上若是使用DSP的片內ADC,大部分都會用PWM觸發ADC,或者外部中斷啓動ADC。rem
PWM啓動ADC,主要是考慮啓動ADC的週期,常規的作法啓動ADC轉換的週期就是PWM的週期,這種作法適用於PWM週期比較長的狀況下,若是PWM週期比較短,可能須要隔好幾個PWM週期,再啓動一次ADC轉換。同步
//ADC SOC EPwm1Regs.ETSEL.bit.SOCAEN = 1; // Enable SOC on A group EPwm1Regs.ETSEL.bit.SOCASEL = 1; // When TBCTR == 0x0000,EPWMxSOCA pulse will be //generated EPwm1Regs.ETPS.bit.SOCAPRD = 1; // Generate pulse on 1st event
* PWM觸發中斷it
通常DSP系統中的主中斷,都是ADC轉換完成後觸發的主中斷,由於大部分的應用需求,都是但願DSP進入主中斷後可以讀取ADCRESULT,因此採用ADC觸發的中斷,一點都不浪費時間。
但有人認爲ADC是個不穩定的東西,他們認爲ADC轉換過程當中有機率出現問題,這種狀況下,會致使系統沒法進入主中斷,而產生一系列問題?因此也有人用PWM的CMPB觸發的中斷做爲主中斷,但CMPB要在ADC轉換完成以後才能觸發中斷,,這是爲了進入主中斷後讀取的ADCRESULT,是當前週期轉換的,而不是上個週期的。
EPwm1Regs.ETSEL.bit.INTSEL = 6; // time-base counter equal to //CMPB when the timer //is incrementin EPwm1Regs.ETPS.bit.INTPRD = 1; // Generate interrupt on 1st event EPwm1Regs.CMPB = 1000;
* PWM的TRIP模塊
TRIP這個詞,很差翻譯,暫時仍是用英文吧,筆者也沒有看過特別合適的中文翻譯,PWM的TRIP模塊,主要功能是關係到PWM的釋放與閉鎖,閉鎖通常是使PWM的A、B 引腳輸出低電平。
而後TRIP分爲硬件TRIP、軟件TRIP,這二者實現的功能是相同的,只是觸發TRIP事件的源頭不一樣。硬件TRIP事件是怎麼產生的,把DSP的一個GPIO設置爲TRIP引腳,當該引腳的電平被拉低時,當即產生TRIP事件,此時PWM即會被閉鎖。硬件TRIP閉鎖PWM的速度很快,軟件閉鎖,可能至少須要幾十us或者一箇中斷週期纔可以閉鎖PWM。
軟件TRIP就是實現人爲的閉鎖、釋放PWM功能。
EPwm1Regs.TZSEL.bit.OSHT1 = 1; // one-shit EPwm1Regs.TZCTL.bit.TZA = TZ_FORCE_LO; //Force EPWMxA to a low state EPwm1Regs.TZCTL.bit.TZB = TZ_FORCE_LO; // Force EPWMxB to a low state
* PWM的脈衝同步性
PWM的同步性,主要是針對各個PWM模塊而說的,好比PWM1與PWM12模塊,但願這兩個PWM模塊的脈衝可以同步,這裏同步就是指二者的波形可以重合,沒有us級的差異。
EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE; // Master module EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO; // Sync down-stream module
* PWM的引腳輸出模式
一個PWM模塊有PWM_A引腳,也有PWM_B引腳,這兩個引腳的輸出模式能夠設置爲互補模式,也能夠設置爲獨立模式。
//獨立模式 EPwm1Regs.AQCTLA.bit.CAD = AQ_SET; //大於比較值爲0,小於比較值爲1 EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR; EPwm1Regs.AQCTLB.bit.CBD = AQ_SET; EPwm1Regs.AQCTLB.bit.CBU = AQ_CLEAR; EPwm1Regs.DBCTL.bit.POLSEL = DB_ACTV_HI; EPwm1Regs.DBCTL.bit.OUT_MODE = DB_DISABLE; //互補模式 EPwm1Regs.AQCTLA.bit.CAD = AQ_SET; //大於比較值爲0,小於比較值爲1 EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR; EPwm1Regs.AQCTLB.bit.CBD = AQ_NO_ACTION; EPwm1Regs.AQCTLB.bit.CBU = AQ_NO_ACTION; EPwm1Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC; EPwm1Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;
* PWM的相位
不一樣PWM模塊之間的相位,能夠同步,也能夠相互錯開,這種模式筆者測試過,尚未正式在項目中使用過,這種模式的設置應該和PWM的相位寄存器設置有關。
* PWM的死區
// Active Low PWMs - Setup Deadband EPwm1Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; // EPwm1Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC; //DB_ACTV_HIC EPwm1Regs.DBCTL.bit.IN_MODE = DBA_ALL; //EPWMxA In (from the action-qualifier) is the //source for both falling-edge and rising-edge delay EPwm1Regs.DBRED = 400; EPwm1Regs.DBFED = 400; // TBCLK = SYSCLK 5.00 μS