⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dc_control.c

📁 基于双向DC-DC变换器
💻 C
字号:
#include "DSP281x_Device.h"     // DSP281x Headerfile Include File
#include "DSP281x_Examples.h"   // DSP281x Examples Include File
#include "DSP281x_Gpio.h"
#include "math.h"

#include "DSP281x_GlobalPrototypes.h"

interrupt void adc_isr(void);   //ADC中断函数
//void delay(int16 z);
volatile int16 i=0;
int16 voltage[5]={0,0,0,0,0},current[5]={0,0,0,0,0}, givevoltage[5]={0,0,0,0,0};
volatile int16 ave_givevoltage=0,ave_current=0,ave_voltage=0;
volatile int16 temp1=0,temp2=0,error_v=0,error_c=0,con1=0,con2=0;
volatile float gdv=0,sjv=0,sjc=0;

#define  lev 1707          //1707~1.25V
#define  led *(int *)0xC0000
#define  D 0.00293

volatile  Uint16 loopcount=0,Duty_cycle=0;
volatile  int16 flag=0,N=5;
volatile  int16 ref_current=40,error_c_ago=0,error_v_ago=0; 
volatile  int16 I_c=0,I_v=0,vol_cnt=0;
volatile  float Vkp=2,Vki=1,Vkd=0,Ikp=1,Iki=0.1,Ikd=0; 
volatile  float P_v=0,D_v=0,PID_v=0;  
volatile  float P_c=0,D_c=0,PID_c=0;       

void setad()
{
   EALLOW;
   AdcRegs.ADCMAXCONV.all = 0x0002;  // Setup 2 conv's on SEQ1
   AdcRegs.ADCCHSELSEQ1.all= 0x3210; // Setup ADCINA3 as 1st SEQ1 conv.
// AdcRegs.ADCCHSELSEQ2.all= 0x7654;
// AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x2; // Setup ADCINA2 as 2nd SEQ1 conv.
   AdcRegs.ADCTRL2.bit.EVA_SOC_SEQ1 = 1;  // Enable EVASOC to start SEQ1
   AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 1;  // Enable SEQ1 interrupt (every EOS)
//  EvaRegs.T1CMPR = 0x0080;       // Setup T1 compare value
   AdcRegs.ADCTRL1.bit.ACQ_PS = 0x06;   //采样窗长度
   AdcRegs.ADCTRL1.bit.CPS = 1;     //45M adc  core timer equal HSPCLK/2  (SYSCLK)

   AdcRegs.ADCTRL3.bit.ADCCLKPS = 0x3;     //00//adc core clock=15M  ????
  
   EvaRegs.GPTCONA.bit.T1TOADC = 0x2; //1// Enable EVASOC in EVA
   EvaRegs.T1CON.bit.TMODE = 0x02;
   EvaRegs.T1CON.bit.TPS = 0x02;     //0//timer CLK(15M) = HSPCLK=SYSCLK(90M)/6
   EvaRegs.T1CON.bit.TENABLE = 1;
   EvaRegs.T1CON.bit.TCLKS10 = 0x0;//选择内部时钟(如HSPCLK)
  
   EvaRegs.T1PR =9000;   //6000/ (4E1) T = Txpr+1   20KHz 0.05ms  SYSCLK=120MHz 
   EvaRegs.T1CNT = 0x0000;   // 2FE  32.55KHz      9C3~10KHz  341~30K

   EDIS;

}

