全国电子设计大赛三相电压逆变程序 芯片 dspic4011 dspic.docx
《全国电子设计大赛三相电压逆变程序 芯片 dspic4011 dspic.docx》由会员分享,可在线阅读,更多相关《全国电子设计大赛三相电压逆变程序 芯片 dspic4011 dspic.docx(37页珍藏版)》请在冰豆网上搜索。
全国电子设计大赛三相电压逆变程序芯片dspic4011dspic
#include//中断优先级还没设置,先t2,t1,spwm,其他
#defineLINE10b10000000//lcd显示的第一第二排
#defineLINE20b11000000
unsignedchargw,sw,bw,qw,ww;
#include"lcd.h"
//#definejidianqi_RD2
#define_T1ONT1CONbits.TON
#define_T2ONT2CONbits.TON
_FOSC(CSW_FSCM_OFF&XT_PLL8);
_FWDT(WDT_OFF);
_FBORPOR(RST_PWMPIN&PWMxH_ACT_HI&PWMxL_ACT_HI&PBOR_OFF&MCLR_EN);
_FGS(CODE_PROT_OFF);
unsignedcharDISP_N;
unsignedintLED_N;
unsignedintPWM_N=0,k=0,a=50000;//n=当前在的段的位置,k映射到0~99的查表位置,a变比后期主要控制这个
unsignedintAD_N,f;//f:
频率从内部检测得到频率,F_N手动输入的频率。
//ad_$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
//**************************************************
//新三相电流电压采样变量定义
//**************************************************
unsignedintUA1,UA2,UA3,UB1,UB2,UB3,UC1,UC2,UC3,UA_M_3,UA_M_T,UB_M_3,UB_M_T,UC_M_3,UC_M_T;
unsignedintIOA1,IOA2,IOA3,IOB1,IOB2,IOB3,IOC1,IOC2,IOC3,IOA_M_3,IOA_M_T,IOB_M_3,IOB_M_T,IOC_M_3,IOC_M_T;
unsignedintAD_UA,AD_UB,AD_UC,AD_IOA,AD_IOB,AD_IOC,AD_US;
unsignedintUS_1_4T;
unsignedcharsmo,SUM_1;
unsignedinttemp1;
unsignedcharoverload,qianya,quexiang,guoliu,buduichen;
unsignedcharERROR_N;
//**************************************************
//电压平滑度测试
//**************************************************
unsignedintsmooth_3_test_u(unsignedinta,unsignedintb,unsignedintc)
{
unsignedintd;
smo=0;
if(a-70
{
smo=1;
/*d=a;
if(d
if(dreturnd;*/
if(a
if(aif(breturnb;
}
return0;
}
//**************************************************
//MAX电压周期最大值采样结果MAX平滑度测试
//**************************************************
//算法说明:
a,b,cc点与a,b比较,与其中之一个平滑,则取c点,如果都不平滑,取b点。
unsignedintUA_M_T_0,UA_M_T_1,UA_M_T_TEMP;
voidsmooth_t_uo(unsignedinta,unsignedintb,unsignedintc)//smooth_t_uo(UA_M_T_0,UA_M_T_1,UA_M_T);
{
if((b-45//偏差值待定,加大误差,取中间值(周期采样偏差很小的哦,所以15合适了,因为偏差小的时候只有+-3)
//在调pi的时候可能偏差会比较大,这各值,不太合理吧。
或许还不够大吧,因为一个周期变化大。
再大点吧。
elseUA_M_T_TEMP=b;//给足够大的值,要不然虑掉正常的波,其他全部都没了。
if(UA_M_T_TEMP<10)UA_M_T_TEMP=b;
}
//**************************************************
//MAX电流周期最大值采样结果MAX平滑度测试
//**************************************************
unsignedintIOA_M_T_0,IOA_M_T_1,IOA_M_T_TEMP;
unsignedintIOB_M_T_0,IOB_M_T_1,IOB_M_T_TEMP;
unsignedintIOC_M_T_0,IOC_M_T_1,IOC_M_T_TEMP;
voidsmooth_t_io(unsignedinta,unsignedintb,unsignedintc,unsignedintflag)
{
unsignedintio_temp;
if((b-45elseio_temp=b;
if(flag==1)IOA_M_T_TEMP=io_temp;
if(flag==2)IOB_M_T_TEMP=io_temp;
if(flag==3)IOC_M_T_TEMP=io_temp;
if(io_temp<10)io_temp=c;
}
//**************************************************
//电流平滑度测试,因为参数不同,所以这里分开了为两个子函数
//**************************************************
unsignedintsmooth_3_test_i(unsignedinta,unsignedintb,unsignedintc)
{
unsignedintd;
smo=0;
if(a-75
{
smo=1;
d=a;
if(d
if(dreturnd;
}
return0;
}
//**************************************************
//mppt稳压wenya
//**************************************************
#defineU_GETUA_M_T
//这个宏定义定义了采样反馈的目的电压,UA_M_T,UB_M_T,UC_M_T之一//o相o线i相
//VREF为对应稳定时的采样值
unsignedlongpid1,pid2,pid3;
unsignedintuk0,uk1;
unsignedintKP=60,KI=7,VREF=418;//verf采样结果看着,待定。
voidWENYA(void)
{
uk0=uk1;
uk1=U_GET;
pid1=(unsignedlong)a+(unsignedlong)KP*uk0+(unsignedlong)KI*VREF;
pid2=(unsignedlong)uk1*(KP+KI);
if(pid1>pid2)
{
pid3=pid1-pid2;
if(pid3>65530)a=65530;
elsea=pid3;
}
elsea=0;
}
//**************************************************
//三相过流和不对称保护和缺相
//**************************************************
unsignedintIO_M_VALUE,IO_SMOOTH_MIN=125,IO_QUEXIANG_MAX=10;//三个数待测125
voidIO3_PROTECT(void)
{
//过流保护测试
if(IOA_M_T_TEMP>IO_M_VALUE||IOB_M_T_TEMP>IO_M_VALUE||IOC_M_T_TEMP>IO_M_VALUE)//加入过流的值
overload=1;
//显示过流的屏幕信号
elseoverload=0;
//不对称测试
if(0)
if(IOA_M_T_TEMP-IO_SMOOTH_MIN&&IOA_M_T_TEMP-IO_SMOOTH_MIN&&IOB_M_T_TEMP-IO_SMOOTH_MIN)buduichen=0;
elsebuduichen=1;
//缺相保护
if
(1)
if(IOA_M_Tquexiang=1;
elsequexiang=0;
}
//**************************************************
//欠压保护保护
//**************************************************
unsignedintUS_MIN=360;
voidUS_LOW_PROTECT(void)
{
if(US_1_4T<10)return;
if(US_1_4Telseqianya=0;
//if(qianya==1)jidianqi=1;//检测到欠压也不动作,要主控的,检测到多个错误时才动作
}
unsignedintjdt_0,jdt_1;//检测继电器下降沿用的当_LATRD2的值。
unsignedinttempad,IO10,IO20,IO30;
unsignedintIO1,IO2,IO3,IO_TEMP,IO11,IO22,IO33,IOAA,IOBB,IOCC;
unsignedintjs1;//计算一次
//**************************************************
//ADC中断
//**************************************************
void__attribute__((interrupt))_ADCInterrupt(void)
{
//采样7个结果
//AD_US=AD_US+ADCBUF0;
//AD_UA=ADCBUF1;
//AD_UB=ADCBUF2;
//AD_UC=ADCBUF3;
//tempad=ADCBUF4;
//AD_IOA=ADCBUF5;IO10=IO1;IO1=ADCBUF5;
//AD_IOB=ADCBUF6;IO20=IO2;IO2=ADCBUF6;
//AD_IOC=ADCBUF7;IO30=IO3;IO3=ADCBUF7;
AD_UA=ADCBUF0;
AD_IOA=ADCBUF1;
AD_IOB=ADCBUF2;
AD_IOC=ADCBUF3;
AD_US=AD_US+ADCBUF4;
/*
if(IO10-10if(IO20-20if(IO30-20if(AD_N==0)
{
IOAA=IO11;IO11=0;
IOBB=IO22;IO22=0;
IOCC=IO33;IO33=0;
IO1=0;IO2=0;IO3=0;IO10=0;IO20=0;IO30=0;
}
*/
//**************************************************
//电流搞起start
//**************************************************
if(PWM_N<=4&&js1==0)
{
js1=1;
SUM_1=0;
UA1=0;
UA2=0;
UA3=0;
UB1=0;
UB2=0;
UB3=0;
UC1=0;
UC2=0;
UC3=0;
UA_M_3=0;
UB_M_3=0;
UC_M_3=0;
UA_M_T_0=UA_M_T_1;UA_M_T_1=UA_M_T;
UA_M_T=0;
UB_M_T=0;
UC_M_T=0;
IOA1=0;
IOA2=0;
IOA3=0;
IOB1=0;
IOB2=0;
IOB3=0;
IOC1=0;
IOC2=0;
IOC3=0;
IOA_M_3=0;
IOB_M_3=0;
IOC_M_3=0;
IOA_M_T=0;
IOB_M_T=0;
IOC_M_T=0;
}
if(4{
js1=0;
//U传递
UA1=UA2;
UA2=UA3;
UA3=AD_UA;
UB1=UB2;
UB2=UB3;
UB3=AD_UB;
UC1=UC2;
UC2=UC3;
UC3=AD_UC;
//I传递
IOA1=IOA2;
IOA2=IOA3;
IOA3=AD_IOA;
IOB1=IOB2;
IOB2=IOB3;
IOB3=AD_IOB;
IOC1=IOC2;
IOC2=IOC3;
IOC3=AD_IOC;
//调用函数取值电压3点最大
temp1=smooth_3_test_u(UA1,UA2,UA3);
if(smo==1)
{
UA_M_3=temp1;
if(UA_M_T}
temp1=smooth_3_test_u(UB1,UB2,UB3);
if(smo==1)
{
UB_M_3=temp1;
if(UB_M_T}
temp1=smooth_3_test_u(UC1,UC2,UC3);
if(smo==1)
{
UC_M_3=temp1;
if(UC_M_T}
//调用函数取值电流3点最大
temp1=smooth_3_test_i(IOA1,IOA2,IOA3);
if(smo==1)
{
IOA_M_3=temp1;
if(IOA_M_T}
temp1=smooth_3_test_i(IOB1,IOB2,IOB3);
if(smo==1)
{
IOB_M_3=temp1;
if(IOB_M_T}
temp1=smooth_3_test_i(IOC1,IOC2,IOC3);
if(smo==1)
{
IOC_M_3=temp1;
if(IOC_M_T}
}
if(395<=PWM_N&&SUM_1==0)//SUM_1,此次执行与否位,0表示没有执行,1执行了,检测执行与否后,来执行
{
SUM_1=1;
//if(_LATD2==0)//如果继电器关闭,则关闭输出值的处理
//{//继电器关了也进行检测,结果都是关闭,没关系,当故障排除后,
WENYA();
//a=50000;
smooth_t_uo(UA_M_T_0,UA_M_T_1,UA_M_T);//周期结果滤波,不滤去结果,关键是在现实的pi用滤过后的值,
//这个效果不好,给显示用了
//a=60000;//这个调试用的
smooth_t_io(IOA_M_T_0,IOA_M_T_1,IOA_M_T,1);
smooth_t_io(IOB_M_T_0,IOB_M_T_1,IOB_M_T,2);
smooth_t_io(IOC_M_T_0,IOC_M_T_1,IOC_M_T,3);
IO3_PROTECT();
//}
}
//**************************************************
//电流搞起end
//**************************************************
//**************************************************
//直流的电压用AD_N搞定,50次平均一次start
//**************************************************
AD_N++;
if(AD_N==50)
{
AD_N=0;
US_1_4T=AD_US/50;
AD_US=0;
US_LOW_PROTECT();
}
//**************************************************
//直流的电压用AD_N搞定,50次平均一次end
//**************************************************
//继电器动作
if(overload==1||buduichen==1||quexiang==1||qianya==1)//欠压四分之一周期就可以动作一次,所以这个50次还是比较合理的,欠压快点,因为也比较准,其他比较容易被干扰,所以长点时间动作合理,
{
ERROR_N++;
if(ERROR_N>1000)
{
jdt_0=_LATD2;
_RD2=1;
jdt_1=_LATD2;
if(jdt_0==1&&jdt_1==0)DISP_N=1;
ERROR_N=0;
}
//*只有当连续出现多次,10次(待定)错误时才动作
//*错可能一周出现多个,所以用>10,继电器关闭后N=0,这样继电器on上时N=0,才能正常工作
//*关闭的触发条件是什么,这在恢复保护时,处理好它,保护能否恢复它是关键
//继电器下降沿时DISP_N=1,其他时候当然不干
}
elseERROR_N=0;
_ADIF=0;
}
//******************************************************************
//ADC初始化,四通道,同时采样,顺序转换,触发信号,由T1给,其他自动工作
//********************************************************************
voidAD_INI(void)
{
_TRISB0=1;//ua
_TRISB1=1;//ub
_TRISB2=1;//uc
_TRISB3=1;//ioa
_TRISB4=1;//ioB
_TRISB5=1;//iOC
_TRISB6=1;//US
//adcon1
_ADON=0;
_ADSIDL=0;
_FORM=0;
_SSRC=0B111;//自动采样,结束采样位,开始转换
_SIMSAM=0;
_ASAM=0;//自动采样
_SAMP=0;//开始采样
/