華大單片機(jī)可以通過(guò)種方式進(jìn)行PWM輸出,工程師反應(yīng)使用高級(jí)定時(shí)器輸出PWM的時(shí)候,不能輸出占空比為0或100%的波形。這時(shí)由于高級(jí)定時(shí)器輸出PWM時(shí)設(shè)置會(huì)比較特殊,下面進(jìn)行相關(guān)的介紹。
高級(jí)定時(shí)器進(jìn)行PWM輸出時(shí),波形主要由下面幾個(gè)寄存器的值來(lái)決定:
PCONR.PERCx(x=A/B) : CHA和CHB的周期匹配時(shí),輸出電平狀態(tài),設(shè)置的是PWM周期結(jié)束后電平狀態(tài);
PCONR.CMPCx(x=A/B): CHA和CHB的比較匹配時(shí),輸出電平狀態(tài),設(shè)置的是計(jì)數(shù)到計(jì)數(shù)點(diǎn)后電平的狀態(tài);
PCONR.STASTPSx(x=A/B):CHA和CHB的起始和停止電平選擇;
PCONR.STACx(x=A/B): 計(jì)數(shù)開(kāi)始時(shí)CHA和CHB電平狀態(tài),PWM開(kāi)始前端口的電平狀態(tài);
PCONR.STPCx(x=A/B):計(jì)數(shù)結(jié)束時(shí)CHA和CHB電平狀態(tài),PWM停止后端口的電平狀態(tài);
前兩個(gè)寄存器用來(lái)設(shè)置PWM輸出周期的波形,后三個(gè)寄存器用來(lái)設(shè)置PWM開(kāi)始和結(jié)束時(shí)端口的電平。
本文開(kāi)頭提到的問(wèn)題通過(guò)設(shè)置前兩個(gè)寄存器就可以實(shí)現(xiàn)。下面以起始低電平,計(jì)數(shù)匹配后高電平的PWM波形來(lái)說(shuō)明。起始低電平說(shuō)明PWM周期匹配后,新的周期開(kāi)始時(shí)端口的電平為低電平,需要把PCONR.PERCx設(shè)置為低電平;計(jì)數(shù)匹配后為高電平,把PCONR.CMPCx設(shè)置為高電平就可以。這樣的設(shè)置可以輸出0~(《100%)占空比的波形。100%這點(diǎn)需要始終是高電平,也就是說(shuō)周期匹配的時(shí)候不能輸出低電平,設(shè)置為低電平的話,當(dāng)周期匹配的時(shí)候會(huì)立刻輸出一個(gè)低電平,再進(jìn)行比較匹配的判斷,匹配分輸出高電平,這樣就存在一個(gè)很小的低電平脈沖,不是我們所需要的。
當(dāng)要輸出100%占空比的時(shí)候,要把PCONR.PERCx設(shè)置為高電平,這樣就周期匹配的時(shí)候會(huì)輸出高電平,不會(huì)再有低電平脈沖。當(dāng)占空比不是100%的時(shí)候,再把PCONR.PERCx設(shè)置回低電平就可以。
以華大單片機(jī)HC32F003芯片TIM4定時(shí)器CHA通道為例,每一秒改變?cè)黾?0%占空比,輸出100%后,占空比改為0輸出。代碼部分如下:
?
int32_t main(void)
{
? ? ? ?float fPwmDyty = 0.0;
? ?en_adt_unit_t enAdt;
? ?uint16_t u16Period;
? ?en_adt_compare_t enAdtCompare;
? ?uint16_t u16Compare;
? ?stc_adt_basecnt_cfg_t stcAdtBaseCntCfg;
? ?stc_adt_CHxX_port_cfg_t stcAdtTIM4ACfg;
?
?
? ?DDL_ZERO_STRUCT(stcAdtBaseCntCfg);
? ?DDL_ZERO_STRUCT(stcAdtTIM4ACfg);
?
? ?Clk_SetPeripheralGate(ClkPeripheralGpio, TRUE);? ? ? ? ? ? ? ? ? ? ? ?//端口外設(shè)時(shí)鐘使能
?
? ?
? ?Gpio_SetFunc_TIM4_CHA_P23();
?
?
? ?Clk_SetPeripheralGate(ClkPeripheralAdt, TRUE);? ? ? ? ? ? ? ? ? ? ? ? ?//ADT外設(shè)時(shí)鐘使能
?
? ?enAdt = AdTIM4;
? ?Adt_StopCount(enAdt);
? ?Adt_ClearCount(enAdt);
?
? ?stcAdtBaseCntCfg.enCntMode = AdtSawtoothMode;? ? ? ? ? ? ? ? ? ? //ADT載波為三角波
? ?stcAdtBaseCntCfg.enCntDir = AdtCntUp;? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //向上計(jì)數(shù)
? ?stcAdtBaseCntCfg.enCntClkDiv = AdtClkPClk0Div8;? ? ? ? ? ? ? ? ? ? //PCLK8分頻
? ?Adt_Init(enAdt, &stcAdtBaseCntCfg);? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??//ADT載波、計(jì)數(shù)模式、時(shí)鐘配置
? ?
? ?u16Period = 0xEEEE;
? ?Adt_SetPeriod(enAdt, u16Period);? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//設(shè)置PWM周期
?
? ?enAdtCompare = AdtCompareA;
? ?u16Compare = 0xEEEE;
? ?Adt_SetCompareValue(enAdt, enAdtCompare, u16Compare);? ? ? ?//設(shè)置CHA通道PWM低電平時(shí)間
? ?
? ?enAdtCompare = AdtCompareC;
? ?u16Compare = 0xEEEE;
? ?Adt_SetCompareValue(enAdt, enAdtCompare, u16Compare);? ? ? //設(shè)置CHA通道比較緩存值
?
? ?Adt_EnableValueBuf(enAdt, AdtCHxA, TRUE);? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//使能CHA通道緩存輸出
?
? ?stcAdtTIM4ACfg.enCap = AdtCHxCompareOutput;? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //比較輸出
? ?stcAdtTIM4ACfg.bOutEn = TRUE;? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//端口輸出使能
? ?stcAdtTIM4ACfg.enPerc = AdtCHxPeriodLow;? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//周期匹配時(shí)輸出低電平
? ?stcAdtTIM4ACfg.enCmpc = AdtCHxCompareHigh;? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//比較匹配時(shí)輸出高電平
? ?stcAdtTIM4ACfg.enStaStp = AdtCHxStateSelSS;? ? ? ? ? ? ? ? ? ? ?? ? ? ? ? ? ?//計(jì)數(shù)開(kāi)始或停止時(shí),CHA端口輸出由STACB、STPCB決定
? ?stcAdtTIM4ACfg.enStaOut = AdtCHxPortOutLow;? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//計(jì)數(shù)開(kāi)始時(shí)CHA端口輸出設(shè)定為低電平
? ?stcAdtTIM4ACfg.enStpOut = AdtCHxPortOutLow;? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//計(jì)數(shù)停止時(shí)CHA端口輸出設(shè)定為低電平
? ?Adt_CHxXPortConfig(enAdt, AdtCHxA, &stcAdtTIM4ACfg);? ? ? ?//端口CHA配置
? ?
? ?Adt_StartCount(enAdt);? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //開(kāi)啟ADT
? ?
? ?while(1)
? ? ? ?{
? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? ? ?delay1ms(1000);
? ? ? ? ? ? ? ? ? ?if(fPwmDyty < 1)? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//占空比小于100%,將占空比加10%
? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? ? ? fPwmDyty += 0.1;
? ? ? ? ?? ? ? ? }
? ? ? ? ? ? ? ? ? else? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//占空比大于等于100%,將占空比設(shè)置為0%
? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? ? ? fPwmDyty = 0;
? ? ? ? ? ? ? ? ? }
?
? ? ? ? ? ? ? ? ? if (fPwmDyty < 1)? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //占空比小于100%,將計(jì)數(shù)周期結(jié)束時(shí)輸出設(shè)置為低
? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? ? ? M0P_ADT0->PCONR_f.PERCA = 0;?
? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? else? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //占空比大于等于100%,將計(jì)數(shù)周期結(jié)束時(shí)輸出設(shè)置為高
? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? ? ?M0P_ADT0->PCONR_f.PERCA = 1;?
? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? ? Adt_SetCompareValue(AdTIM4, AdtCompareC, (1-fPwmDyty)*u16Period);
? ? ? ? ? ? ? ?
? ? ? ? ?}
}
責(zé)任編輯:tzh
評(píng)論
查看更多