📄 motor.c
字号:
//============================================================================
// 反时限表
//============================================================================
//过流保护反时限表
const unsigned int IDT_Table_OC[3][50]={
0, 0, 0, 0, 0, 10, 18, 27, 37, 47, //0.2~2.0
59, 72, 86, 101, 117, 135, 153, 172, 193, 215, //2.2~4.0
238, 262, 287, 313, 340, 369, 398, 429, 461, 494, //4.2~6.0
528, 563, 599, 636, 675, 714, 755, 797, 840, 884, //6.2~8.0
929, 975,1023,1071,1121,1171,1223,1276,1330,1385, //8.2~10.0
0, 0, 0, 0, 0, 10, 18, 27, 37, 47, //0.2~2.0
59, 72, 86, 101, 117, 135, 153, 172, 193, 215, //2.2~4.0
238, 262, 287, 313, 340, 369, 398, 429, 461, 494, //4.2~6.0
528, 563, 599, 636, 675, 714, 755, 797, 840, 884, //6.2~8.0
929, 975,1023,1071,1121,1171,1223,1276,1330,1385, //8.2~10.0
0, 0, 0, 0, 0, 10, 18, 27, 37, 47, //0.2~2.0
59, 72, 86, 101, 117, 135, 153, 172, 193, 215, //2.2~4.0
238, 262, 287, 313, 340, 369, 398, 429, 461, 494, //4.2~6.0
528, 563, 599, 636, 675, 714, 755, 797, 840, 884, //6.2~8.0
929, 975,1023,1071,1121,1171,1223,1276,1330,1385}; //8.2~10.0
//过流保护反时限表
const unsigned int IDT_Table_UB[50]={
10, 28, 52, 80, 112, 133, 154, 175, 196, 217,
238, 259, 280, 300, 321, 341, 362, 382, 403, 423,
443, 463, 484, 504, 524, 544, 564, 584, 604, 624,
644, 664, 684, 704, 724, 744, 763, 783, 803, 823,
842, 862, 882, 902, 921, 941, 960, 980,1000,1019};
//============================================================================
// 反时限保护子程序
//============================================================================
unsigned char protect_idt(unsigned int TestValue,struct PRT_UNIT *p1,
struct PRT_CNST *p2,unsigned char type)
//保护单元结构:越限 p1->OverLmt
// 瞬时越限 p1->OverLmtInst
// 动作延迟计数 p1->ActDT
// 复位延迟计数 p1->RstDT
//保护参数结构:整定值 p2->ActLvl
// 返回值 p2->RstLvl
// 复位延迟时间 p2->RstTim
// 动作延迟时间 p2->ActTim
//type: 0-过流;1-不平衡
{ unsigned int temp;
if(type==0)
temp=(TestValue/RateCrt-2)>>1;
else
temp=TestValue/RateCrt-1;
if(temp>49) temp=49;
if(TestValue>p2->ActLvl){
p1->OverLmtInst=1; //大于动作定值
if(type==1)
p1->ActDT+=IDT_Table_UB[temp];
if(type==0)
p1->ActDT+=IDT_Table_OC[1][temp];
if(p1->ActDT>=p2->ActTim*100) p1->OverLmt=1;
p1->RstDT=0;
}
if(TestValue<p2->RstLvl){
p1->OverLmtInst=0; //小于返回定值
(p1->RstDT)++;
if(p1->RstDT>=p2->RstTim){
p1->ActDT=0; p1->OverLmt=0;
}
else{
if(p1->OverLmtInst==0){
if(type==1)
p1->ActDT+=IDT_Table_UB[temp];
if(type==0)
p1->ActDT+=IDT_Table_OC[1][temp];
if(p1->ActDT>=p2->ActTim*100){
p1->OverLmt=1;
p1->RstDT=0;
}
}
else{
(p1->RstDT)++;
if(p1->RstDT >= p2->RstTim){
p1->ActDT=0;p1->OverLmtInst=0;
}
}
}
}
return p1->OverLmt;
}
//============================================================================
// 读EE子程序
//============================================================================
unsigned char eeread(unsigned int eeaddr)
{ unsigned char data;
while(EECR&1<<EEWE);
EEARL=eeaddr;
EEARH=eeaddr>>8;
if(SREG&0x80){
CLI();
EECR|=1<<EERE;
data=EEDR;
SEI();
}
else{
EECR|=1<<EERE;
data=EEDR;
}
return data;
}
//============================================================================
// 写EE子程序
//============================================================================
void eewrite(unsigned int eeaddr,unsigned char eedata)
{ while(EECR&1<<EEWE);
EEARL=eeaddr;
EEARH=eeaddr>>8;
EEDR=eedata;
if(SREG&0x80){
CLI();
EECR|=1<<EEMWE;
EECR|=1<<EEWE;
SEI();
}
else{
EECR|=1<<EEMWE;
EECR|=1<<EEWE;
}
}
//============================================================================
// 保护处理子程序(每10ms)
//============================================================================
void _10ms_process(void)
{unsigned int max,min;
unsigned char i,j;
_10msCnt++;
SEI();
//模拟输入(200us)
#ifdef DEBUG
for(i=0;i<ADBufLen;i++){
j=i;
if(j>=16) j-=16;
ADBuf[0][i]=debug_data0[j];
ADBuf[1][i]=debug_data1[j];
ADBuf[2][i]=debug_data2[j];
ADBuf[3][i]=debug_data3[j];
ADBuf[4][i]=debug_data4[j];
ADBuf[5][i]=debug_data5[j];
}
ADBufCnt=0;
#endif
ADBufCntHold=ADBufCnt;
//数字傅氏变换(1400us)
for(i=0;i<8;i++){
dft(i);
}
//有效值计算(2200us)
for(i=0;i<8;i++){
IU[i]=sqrt_32(((unsigned long)ab[i][0]*ab[i][0]+(unsigned long)ab[i][1]*ab[i][1])>>1);
IU[i]=(unsigned long)IU[i]*1852/1000;
if(i<3)
IU[i]=(unsigned long)IU[i]*adc_rate;
else if(i<6)
IU[i]=(unsigned long)IU[i]*10*adc_rate; //满量程为1000.0A
}
//量程切换
if((IU[3]>1000)||(IU[4]>1000)||(IU[5]>1000)){
I1=IU[3];
I2=IU[4];
I3=IU[5];
}
else{
I1=IU[0];
I2=IU[1];
I3=IU[2];
}
//不平衡电流
min=I1;max=I1;
if(I2<min) min=I2;
if(I3<min) min=I3;
if(I2>max) max=I2;
if(I3>max) max=I3;
I0=max-min;
//电流检测
I=(I1+I2+I3)/3;
if(I>RateCrt*4){ //>0.4x额定电流
PowOffCnt=0;
if(PowOnCnt++>100){ //持续1s
COMF|=comf_pw_on;
PowOnCnt=100;
}
}
if(I<RateCrt){ //<0.1x额定电流
PowOffCnt++;
PowOnCnt=0;
if(PowOffCnt>1000){ //持续10s
COMF&=~comf_pw_on;
PowOffCnt=1000;
}
}
//电容器投入
if(COMF&comf_pw_on){
if(CapDlyCnt++>CapDlyTime){ //通电延迟后接通电容器
CapDlyCnt=CapDlyTime;
PORTB|=bRL1;
}
}
//过流保护
if (protect_idt(I1,&UnitOC[0],&CnstOC,0)) //A相过流
PRS|=prs_oc1;
else
PRS&=~prs_oc1;
if (protect_idt(I2,&UnitOC[1],&CnstOC,0)) //B相过流
PRS|=prs_oc2;
else
PRS&=~prs_oc2;
if (protect_idt(I3,&UnitOC[2],&CnstOC,0)) //C相过流
PRS|=prs_oc3;
else
PRS&=~prs_oc3;
//电流不平衡保护
if (protect_idt(I0,&UnitUB,&CnstUB,1)) //不平衡
PRS|=prs_ub;
else
PRS&=~prs_ub;
//跳闸处理
if(PRS&(prs_oc1|prs_oc2|prs_oc3|prs_ub)){
PORTB|=bRL2;
TripDlyCnt=0;
PRSH|=PRS;
}
if(PORTB&bRL2){
if(TripDlyCnt++>200) //吸合时间2s
PORTB&=~bRL2;
}
//电流(电压)平均
Iacc+=I;
Uacc+=U;
if(AveCnt++>=49){
Iave=(Iacc+25)/50;
Uave=(Uacc+25)/50;
Iacc=0;
Uacc=0;
AveCnt=0;
}
//按键扫描
if(!(PINB&bS1)){
if(S1DownCnt++>5)
COMF|=comf_s1down;
S1UpCnt=0;
}
else{
if(S1UpCnt++>5)
COMF&=~comf_s1down;
S1DownCnt=0;
}
if(!(PINB&bS2)){
if(S2DownCnt++>5)
COMF|=comf_s2down;
S2UpCnt=0;
}
else{
if(S2UpCnt++>5)
COMF&=~comf_s2down;
S2DownCnt=0;
}
//字符定义 afbedhcg
#define _1 0b11011101
#define _2 0b01000110
#define _3 0b01010100
#define _b 0b10100000
#define _C 0b00100011
#define _E 0b00100110
#define _O 0b00000001
#define _P 0b00001110
#define _r 0b11101110
#define _U 0b10000001
#define _V 0b10000101
#define _c 0b11100110
#define __ 0b11110111
#define _o 0b11100100
#define _n 0b11101100
if(DspBlinkCnt++>99) DspBlinkCnt=0;
//s1按下,显示保护定值
if(COMF&comf_s1down){
LED[3]=_P;//PrXX
LED[2]=_r;
if(DspBlinkCnt<50){
LED[1]=LEDChar[crt_rv[PRV]/10];
LED[0]=LEDChar[crt_rv[PRV]%10];
}
else{
if(eeread(EERate)!=PRV){
LED[1]=0xff;
LED[0]=0xff;
}
else{
LED[1]=LEDChar[crt_rv[PRV]/10];
LED[0]=LEDChar[crt_rv[PRV]%10];
}
}
if((COMF&comf_s2down)&&(!(COMFP&comf_s2down))){
PRV++;
if(PRV>5) PRV=0;
}
}
//S1不按下
//新定值写入EE
else if(!(COMF&comf_s1down)&&(COMFP&comf_s1down)){
if(eeread(EERate)!=PRV){
COMF|=comf_eewrt;
}
}
else{
if(DspBlinkCnt<50){
INT2SEC(Iave); //XXXX
if(CapDlyCnt<CapDlyTime){
LED[0]&=LEDChar[16];
}
}
else{
LED[3]=0xff;
LED[2]=0xff;
LED[1]=0xff;
LED[0]=0xff;
i=0;
if(PRSH&(prs_oc1|prs_oc2|prs_oc3)){
LED[1]=_O;
LED[0]=_C;
i=1;
}
if(PRSH&prs_ub){
LED[3]=_U;
LED[2]=_b;
i=2;
}
if(COMF&comf_err_ee){
LED[3]=_E;//Err2
LED[2]=_r;
LED[1]=_r;
LED[0]=_2;
i=3;
}
if(COMF&comf_err){
LED[3]=_E;//Err1
LED[2]=_r;
LED[1]=_r;
LED[0]=_1;
i=4;
}
if(COMF&comf_err_cal){
LED[3]=_E;//Err3
LED[2]=_r;
LED[1]=_r;
LED[0]=_3;
i=5;
}
if(i==0)
INT2SEC(Iave); //XXXX
}
//清除故障显示
if(S2ClikDly!=0)
S2ClikDly--;
if(COMF&comf_s2down){
if(!(COMFP&comf_s2down)){
S2ClikCnt++;
S2ClikDly=50;
}
if(S2ClikDly<=10){
if(S2ClikCnt==1){
INT2SEC(Uave); //显示电压
}
if(S2ClikCnt==2){
INT2SEC(PRSH); //显示保护状态
}
if(S2ClikCnt==3){
INT2SEC(PRSH); //清除保护状态
PRSH=0;
}
if(S2ClikCnt==6){
COMF|=comf_cal; //校准
S2ClikCnt=0;
}
}
}
else if(S2ClikDly==0)
S2ClikCnt=0;
}
COMFP=COMF;
WDF|=wdf_t2; //置看门狗标志
PowOnDlyCnt++;
#ifdef DEBUG_P
if(DspBlinkCnt==0){
if(DspCnt++>15) DspCnt=0;
}
PORTB|=bRL1|bRL2;
LED[3]=LEDChar[DspCnt];
LED[2]=LEDChar[DspCnt];
LED[1]=LEDChar[DspCnt];
LED[0]=LEDChar[DspCnt];
#endif
}
//============================================================================
// 读校准值子程序
//============================================================================
void read_cal()
{
unsigned char i;
COMF&=~comf_err_cal;
for(i=0;i<7;i++){
CalValue[i]=eeread(EECal+i*2);
CalValue[i]+=(eeread(EECal+i*2+1)<<8);
if((CalValue[i]>0x9000)||(CalValue[i]<0x7000)||(CalValue[i]==0x8000)){
CalValue[i]=0x8000;
COMF|=comf_err_cal;
}
}
}
//============================================================================
// 读保护定值子程序
//============================================================================
void read_rate()
{
//读保护定值
COMF&=~comf_err;
PRV=eeread(EERate);
if(PRV>5){
PRV=5;
COMF|=comf_err;
}
RateCrt=crt_rv[PRV];
CnstOC.ActLvl=(unsigned long)RateCrt*overcrt_rv; //过流动作整定值
CnstOC.RstLvl=(unsigned long)RateCrt*overcrt_rtn;//过流动作返回值
CnstOC.RstTim=overcrt_rst_t; //过流复位延迟时间
CnstOC.ActTim=overcrt_dly_t; //过流动作延迟时间
CnstUB.ActLvl=(unsigned long)RateCrt*unblnc_rv; //不平衡动作整定值
CnstUB.RstLvl=(unsigned long)RateCrt*unblnc_rtn; //不平衡动作返回值
CnstUB.RstTim=unblnc_rst_t; //不平衡复位延迟时间
CnstUB.ActTim=unblnc_dly_t; //不平衡动作延迟时间
}
//============================================================================
// 主程序
//============================================================================
void main(void)
{
int i;
//初始化
CLI();
port_init();
watchdog_init();
timer0_init();
timer2_init();
adc_init();
MCUCR = 0x00;
// GICR = 0x00;
TIMSK = 0x81;
COMF=0;
COMFP=0;
//读入校准值
read_cal();
read_rate();
SEI();
while(PowOnDlyCnt<20);
PRS=0;
PRSH=0;
Iacc=0;
//主程序循环
do{
if((WDF&wdf_ad)&&(WDF&wdf_t2)&&(WDF&wdf_main)){
WDR();
WDF&=~(wdf_ad|wdf_t2|wdf_main);
}
if(COMF&comf_eewrt){
COMF&=~comf_err_ee;
eewrite(EERate,PRV);
if(eeread(EERate)!=PRV){
eewrite(EERate,PRV);
if(eeread(EERate)!=PRV){
COMF|=comf_err_ee;
}
else
read_rate();
}
else
read_rate();
COMF&=~comf_eewrt;
}
if((COMF&comf_cal)&&(S2ClikDly==0)){
if((U>=CALUMin)&&(U<=CALUMax))
CalValue[0]=(long)0x8000*CALU/U;
for(i=0;i<3;i++){
if((IU[i]>=CALiMin)&&(IU[i]<=CALiMax))
CalValue[i+1]=(long)0x8000*CALi/IU[i];
}
for(i=3;i<6;i++){
if((IU[i]>=CALIMin)&&(IU[i]<=CALIMax))
CalValue[i+1]=(long)0x8000*CALI/IU[i];
}
for(i=0;i<7;i++){
eewrite(EECal+i*2,CalValue[i]);
eewrite(EECal+i*2+1,CalValue[i]>>8);
}
while(1);
}
WDF|=wdf_main;
}while(1);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -