TI中文支持网
TI专业的中文技术问题搜集分享网站

麻烦专家帮我看一下我这个带软启动的电压闭环程序

您好,今天我调试带软启动的电压闭环程序,为什么这样写程序不能实现,在按下开关后软启动程序先起作用,然后在开始PI运算的功能呢?麻烦您帮我看一下哪地方写的不合适?

这个是F28035

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: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 GPIO0()
{
EALLOW;
GpioCtrlRegs.GPAPUD.bit.GPIO0 = 0; // Enable pullup on GPIO3(上拉电阻是做什么的?一般情况下都是会设置成使用上拉电阻模式)
GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 0; // GPIO0 = GPIO0
GpioCtrlRegs.GPADIR.bit.GPIO0 = 1; // GPIO0 = output
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)

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.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 使能事件,当定时器递增时时间基准计数器等于CMPA
EPwm3Regs.ETPS.bit.SOCAPRD = 1; // Generate pulse on 1st event 在第一个件上生成ePWMxSOCA脉冲:ETPS[SOCACNT]=0,1

}

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
// = = = = = = = = = = = = = = = = = = = = = = = =
// 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; //11
EPwm3Regs.DBCTL.bit.POLSEL=DB_ACTV_HIC; //10
EPwm3Regs.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 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.CMPA.half.CMPA =0;
//EPwm6Regs.CMPB=0;

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=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 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)(默认状态)。

EDIS; //但是,如果PCLKCR1寄存器的EPWM时钟使能位被置位,那么EPWM模块仍然由SYSCLKOUT来计时,即使TBCLKSYNC为0。

delay();
Init_Adc(); // For this example, init the ADC
Init_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通道采U1
Voltage1[ConversionCount] = AdcResult.ADCRESULT7; //ADC的最近10次采样结果放在Voltage1数组中

// If 10 conversions have been logged, start over
if(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;

}

Eric Ma:

你这个是什么应用,软启动功能具体是什么?你想怎么来控制。

ERIC

赞(0)
未经允许不得转载:TI中文支持网 » 麻烦专家帮我看一下我这个带软启动的电压闭环程序
分享到: 更多 (0)