一个有效的PWM外设能够占用最少的CPU资源和中断,但可以产生灵活配置的脉冲波形,并且可以方便地被理解与使用。单周期的PWM波形很简单,主要就是控制脉冲的周期,脉冲的宽度,脉冲起落的时间,一个周期内的脉冲个数,但事实是产生PWM波形时,要结合实际应用,每个要素都要顾及,需要灵活配置,涉及到强电控制与弱电控制的结合,有一定的难度与技术门槛,需要耐心的探索。 每个ePWM模块由两路ePWM输出组成,分别为ePWMxA和ePWMxB,这一对PWM输出,可以配置成两路独立的单边沿PWM输出,或者两路独立的但互相对称的双边沿PWM输出,或者一对双边沿非对称的PWM输出,共有6对这样ePWM模块,因为每对PWM模块中的两个PWM输出均可以单独使用,所以也可以认为有12路单路ePWM,除此之外还有6个APWM,这6个APWM通过CAP模块扩展配置,可以独立使用,所以F28027最多可以有18路PWM输出。每一组ePWM模块都包含以下8个模块:时基模块TB、计数比较模块CC、动作模块AQ、死区产生模块DB、PWM斩波模块PC、错误联防模块TZ、事件触发模块ET,数字比较模块DC。 使用Hawwking IDE V0.5.0版本新建一个基于DSC28034的PWM工程,具体新建过程如之前的帖子所示,产生ePWM的工程编写过程如下所示: 第一步:配置GPIO为ePWM外设模式 /****************************************************************** 函数名:void InitEPwm1_Gpio(void) 参 数:无 返回值:无 作 用:配置GPIO0、GPIO1、GPIO2、GPIO3配置成epwm模式, ******************************************************************/ void InitEPwm1_Gpio(void) { EALLOW; GpioCtrlRegs.GPAPUD.bit.GPIO0 = 1; GpioCtrlRegs.GPAPUD.bit.GPIO1 = 1; GpioCtrlRegs.GPAPUD.bit.GPIO2 = 1; GpioCtrlRegs.GPAPUD.bit.GPIO3 = 1; GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 1; GpioCtrlRegs.GPAMUX1.bit.GPIO1 = 1; GpioCtrlRegs.GPAMUX1.bit.GPIO2 = 1; GpioCtrlRegs.GPAMUX1.bit.GPIO3 = 1; EDIS; } 第二步配置ePWM波的工作模式 /****************************************************************** 函数名:void pwm1_config(void) 参 数:无 返回值:无 作 用:配置pwm1为中心对齐方式,TBCLK = SYSCLKOUT/(HSPCLKDIV*CLKDIV) 如果是向上或者向下计数模式PWM的周期计算公式=TBCLK*TBPRD,PWM1A的占空比=CMPA/TBPRD, PWM1B的占空比 = CMPB/TBPRD,如果是中心对齐方式PWM得周期计算公式 = 2*TBCLK*TBPRD ******************************************************************/ void pwm1_config() { EPwm1Regs.TBPRD = 3750; //设定pwm的周期是3749个TBclk时钟周期 EPwm1Regs.CMPA.half.CMPA = 1875; //比较器A为512个TBCLK时钟周期 EPwm1Regs.CMPB = 1875; //比较器B为1875个TBCLK时钟周期 EPwm1Regs.TBCTR = 0x0000; //clear counter EPwm1Regs.TBPHS.half.TBPHS = 0x0000; //相位寄存器清零,是设置翻转计数器的时刻 //EPwm1Regs.AQCTLA.bit.ZRO = 0; //最小值 //EPwm1Regs.AQCTLA.bit.PRD = 0x10; //当时基计数器的值与周期寄存器的值相等时置位 EPwm1Regs.AQCTLA.bit.CAD = AQ_CLEAR; //向下计数时,时基计数器的值与CMPA寄存器的值相等时清零 EPwm1Regs.AQCTLA.bit.CAU = AQ_SET; //向上计数时,时基计数器的值与CMPA寄存器的值相等时置1 EPwm1Regs.AQCTLB.bit.CBD = AQ_CLEAR; //向下计数时,时基计数器的值与CMPB寄存器的值相等时清零 EPwm1Regs.AQCTLB.bit.CBU = AQ_SET; //向上计数时,时基计数器的值与CMPB寄存器的值相等时置1 EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; //向上向下计数方式 EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE; //计数寄存器装载相位寄存器禁止装载 EPwm1Regs.TBCTL.bit.PRDLD = TB_SHADOW; //当计数器的值为0时周期寄存器TBPRD装载影子寄存器的值 EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO; //同步信号输出选择,当时基计数器等于0时,ePWMxSYNCO信号输出 EPwm1Regs.TBCTL.bit.SWFSYNC = 0; //软件强制同步脉冲,写0没有效果 EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1; EPwm1Regs.ETSEL.bit.INTSEL = ET_DCAEVT1SOC; //保留 EPwm1Regs.ETSEL.bit.INTEN = 0; //Disable EPWMx_INT generation EPwm1Regs.ETSEL.bit.SOCASEL = 2; //当TB计数器等于周期的时候 EPWMxSOCA 脉冲将产生 EPwm1Regs.ETSEL.bit.SOCAEN = 1; //使能EPWMxSOCA pulse EPwm1Regs.ETSEL.bit.SOCBEN = 0; EPwm1Regs.ETSEL.bit.SOCBSEL = 0; EPwm1Regs.ETPS.bit.SOCAPRD = 1; } 第三步,在main()函数中实现函数的调用 int main(void) { EALLOW; P_SysCtrlRegs->INTOSC1TRIM.bit.FINETRIM = 0; P_SysCtrlRegs->INTOSC2TRIM.bit.FINETRIM = 0; EDIS; //volatile unsigned int i; InitSysCtrl(); //将PLL配置成10倍频1分频,配置系统时钟为120M InitEPwm1_Gpio(); //配置GPIO0,1为PWM波输出模式 pwm1_config(); //16k的PWM频率 while(1){ // i++; } return 0; } 注意:InitSysCtrl(); 为系统库函数,此函数中实现了外设的时钟配置,还可以配置系统时钟 实验现象:把示波器与GPIO0或GPIO1连接,测量PWM波的频率,波形如下所示:可以看到频率为16k |