📄 main.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 + -