DSP

基于DSP28335的单相PWM整流 双闭环PI控制

2019-07-13 10:18发布


/********************************************************************************************************
---------------------自带头文件-----------------------------*/
#include "DSP2833x_Device.h"     // DSP2833x Headerfile Include File
#include "DSP2833x_Examples.h"   // DSP2833x Examples Include File
/*--------------------自定义头文件----------------------------*/
#include "user_header.h"        //变量常量定义
#include "user_macro.h"       //宏函数        //工作控制
#include "math.h"
#include "Ad7606.h"
#include "DA5344.h"#pragma CODE_SECTION(epwm1_isr, "ramfuncs");#define AD_ASTART ((Uint16 *)0x100000)      //片外AD的数据读取首地址
#define AD_BSTART ((Uint16 *)0x110000)       //片外AD的数据读取首地址//定义AD7656转换启动和复位操作#define   AD_BUSY         GpioDataRegs.GPADAT.bit.GPIO14
#define   SET_ADRST       GpioDataRegs.GPBSET.bit.GPIO60=1
#define   CLEAR_ADRST     GpioDataRegs.GPBCLEAR.bit.GPIO60=1
#define   SET_ADCLK       GpioDataRegs.GPASET.bit.GPIO15=1
#define   CLR_ADCLK       GpioDataRegs.GPACLEAR.bit.GPIO15=1//四路DA通道的地址
#define DA_ADD0  ((Uint16 *)0x1B0000)      //输出地址0
#define DA_ADD1  ((Uint16 *)0x1B0001)      //输出地址1
#define DA_ADD2  ((Uint16 *)0x1B0002)      //输出地址2
#define DA_ADD3  ((Uint16 *)0x1B0003)       //输出地址3
#define CPU_CLK    150e6
#define PWM_CLK    20e3      // If diff freq. desired, change freq here.载波频率
#define BUF_SIZE 16
#define SCALE  10.0    //量程为10Vint   g=0,h=0,i=0,k=0;
int16 addat[16];
float ad_realvalue[6];
float exadc[6];
float SVPWM_FULL=CPU_CLK/2/PWM_CLK;
float Time=0;
float Phase=0,Phase_Old;      //相位   母线电压相位
float Phase_Flag=0;
float Ualpha;
float Ubeta;
float Ud=10;
float Uq=0,Uq_last;
float Rms=20;
float dq_P=1,dq_I=0.00001,dq_Inter,dq_Out;
float Uac;         // 交流母线侧电压
float Udc, Udc_ref=48, Udc_error, Udc_Inter=0, Udc_out, Udc_P=1, Udc_I=0.001;
float Iac, Iac_ref,    Iac_error, Iac_Inter=0, Iac_out, Iac_P=1,  Iac_I=10;
float Uzaibo,Uac_tiaozhibo,Uzaibo_out;
interrupt void epwm1_isr(void);    // EPWM中断函数声明
void EPwmSetup(void);
void ADC7606(void);
void DA(void);// These are defined by the linker (see F28335.cmd)
/*extern Uint16 RamfuncsLoadStart;
extern Uint16 RamfuncsLoadEnd;
extern Uint16 RamfuncsRunStart;
extern Uint16 RamfuncsLoadSize;long sampleCount*/
#define n  5
float testSample0[n],testSample1[n],testSample2[n],//6个数组存放AD数据
      testSample3[n],testSample4[n],testSample5[n];void main(void)
{ InitSysCtrl();        // 系统初始化
 InitGpio();         // 初始化GPIO
 InitEPwm1Gpio();       // GPIO0,GPIO1,GPIO2,GPIO3,设为外设功能
 InitEPwm2Gpio();
 DINT;          // 设置中断之前,需要先关闭中断 InitPieCtrl();        //初始化中断控制
 InitPieVectTable();       //初始化中断向量表 memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (Uint32)&RamfuncsLoadSize);
    // Call Flash Initialization to setup flash waitstates
 // This function must reside in RAM
    InitFlash(); IER = 0x0000;        //CPU中断寄存器清零
 IFR = 0x0000; EALLOW;
    PieVectTable.EPWM1_INT = &epwm1_isr;   // 指向EPWM1中断模块
    EDIS; EALLOW;
    SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;  // For this example, only initialize the ePWM
    EDIS;    EPwmSetup();    EALLOW;
    SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;
    EDIS;// Step 5. User specific code, enable interrupts:// Enable CPU INT3 which is connected to EPWM1-3 INT:
    IER |= M_INT3;// Enable EPWM INTn in the PIE: Group 3 interrupt 1-3
    PieCtrlRegs.PIEIER3.bit.INTx1 = 1;// Enable global Interrupts and higher priority real-time debug events:
    EINT;            // Enable Global interrupt INTM
    ERTM;             // Enable Global realtime interrupt DBGM SET_ADRST;
 DELAY_US(0.5L);
 CLEAR_ADRST;
 DELAY_US(0.5L);
 SET_ADRST;    for(i=0;i {
       exadc[i]=0;
 }// Step 6. IDLE loop. Just sit and loop forever (optional):
 for(;;)
 {  asm("          NOP");
 }
}interrupt void epwm1_isr(void)
{
 g=g+1;
 SVPWM_FULL = CPU_CLK/2/PWM_CLK;
 ADC7606();
 //PLL();
    /*****************************************************************************************/
    // 电压外环
    Uac=ad_realvalue[2];
    Udc=ad_realvalue[0];                 // 通道[0]为直流母线侧电压
    Udc_error=Udc_ref-Udc;
    Udc_Inter+=Udc_error*Udc_I;               // 积分值    if(Udc_Inter>5900)                          // 积分限幅
     Udc_Inter=5900;
    if(Udc_Inter<-5900)
     Udc_Inter=-5900;
    Udc_out=Udc_Inter+Udc_P*Udc_error;       // 电流幅值的给定值
    if(Udc_out>6000)                           // 电流给定输出限幅
     Udc_out=6000;
    if(Udc_out<-6000)
     Udc_out=-6000;
    Iac_ref=Udc_out/6000*Uac/20;
    //Iac_ref=Uac/20;
    //Iac_ref=Udc_out*sin((float)(Phase));     // 电压电流同相,单位功率因数控制
    //Iac_ref=3*sin((float)(Phase));    // 电流内环
    Iac=ad_realvalue[1];
    Iac_error=Iac_ref-Iac;
    Iac_Inter+=Iac_error*Iac_I;       // 积分项
    if(Iac_Inter>400)                  // 积分限幅
     Iac_Inter=400;
    if(Iac_Inter<-400)
     Iac_Inter=-400;
    Iac_out=Iac_Inter+Iac_P*Iac_error;
    //Iac_out=voltage_PR(Iac_ref,Iac);
    if(Iac_out>500)
     Iac_out=500;
    if(Iac_out<-500)
     Iac_out=-500;
    Uzaibo=Iac_out/500.0;
    Uzaibo_out=-Uzaibo*SVPWM_FULL/2+SVPWM_FULL/2;
    //--------------------------
    if(Uzaibo_out>SVPWM_FULL*0.99)  Uzaibo_out=SVPWM_FULL*0.99;//SVPWM_FULL=3750;
    if(Uzaibo_out EPwm2Regs.CMPA.half.CMPA=SVPWM_FULL-Uzaibo_out;
 //EPwm1Regs.CMPA.half.CMPA=SVPWM_FULL/2;
 //EPwm2Regs.CMPA.half.CMPA=SVPWM_FULL/2;
 //-------------DA 输出观测值
 DA();    EPwm1Regs.ETCLR.bit.INT=1;
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;
}
void EPwmSetup()
{
   // Setup TBCLK
 EPwm1Regs.TBCTL.bit.CTRMODE = 2;             // Count up
    EPwm1Regs.TBPRD = SVPWM_FULL;                      // Set timer period
    EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE;      // Disable phase loading
    EPwm1Regs.TBPHS.half.TBPHS = 0x0000;         // Phase is 0
    EPwm1Regs.TBCTR = 0x0000;                    // Clear counter
    EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;     // Clock ratio to SYSCLKOUT
    EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1;    // Setup TBCLK
 EPwm2Regs.TBCTL.bit.CTRMODE = 2;             // Count up
 EPwm2Regs.TBPRD = SVPWM_FULL;                   // Set timer period
 EPwm2Regs.TBCTL.bit.PHSEN = TB_DISABLE;      // Disable phase loading
 EPwm2Regs.TBPHS.half.TBPHS = 0x0000;         // Phase is 0
 EPwm2Regs.TBCTR = 0x0000;                    // Clear counter
 EPwm2Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;     // Clock ratio to SYSCLKOUT
 EPwm2Regs.TBCTL.bit.CLKDIV = TB_DIV1;   // Setup shadow register load on ZERO
    EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
    EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
    EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
    EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;    // 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
    EPwm1Regs.CMPA.half.CMPA = 100;        // Set compare A value
    // Set Compare values
    EPwm2Regs.CMPA.half.CMPA = 100;        // Set compare A value   // Set actions
    EPwm1Regs.AQCTLA.bit.CAD = AQ_SET;
    EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR;    // Set actions
    EPwm2Regs.AQCTLA.bit.CAD = AQ_SET;
    EPwm2Regs.AQCTLA.bit.CAU = AQ_CLEAR;    // EPWMxB is inverted
    EPwm1Regs.DBCTL.all=0xb;
  EPwm1Regs.DBRED=500;
  EPwm1Regs.DBFED=500;
    // EPWMxB is inverted
    EPwm2Regs.DBCTL.all=0xb;
    EPwm2Regs.DBRED=500;
 EPwm2Regs.DBFED=500;  // Interrupt where we will change the Compare Values
    EPwm1Regs.ETSEL.bit.INTSEL = ET_CTR_PRD;  // Interrupt when TBCTR = TBPRD
    EPwm1Regs.ETSEL.bit.INTEN = 1;                 // Enable INT
    EPwm1Regs.ETPS.bit.INTPRD = ET_1ST;
}void ADC7606()
{
 h++;
 //-------------复位AD7606--------------------------------
 SET_ADRST;
 DELAY_US(0.5L);
 CLEAR_ADRST;
 DELAY_US(0.5L);
 SET_ADRST;
 //--------------------------------复位AD7606--------------------------------
 SET_ADCLK;//xhold--ADCONV,启动AD转换
 DELAY_US(0.5L);
 CLR_ADCLK;
 DELAY_US(0.5L);
 SET_ADCLK;
 DELAY_US(5L);
//------------------------------数据读取---------------------------------
//该组AD数据是100us之前的结果
 if(AD_BUSY==0)//AD_BUSY
 {
  k++;
  for(i=0;i<15;i++)
  {
   addat[i] = *AD_ASTART;       // UACA1交流侧电压Uab
  }
 }
 for(i=0;i<6;i++)
 {
       exadc[i]=(addat[i])*SCALE/32768.0;
 }
 // 转化为实际的电压电流值
 ad_realvalue[0]=exadc[0]*80.17+0.921; //整流器输出电压采样
 ad_realvalue[1]=exadc[1]*1.3417+0.0077; //整流器输入电流采样
 ad_realvalue[2]=exadc[2]*32.56+0.3134; //整流器输入电压采样
}
void DA()
{
 *DA_ADD0=Udc*10+2048;                // 直流电压
 *DA_ADD1=Iac*20+2048;                // 交流电流
 *DA_ADD2=Uac*20+2048;                 // 交流电压
 *DA_ADD3=Phase*10+2048;              // 锁相环
}