void InitEva()
{
   
  EALLOW;
   EvaRegs.T1PR = 9000;            //9000 T = Txpr+1   10KHz 0.1ms  SYSCLK=90MHz 
   EvaRegs.T1CNT = 0x0000;         // 定时器1清零
   
   EvaRegs.ACTRA.all=0x00FD;        //pwm1低有效 pwm2~3强制高 pwm4强制高
   EvaRegs.DBTCONA.all=0X0000;     //禁止使用死区
   EvaRegs.CMPR1=4500;             //初始化占空比50%
   EvaRegs.COMCONA.all=0X0A400;//使能比较操作 T1CNT=0或T1PR时CMPR重载,禁止SVPWM,T1CNT=0
   
   EvaRegs.GPTCONA.bit.T1TOADC = 0x2; //设置周期中断标志启动ADC 通用定时器1启动ADC
   EvaRegs.T1CON.bit.TMODE = 0x02;    //连续增计数
   EvaRegs.T1CON.bit.TPS = 0x00;     //0//timer CLK(15M) = HSPCLK
   EvaRegs.T1CON.bit.TENABLE = 0;    //不使能定时器1
   EvaRegs.T1CON.bit.TCLKS10 = 0x0; //使用内部时钟                                                      //或T1PR时ACTR重载,先令PWM输出为高阻抗,待初始化完毕后,再令FCOMPOE=1启动PWM 
  
   //EvaRegs.T1CON.bit.TECMPR = 0x1; //使能定时器比较操作
   EDIS;
}

int filter_givevoltage()
{
   int count,a,b,temp,M;
   int  sum=0;
   for (b=0;b<N;b++)          //从大往小找数
 {  
     for (a=0;a<N-1-b;a++)      //比较相邻数的大小,只能找到几个数中的最大值,不能找到最小值,最小值通过第1个循环来找  
      {
         if ( givevoltage[a]>givevoltage[a+1] )
        {
            temp=givevoltage[a];
            givevoltage[a]=givevoltage[a+1]; 
            givevoltage[a+1]=temp;
         }
      }
   }
   for(count=1;count<N-1;count++)
      {sum+=givevoltage[count];}
      M=N-2;
  return (int)(sum/M);
}

int filter_current()
{  
    int  count,a,b,temp,M;
    int  sum=0;
    for (b=0; b<N; b++)          //从大往小找数
    {
     for (a=0; a<N-1-b; a++)      //比较相邻数的大小,只能找到几个数中的最大值,不能找到最小值,最小值通过第1个循环来找  
      {
         if ( current[a]>current[a+1] )
         {
            temp=current[a];           //temp还需要定义吗?
            current[a]=current[a+1]; 
            current[a+1]=temp;
         }
      }
    }
    for(count=1; count<N-1; count++)
     { sum+=current[count];}
      M=N-2;
   return (int)(sum/M);
}

int filter_voltage()
{
   int count,a,b,temp,M;
   int  sum=0;
   for (b=0;b<N;b++)          //从大往小找数
   {
     for (a=0;a<N-1-b;a++)      //比较相邻数的大小,只能找到几个数中的最大值,不能找到最小值,最小值通过第1个循环来找  
      {
         if ( voltage[a]>voltage[a+1] )
         {
            temp=voltage[a];
            voltage[a]=voltage[a+1]; 
            voltage[a+1]=temp;
         }
      }
   }
   for(count=1;count<N-1;count++)
      {sum+=voltage[count];}
      M=N-2;
   return (int)(sum/M);
}

int current_PID()
{    
     
     error_c=ref_current-ave_current;
     P_c=Ikp*error_c;
     if(error_c<80)
     {
      I_c=I_c+Iki*error_c;            //I_c为全局变?
     } 
     D_c=Ikd*(error_c-error_c_ago);   //error_c_ago是全局变量
     error_c_ago=error_c;
     PID_c=P_c+I_c+D_c;
     con1=ceil(PID_c);//ceil函数的作用是求不小于给定实数的最小整数
     if(con1<0)
     {
          temp1=-con1;
          
     }
     else  temp1=con1;
    if(temp1>9000)                //limt是限幅值,可以赋给它周期寄存器的值
     {  
       temp1=9000;
     } 
    return (int)(temp1);
}

int voltage_PID()
{
      
      error_v=ave_givevoltage-ave_voltage;
      P_v=Vkp*error_v;
      if(error_v<80)
      { 
       I_v=I_v+Iki*error_v;  
      }                          // I为全局变量  
      D_v=Vkd*(error_v-error_v_ago);                  // error_old还没设置,应该是全局变量
      error_v_ago=error_v;
      PID_v=P_v+I_v+D_v;
      con2=ceil(PID_v); //answer = ceil(3.1415); answer = 4.0 answer = ceil(-3.5); answer = -3.0
      if(con2<0)                           
      {
           temp2=-con2;
      }
     else  temp2=con2;
     if(temp2>2000)     //13A                    
       {  
            temp2=2000;
       }
     return (int)(temp2);          
}

