📄 control.c
字号:
/*
*/
#include <absacc.h>
#include <stdlib.h>
#include <AT89X52.H>
#include <INTRINS.h>
#include "charger.h"
/*
//init_system_work_point
*/
#define BENCHMARK 4.5
#define AMPLIFICATORY 10//predefine 0.1 proccess, amplificatory 10
#define ADMAX 4096
#define system_volatage sys[7]
#define discharge_model sys[8]
#define charge_model sys[9]
#define float_revise sys[10]
#define test_temp sys[11]
#define desinged_rate sys[12]
//alarm overload
#define overload sys[6]
//static array daydata change to loop link
//sizeof(daydata)=0x2B
extern daydata xdata looplink[BUFFSIZE];
void init_history_buffer(void)
{
unsigned char data i;
//Init DoubleLoopLink
for(i=0;i<BUFFSIZE-1;i++)
{
looplink[i].next=&looplink[i+1];
looplink[i+1].up=&looplink[i];
RESET_DOG;
}
looplink[BUFFSIZE-1].next=&looplink[0];
looplink[0].up=&looplink[BUFFSIZE-1];
today.next=&looplink[0];
today.up=&looplink[BUFFSIZE-1]; //is head->up;
today.up->date[0]=0;//break looplink
today.up->date[1]=0;//break looplink
today.up->date[2]=0;//break looplink
RESET_DOG;
}
void init_rate_workpoint(unsigned char n)
{
unsigned char data i;
//2005/4
n=DEFSYSV;
//2005/4
if(n<4)//system volatage changed
for(i=0;i<12;i++)//Init default seting
{
if(i<7)
{//work point
sys[i]=dtab[n][i];
}
else
{
if(i==11)//sys[11] is test temp.
sys[12]=stab[4][n];//desinged_rate
else sys[i]=stab[i-7][n];
}
}
i=45;//BENCHMARK*AMPLIFICATORY=45;
crate.temperature = i*100;
crate.volatage = i*desinged_rate;//battery volatage
crate.discharge = i*discharge_model/4;
crate.charge = i*charge_model/4;
//check overload <= discharger model
if(overload>discharge_model)overload=discharge_model;
RESET_DOG;
}
//intput data from tlc1543,changed and saved
const adintimes =0xDB24;
const adinadd =0xDB28;
const tmpAh =0xDB44;
//today at
#define ADCOUNT 10
void getadin(void)
{
unsigned char data i;
unsigned long data tmp;
unsigned long xdata *s;//adinadd
unsigned int xdata *t;
for(i=0;i<10;i++)//9 way, the 8 way is no use
if(i!=7)
{
unsigned char data c;
tmp=0;
for(c=0;c<ADCOUNT;c++)tmp+=tlc1543(i);
RESET_DOG;
tmp /= ADCOUNT;
if(i<6)
{
tmp *= crate.charge;
tmp /= ADMAX; adin[i]=(unsigned int)tmp;
}
if(i==6)
{
tmp *= crate.discharge;
tmp /= ADMAX; adin[6]=(unsigned int)tmp;
}
if(i==8)
{
tmp *= crate.temperature;
tmp /= ADMAX; adin[7]=(unsigned int)tmp;
if(adin[7]<2730)adin[7]=2730;
if(adin[7]>3080)adin[7]=3080;
adtemp=adin[7];//save no just temperature
/*2005/4
if(test_temp<3230&&test_temp>2230)adin[7]+=just;//+/-50d
2005/4*/
}
if(i==9)
{
tmp *= crate.volatage;
tmp /= ADMAX; adin[8]=(unsigned int)tmp;
}
}
for(i=0;i<9;i++)
{
if(i>6)//save min value of battery vola.&temperature
if(adin[i]<today.work[2*i+1]||today.work[2*i+1]==0)
today.work[i*2+1]=adin[i];
//only save max value
if(adin[i]>today.work[2*i])today.work[i*2]=adin[i];
}
//counter times and add to add current
s=adinadd;
for(i=0;i<7;i++)*s+++=(unsigned long)adin[i];
t=adintimes;
(*t)++;
RESET_DOG;
}
//-----------------------------
//check error
void syserror(void)
{
//系统设置检错
unsigned char data i;
for(i=0;i<7;i++)
if(sys[i]>400||sys[i]<30)
{init_rate_workpoint(DEFSYSV);return;}
if(!(sys[7]==48||sys[7]==110||sys[7]==220||sys[7]==300))
{
init_rate_workpoint(DEFSYSV);
//控制器失效,需要重新设置或者重新上电
}
}
/*
//count today working result
*/
void account(void)
{
static bit bdata cc;
if(tlong%60>50)//50s
{
if(!cc)
{
char data i;
unsigned long xdata *s;
unsigned long xdata *Ah;//adinadd
unsigned int xdata *t;
t=adintimes;
s=adinadd;
Ah=tmpAh;
for(i=0;i<7;i++)
{ //save current integral value (Ah)
unsigned long data taa;
if(*t!=0)*Ah+=*s/(unsigned long)(*t);//保证精度不损失
else return;
taa=(unsigned long)(*Ah/60);
today.work[i*2+1]=(unsigned int)taa;
*s++=0;
Ah++;
RESET_DOG;
}
cc=1; *t=0;
}
}
else cc=0;
}
/*
//output control,switch operation
*/
#define boostvolatage sys[0]
#define booststart sys[1]
#define floatstop sys[2]
#define floatstart sys[3]
#define moterstart sys[4]
#define lowlevel sys[5]
#define dischargecurrent adin[6]
#define BatteryVolatage adin[8]
//-----------------------------
//System flag,char of control;
//-----------------------------
//control state character
#define fstopc 0x17
#define fstarc 0x12
#define bstopc 0x15
#define bstarc 0x18
#define lowerc 0x2
#define overc 0x13
#define motorc 0xf
#define loadoverswitch P3_3
bit bdata boostflag;
#pragma DISABLE
void control(void)
{
static bit bdata motoropen,exe,ffo;
static unsigned char idata switchchar=0xff; //all close
unsigned int data ofv,cfv;
unsigned char data fk;
unsigned int data temp_flr;
temp_flr=float_revise/10;//100*10=1000
if(t50ms%40>20)//2s
{if(exe)return;}
else {exe=0; return;}
exe=1;
syserror();//check sys rightly
//float charge Temperature revise
if(adin[7]>2980)//25^C
{
cfv=floatstop*AMPLIFICATORY-((adin[7]-2980)*temp_flr)/100;// /1000;
ofv=floatstart*AMPLIFICATORY-((adin[7]-2980)*temp_flr)/100;
}
else
{
cfv=floatstop*AMPLIFICATORY+((2980-adin[7])*temp_flr)/100;
ofv=floatstart*AMPLIFICATORY+((2980-adin[7])*temp_flr)/100;
}
if(controlstate==fstopc)fk=0;
if(BatteryVolatage > boostvolatage*AMPLIFICATORY)
{
boostflag=0; controlstate=bstopc;
if(switchchar!=0xff)
{
fk=1;
while(switchchar==(switchchar|fk))fk<<=1;
switchchar|=fk; switchchar|=0xC0;
}else controlstate=fstopc;
}
else
{
if(boostflag)
{
controlstate=bstarc;//boost charge start
switchchar|=0xC0;
if((switchchar&0x3F) !=0x00)
{
fk=1;
while(switchchar==(switchchar&~fk))fk<<=1;
switchchar&=~fk;
}
if(BatteryVolatage< moterstart*AMPLIFICATORY)
{
motoropen=1;//and motor start
if(BatteryVolatage<lowlevel*AMPLIFICATORY)
{//controlstate=lowerc;
switchchar&=0x7F;}//not enough volatage alarm,6 way start
}
}
else //float controll
{
if(BatteryVolatage >cfv)//float stop
{
ffo=0;
motoropen=0; controlstate=fstopc;
if(switchchar!=0xff)
{
fk=1; controlstate=fstarc;
while(switchchar==(switchchar|fk))fk<<=1;
switchchar|=fk; switchchar|=0xC0;
}
}//stop motor,close 1 way
else
{
if(switchchar==0xff)controlstate=fstopc;
else controlstate=fstarc;
if(ffo)
if((switchchar&0x3F) !=0x00)
{
fk=1;
while(switchchar==(switchchar&~fk))fk<<=1;
switchchar&=~fk; switchchar|=0xC0;
}
if(BatteryVolatage < ofv)//float start
{
ffo=1;
if(BatteryVolatage < booststart*AMPLIFICATORY)
{
boostflag=1; controlstate=bstarc;//boost charge start
}
}
}
}
}
if(motoropen)
if(BatteryVolatage <cfv)//float stop,stop motor
{ if(t50ms%15<7)controlstate=motorc; switchchar &=0xBF;}//motor mask
else {switchchar |=0x40;motoropen=0;}
//Send control to port
P8255B=switchchar;
RESET_DOG;
}
void overloadctl(void)
{
//OverLoad alarm
if(dischargecurrent>(overload*AMPLIFICATORY))
{
if(loadoverswitch)//P3_3
{controlstate=overc;loadoverswitch=0;_nop_();_nop_();}
else loadoverswitch=1;
}
//Lower volotage alarm
if(BatteryVolatage<lowlevel*AMPLIFICATORY)
{static data unsigned char i;i++;
if(i&1)return;
if(loadoverswitch)//P3_3
{controlstate=lowerc;loadoverswitch=0;_nop_();_nop_();}
else loadoverswitch=1;
}
if(dischargecurrent<(overload*AMPLIFICATORY)&&(BatteryVolatage>lowlevel*AMPLIFICATORY))
loadoverswitch=1;
_nop_();_nop_();
}
//----------------------------------------
///save tab to xdata at the one day
//-----Xsave the first value---------
static unsigned char xdata day[3] _at_ 0xD580;
void save(void)
{
if(today.date[2]==day[2])return;
if(day[2]==0||day[2]>31)
{
day[2]=today.date[2];
day[1]=today.date[1];
day[0]=today.date[0];
return;
}
{
unsigned long xdata *Ah;
unsigned char data i;
link p;
p=today.next;
//save data to dubluelooplinktable
for(i=0;i<18;i++)//copy today to today.next
{
if(i<3)
{
p->date[i]=day[i];
day[i]=today.date[i];
};
p->work[i]=today.work[i];
today.work[i]=0;//clear buffer
}
Ah=tmpAh;
for(i=0;i<7;i++)*Ah++=0;//clear Ahtmp
today.next=p->next;//OR today.next->next
today.up=p;
p=today.next;
p->date[0]=0;
p->date[1]=0;
p->date[2]=0;//break looplink
}
RESET_DOG;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -