主时钟100MHz,经EPWMCLKDIV二分频,HSPCLKDIV二分频,CLKDIV二分频,相当于ePWM的TBCLK时钟为12.5MHz,使用查表法产生SPWM,然而在检查正弦表无误的情况下,波形有一定的瑕疵,周期性地出现满占空比的情况,如图(请忽略噪声尖峰的问题):
以前用MSP430做SPWM波形,也出现过这个问题,最后把定时器时钟设置得远远慢于主时钟才得以解决。MSP430功能不适合做SPWM,这也就算了,但是C2000应该不至于出现这种问题把?我以前用STM32,主时钟72MHz,定时器36MHz都不会出现这种满占空比的问题。请问这种情况该如何解决?或者官方有没有提供SPWM的源程序?在controlSUITE暂时没找到。
囧:
满占空比的原因是因为你的表里的duty和周期值一样大了。和芯片本身没有关系。
主时钟100MHz,经EPWMCLKDIV二分频,HSPCLKDIV二分频,CLKDIV二分频,相当于ePWM的TBCLK时钟为12.5MHz,使用查表法产生SPWM,然而在检查正弦表无误的情况下,波形有一定的瑕疵,周期性地出现满占空比的情况,如图(请忽略噪声尖峰的问题):
以前用MSP430做SPWM波形,也出现过这个问题,最后把定时器时钟设置得远远慢于主时钟才得以解决。MSP430功能不适合做SPWM,这也就算了,但是C2000应该不至于出现这种问题把?我以前用STM32,主时钟72MHz,定时器36MHz都不会出现这种满占空比的问题。请问这种情况该如何解决?或者官方有没有提供SPWM的源程序?在controlSUITE暂时没找到。
mangui zhang:
你这个看的不是很明显 没有表现是SPWM波的情况啊
我以前做看着效果很好 LC滤波输出效果很好
我觉得应该是你的正弦波不太好吧
主时钟100MHz,经EPWMCLKDIV二分频,HSPCLKDIV二分频,CLKDIV二分频,相当于ePWM的TBCLK时钟为12.5MHz,使用查表法产生SPWM,然而在检查正弦表无误的情况下,波形有一定的瑕疵,周期性地出现满占空比的情况,如图(请忽略噪声尖峰的问题):
以前用MSP430做SPWM波形,也出现过这个问题,最后把定时器时钟设置得远远慢于主时钟才得以解决。MSP430功能不适合做SPWM,这也就算了,但是C2000应该不至于出现这种问题把?我以前用STM32,主时钟72MHz,定时器36MHz都不会出现这种满占空比的问题。请问这种情况该如何解决?或者官方有没有提供SPWM的源程序?在controlSUITE暂时没找到。
Liliang Zhong1:
回复 囧:
所以我特别说了下,检查了正弦表数据无误,我把代码贴出来吧……
#include "F28x_Project.h"
unsigned int sinetable[]={ 317,322,327,332,336,341,346,351,356,361,366,370,375,380,385,389,394,399,404,408,413,418,422,427,431,436,440,445,449,453,458,462,466,471,475,479,483,487,491,495,499,503,507,511,514,518,522,525,529,532,536,539,542,546,549,552,555,558,561,564,567,570,572,575,578,580,583,585,587,590,592,594,596,598,600,602,603,605,607,608,610,611,612,614,615,616,617,618,619,620,620,621,622,622,623,623,623,623,623,623,623,623,623,623,623,622,622,621,620,620,619,618,617,616,615,614,612,611,610,608,607,605,603,602,600,598,596,594,592,590,587,585,583,580,578,575,572,570,567,564,561,558,555,552,549,546,542,539,536,532,529,525,522,518,514,511,507,503,499,495,491,487,483,479,475,471,466,462,458,453,449,445,440,436,431,427,422,418,413,408,404,399,394,389,385,380,375,370,366,361,356,351,346,341,336,332,327,322,317,312,307,302,297,292,288,283,278,273,268,263,258,254,249,244,239,235,230,225,220,216,211,206,202,197,193,188,184,179,175,171,166,162,158,153,149,145,141,137,133,129,125,121,117,113,110,106,102,99,95,92,88,85,82,78,75,72,69,66,63,60,57,54,52,49,46,44,41,39,37,34,32,30,28,26,24,22,21,19,17,16,14,13,12,10,9,8,7,6,5,4,4,3,2,2,1,1,1,1,1,1,1,1,1,1,1,2,2,3,4,4,5,6,7,8,9,10,12,13,14,16,17,19,21,22,24,26,28,30,32,34,37,39,41,44,46,49,52,54,57,60,63,66,69,72,75,78,82,85,88,92,95,99,102,106,110,113,117,121,125,129,133,137,141,145,149,153,158,162,166,171,175,179,184,188,193,197,202,206,211,216,220,225,230,235,239,244,249,254,258,263,268,273,278,283,288,292,297,302,307,312
};unsigned char i=0;
void InitEPwm2Example(void);__interrupt void epwm2_isr(void);void update_compare();
#define EPWM2_TIMER_TBPRD 624 // Period register#define EPWM_CMP_UP 1#define EPWM_CMP_DOWN 0
void main(void){ InitSysCtrl(); InitEPwm2Gpio(); DINT; InitPieCtrl(); IER = 0x0000; IFR = 0x0000; InitPieVectTable();
EALLOW; // This is needed to write to EALLOW protected registers PieVectTable.EPWM2_INT = &epwm2_isr; EDIS; // This is needed to disable write to EALLOW protected registers
EALLOW; CpuSysRegs.PCLKCR0.bit.TBCLKSYNC =0; EDIS;
InitEPwm2Example();
EALLOW; CpuSysRegs.PCLKCR0.bit.TBCLKSYNC =1; EDIS;
IER |= M_INT3; PieCtrlRegs.PIEIER3.bit.INTx2 = 1;
EINT; // Enable Global interrupt INTM ERTM; // Enable Global realtime interrupt DBGM
for(;;) {
}}
__interrupt void epwm2_isr(void){ // Update the CMPA and CMPB values update_compare(); // Clear INT flag for this timer EPwm2Regs.ETCLR.bit.INT = 1; // Acknowledge this interrupt to receive more interrupts from group 3 PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;}
void InitEPwm2Example(){ // Setup TBCLK EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Count up EPwm2Regs.TBPRD = EPWM2_TIMER_TBPRD; // Set timer period EPwm2Regs.TBCTL.bit.PHSEN = TB_DISABLE; // Disable phase loading EPwm2Regs.TBPHS.bit.TBPHS = 0x0000; // Phase is 0 EPwm2Regs.TBCTR = 0x0000; // Clear counter EPwm2Regs.TBCTL.bit.HSPCLKDIV =1;// TB_DIV2; // Clock ratio to SYSCLKOUT EPwm2Regs.TBCTL.bit.CLKDIV =1;// TB_DIV2;
// Setup shadow register load on ZERO EPwm2Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; EPwm2Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW; EPwm2Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; EPwm2Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
// Set Compare values EPwm2Regs.CMPA.bit.CMPA = sinetable[i]; // Set compare A value EPwm2Regs.CMPB.bit.CMPB = sinetable[i]; // Set Compare B value
// Set actions EPwm2Regs.AQCTLA.bit.PRD = AQ_CLEAR; // Clear PWM2A on Period EPwm2Regs.AQCTLA.bit.CAU = AQ_SET; // Set PWM2A on event A, up count
EPwm2Regs.AQCTLB.bit.PRD = AQ_CLEAR; // Clear PWM2B on Period EPwm2Regs.AQCTLB.bit.CBU = AQ_SET; // Set PWM2B on event B, up count
// Interrupt where we will change the Compare Values EPwm2Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO; // Select INT on Zero event EPwm2Regs.ETSEL.bit.INTEN = 1; // Enable INT EPwm2Regs.ETPS.bit.INTPRD = ET_3RD; // Generate INT on 3rd event
}
void update_compare(){ EPwm2Regs.CMPA.bit.CMPA = sinetable[++i]; // Set compare A value EPwm2Regs.CMPB.bit.CMPB = sinetable[++i]; // Set Compare B value if(i>=400) i=0;}
主时钟100MHz,经EPWMCLKDIV二分频,HSPCLKDIV二分频,CLKDIV二分频,相当于ePWM的TBCLK时钟为12.5MHz,使用查表法产生SPWM,然而在检查正弦表无误的情况下,波形有一定的瑕疵,周期性地出现满占空比的情况,如图(请忽略噪声尖峰的问题):
以前用MSP430做SPWM波形,也出现过这个问题,最后把定时器时钟设置得远远慢于主时钟才得以解决。MSP430功能不适合做SPWM,这也就算了,但是C2000应该不至于出现这种问题把?我以前用STM32,主时钟72MHz,定时器36MHz都不会出现这种满占空比的问题。请问这种情况该如何解决?或者官方有没有提供SPWM的源程序?在controlSUITE暂时没找到。
Liliang Zhong1:
回复 mangui zhang:
可否能分享一下代码呢?我的意思就是我产生的的SPWM波形会产生在明明不该出现满占空比的地方出现满占空比,而且确实不是正弦表的问题…..
主时钟100MHz,经EPWMCLKDIV二分频,HSPCLKDIV二分频,CLKDIV二分频,相当于ePWM的TBCLK时钟为12.5MHz,使用查表法产生SPWM,然而在检查正弦表无误的情况下,波形有一定的瑕疵,周期性地出现满占空比的情况,如图(请忽略噪声尖峰的问题):
以前用MSP430做SPWM波形,也出现过这个问题,最后把定时器时钟设置得远远慢于主时钟才得以解决。MSP430功能不适合做SPWM,这也就算了,但是C2000应该不至于出现这种问题把?我以前用STM32,主时钟72MHz,定时器36MHz都不会出现这种满占空比的问题。请问这种情况该如何解决?或者官方有没有提供SPWM的源程序?在controlSUITE暂时没找到。
Liliang Zhong1:
我把波形出错的地方标记出来了:
三张图是依次放大的。我被这个问题困扰很久了,很希望能有人帮忙被解决下……
主时钟100MHz,经EPWMCLKDIV二分频,HSPCLKDIV二分频,CLKDIV二分频,相当于ePWM的TBCLK时钟为12.5MHz,使用查表法产生SPWM,然而在检查正弦表无误的情况下,波形有一定的瑕疵,周期性地出现满占空比的情况,如图(请忽略噪声尖峰的问题):
以前用MSP430做SPWM波形,也出现过这个问题,最后把定时器时钟设置得远远慢于主时钟才得以解决。MSP430功能不适合做SPWM,这也就算了,但是C2000应该不至于出现这种问题把?我以前用STM32,主时钟72MHz,定时器36MHz都不会出现这种满占空比的问题。请问这种情况该如何解决?或者官方有没有提供SPWM的源程序?在controlSUITE暂时没找到。
囧:
回复 Liliang Zhong1:
你的计数模式配置有问题,一般SPWM都是增减计数,你没有设置,那默认是单增,周期应该Period寄存器值-1,所以在623时就会满值。你设置一下增减计数,然后改一下以下地方
void InitEPwm2Example(){// Setup TBCLKEPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Count upEPwm2Regs.TBPRD = EPWM2_TIMER_TBPRD; // Set timer periodEPwm2Regs.TBCTL.bit.PHSEN = TB_DISABLE; // Disable phase loadingEPwm2Regs.TBPHS.bit.TBPHS = 0x0000; // Phase is 0EPwm2Regs.TBCTR = 0x0000; // Clear counterEPwm2Regs.TBCTL.bit.HSPCLKDIV =1;// TB_DIV2; // Clock ratio to SYSCLKOUTEPwm2Regs.TBCTL.bit.CLKDIV =1;// TB_DIV2;
// Setup shadow register load on ZEROEPwm2Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;EPwm2Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;EPwm2Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;EPwm2Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
// Set Compare valuesEPwm2Regs.CMPA.bit.CMPA = sinetable[i]; // Set compare A valueEPwm2Regs.CMPB.bit.CMPB = sinetable[i]; // Set Compare B value
// Set actionsEPwm2Regs.AQCTLA.bit.CAD= AQ_CLEAR; // Clear PWM2A on PeriodEPwm2Regs.AQCTLA.bit.CAU = AQ_SET; // Set PWM2A on event A, up count
EPwm2Regs.AQCTLB.bit.CBD= AQ_CLEAR; // Clear PWM2B on PeriodEPwm2Regs.AQCTLB.bit.CBU = AQ_SET; // Set PWM2B on event B, up count
// Interrupt where we will change the Compare ValuesEPwm2Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO; // Select INT on Zero eventEPwm2Regs.ETSEL.bit.INTEN = 1; // Enable INTEPwm2Regs.ETPS.bit.INTPRD = ET_3RD; // Generate INT on 3rd event
}
主时钟100MHz,经EPWMCLKDIV二分频,HSPCLKDIV二分频,CLKDIV二分频,相当于ePWM的TBCLK时钟为12.5MHz,使用查表法产生SPWM,然而在检查正弦表无误的情况下,波形有一定的瑕疵,周期性地出现满占空比的情况,如图(请忽略噪声尖峰的问题):
以前用MSP430做SPWM波形,也出现过这个问题,最后把定时器时钟设置得远远慢于主时钟才得以解决。MSP430功能不适合做SPWM,这也就算了,但是C2000应该不至于出现这种问题把?我以前用STM32,主时钟72MHz,定时器36MHz都不会出现这种满占空比的问题。请问这种情况该如何解决?或者官方有没有提供SPWM的源程序?在controlSUITE暂时没找到。
囧:
回复 囧:
另外你可以不用CMPB,直接用CMAP然后输出到死区直接反向就可以了。
更正一下,刚刚红色的地方,CAD和CAU的set 和clear还要反一下,
主时钟100MHz,经EPWMCLKDIV二分频,HSPCLKDIV二分频,CLKDIV二分频,相当于ePWM的TBCLK时钟为12.5MHz,使用查表法产生SPWM,然而在检查正弦表无误的情况下,波形有一定的瑕疵,周期性地出现满占空比的情况,如图(请忽略噪声尖峰的问题):
以前用MSP430做SPWM波形,也出现过这个问题,最后把定时器时钟设置得远远慢于主时钟才得以解决。MSP430功能不适合做SPWM,这也就算了,但是C2000应该不至于出现这种问题把?我以前用STM32,主时钟72MHz,定时器36MHz都不会出现这种满占空比的问题。请问这种情况该如何解决?或者官方有没有提供SPWM的源程序?在controlSUITE暂时没找到。
Liliang Zhong1:
回复 囧:
谢谢你啊~~但是我照着你说的修改之后还是有这个问题,不过因为是增减计数,现在周期性出现错误满占空比的情况变成了出现50%占空比,如图:
如果可以的话还是请发一份您写的SPWM程序吧….多谢了!
主时钟100MHz,经EPWMCLKDIV二分频,HSPCLKDIV二分频,CLKDIV二分频,相当于ePWM的TBCLK时钟为12.5MHz,使用查表法产生SPWM,然而在检查正弦表无误的情况下,波形有一定的瑕疵,周期性地出现满占空比的情况,如图(请忽略噪声尖峰的问题):
以前用MSP430做SPWM波形,也出现过这个问题,最后把定时器时钟设置得远远慢于主时钟才得以解决。MSP430功能不适合做SPWM,这也就算了,但是C2000应该不至于出现这种问题把?我以前用STM32,主时钟72MHz,定时器36MHz都不会出现这种满占空比的问题。请问这种情况该如何解决?或者官方有没有提供SPWM的源程序?在controlSUITE暂时没找到。
囧:
回复 Liliang Zhong1:
你的周期值是不是改成原来的一倍了?按照你原来的CMPA值,肯定会有最中间的几个周期是满占空比的。因为如果是单增模式,
TPWM = (TBPRD + 1) x TTBCLK
如果是增减模式:TPWM = 2 x TBPRD x TTBCLK,所以你只要改成增减模式就可以。
可以先固定CMPA=623看一下是不是满占空比
主时钟100MHz,经EPWMCLKDIV二分频,HSPCLKDIV二分频,CLKDIV二分频,相当于ePWM的TBCLK时钟为12.5MHz,使用查表法产生SPWM,然而在检查正弦表无误的情况下,波形有一定的瑕疵,周期性地出现满占空比的情况,如图(请忽略噪声尖峰的问题):
以前用MSP430做SPWM波形,也出现过这个问题,最后把定时器时钟设置得远远慢于主时钟才得以解决。MSP430功能不适合做SPWM,这也就算了,但是C2000应该不至于出现这种问题把?我以前用STM32,主时钟72MHz,定时器36MHz都不会出现这种满占空比的问题。请问这种情况该如何解决?或者官方有没有提供SPWM的源程序?在controlSUITE暂时没找到。
que wu:
回复 囧:
囧 先生您好,今天我调试,带软启动的电压闭环程序,为什么这样写程序不能实现,在按下开关后软启动程序先起作用,然后在开始PI运算的功能呢?麻烦您帮我看一下哪地方写的不合适?
Uint16 Voltage1[10];Uint16 Voltage2[10];Uint16 ConversionCount;Uint16 count;//用以表示EPWM1INT中断开始工作Uint32 ss_count;Uint16 ss_flag;
_iq U_Kp=_IQ(1),U_Ki=_IQ(0); //Ki=12000*Tsample Ki乘以采样周期定标_iq Ue0=0,Ue1=0,Ue2=0,Uref=0,Up=0,Ui=0,Uo0=0,Uo1=0,Uo2=0,Ureal=0;long U1,I1;long CA,CB;long temp1,temp2;int U_Ref= 265 ;
void Init_Gpio(void) //初始化GPIO
{EALLOW;GpioCtrlRegs.GPAMUX1.bit.GPIO4=1; //设置GPIO4口为EPWM3A波形输出引脚GpioCtrlRegs.GPADIR.bit.GPIO4=1; //设置GPIO4口方向为输出GpioCtrlRegs.GPAMUX1.bit.GPIO5=1; //设置GPIO5口为EPWM3B波形输出引脚GpioCtrlRegs.GPADIR.bit.GPIO5=1; //设置GPIO5口方向为输出
GpioCtrlRegs.GPAMUX1.bit.GPIO10=01; //设置GPIO10口为EPWM6A波形输出引脚GpioCtrlRegs.GPADIR.bit.GPIO10=1; //设置GPIO10口方向为输出GpioCtrlRegs.GPAMUX1.bit.GPIO11=01; //设置GPIO11口为EPWM6B波形输出引脚GpioCtrlRegs.GPADIR.bit.GPIO11=1; //设置GPIO11口方向为输出
GpioCtrlRegs.GPAMUX2.bit.GPIO17 = 0; // 0:GPIO 1:PeripheralGpioCtrlRegs.GPADIR.bit.GPIO17 = 1; // 0:Input 1:Output
GpioCtrlRegs.GPAMUX2.bit.GPIO18 = 0; // 0:GPIO 1:PeripheralGpioCtrlRegs.GPADIR.bit.GPIO18 = 1; // 0:Input 1:Output
GpioCtrlRegs.GPBMUX1.bit.GPIO34 = 0; // 0:GPIO 1:PeripheralGpioCtrlRegs.GPBDIR.bit.GPIO34 = 0; // 0:Input 1:OutputGpioCtrlRegs.GPBCTRL.bit.QUALPRD0 = 1;//两个机器周期检测一次GpioCtrlRegs.GPBQSEL1.bit.GPIO34 = 2; //使用6次采样鉴定GpioCtrlRegs.GPAPUD.all = 0x0000; //上拉EDIS;}/*void GPIO0(){EALLOW;GpioCtrlRegs.GPAPUD.bit.GPIO0 = 0; // Enable pullup on GPIO3(上拉电阻是做什么的?一般情况下都是会设置成使用上拉电阻模式)GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 0; // GPIO0 = GPIO0GpioCtrlRegs.GPADIR.bit.GPIO0 = 1; // GPIO0 = outputEDIS;}
void Init_Adc(void) //初始化ADC模块{EALLOW;AdcRegs.ADCCTL1.bit.ADCBGPWD = 1; // Power ADC BG ADCCTL1的位6 带隙上电AdcRegs.ADCCTL1.bit.ADCREFPWD = 1; // Power reference ADCCTL1的位5 参考上电AdcRegs.ADCCTL1.bit.ADCPWDN = 1; // Power ADC ADCCTL1的位7 Power up rest of ADC除带隙和参考上电以外的上电AdcRegs.ADCCTL1.bit.ADCENABLE = 1; // Enable ADC ADCCTL1的位14AdcRegs.ADCCTL1.bit.ADCREFSEL = 0; // Select interal BG 建议使用内部基准 内部基准一般就是指3.3v ( Digital Value = 4096 [(Input – VREFLO)/3.3v] when 0v < Input < 3.3v)DELAY_US(ADC_usDELAY);
//选择序列采样模式AdcRegs.ADCSAMPLEMODE.bit.SIMULEN0=0; //SOC0和SOC1AdcRegs.ADCSAMPLEMODE.bit.SIMULEN2=0; //SOC2和SOC3AdcRegs.ADCSAMPLEMODE.bit.SIMULEN4=0; //SOC4和SOC5AdcRegs.ADCSAMPLEMODE.bit.SIMULEN6=0; //SOC6和SOC7
AdcRegs.ADCSOC7CTL.bit.CHSEL = 7; //set SOC7 channel select to ADCINA7 SOC1选择ADCINA1通道 A1通道采U1 SOC1的结果存于ADCRETSULT1寄存器中
AdcRegs.ADCSOC7CTL.bit.TRIGSEL = 9; // SOC7的触发源选择EPWM3A
AdcRegs.ADCSOC7CTL.bit.ACQPS = 6; //set SOC7 S/H Window to 7 ADC Clock Cycles, (6 ACQPS plus 1) SOC1的采样窗口为7个周期长度EDIS;// Assumes ePWM1 clock is already enabled in InitSysCtrl();EPwm3Regs.ETSEL.bit.SOCAEN = 1; // Enable SOC on A group 使能ADC开始转换A(EPEMxSOCA)脉冲EPwm3Regs.ETSEL.bit.SOCASEL = 4; // Select SOC from from CPMA on upcount 使能事件,当定时器递增时时间基准计数器等于CMPAEPwm3Regs.ETPS.bit.SOCAPRD = 1; // Generate pulse on 1st event 在第一个件上生成ePWMxSOCA脉冲:ETPS[SOCACNT]=0,1
}
void Init_EPwm3(void){// Initialization TimerEPwm3Regs.TBPRD = 300; // Period = 2*300 TBCLK countsEPwm3Regs.TBPHS. half.TBPHS= 0; // Set Phase register to zeroEPwm3Regs.TBCTR = 0; // clear TB counterEPwm3Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // SymmetricEPwm3Regs.TBCTL.bit.PHSEN = TB_ENABLE; // Phase loading disabledEPwm3Regs.TBCTL.bit.PRDLD = TB_SHADOW;EPwm3Regs.TBCTL.bit.SYNCOSEL = 00;EPwm3Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // TBCLK = SYSCLKOUTEPwm3Regs.TBCTL.bit.CLKDIV = TB_DIV1;EPwm3Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;EPwm3Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;EPwm3Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // load on CTR = ZeroEPwm3Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; // load on CTR = ZeroEPwm3Regs.AQCTLA.bit.ZRO = AQ_SET; // set actions for EPWM1AEPwm3Regs.AQCTLA.bit.PRD = AQ_CLEAR; //S1EPwm3Regs.AQCTLB.bit.ZRO = AQ_CLEAR;EPwm3Regs.AQCTLB.bit.PRD = AQ_SET; //S2////Run Time// = = = = = = = = = = = = = = = = = = = = = = = =// EPwm1Regs.CMPA.half.CMPA = 360; // adjust duty for output EPWM1A// EPwm1Regs.CMPB=75; // adjust duty for output EPWM1B 移向45度EPwm3Regs.DBCTL.bit.OUT_MODE=DB_FULL_ENABLE; //11EPwm3Regs.DBCTL.bit.POLSEL=DB_ACTV_HIC; //10EPwm3Regs.DBCTL.bit.IN_MODE=00; //选Epwm1A为下降沿和上升沿延迟输入源EPwm3Regs.DBRED=30; //上升沿延迟时间EPwm3Regs.DBFED=30; //下降沿延迟时间
EPwm3Regs.TZSEL.bit.OSHT1=1;EPwm3Regs.TZCTL.bit.TZA=TZ_FORCE_LO;EPwm3Regs.TZCTL.bit.TZB=TZ_FORCE_LO;
//产生EPWM3INT3中断EPwm3Regs.ETSEL.bit.INTSEL=ET_CTR_ZERO; //当时基计数器等于0时产生EPWM3INT1中断EPwm3Regs.ETPS.bit.INTPRD =ET_3RD; //在第3个事件时产生中断EPwm3Regs.ETSEL.bit.INTEN=1; //EPWM1 INT中断使能
}void Init_EPwm6(void) //初始化EPWM2 开关管S3,S4{// Initialization TimerEPwm6Regs.TBPRD = 300; // Period = 2*300 TBCLK countsEPwm6Regs.TBPHS. half.TBPHS= 0; // Set Phase register to zeroEPwm6Regs.TBCTR = 0; // clear TB counterEPwm6Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // SymmetricEPwm6Regs.TBCTL.bit.PHSEN = TB_ENABLE; // Phase loading disabledEPwm6Regs.TBCTL.bit.PRDLD = TB_SHADOW;EPwm6Regs.TBCTL.bit.SYNCOSEL = 00;EPwm6Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // TBCLK = SYSCLKOUTEPwm6Regs.TBCTL.bit.CLKDIV = TB_DIV1;EPwm6Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;EPwm6Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;EPwm6Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // load on CTR = ZeroEPwm6Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; // load on CTR = ZeroEPwm6Regs.AQCTLA.bit.CAU = AQ_SET; // set actions for EPWM3AEPwm6Regs.AQCTLA.bit.CBD = AQ_CLEAR; //S5EPwm6Regs.AQCTLB.bit.CAU = AQ_CLEAR;EPwm6Regs.AQCTLB.bit.CBD = AQ_SET; //S6////Run Time// = = = = = = = = = = = = = = = = = = = = = = = =//EPwm6Regs.CMPA.half.CMPA =0;//EPwm6Regs.CMPB=0;
EPwm6Regs.DBCTL.bit.OUT_MODE=DB_FULL_ENABLE; //11EPwm6Regs.DBCTL.bit.POLSEL=DB_ACTV_HIC; //10EPwm6Regs.DBCTL.bit.IN_MODE=0; //选Epwm2A为下降沿和上升沿延迟输入源EPwm6Regs.DBRED=30; //上升沿延迟时间EPwm6Regs.DBFED=30; //下降延迟时间
EPwm6Regs.TZSEL.bit.OSHT1=1;EPwm6Regs.TZCTL.bit.TZA=TZ_FORCE_LO;EPwm6Regs.TZCTL.bit.TZB=TZ_FORCE_LO;
}
void delay(){Uint16 i=0, j=0;for(i=0; i<1000; i++)for(j=0; j<10; j++);}
void main(void){
InitSysCtrl();Init_Gpio();// For this case just init GPIO pins for ePWM1, ePWM2, and TZ1 pins
DINT;InitPieCtrl(); // 初始化 PIE 控制寄存器IER = 0x0000; // 禁止 CPU 中断IFR = 0x0000; //清除 CPU 中断标志InitPieVectTable(); // 初始化 中断向量表
EALLOW;PieVectTable.EPWM3_INT = &epwm3_isr;//&表示取地址,此句表示设置EPWM3_INT中断服务程序的入口地址为epwm1_isr
EDIS;IER |= M_INT3;// Enable EPWM INT1 in the PIE: Group 3 interrupt 1,且使能group 1 interrupt 1PieCtrlRegs.PIEIER3.bit.INTx3 = 1;EINT; // Enable Global interrupt INTMERTM; // Enable Global realtime interrupt DBGM
EALLOW;SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;//停止每个已使能EPWM模块内的时基时钟(TBCLK)(默认状态)。
EDIS; //但是,如果PCLKCR1寄存器的EPWM时钟使能位被置位,那么EPWM模块仍然由SYSCLKOUT来计时,即使TBCLKSYNC为0。
delay();Init_Adc(); // For this example, init the ADCInit_EPwm3();Init_EPwm6();
EALLOW;SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;//所有已使能的EPWM模块的时钟在已校准的TBCLK的第一个上升沿启动。为了得到完美同//步的TBCLK,每个EPWM模块的TBCLK寄存器中的预分频器位必须设置相同。使能EPWM时钟的正确过程如下所示:在PCLKCR1寄存器中//使能EPWM模块时钟;将TBCLKSYNC设置为0;配置预分频器值和EPWM模式;将TBCLKSYNC设置为1。EDIS;
Restart_Begining:
GpioDataRegs.GPADAT.bit.GPIO17 = 0;DELAY_US(10L);GpioDataRegs.GPADAT.bit.GPIO18 = 0;
CA=0,CB=0;count=0;temp1=0;temp2=0;ss_count=0;ss_flag=0;EPwm6Regs.CMPA.half.CMPA =0;EPwm6Regs.CMPB=0;EALLOW;EPwm6Regs.TZFRC.bit.OST = 1;EPwm3Regs.TZFRC.bit.OST = 1;EDIS;
//检测开关是否闭合,开始软启动while(1){if(GpioDataRegs.GPBDAT.bit.GPIO34 == 0){delay();if(GpioDataRegs.GPBDAT.bit.GPIO34 == 0) break;}}ss_flag = 1;
EALLOW;EPwm3Regs.TZCLR.bit.OST = 1;EPwm6Regs.TZCLR.bit.OST = 1;EDIS;
// Step 7. IDLE loop. Just sit and loop forever (optional):for(;;){if(GpioDataRegs.GPBDAT.bit.GPIO34 == 1){delay();if(GpioDataRegs.GPBDAT.bit.GPIO34 == 1)goto Restart_Begining;}
}
}
interrupt void epwm3_isr(void){
if(ss_flag == 1){if(ss_count<=307200){ss_count++;temp1=(long)((ss_count)>>11);
EPwm6Regs.CMPA.half.CMPA =300-temp1;EPwm6Regs.CMPB=temp1;
}}
U1= AdcResult.ADCRESULT7; //U1电压, A7通道采U1Voltage1[ConversionCount] = AdcResult.ADCRESULT7; //ADC的最近10次采样结果放在Voltage1数组中
// If 10 conversions have been logged, start overif(ConversionCount == 9){ConversionCount = 0;
}else //AD采样值是经过10次求平均得到的
{ConversionCount++;}
//pi程序Ureal=_IQ(U1);
Uref=_IQ(U_Ref); //300缩放为2.3,对应数字量为2855
Ue1=Uref-Ureal ;
Ue2=Ue1-Ue0; //两者的误差
Up=_IQmpy(U_Kp,Ue2);
Ui=_IQmpy(U_Ki,Ue1);
Uo1=Uo0+Up+Ui;
Ue0=Ue1;
Uo0=Uo1;
if(Uo1>=_IQ(EPwm3Regs.TBPRD*0.9)) Uo1 =_IQ(EPwm3Regs.TBPRD*0.9); // PI 输出上限幅
if(Uo1<=_IQ(1)) Uo1 =_IQ(1); // PI 输出下限幅
temp2=(long)((Uo1)>>18); //调制波得到数据
if ( temp2>=270) { temp2=270; EPwm6Regs.CMPA.half.CMPA = temp2; EPwm6Regs.CMPB=300-temp2; }else if ( temp2<=0) { temp2=1; EPwm6Regs.CMPA.half.CMPA = temp2; EPwm6Regs.CMPB=300-temp2; } //设置移向角范围为0.6度到90
CA=temp2;CB=300-temp2;EPwm6Regs.CMPA.half.CMPA =CA; //移向角EPwm6Regs.CMPB=CB;
// I1= AdcResult.ADCRESULT0; //I1电压, A0通道采I1
count++;GpioDataRegs.GPATOGGLE.bit.GPIO0=1;/*
*/GpioDataRegs.GPATOGGLE.bit.GPIO0=0;EPwm3Regs.ETCLR.bit.INT = 1; //清除EPWM1 INT的中断标志位PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;
}