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

📄 main.c

📁 实验室做的SVC无功补偿项目
💻 C
字号:

#include "DSP28_Device.h"
#include "fft.h"
#include "math.h"

#define N   128
#pragma DATA_SECTION(ipcb, "FFTipcb");  //difine fft section
#pragma DATA_SECTION(mag, "FFTmag");
CFFT32  fft=CFFT32_128P_DEFAULTS; 
long ipcb[2*N];
long mag[N];
//define date section
Uint16 m=0,n=0,trigflag=0;
 
int i=0,k=0,zhy=0,countad=0,nzh=0,bb=0,nzh3,nzh4,bb3,bb4; //counad用于调程序时检查
int temp2,temp3,temp4;//中间变量
double P=0,Q=0,pf=0,pf1=0,f=50,q=0,Qtemp1=0,S=0,Qtemp2=0;
double t=0,trigarf=180,oldtrig=0,newtrig=0,trigarf1=180;
double Va[128],Ia[128],va=0,ia=0,Vac[128],Iac[128];//从左到右,分别为电压数组,电流数组,电压电流有效值
double arf=0,temp=0,detQ=0,arfva=0,arfia=0;//从左到右,分别为功率角,临时单元,电压相角,电流相角
const double tcrq[46]={-5745.4934,-5490.2419,-5235.6118,-4982.2218,-4730.6843,\
-4481.6026,-4235.5684,-3993.1582,-3754.9309,-3521.4252,-3293.1567,-3070.6154,\
-2854.2634,-2644.5328,-2441.8234,-2246.5007,-2058.8942,-1879.296,-1707.9589,\
-1545.0957,-1390.8777,-1245.4344,-1108.8523,-981.1746,-862.4015,-752.4896,\
-651.3522,-558.8602,-474.842,-399.085,-331.3362,-271.3037,-218.6578,-173.0331,\
-134.0298,-101.2159,-74.1292,-52.2796,-35.1516,-22.2066,-12.8855,-6.6119,-2.7941,\
-0.8289,0.1037, 0 };//根据电抗器计算出来的数组
const double Qd=0,qd=0;//qd的值需根据负载变化计算确定,表示是否需要补偿的尺度;Qd表示连续两次计算的无功差值,决定是否需要重新计算触发角;
double zero_kCAP3,zero_kCAP4,zero_kCAP6;
double yy=0;
double arfcount=0,quotient=0;
void counttrig()//角度计算
{
   pf1=0.8;//用户指定的功率因数
   detQ=0;//实验时设定值
   detQ=Q/3.0;//需要补偿的无功量
   for(i=0;i<=46;i++)  //传输数据
   {
   if (detQ>tcrq[i])
   {
   temp=tcrq[i];
   t=i;
   }
   else
   {
   temp=tcrq[i-1];
   t=i-1;
   break;
   }
   }
   trigarf=(90+2*t);//计算arf角度
   
   trigflag=1;
}


void FFT(double b[])    //调用库函数进行fft计算
{
  fft.ipcbptr=ipcb;
  fft.magptr=mag;  
  fft.init(&fft);  
  for(i=0;i<128;i++)
    {
  ipcb[i]=(long)(b[i])<<12;//左移12位达到fft库函数的要求
    }
  CFFT32_brev1(ipcb,ipcb,N);//数据翻转
  fft.izero(&fft); 
  fft.calc(&fft);
  fft.mag(&fft); //计算幅值
  
}
                
double countyouxiaozhi(double a[])  //计算有效值
{
    temp=0;
    for(i=0;i<128;i++)
    {
    temp=a[i]*a[i]+temp;
    }
    temp=temp/128;
    temp=sqrt(temp);
    return temp;
    }

interrupt void ad(void);
interrupt void CAPINT3(void);//对三路过零信号捕获中断
interrupt void CAPINT5(void);
interrupt void CAPINT6(void);
interrupt void T2CCINT(void);//对应触发角计数中断
interrupt void T3CCINT(void);
interrupt void T4CCINT(void);


