在这里插入代码片
@TOC
/*------本例为Buck变换,输入电压为36V,输出电压为24V,输出功率60W,电压纹波小于5%; PWM频率为12.8kHz。---------*/
#include "DSP2833x_Device.h" // DSP2833x Headerfile Include File
#include "DSP2833x_Examples.h" // DSP2833x Examples Include File
#include "math.h"
//#define ACTV_LOW //驱动电路低有效
#define ACTV_HIGH //驱动电路高有效
void adc_isr(void); //声明AD采集子程序
interrupt void ISRepwm1(void); //声明EPWM中断服务子程序
void EPwmSetup(void); //声明EPWM模块初始化子函数
float D=0.5; //占空比赋初值
Uint32 k=0, j=0,close=0, pwm_cnt1;
//AD采集相关
float u1,sum1,sum=0,Voltage1[10]; //u1为采集值,数组用于平均值计算,sum1为和,sum为平均值
float bian=40,pian=1.50,U=24; //bian为调理电路变比,pian为电路偏置电压,没有偏置设为零,U为给定电压
//PI调节相关
float e,e1=0,e2,PID,PIDold,Kp=0.01,Ki=0.001;//Kp和Ki分别为比例和积分常数
main()
{
InitSysCtrl();
InitGpio();
DINT;//禁止CPU中断
InitPieCtrl();
IER = 0x0000;
IFR = 0x0000;
InitPieVectTable();
EALLOW;
PieVectTable.EPWM1_INT=&ISRepwm1;//重新映射本处使用的中断向量,使其指向中断服务函数
EDIS;
InitAdc(); //AD初始化
EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;//停止所有epwm通道的时钟
EDIS;
EPwmSetup();//初始化epwm
EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;//允许EPWM通道的时钟
EDIS;
PieCtrlRegs.PIECTRL.bit.ENPIE = 1; //允许从PIE向量表中读取中断向量
PieCtrlRegs.PIEIER3.bit.INTx1 = 1;//允许PIE中断组3中EPWM1_INT中断
IER |= M_INT3;//允许中断
EINT; // Enable Global interrupt INTM
ERTM; // Enable Global realtime interrupt DBGM
EPwm1Regs.ETSEL.bit.INTEN=1;//ETSEL.bit.INTEN 中断使能,即允许标志位EPWM1_I
EPwm1Regs.ETCLR.bit.INT=1; //ETCLR.bit.INT 清除标志位
for(;;)
{asm(" NOP");}
}
void adc_isr()//AD采集子程序
{
u1 = ((float)AdcRegs.ADCRESULT0)*3/65536;
Voltage1[k]=bian*(u1-pian);
//平均值计算
k++;
if(k ==10)
{
k = 0;
sum1=0;//Voltage1[0];
for(j=0;j<10;j++)
{
sum1=sum1+Voltage1[j]; //求和
}
sum= sum1/10;//平均值
//PI调节
e1=U-sum;
if(e1>0.2) e1=0.2;
if(e1<-0.2) e1=-0.2;
e=e1-e2;
PID=Kp*e +Ki*e1+PIDold;
if(PID>0.95) PID=0.95;
if(PID<0.2) PID=0.2;
PIDold=PID;
e2=e1;
if(close==1)D=PID;//开闭调节转换控制,一般先使close=0进行开环调试,然后再使close=1进行闭环调试
}
return;
}
interrupt void ISRepwm1(void)
{
adc_isr(); // 调用AD子程序
//计算比较寄存器的值
#ifdef ACTV_LOW //驱动电路低有效
pwm_cnt1=(Uint16)(EPwm1Regs.TBPRD*(1-D));
#endif
#ifdef ACTV_HIGH //驱动电路高有效
pwm_cnt1=(Uint16)(EPwm1Regs.TBPRD*D);
#endif
//更新比较寄存器值
EPwm1Regs.CMPA.half.CMPA = pwm_cnt1;
EPwm1Regs.CMPB = pwm_cnt1;
EPwm1Regs.ETSEL.bit.INTEN=1;//使能epwm1 中断
EPwm1Regs.ETCLR.bit.INT=1;//清除标志位
PieCtrlRegs.PIEACK.all=PIEACK_GROUP3;//清除应答
EINT;
}