Part Number:TMS320F28035
//************************************************************************************************ #include "DSP28x_Project.h"// Device Headerfile and Examples Include File #define SYSCLK 60E6 // 60MHz system clock #define PWMFREQ 100E3 // 100kHz PWM frequency #define DUTY_CYCLE 0.4// duty cycle #define DEAD_BAND 0.2 // dead band //#define TB_PERIOD (SYSCLK / (2 * PWMFREQ)) // Calculate period for up-down count mode //#define TB_PERIOD (SYSCLK / PWMFREQ) // Calculate period for up-down count mode #define TB_PERIOD (SYSCLK / (4 * PWMFREQ)) // Calculate period for up-down count mode #define DUTY_VALUE (TB_PERIOD * DUTY_CYCLE) #define DB_VALUE (TB_PERIOD * DEAD_BAND) // 函数声明 void SetGpio() {EALLOW;GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 1; // Configure GPIO0 as EPWM1AGpioCtrlRegs.GPADIR.bit.GPIO0 = 1; //Set as outputGpioCtrlRegs.GPAMUX1.bit.GPIO1 = 1; // Configure GPIO1 as EPWM1BGpioCtrlRegs.GPADIR.bit.GPIO1 = 1; //Set as outputEDIS; } void InitEPWM1(void) {EPwm1Regs.TBPRD = TB_PERIOD; // 设置周期EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // 设置上下计数模式EPwm1Regs.CMPA.half.CMPA = DUTY_VALUE; // 设置 ePWM1A 的占空比EPwm1Regs.CMPB = DUTY_VALUE; // 设置 ePWM1B 的占空比EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR; // 设置 ePWM1A 在计数器向上计数时设置为高电平EPwm1Regs.AQCTLA.bit.CAD = AQ_SET; // 设置 ePWM1A 在计数器向下计数时设置为低电平 //EPwm1Regs.AQCTLB.bit.CBU = AQ_CLEAR; // 设置 ePWM1B 在计数器向上计数时设置为低电平 //EPwm1Regs.AQCTLB.bit.CBD = AQ_SET; // 设置 ePWM1B 在计数器向下计数时设置为高电平EPwm1Regs.AQCTLB.bit.CBU = AQ_CLEAR; // 设置 ePWM1B 在计数器向上计数时设置为低电平EPwm1Regs.AQCTLB.bit.CBD = AQ_SET; // 设置 ePWM1B 在计数器向下计数时设置为高电平EPwm1Regs.DBCTL.bit.IN_MODE = DBA_ALL; // 设置死区输入模式EPwm1Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; // 设置死区输出模式EPwm1Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC;//=DB_ACTV_HIC(DB_ACTV_HI,DB_ACTV_LOC,DB_ACTV_HIC,DB_ACTV_LO)EPwm1Regs.DBRED = DB_VALUE; // 设置死区上升沿延迟EPwm1Regs.DBFED = DB_VALUE; // 设置死区下降沿延迟EPwm1Regs.TBCTL.bit.PHSEN = TB_ENABLE; // 启用相位加载EPwm1Regs.TBPHS.half.TBPHS = EPwm1Regs.TBPRD / 2; // 设置 ePWM1B 的相位偏移SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1 } void main(void) {InitSysCtrl(); // 初始化系统时钟和PLLDINT;// 禁止所有中断InitPieCtrl(); // 初始化和启用CPU PIEIER = 0x0000;IFR = 0x0000;InitPieVectTable(); // 初始化PIE向量表SetGpio(); // Initialize GPIOEALLOW;SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0; // 停止所有ePWM时钟EDIS;InitEPWM1(); // 初始化ePWM1EALLOW;SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1; // 启动所有ePWM时钟EDIS;for(;;){// 主循环} } *********************************************************************************************8
代码已经上传了。
我想让epwm1a和epwm1b生成占空比和死区时间都一样的波形,而且epwm1b的波形向右偏移半个周期。
我在代码里设置了相位偏移如下:
但是生成的波形没有任何偏移:
调了一周了实在没办法了,老板又一直催所以来这问一下,谢谢各位大神。
chenzheng:
是不是只有不同的epwm例如epwm1和epwm2之间能实现移相,epwm1a和epwm1b之间是不能实现移相的?
,
Yale Li:
chenzheng said:是不是只有不同的epwm例如epwm1和epwm2之间能实现移相,
是的,TB子模块的移相功能是作用于不同ePWM模块间的;
同个ePWM模块上的两路输出之间要做到移相,比较简单的做法是在输出后面加一个FPGA,通过FPGA来做这个逻辑。当然其它的后处理方式也是可以的。只不过用FPGA相对来说比较简单灵活,如果有其它需求的话还可以对信号进行更多的处理,实现一些ePWM模块所不具备的一些逻辑。
所以TI也推出了一些集成了CLB模块的C2000器件,比如TMS320F280049C。CLB就是一个类似于FPGA的模块。
如果非想用单F28035实现,我可以提供一个大概思路:
1. 以ePWM1为例。ePWM1A正常输出,比如CTR = 0处置高,CTR = CMPA处置低;ePWM1B采用软件输出;
2. ePWM1在配置的时候,要使能波形跳变点的中断(但有一点要注意,每个ePWM模块的中断源只能选择一个,所以在每次ISR的最后要切换中断源);
3. CTR = 0时,ePWM1A置高,同时触发中断,中断中使用NOP指令延时(这个时间就是移相值。还需要加上现场保护及恢复的时间,这个时间与代码量有一定的关系,需要经过测试得出),然后对ePWM1B采用软件置高,之后切换中断源为CTR = CMPA;
4. CTR = CMPA时,同样的操作。
当然还有许多细节的地方要注意,比如软件触发要选择立即模式、软件触发有一个TBCLK的延迟、波形第1个周期的配置需要特殊处理一下、用汇编实现效果也会更好(无论是波形的时序还是对于CPU的负载)、移相值最好远小于周期值、这个处理也可以放到CLA核来做、等等。
当然我这个思路也只是理论上的,实际是否可行有待验证。
,
Yale Li:
上面这个做法其实相当麻烦,更简答的做法是转换思路:
想要A路与B路之间做到移相,模块本身并没有这个功能;那干脆把一个ePWM模块看成A路、另一个ePWM模块看成B路,每一个模块只用它一路输出。