void main(void)
{
   /*初始化系统*/
	InitSysCtrl();
   /*关中断*/
	DINT;
	IER = 0x0000;
	IFR = 0x0000;
    /*初始化PIE控制寄存器*/
	InitPieCtrl();

    /*初始化PIE矢量表*/
	InitPieVectTable();	
	
	EvaRegs.EVAIFRC.bit.CAP3INT=1;//CAP3INT中断标志位置位
    EvaRegs.EVAIMRC.bit.CAP3INT=1;//CAP3INT中断屏蔽位使能
    EvbRegs.EVBIFRC.bit.CAP5INT=1;//CAP5INT中断标志位置位
    EvbRegs.EVBIMRC.bit.CAP5INT=1;//CAP5INT中断屏蔽位使能
    EvbRegs.EVBIFRC.bit.CAP6INT=1;//CAP6INT中断标志位置位
    EvbRegs.EVBIMRC.bit.CAP6INT=1;//CAP6INT中断屏蔽位使能
    EvaRegs.EVAIFRB.bit.T2CINT= 1;//T2CINT中断标志位置位
    EvaRegs.EVAIMRB.bit.T2CINT= 1;//T2CINT中断屏蔽位使能
    EvbRegs.EVBIFRA.bit.T3CINT= 1;//T3CINT中断标志位置位
    EvbRegs.EVBIMRA.bit.T3CINT= 1;//T3CINT中断屏蔽位使能
    EvbRegs.EVBIFRB.bit.T4CINT= 1;//T4CINT中断标志位置位
    EvbRegs.EVBIMRB.bit.T4CINT= 1;//T4CINT中断屏蔽位使能
    
    
    PieCtrl.PIEIER3.bit.INTx2=1;//T2CINT中断使能位使能,对应中断组3的第2位
    PieCtrl.PIEIER3.bit.INTx7=1;//CAP3INT中断使能位使能,对应中断组3的第7位
    PieCtrl.PIEIER4.bit.INTx5=1;//T3CINT中断使能位使能,对应中断组4的第5位
    PieCtrl.PIEIER5.bit.INTx2=1;//T3CINT中断使能位使能,对应中断组5的第2位
    PieCtrl.PIEIER5.bit.INTx6=1;//CAP5INT中断使能位使能,对应中断组5的第6位
    PieCtrl.PIEIER5.bit.INTx7=1;//CAP6INT中断使能位使能,对应中断组5的第7位
    
	EALLOW;	// This is needed to write to EALLOW protected registers
    PieVectTable.ADCINT=&ad;//各个中断入口,下面类同
	PieVectTable.CAPINT6=&CAPINT6;
    PieVectTable.CAPINT3=&CAPINT3;
    PieVectTable.CAPINT5=&CAPINT5;
    PieVectTable.T2CINT  = &T2CCINT;
    PieVectTable.T3CINT  = &T3CCINT;
    PieVectTable.T4CINT  = &T4CCINT;
    
	EDIS;   // This is needed to disable write to EALLOW protected registers
	 
    InitGpio();//初始化
    InitEv();
    InitAdc();
     EvaRegs.COMCONA.bit.FCOMPOE=1;//使能PWM1-6
     
    //PieCtrl.PIEIER3.bit.INTx7=0;
    IER|=(M_INT3|M_INT4|M_INT5);
    IER|=M_INT1; //cpu级中断允许
	//KickDog();
    // Enable global Interrupts and higher priority real-time debug events:
	
	EINT;   // Enable Global interrupt INTM
	ERTM;	// Enable Global realtime interrupt DBGM
 	
	while(AdcRegs.ADC_ST_FLAG.bit.SEQ1_BSY==0)
		{			

			AdcRegs.ADCTRL2.bit.SOC_SEQ1=1;//软件触发ad转换

		}
		
   for(;;)
     
    {  

   for(n=0;n<=200;n++)
    {
    for(m=0;m<=30000;m++)//延时
      {}
      }   
   if (countad>=128)
    {
    countad=0;
    for(i=0;i<=127;i++)
    {
    Vac[i]=Va[i];
    Iac[i]=Ia[i];//将采样值转存以便计算
    }
    va=countyouxiaozhi(Vac);//计算电压电流有效值
    ia=countyouxiaozhi(Iac);
    P=0;
    for(i=0;i<128;i++)
    {
    P=Vac[i]*Iac[i]+P;//计算有功无功等
    }
    P=P/128;
    S=va*ia;
    
    pf=cos(arf*3.1415926/180.0);//计算功率因数
    Q=1.76*P;
    FFT(Vac);//电压fft变换
   arfva=atan2(ipcb[2],ipcb[3])*180/3.1415926+90;//电压相角
   if(arfva<0)
   arfva=360+arfva;
   FFT(Iac);          
   arfia=atan2(ipcb[2],ipcb[3])*180/3.1415926;//电流相角
   if(arfia<0)
   arfia=360+arfia;
   arf=arfia-arfva;//功率角
   if(arf<-180)
   arf=arf+360;
   if(arf>180)
   arf=arf-360;
   if(arf>0)
  { Q=Q;
   pf=pf;
   }
   else
   {Q=0-Q;
   pf=0-pf;
   }
      }
      
      
   //if(abs(Q-Qtemp1)>3000)
   //{trigflag=0;
   //Qtemp1=Q;}
   if(trigflag==0)
   {
   counttrig();
   trigarf1=trigarf+55;//加55度表示抵消带铁心电抗器铁心的影响
   }
     if(pf<0)  
     {
     if(abs(pf)<=0.94)
     {trigarf1-=2;}
     if(0.94<abs(pf)<=1)
     {trigarf1-=0.5;}
     }//当功率因数低于0.94时进行大范围调整
     
     
     if(pf>=0.98)
     {trigarf1+=0.5;}
     else
     {if(pf>0)
     {if(abs(Q)>1500)
     {trigarf1+=0.5;}}}//当功率因数在0.94和0.98之间时进行小范围调整,避免振荡
     
    if(trigarf1<=90)
    {trigarf1=180;}
    yy=4687/180.0*trigarf1;    //计算出来的arf角度跟踪调整
    arfcount=(long)yy;
          
     {PieCtrl.PIEIER3.bit.INTx7=1;  //after counting,begin the ad again
	AdcRegs.ADCTRL2.bit.RST_SEQ1=1;
	AdcRegs.ADC_ST_FLAG.bit.INT_SEQ1_CLR=1;
	while(AdcRegs.ADC_ST_FLAG.bit.SEQ1_BSY==0)
		{			

			AdcRegs.ADCTRL2.bit.SOC_SEQ1=1;

		}
		}
       
    
     
}
}

interrupt void CAPINT3(void)
{
   nzh+=1;
   EvaRegs.T2CON.bit.TENABLE=1;//使用定时器操作
    EvaRegs.T2CNT=0;
    EvaRegs.T2CMPR = arfcount;//arfcount对应触发角
    
  
    EvaRegs.CAPFIFOA.bit.CAP3FIFO=1;//为下次捕获准备,详见书本介绍
    EvaRegs.EVAIFRC.bit.CAP3INT=1;
    PieCtrl.PIEACK.all=0x0004;//对应中断组相响应
    EINT;                       //开全局中断
    return;
}

interrupt void T2CCINT(void)
{  
   temp2=EvaRegs.T2CNT;//temp2是中间变量
   bb+=2;//无意义,主要是检测是否进中断
   
   EINT;
   
   if(GpioDataRegs.GPADAT.bit.GPIOA7==0)//通过GPIOA7判断信号是高或低电平,对应电源电压的正负半波
    {
     
     GpioDataRegs.GPADAT.bit.GPIOA0= 0;//PWM1输出低
     while(EvaRegs.T2CNT<temp2+5);
     GpioDataRegs.GPADAT.bit.GPIOA0= 1;//PWM1输出高
    }
   else
    {
     GpioDataRegs.GPADAT.bit.GPIOA1= 0;//PWM2输出低
     while(EvaRegs.T2CNT<temp2+5);
     GpioDataRegs.GPADAT.bit.GPIOA1= 1;//PWM2输出高
     
    }
    EvaRegs.T2CON.bit.TENABLE=0;//为下次中断作准备,详见书本介绍
    //EvaRegs.T1CMPR=0xFFFF;
    EvaRegs.EVAIMRB.bit.T2CINT=1;
    EvaRegs.EVAIFRB.bit.T2CINT=1;
    PieCtrl.PIEACK.all=0x0004;//对应中断组相响应
    
    EINT; 
    return;
     
}


interrupt void CAPINT5(void)
{
   nzh3+=1;
   EvbRegs.T3CON.bit.TENABLE=1;//使用定时器操作
    EvbRegs.T3CNT=0;
    EvbRegs.T3CMPR = arfcount;//arfcount对应触发角
    
  
    EvbRegs.CAPFIFOB.bit.CAP5FIFO=1;//为下次捕获准备,详见书本介绍
    EvbRegs.EVBIFRC.bit.CAP5INT=1;
    PieCtrl.PIEACK.all=0x0010;
    EINT;                       //开全局中断
    return;
    
    
}