interrupt void adc_isr(void)
{

     loopcount++;
     //GpioDataRegs.GPBDAT.all=0x0000;
     
     
     asm(" clrc   SXM");	                        // 抑制符号位扩展
     
     current[i]=(AdcRegs.ADCRESULT0 >>4)-lev;                     // 电流结果
     givevoltage[i]=(AdcRegs.ADCRESULT1 >>4)-lev;
     voltage[i]=(AdcRegs.ADCRESULT2 >>4)-lev;                
     
     
     i++; 
     if(i==5)
     {  flag=1;                                   // flag是全局变量
        i=0;
     }   
     if(flag==1)    
     { 
       ave_current=filter_current();
       flag=0;//对电流标志位清零
       Duty_cycle=current_PID();
       vol_cnt++;
       
       gdv=ave_givevoltage*D;
       sjv=ave_voltage*D;
       sjc=ave_current*D;
       
       if(vol_cnt==50)
       { 
        ave_givevoltage=filter_givevoltage();
        ave_voltage=filter_voltage();
        ref_current=voltage_PID();
        vol_cnt=0;         
        }
      }
     
     
     //Duty_cycle=4500;
     EvaRegs.CMPR1=Duty_cycle;      
     //*ADCTRL2=*ADCTRL2|0X4200;          
     
    AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1;         // Reset SEQ1复位排序器,使SEQ1指向CONV00
    AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1;       // Clear INT SEQ1 bit清中断标志位(写1清0)
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;   // Acknowledge interrupt to PIE清PIEACK位,ADC中断属于INT1 响应中断
   
     EvaRegs.T1CNT = 0x0000;
     EvaRegs.EVAIFRA.all=0xffff;
     asm(" CLRC INTM");
    
     
     return; 
    
}


void main()          
{
   asm("  SETC OBJMODE");
  
   InitSysCtrl();//调用系统初始化函数
  
   EALLOW;                        //高速外围时钟定标寄存器设置
   SysCtrlRegs.HISPCP.all = 0x0;  //为0时HSPCLK=SYSCLKOUT
   EDIS;
   DINT;//关总中断
   
   InitGpio();         //port A -out   port B -in GPIO口的初始化
    
   InitPieCtrl();//外设中断扩展初始化
    
   IER = 0x0000;
   IFR = 0x0000;
   
   MemCopy(&RamfuncsLoadStart, &RamfuncsLoadEnd, &RamfuncsRunStart);
          
   InitFlash();//初始化Flash寄存器
   
   InitPieVectTable();//初始化中断向量表
   
      
   EALLOW;  // This is needed to write to EALLOW protected register
   PieVectTable.ADCINT = &adc_isr;//赋中断地址
   EDIS;    // This is needed to disable write to EALLOW protected registers
  
   InitAdc();  // For this example, init the ADC  初始化ADC
   
   setad();
   
   InitEva();
   
   PieCtrlRegs.PIEIER1.bit.INTx6 = 1;//使能位于PIE中的组1的第6个中断TINT0
   IER |= M_INT1; // Enable CPU Interrupt 1 ADC处在INT1 使能全局中断INT1
   EINT;          // Enable Global interrupt INTM 使能全局中断INTM
   ERTM;          // Enable Global realtime interrupt DBGM 使能全局实时中断DBGM
   
   
   EALLOW;
   EvaRegs.T1CON.bit.TENABLE = 1;       //使能定时器1
   EvaRegs.COMCONA.all|=0x02E7;
   EDIS;
   
   
   //GpioDataRegs.GPBDAT.all=0xFFFF; 
   
  // delay(30000);
   Duty_cycle=0;
   
   for(;;)
   {
      led=0x000F;
    //loopcount=0;
   	
    }
  
}








⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -