PWM模块总结PWM外设能够占用很小的CPU资源的情况下产生复杂的脉冲输出,也就是其灵活的特点使其必须根据需要进行编程。ePWM单元需要根据时序和控制需求对每一通道独立设置,以避免两个通道之间的干扰,这种互相独立的结构为应用提供了更大的灵活性。PWM模块是很多功率控制系统必须的控制单元,在商业和工业产品中都有应用,例如电机控制、数字开关电源、UPS电源等。ePWM还可以直接实现DAC功能,在作为DAC输出时,占空比与输出电压成正比。 一、F28335ePWM模块概述ePWM模块的每个PWM通道有两个互补的PWM输出:EPWMxA和EPWMxB,共6个ePWM通道,依次与GPIO0-GPIO11引脚复用。为了能够输出更高精度的PWM信号,该模块还提供了HRPWM子模块。ePWM模块所以通道通过时间同步模式彼此联系,在必要的情况下多个通道可以同时操作,类似一个通道,也可以利用捕获单元eCAP实现通道间的同步控制。概括起来,ePWM模块主要特点包括: (1)专用的16位时间基准计数器(定时器),控制PWM输出周期和频率。 (2)两个PWM输出(EPWMxA和EPWMxB)有以下三种工作模式: v 两个独立单边操作的PWM输出; v 两个独立双边对称操作的PWM输出; v 一个独立双边不对称边操作的PWM输出。 (3)软件实现PWM信号异步控制,即可编程相位控制,支持超前和滞后操作。 (4)每个周期硬件锁定相位(同步)关系。 (5)带有上升、下降沿独立控制的死区设置。 (6)可编程错误区域控制。 (7)产生错误时强制PWM输出高电平、低电平或高阻态。 (8)所以事件都能够触发CPU中断或/和ADC启动(SOC). (9)可编程事件预定标中断,减小CPU负载。 (10)高频载波信号产生PWM斩波,常用于脉冲变换门驱动电路。 1.ePWM主要子模块和相应配置参数。
注意:正常的发出PWM波一般需要配置:TB(定时器模块/时间基准模块)、CC(计数器比较模块)、AQ(比较方式预设模块/动作限定模块)、DB(死区模块)、ET(事件触发模块)等五个模块。下面分别介绍每一个模块。 2.常用变量定义(DSP2833x_EPwm_defines.h)// TBCTL (Time-Base Control) //========================== // CTRMODE bits #define TB_COUNT_UP 0x0 #define TB_COUNT_DOWN 0x1 #define TB_COUNT_UPDOWN0x2 #define TB_FREEZE 0x3 // PHSEN bit #define TB_DISABLE 0x0 #define TB_ENABLE 0x1 // PRDLD bit #define TB_SHADOW 0x0 #define TB_IMMEDIATE 0x1 // SYNCOSEL bits #define TB_SYNC_IN 0x0 #define TB_CTR_ZERO 0x1 #define TB_CTR_CMPB 0x2 #define TB_SYNC_DISABLE 0x3 // HSPCLKDIV and CLKDIV bits #define TB_DIV1 0x0 #define TB_DIV2 0x1 #define TB_DIV4 0x2 // PHSDIR bit #define TB_DOWN 0x0 #define TB_UP 0x1
// CMPCTL (Compare Control) //========================== // LOADAMODE and LOADBMODE bits #define CC_CTR_ZERO 0x0 #define CC_CTR_PRD 0x1 #define CC_CTR_ZERO_PRD 0x2 #define CC_LD_DISABLE 0x3 // SHDWAMODE and SHDWBMODE bits #define CC_SHADOW 0x0 #define CC_IMMEDIATE 0x1
// AQCTLA and AQCTLB (Action Qualifier Control) //=================================== // ZRO, PRD, CAU, CAD, CBU, CBD bits #define AQ_NO_ACTION 0x0 #define AQ_CLEAR 0x1 #define AQ_SET 0x2 #define AQ_TOGGLE 0x3
// DBCTL (Dead-Band Control) //========================== // OUT MODE bits #define DB_DISABLE 0x0 #define DBA_ENABLE 0x1 #define DBB_ENABLE 0x2 #define DB_FULL_ENABLE 0x3 // POLSEL bits #define DB_ACTV_HI 0x0 #define DB_ACTV_LOC 0x1 #define DB_ACTV_HIC 0x2 #define DB_ACTV_LO 0x3 // IN MODE #define DBA_ALL 0x0 #define DBB_RED_DBA_FED 0x1 #define DBA_RED_DBB_FED 0x2 #define DBB_ALL 0x3
// CHPCTL (chopper control) //========================== // CHPEN bit #define CHP_DISABLE 0x0 #define CHP_ENABLE 0x1 // CHPFREQ bits #define CHP_DIV1 0x0 #define CHP_DIV2 0x1 #define CHP_DIV3 0x2 #define CHP_DIV4 0x3 #define CHP_DIV5 0x4 #define CHP_DIV6 0x5 #define CHP_DIV7 0x6 #define CHP_DIV8 0x7 // CHPDUTY bits #define CHP1_8TH 0x0 #define CHP2_8TH 0x1 #define CHP3_8TH 0x2 #define CHP4_8TH 0x3 #define CHP5_8TH 0x4 #define CHP6_8TH 0x5 #define CHP7_8TH 0x6
// TZSEL (Trip Zone Select) //========================== // CBCn and OSHTn bits #define TZ_DISABLE 0x0 #define TZ_ENABLE 0x1
// TZCTL (Trip Zone Control) //========================== // TZA and TZB bits #define TZ_HIZ 0x0 #define TZ_FORCE_HI 0x1 #define TZ_FORCE_LO 0x2 #define TZ_NO_CHANGE 0x3
// ETSEL (Event Trigger Select) //============================= #define ET_CTR_ZERO 0x1 #define ET_CTR_PRD 0x2 #define ET_CTRU_CMPA 0x4 #define ET_CTRD_CMPA 0x5 #define ET_CTRU_CMPB 0x6 #define ET_CTRD_CMPB 0x7
// ETPS (Event Trigger Pre-scale) //========================= // INTPRD, SOCAPRD, SOCBPRD bits #define ET_DISABLE 0x0 #define ET_1ST 0x1 #define ET_2ND 0x2 #define ET_3RD 0x3
//-------------------------------- // HRPWM (High Resolution PWM) //========================== // HRCNFG #define HR_Disable 0x0 #define HR_REP 0x1 #define HR_FEP 0x2 #define HR_BEP 0x3
#define HR_CMP 0x0 #define HR_PHS 0x1
#define HR_CTR_ZERO 0x0 #define HR_CTR_PRD 0x1 二.定时器(TB)模块
1.时间基准控制寄存器(TBCTL)
2.时基状态寄存器(TBSTS):用来检测TB模块状态该寄存器不需要进行配置,一般用于编程时使用,写入1到此为将清除此位锁存事件(清零)。
3.时间基准相位寄存器(TBPHS):配置相对其他ePWM模块的时钟基准的相位。
4.时间基准计数器(TBCTR)
5.时间基准周期寄存器(TBPRD):配置ePWM模块工作的频率或周期。
注意:正确使用ePWM时钟PCLKCR0-外设时钟控制寄存器0的TBCLKSYNC位,可以用于全局同步所有ePWM模块的时基时钟。当SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0时,所有的ePWM模块的时基时钟停止;当SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1时,所有的ePWM模块的时基时钟开始。为了精确同步TBCLK,TBCTL的比例因子位必须设置相同。具体步骤如下: (1)禁止各个ePWM模块外设时钟; (2)配置ePWM模块; (3)使能各个ePWM模块外设时钟. EALLOW; SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0; EDIS;
InitEPwm1Example(); ...........................
EALLOW; SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1; EDIS; 三.计数器比较模块作用:设置PWM占空比,计数器比较模块包括以下寄存器比较控制寄存器,比较值寄存器A和比较值寄存器B。
1.比较控制寄存器(CMPCTL)作用:设置CMPA,CMPB寄存器的加载影子寄存器的条件,影子寄存器状态标识位和比较寄存器的影子寄存器使能位。
2.比较值寄存器A(CMPA):设置EPWMxA的比较值,有影子寄存器。
3.比较值寄存器B(CMPB):设置EPWMxB的比较值,有影子寄存器。四.动作限定子模块:比较方式预设模块动作限定子模块在波形构造过程中和PWM产生中具有重要的作用。他决定那个事件转换成各种动作类型,从而得到EPWMA和EPWMB输出要的波形。即动作限定子模块AQ用于设置PWM的动作方式(00:无动作、01:置零、10:置位、11:取反)。 1.PWM xA动作限定输出控制寄存器(AQCTLA)
2.PWMxB 动作限定输出控制寄存器(AQCTLB)五.死区模块(DB)作用:根据信号ePWMxA输入产生带死区的信号对,推荐模式:EPWMxA为上升沿延时,EPWMxB为下降沿延时(EPwm1Regs.DBCTL.all=0x0023)。
图1:死区模块原理图
1.死区控制寄存器(DBCTL):设置S5,S4,S3,S3,S2,S1,S0开关选择的。
2.死区上升沿延迟时间值寄存器( DBRED)作用:在死区模块中可以通过配置DBRED和DBFED寄存器,设置一个周期内信号上升沿延迟值(RED)和下降沿延迟的值(FED),边沿延迟时间与定时器时钟(TBCLK)成正比。
3. 死区下降沿延迟时间值寄存器(DBFED)
六.载波子模块PC——一般情况下禁止1.载波模块控制寄存器(PCCTL)
七.事件触发器(ET):中断管理器
图2:事件触发模块原理图 1.中断选择寄存器(ETSEL)作用:中断使能、及中断源选择(EPWMxSOCA触发ADC转换、EPWMxSOCB触发ADC转换、CPU中断)
2.中断预分频寄存器(ETPS)作用:确定事件产生触发的速度(每个事件发生时或两个、三个四事件发生时产生一次触发)。 xxxCNT记录事件发生次数,当与xxxPRD(预设发生次数)相等时,发出中断信号,xxxCNT停止计数,这时标志位清除时xxxCNT清零重新计数。
3.事件触发标志寄存器(ETFLG)作用:0:没有发生;状态标志位,中断时为1.
4.事件触发清除寄存器(ETCLR)说明:写0无效;写1清除相应的标志位。
一般配置如下:EPwm1Regs.ETSEL.bit.INTEN = 1; // 使能INT EPwm1Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO; // 中断源选择 EPwm1Regs.ETPS.bit.INTPRD = ET_3RD; // 在第三个事件产生中断
【例】:将PWM1配置为,递增递减计数模式并产生死区控制,其中PWM1为低电平有效,相应信号对电平极性取反。PWM配置为第三个事件中断,此时死区调整区间为:0<=DB<=DB_MAX。 //===================================================================== #include "DSP28x_Device.h" #include "DSP28x_Examples.h"
// 本程序所涉及的原函数声明 void InitEPwm1Example(void); interrupt void epwm1_isr(void);
// 本例中的全局变量 Uint32 EPwm1TimerIntCount; Uint16 EPwm1_DB_Direction;
// 最大、最小死区值 #define EPWM1_MAX_DB 0x03FF #define EPWM1_MIN_DB 0
//死区计数方向 #define DB_UP 1 #define DB_DOWN 0 //--------------------------------------------------------------------------------------------------------------------------------------------------------- void main(void) { // Step 1. 初始化系统控制 InitSysCtrl();
// Step 2.初始化GPIO /// 本例涉及 ePWM1的GPIO口引脚 InitEPwm1Gpio();
// Step 3. 关闭所有中断并初始化PIE矢量表: // (1)禁止全局中断 DINT; // (2)初始PIE控制寄存器为初始状态:禁止所有的PIE中断;并且清除所以中断标志位。 InitPieCtrl(); // (3)禁止CPU中断,并且清除所有CPU中断标志位: IER = 0x0000; IFR = 0x0000; // (4)初始化服务子程序(ISR):对所以PIE向量表中的所有中断向量配置对应的入口地址,并对. InitPieVectTable(); // (5)将&epwm1_isr入口地址赋值给EPWM1_INT中断向量:当CPU响应EPWM1_INT中断向量请求时,程序将跳转到epwm1_isr()函数的入口地址,执行这个中断服务程序。 EALLOW; PieVectTable.EPWM1_INT = &epwm1_isr; EDIS;
// Step 4.初始化器件外设:时钟、参数配置等 。 // InitPeripherals(); // 使能外设时钟 //正确ePWM时钟使能 //(1) 禁止各个ePWM模块外设时钟; EALLOW; SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0; EDIS; //(2) 配置ePWM模块; InitEPwm1Example(); //(3) 使能各个ePWM模块外设时钟. EALLOW; SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1; EDIS;
// Step 5. 用户代码,使能中断 // (1) 初始化计数器 EPwm1TimerIntCount = 0; //中断计数变量清零 // (2)使能CPU第3组中断:CPU INT3 IER |= M_INT3; // (3)使能PIE的 EPWM INTn:3组第1个中断的 PieCtrlRegs.PIEIER3.bit.INTx1 = 1; // (4) 使能全局中断和最高优先级的实时调试事件: EINT; // 使能全局中断; ERTM; // 使能全局实时中断DBGM; // Step 6. 循环等待中断: for(;;) { asm(" NOP"); } } ////------------------------------------------------------------------------------------------------------------------------------------------------------- interrupt void epwm1_isr(void) //PWM中断函数 { If (EPwm1_DB_Direction == DB_UP) { if(EPwm1Regs.DBFED < EPWM1_MAX_DB) { EPwm1Regs.DBFED++; EPwm1Regs.DBRED++; } else { EPwm1_DB_Direction = DB_DOWN; EPwm1Regs.DBFED--; EPwm1Regs.DBRED--; } } else { if(EPwm1Regs.DBFED == EPWM1_MIN_DB) { EPwm1_DB_Direction = DB_UP; EPwm1Regs.DBFED++; EPwm1Regs.DBRED++; } else { EPwm1Regs.DBFED--; EPwm1Regs.DBRED--; } } EPwm1TimerIntCount++; //中断计数变量加1 EPwm1Regs.ETCLR.bit.INT = 1; // 清除EPWM1_INT中断标志位 PieCtrlRegs.PIEACK.all = PIEACK_GROUP3; // 清除PIE应答寄存器 } void InitEPwm1Example() //初始化PWM配置函数 { EPwm1Regs.TBPRD = 6000; // 设置时间计数周期 EPwm1Regs.TBPHS.half.TBPHS = 0x0000; // 时间基准相位寄存器清零 EPwm1Regs.TBCTR = 0x0000; // 清零计数寄存器
// 启动 TBCLK EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // 计数模式:对称输出 EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE; // 禁止相位寄存器加载(禁止同步) EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV4; // 高速时钟预分频 EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV4; //时间基准预分频 // 比较寄存器加载模式 EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW; // 阴影寄存器加载条件 EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
// 启动比较器 EPwm1Regs.CMPA.half.CMPA = 3000;
// 配置动作限定模块 EPwm1Regs.AQCTLA.bit.CAU = AQ_SET; // PWM1A =Zero置1 EPwm1Regs.AQCTLA.bit.CAD = AQ_CLEAR; EPwm1Regs.AQCTLB.bit.CAU = AQ_CLEAR; // PWM1A = Zero置1 EPwm1Regs.AQCTLB.bit.CAD = AQ_SET;
// 死区模块配置 EPwm1Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; EPwm1Regs.DBCTL.bit.POLSEL = DB_ACTV_LO; EPwm1Regs.DBCTL.bit.IN_MODE = DBA_ALL; EPwm1Regs.DBRED = EPWM1_MIN_DB; EPwm1Regs.DBFED = EPWM1_MIN_DB; EPwm1_DB_Direction = DB_UP;
// 中断,用户选择死区 EPwm1Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO; // 在第零个事件选择INT EPwm1Regs.ETSEL.bit.INTEN = 1; // 使能INT EPwm1Regs.ETPS.bit.INTPRD = ET_3RD; // 在第三个事件产生中断
} //===================================================================== // No more. //===================================================================== |
|