interrupt void T3CCINT(void)
{  
   temp3=EvbRegs.T3CNT;
   bb3+=1;
  
   if(GpioDataRegs.GPADAT.bit.GPIOA6==0)//通过GPIOA6判断信号是高或低电平,对应电源电压的正负半波
    {
     
     GpioDataRegs.GPADAT.bit.GPIOA2= 0;//PWM3输出低
     while(EvbRegs.T3CNT<temp3+5);
     GpioDataRegs.GPADAT.bit.GPIOA2= 1;//PWM3输出高
    }
   else
    {
     GpioDataRegs.GPADAT.bit.GPIOA3= 0;//PWM4输出低
     while(EvbRegs.T3CNT<temp3+5);
     GpioDataRegs.GPADAT.bit.GPIOA3= 1;//PWM4输出高
     
    }
    EvbRegs.T3CON.bit.TENABLE=0;//为下次中断作准备,详见书本介绍
    //EvaRegs.T1CMPR=0xFFFF;
    EvbRegs.EVBIMRA.bit.T3CINT=1;
    EvbRegs.EVBIFRA.bit.T3CINT=1;
    PieCtrl.PIEACK.all=0x0008;
    
    EINT; 
    return;
     
}


interrupt void CAPINT6(void)
{
    nzh4+=1;
    EvbRegs.T4CON.bit.TENABLE=1;//使用定时器操作
    EvbRegs.T4CNT=0;
    EvbRegs.T4CMPR = arfcount;
    
  
    EvbRegs.CAPFIFOB.bit.CAP6FIFO=1;
    EvbRegs.EVBIFRC.bit.CAP6INT=1;
    PieCtrl.PIEACK.all=0x0010;
    EINT;                       //开全局中断
    return;
}

interrupt void T4CCINT(void)
{  
   temp4=EvbRegs.T4CNT;
   bb4+=1;
   
   
   if(GpioDataRegs.GPBDAT.bit.GPIOB6==0)//通过GPIOB6判断信号是高或低电平,对应电源电压的正负半波
    {
     
     GpioDataRegs.GPADAT.bit.GPIOA4= 0;//PWM5输出低
     while(EvbRegs.T4CNT<temp4+5);
     GpioDataRegs.GPADAT.bit.GPIOA4= 1;//PWM5输出高
    }
   else
    {
     GpioDataRegs.GPADAT.bit.GPIOA5= 0;//PWM6输出低
     while(EvbRegs.T4CNT<temp4+5);
     GpioDataRegs.GPADAT.bit.GPIOA5= 1;//PWM6输出高
     
    }
    EvbRegs.T4CON.bit.TENABLE=0;//为下次中断作准备,详见书本介绍
    //EvaRegs.T1CMPR=0xFFFF;
    EvbRegs.EVBIMRB.bit.T4CINT=1;
    EvbRegs.EVBIFRB.bit.T4CINT=1;
    PieCtrl.PIEACK.all=0x0010;
    
    EINT; 
    return;
     
}

interrupt void ad(void)//ad转换子程序,采用同时采样三相电压电流,抵消时间差的影响
{
	//ad采样子程序
    EINT;

	IFR=0x0000;
//	PieCtrl.PIEIFR1.all = 0;
	PieCtrl.PIEACK.all=5;
	
	countad++;
	
		
	//Va[k]=(AdcRegs.RESULT1>>4)*3.0/4095-1.5;
	//Ia[k]=(AdcRegs.RESULT0>>4)*3.0/4095-1.5;
	Va[k]=(AdcRegs.RESULT1>>4)*3.0*420.315/4095.00-628.3068;
	Ia[k]=(AdcRegs.RESULT0>>4)*3.0*23.4588/4095.00-34.4503;
	
	//Ia[k]=(AdcRegs.RESULT1>>4);
	k++;
	
	
	if(k<128)
	{
	AdcRegs.ADCTRL2.bit.RST_SEQ1=1;
	AdcRegs.ADC_ST_FLAG.bit.INT_SEQ1_CLR=1;
	AdcRegs.ADCTRL2.bit.SOC_SEQ1=1;
	}
	else
	{
	k=0;
	//PieCtrl.PIEIER3.bit.INTx7=1;
	//AdcRegs.ADCTRL2.bit.RST_SEQ1=1;
	//AdcRegs.ADC_ST_FLAG.bit.INT_SEQ1_CLR=1;
	//AdcRegs.ADCTRL2.bit.SOC_SEQ1=0;
	}
	
	
	
		
	
}

⌨️ 快捷键说明

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