This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
这个程序是控制移相全桥的,单电流闭环程序,现在一直闭不上,我实在找不出问题的原因。同样程序,单电压闭环就闭上了。麻烦技术人员帮我看看
Uint16 ConversionCount;
Uint16 count;//用以表示EPWM1INT中断开始工作
Uint32 ss_count;
Uint16 ss_flag;
Uint16 PI_flag;
#define IKp _IQ(0.1) //Kp=0.1 Q16定标5.2
#define IKi _IQ(0.05) //Ki=0.052 Ki乘以采样周期定标0.05 .0065
//_iq Ie1,Ie2,Iref,Ip,Ii,Io1,Ireal;
_iq Ie0,Ie1,Ie2,Iref,Ip,Ii,Io0,Io1,Io2,Ireal;
long U1,I1;
long temp1,temp2;
long I_Ref;//1812 7A电流转变为1.46V电压 对应数字量
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:Peripheral
GpioCtrlRegs.GPADIR.bit.GPIO17 = 1; // 0:Input 1:Output
GpioCtrlRegs.GPAMUX2.bit.GPIO18 = 0; // 0:GPIO 1:Peripheral
GpioCtrlRegs.GPADIR.bit.GPIO18 = 1; // 0:Input 1:Output
GpioCtrlRegs.GPBMUX1.bit.GPIO34 = 0; // 0:GPIO 1:Peripheral
GpioCtrlRegs.GPBDIR.bit.GPIO34 = 0; // 0:Input 1:Output
GpioCtrlRegs.GPBCTRL.bit.QUALPRD0 = 1;//两个机器周期检测一次
GpioCtrlRegs.GPBQSEL1.bit.GPIO34 = 2; //使用6次采样鉴定
GpioCtrlRegs.GPAPUD.all = 0x0000; //上拉
EDIS;
}
void initComp2Gpio()//用于过压保护
{
EALLOW;
GpioCtrlRegs.AIOMUX1.bit.AIO4 = 2; // Configure AIO2 for CMP2A (analog input) operation
EDIS;
}
void initComp3Gpio()//用于过流保护
{
EALLOW;
GpioCtrlRegs.AIOMUX1.bit.AIO6 = 2; // Configure AIO4 for CMP3A (analog input) operation
EDIS;
}
void Init_EPwm3(void)
{
// Initialization Timer
EPwm3Regs.TBPRD = 300; // Period = 2*300 TBCLK counts
EPwm3Regs.TBPHS. half.TBPHS= 0; // Set Phase register to zero
EPwm3Regs.TBCTR = 0; // clear TB counter
EPwm3Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Symmetric
EPwm3Regs.TBCTL.bit.PHSEN = TB_ENABLE; // Phase loading disabled
EPwm3Regs.TBCTL.bit.PRDLD = TB_SHADOW;
EPwm3Regs.TBCTL.bit.SYNCOSEL = 00;
EPwm3Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // TBCLK = SYSCLKOUT
EPwm3Regs.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 = Zero
EPwm3Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; // load on CTR = Zero
EPwm3Regs.AQCTLA.bit.ZRO = AQ_SET; // set actions for EPWM1A
EPwm3Regs.AQCTLA.bit.PRD = AQ_CLEAR; //S1
EPwm3Regs.AQCTLB.bit.ZRO = AQ_CLEAR;
EPwm3Regs.AQCTLB.bit.PRD = AQ_SET; //S2
//
//Run Time
// = = = = = = = = = = = = = = = = = = = = = = = =
EPwm3Regs.DBCTL.bit.OUT_MODE=DB_FULL_ENABLE; //11
EPwm3Regs.DBCTL.bit.POLSEL=DB_ACTV_HIC; //10
EPwm3Regs.DBCTL.bit.IN_MODE=00; //选Epwm1A为下降沿和上升沿延迟输入源
EPwm3Regs.DBRED=24; //上升沿延迟时间
EPwm3Regs.DBFED=24; //下降沿延迟时间
EPwm3Regs.TZSEL.bit.OSHT1=1;
EPwm3Regs.TZCTL.bit.TZA=TZ_FORCE_LO;
EPwm3Regs.TZCTL.bit.TZB=TZ_FORCE_LO;
// 过流、过压保护
Comp2Regs.DACVAL.bit.DACVAL =580; //过电压参考值229V 358
Comp3Regs.DACVAL.bit.DACVAL =627; //过电流参考值12A 647
//comp的输出控制,是否反相,是否同步?
Comp2Regs.COMPCTL.bit.CMPINV =0; //不反相,传送比较器的输出
Comp3Regs.COMPCTL.bit.CMPINV =0; //不反相,传送比较器的输出
Comp2Regs.COMPCTL.bit.SYNCSEL =0; //比较器输出被异步传送
Comp3Regs.COMPCTL.bit.SYNCSEL =0; //比较器输出被异步传送
//设置DC模块,comp1out(当短路时,comp1out的输出是1,否则输出是0)产生DCAEVT1的force信号
EALLOW;
EPwm3Regs.DCTRIPSEL.bit.DCAHCOMPSEL=DC_COMP2OUT; //COMP2OUT是数字比较A(DCAH)的输入选择位
EPwm3Regs.DCTRIPSEL.bit.DCBHCOMPSEL=DC_COMP3OUT;
EPwm3Regs.TZDCSEL.bit.DCAEVT1 = TZ_DCAH_HI; //COMP3OUT输出为高电平,DCAL为任意值时,会产生DCAEVT1事件 DCAH = high, DCAL = don't care
EPwm3Regs.TZDCSEL.bit.DCBEVT1 = TZ_DCBH_HI;
EPwm3Regs.DCACTL.bit.EVT1SRCSEL =0; //DCAEVT1 Source Signal Select Source Is DCAEVT1 Signal
EPwm3Regs.DCBCTL.bit.EVT1SRCSEL =0;
EPwm3Regs.DCACTL.bit.EVT1FRCSYNCSEL =1; //DCAEVT1是异步信号,不进行同步,这时是不需要设置TZFRC[DCAEVT1]的,因为是两种使得DCAEVT1force产生的方式,要产生DCAEVT1force这个信号是可以直接用软件实现的。
EPwm3Regs.DCBCTL.bit.EVT1FRCSYNCSEL =1;
EDIS;
//封锁超前管PWM波
EALLOW;
EPwm3Regs.TZSEL.bit.DCAEVT1 = 1; //DCAEVT1是单次触发的故障源
EPwm3Regs.TZSEL.bit.DCBEVT1 = 1;
EPwm3Regs.TZCTL.bit.TZA =TZ_FORCE_LO; //DCAEVT1触发事件发生时,将EPWM1A设置成出错时变低
EPwm3Regs.TZCTL.bit.TZB =TZ_FORCE_LO; //DCBEVT1触发事件发生时,将EPWM1B设置成出错时变低
EPwm3Regs.TZEINT.bit.OST = 1; //使能综合的中断 Enable Interrupt generation; a one-shot trip event will cause a EPWMx_TZINT PIE interrupt
EDIS;
//产生EPWM3INT3中断
EPwm3Regs.ETSEL.bit.INTSEL=ET_CTR_ZERO; //当时基计数器等于0时产生EPWM3INT1中断
EPwm3Regs.ETPS.bit.INTPRD =0x2; //在第3个事件时产生中断
EPwm3Regs.ETSEL.bit.INTEN=1; //EPWM1 INT中断使能
}
void Init_EPwm6(void) //初始化EPWM2 开关管S3,S4
{
// Initialization Timer
EPwm6Regs.TBPRD = 300; // Period = 2*300 TBCLK counts
EPwm6Regs.TBPHS. half.TBPHS= 0; // Set Phase register to zero
EPwm6Regs.TBCTR = 0; // clear TB counter
EPwm6Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Symmetric
EPwm6Regs.TBCTL.bit.PHSEN = TB_ENABLE; // Phase loading disabled
EPwm6Regs.TBCTL.bit.PRDLD = TB_SHADOW;
EPwm6Regs.TBCTL.bit.SYNCOSEL = 00;
EPwm6Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // TBCLK = SYSCLKOUT
EPwm6Regs.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 = Zero
EPwm6Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; // load on CTR = Zero
EPwm6Regs.AQCTLA.bit.CAU = AQ_SET; // set actions for EPWM3A
EPwm6Regs.AQCTLA.bit.CBD = AQ_CLEAR; //S5
EPwm6Regs.AQCTLB.bit.CAU = AQ_CLEAR;
EPwm6Regs.AQCTLB.bit.CBD = AQ_SET; //S6
//
//Run Time
// = = = = = = = = = = = = = = = = = = = = = = = =
EPwm6Regs.DBCTL.bit.OUT_MODE=DB_FULL_ENABLE; //11
EPwm6Regs.DBCTL.bit.POLSEL=DB_ACTV_HIC; //10
EPwm6Regs.DBCTL.bit.IN_MODE=0; //选Epwm2A为下降沿和上升沿延迟输入源
EPwm6Regs.DBRED=24; //上升沿延迟时间
EPwm6Regs.DBFED=24; //下降延迟时间
EPwm6Regs.TZSEL.bit.OSHT1=1;
EPwm6Regs.TZCTL.bit.TZA=TZ_FORCE_LO;
EPwm6Regs.TZCTL.bit.TZB=TZ_FORCE_LO;
//过流、过压保护
Comp2Regs.DACVAL.bit.DACVAL =580; //过电压参考值229V
Comp3Regs.DACVAL.bit.DACVAL =627; //过电流参考值12A
//comp的输出控制,是否反相,是否同步?
Comp2Regs.COMPCTL.bit.CMPINV =0; //不反相,传送比较器的输出
Comp3Regs.COMPCTL.bit.CMPINV =0; //不反相,传送比较器的输出
Comp2Regs.COMPCTL.bit.SYNCSEL =0; //比较器输出被异步传送
Comp3Regs.COMPCTL.bit.SYNCSEL =0; //比较器输出被异步传送
//设置DC模块,comp1out(当短路时,comp1out的输出是1,否则输出是0)产生DCAEVT1的force信号
EALLOW;
EPwm6Regs.DCTRIPSEL.bit.DCAHCOMPSEL=DC_COMP2OUT; //COMP2OUT是数字比较A(DCAH)的输入选择位
EPwm6Regs.DCTRIPSEL.bit.DCBHCOMPSEL=DC_COMP3OUT;
EPwm6Regs.TZDCSEL.bit.DCAEVT1 = TZ_DCAH_HI; //COMP2OUT输出为高电平,DCAL为任意值时,会产生DCAEVT1事件 DCAH = high, DCAL = don't care
EPwm6Regs.TZDCSEL.bit.DCBEVT1 = TZ_DCBH_HI;
EPwm6Regs.DCACTL.bit.EVT1SRCSEL =0; //DCAEVT1 Source Signal Select Source Is DCAEVT1 Signal
EPwm6Regs.DCBCTL.bit.EVT1SRCSEL =0;
EPwm6Regs.DCACTL.bit.EVT1FRCSYNCSEL =1; //DCAEVT1是异步信号,不进行同步,这时是不需要设置TZFRC[DCAEVT1]的,因为是两种使得DCAEVT1force产生的方式,要产生DCAEVT1force这个信号是可以直接用软件实现的。
EPwm6Regs.DCBCTL.bit.EVT1FRCSYNCSEL =1;
EDIS;
//是否封锁滞后管PWM波
EALLOW;
EPwm6Regs.TZSEL.bit.DCAEVT1 = 1; //DCAEVT1是单次触发的故障源
EPwm6Regs.TZSEL.bit.DCBEVT1 = 1;
EPwm6Regs.TZCTL.bit.TZA =TZ_FORCE_LO; //DCAEVT1触发事件发生时,将EPWM1A设置成出错时变低
EPwm6Regs.TZCTL.bit.TZB =TZ_FORCE_LO; //DCBEVT1触发事件发生时,将EPWM1B设置成出错时变低
EPwm6Regs.TZEINT.bit.OST = 1; //使能综合的中断 Enable Interrupt generation; a one-shot trip event will cause a EPWMx_TZINT PIE interrupt
EDIS;
}
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的位14
AdcRegs.ADCCTL1.bit.ADCREFSEL = 0; // Select interal BG 建议使用内部基准 内部基准一般就是指3.3v ( Digital Value = 4096 [(Input – VREFLO)/3.3v] when 0v < Input < 3.3v)
//外部基准 (Digital Value = 4096 [(Input – VREFLO)/(VREFHI – VREFLO)] when VREFLO < Input < VREFHI)
//延迟
DELAY_US(ADC_usDELAY);
//选择序列采样模式
AdcRegs.ADCSAMPLEMODE.bit.SIMULEN0=0; //SOC0和SOC1
AdcRegs.ADCSAMPLEMODE.bit.SIMULEN2=0; //SOC2和SOC3
AdcRegs.ADCSAMPLEMODE.bit.SIMULEN4=0; //SOC4和SOC5
AdcRegs.ADCSAMPLEMODE.bit.SIMULEN6=0; //SOC6和SOC7
AdcRegs.ADCSOC0CTL.bit.CHSEL = 0; //set SOC0 channel select to ADCINA0 SOC0选择ADCINA0通道 A0通道采I1 SOC0的结果存于ADCRETSULT0寄存器中
// AdcRegs.ADCSOC7CTL.bit.CHSEL = 7; //set SOC7 channel select to ADCINA7 SOC1选择ADCINA1通道 A1通道采U1 SOC1的结果存于ADCRETSULT7寄存器中
AdcRegs.ADCSOC0CTL.bit.TRIGSEL = 9; // SOC0的触发源选择EPWM3A
// AdcRegs.ADCSOC7CTL.bit.TRIGSEL = 9; // SOC7的触发源选择EPWM3A
AdcRegs.ADCSOC0CTL.bit.ACQPS = 6; //set SOC0 S/H Window to 7 ADC Clock Cycles, (6 ACQPS plus 1) SOC0的采样窗口为7个周期长度
// AdcRegs.ADCSOC7CTL.bit.ACQPS = 6; //set SOC7 S/H Window to 7 ADC Clock Cycles, (6 ACQPS plus 1) SOC1的采样窗口为7个周期长度
//设定采集窗口大小,即决定保持多长时间,可理解为相邻采样之间时间差,即SOC的宽度为ADCTRL1[11:8]+1个ADCCLK
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 使能事件,当定时器递增时时间基准计数器等于CMPA
EPwm3Regs.ETPS.bit.SOCAPRD = 1; // Generate pulse on 1st event 在第一个件上生成ePWMxSOCA脉冲:ETPS[SOCACNT]=0,1
count++;
}
void delay()
{
Uint16 i=0, j=0;
for(i=0; i<1000; i++)
for(j=0; j<10; j++);
}
void main(void)
{
//Copy InitFlash function code and Flash setup code to RAM
MemCopy(&RamfuncsLoadStart, &RamfuncsLoadEnd,&RamfuncsRunStart);
//This function must reside in RAM
InitFlash();
InitSysCtrl();
DINT;
Init_Gpio();
initComp2Gpio();//设置AIO2口作为COMP1A的端口
initComp3Gpio();//设置AIO4口作为COMP2A的端口
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 1
PieCtrlRegs.PIEIER3.bit.INTx3 = 1;
EINT; // Enable Global interrupt INTM
ERTM; // Enable Global realtime interrupt DBGM
EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;//停止每个已使能EPWM模块内的时基时钟(TBCLK)(默认状态)。
SysCtrlRegs.PCLKCR0.bit.ADCENCLK = 1; // Enable Clock to the ADC
AdcRegs.ADCCTL1.bit.ADCBGPWD = 1; // Comparator shares the internal BG reference of the ADC, must be powered even if ADC is unused
SysCtrlRegs.PCLKCR3.bit.COMP2ENCLK = 1; // Enable clock to the Comparator 1 block
SysCtrlRegs.PCLKCR3.bit.COMP3ENCLK = 1; // Enable clock to the Comparator 2 block
Comp2Regs.COMPCTL.bit.COMPDACEN = 1; // Power up Comparator 1 locally 比较器/DAC逻辑上电
Comp3Regs.COMPCTL.bit.COMPDACEN = 1; // Power up Comparator 2 locally 比较器/DAC逻辑上电
Comp2Regs.COMPCTL.bit.COMPSOURCE =0; //使用DAC内部基准 比较器的负极输入连接到内部ADC
Comp3Regs.COMPCTL.bit.COMPSOURCE =0; //使用DAC内部基准 比较器的负极输入连接到内部ADC
EDIS; //但是,如果PCLKCR1寄存器的EPWM时钟使能位被置位,那么EPWM模块仍然由SYSCLKOUT来计时,即使TBCLKSYNC为0。
// For this example, init the ADC
Init_Adc();
delay();
Init_EPwm3();
Init_EPwm6();
EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;
EDIS;
Restart_Begining:
GpioDataRegs.GPADAT.bit.GPIO17 = 0;
DELAY_US(10L);
GpioDataRegs.GPADAT.bit.GPIO18 = 0;
// Ie1=0,Ie2=0,Iref=0,Ip=0,Ii=0,Io1=0,Ireal=0;
count=0;
Ie0=0,Ie1=0,Ie2=0,Iref=0,Ip=0,Ii=0,Io0=0,Io1=0,Io2=0,Ireal=0;
temp2=0;
ss_count=0;
ss_flag=0;
I_Ref=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(I_Ref<1554)//ss_count<_IQ(1812)
{
ss_count=ss_count+_IQ(0.0777);
I_Ref=(long)((ss_count)>>16);
}
else{I_Ref=1554;}
I1= AdcResult.ADCRESULT0; //I1电电流, A0通道采I1
Ireal=_IQ(I1);
Iref=_IQ(I_Ref); //6A缩放为1.252V,对应数字量为1554
Ie1=Iref-Ireal ;
Ie2=Ie1-Ie0; //两者的误差
Ip=_IQmpy(IKp,Ie2);
Ii=_IQmpy(IKi,Ie1);
Io1=Io0+Ip+Ii;
Ie0=Ie1;
Io0=Io1;
temp2=(long)((Io1)>>16); //调制波得到数据
if ( temp2>=298) temp2=285;
else if ( temp2<=30) temp2=40;
EPwm6Regs.CMPA.half.CMPA =300-temp2; //移向角
EPwm6Regs.CMPB=temp2;
}
EPwm3Regs.ETCLR.bit.INT = 1; //清除EPWM1 INT的中断标志位
PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;
}
F28035板子是自己画,应该没问题,因为电压闭环闭上了,现在电流闭环,我想输出6A电流,无论怎么调解KP,输出电流一直不超过2A,然后我加入KI参数,输出电流一直程梯形波震荡
我使用的是ADCINA0采样通道,当给ADCINA0采样通道一个固定电压时,结果寄存器里储存的值,比用公式4096*(input Analog -0)/3.3算出来的数大100左右。我输出电压采样通道用的是ADCINA7,结果寄存器里的值与与公式计算的值基本上一样,这是为什么呢?难道ADCINA0这个采样通道有问题吗?还有我直接用结果寄存器里的值来进行PI运算,并没有把结果寄存器里的值乘系数转换为实际电流值,这样可以吗。