📄 solarctrl.cpp
字号:
//////////////////////////////////////////////////////////////
// //
// 无线数据采集模块操作系统 (V1.1.00) //
// 建于:2007-9-26 //
// 初完于: //
// 测试完于: //
// 作者:苏伟 //
// E_MAIL:SUWEI0527@LIVE.CN //
//////////////////////////////////////////////////////////////
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// %
//本程序是由GCC编译,由PROGRAMMERS NOTEPAD 2编写%
// %
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#include"avr/io.h"
#include<avr/interrupt.h>
#include"solar_ctrl.h"
//-----------------------------
//AD数据采集
int adcsum;
char adc_chnum;
bool ADC_FINISHED;
#if debug
#define ADCCTNUM 1
#else
#define ADCCTNUM 6
#endif
int adc_max;
int adc_min;
char adccount;
ISR(SIG_ADC)//数据采集ADC
{
char adcl;
int adcsum1;
cli();
adcl=ADCL;
adcsum1=ADCH;
adcsum1<<=8;
adcsum1+=adcl;
#if debug
adcsum=adcsum1;
#else
if(adc_max<adcsum1)
adc_max=adcsum1;
if((adccount==null)||(adc_min>adcsum1))
adc_min=adcsum1;
adcsum+=adcsum1;
#endif
adccount++;
if(adccount<ADCCTNUM)
START_ADC();
else
{
ADC_FINISHED=true;
adccount=null;
}
sei();
}
char timer_cn;
ISR(SIG_OVERFLOW0)
{
cli();
TCNT0=0x82; //125=7D FF-7D=82;1MHzMCUKC时,12小时误差为:5.76分钟
//125个64分频为8毫秒,处理125次为 1秒
timer_cn++;
if(timer_cn==timer_second)
{
timer_cn=0x00;
timer_th++;//最大12小时,12X3600=43200
if((timer_tc!=null)&&(timer_th==timer_tc))
{
timer_th=0x00;
turnoff_load();
T0stoptimer();
}
}
if(adccount==null)
START_ADC();
sei();
}
ISR(SIG_OVERFLOW1)
{
cli();
sei();
}
//--------------------------------
//
#if !tra_data
void display(char ad)
{
if(ad==null)
{
PORTB&=~(1<<PORTB4);
PORTA&=~(1<<PORTA6);
PORTA&=~(1<<PORTA7);
return;
}
if(ad==0xff)
{
PORTB|=1<<PORTB4;
PORTA|=1<<PORTA6;
PORTB|=1<<PORTA7;
return;
}
if((ad&WORK_LED)!=null)
PORTB|=(1<<PORTB4);
else
PORTB&=~(1<<PORTB4);
if((ad&CHARGE_LED)!=null)
PORTA|=(1<<PORTA6);
else
PORTA&=~(1<<PORTA6);
if((ad&OVERCH_LED)!=null)
PORTA|=(1<<PORTA7);
else
PORTA&=~(1<<PORTA7);
}
#else
void display(int ad)
{
int i,j,k;
j=0x01;
for(i=0;i<=9;i++)
{
PORTB&=~(1<<PORTB4);
if((ad&j)!=null)
PORTA|=(1<<PORTA6);
else
PORTA&=~(1<<PORTA6);
nop();
nop();
nop();
nop();
nop();
nop();
PORTB|=(1<<PORTB4);
nop();
nop();
nop();
nop();
nop();
nop();
nop();
nop();
nop();
nop();
nop();
nop();
nop();
nop();
nop();
nop();
nop();
nop();
nop();
nop();
nop();
nop();
nop();
nop();
nop();
nop();
nop();
nop();
nop();
nop();
nop();
nop();
nop();
nop();
nop();
nop();
nop();
nop();
nop();
nop();
nop();
nop();
nop();
nop();
nop();
nop();
nop();
nop();
do{
k=PINA;
k&=0X80;
}while(!k);
j<<=1;
}
}
#endif
void beep(void)
{
char pb;
pb=PORTB;
if((pb&0x04)!=null)
PORTB&=(~(1<<PORTB2));
else
PORTB|=(1<<PORTB2);
}
int adc_result_op(void)
{
int res1;
#if debug
res1=null;
return adcsum;
#else
adcsum=adcsum-adc_max-adc_min;
res1=adcsum/(ADCCTNUM-2);
if(adcsum!=null)
adcsum=null;
adc_max=null;
adc_min=null;
return res1;
#endif
}
int cycle_out(int vin,int vout)
{
int sd;
int toff;
int vf=5;
int vsat=3;
if((vin<=vsat)||(vin>=vout))
return null;
sd=((vout+(2*vf)-vin)*100)/(vin-vf-vsat);
//toff=(sd*OC_CYCLE)/(sd+100);//TON
toff=(100*OC_CYCLE)/(sd+100); //TOFF
if(toff>=OC_CYCLE)
toff=null;
return toff;
}
void battery_chg(int batmax)
{
int toff;
if(batmax!=null)
{
if(solar_nmv!=solar_ch)//太阳电池低,升压
{
toff=cycle_out(solar_nmv,batmax);
solar_ch=solar_nmv;
if(toff>OC_CYCLE/2)
toff=OC_CYCLE/2;
OC1A_V(OC_CYCLE-toff);//此值为 Toff
OC1C_V(OC_CYCLE);
OC1B_V(null);
T11CK();
}
}else
if(OCR1A!=NULL)
{
OC1A_V(NULL);
STOPT1CK();
}
}
void init_register(void)
{
//MCU寄存器设置
MCUCR=0X40;
MCUSR=NULL;
//定时器中断使能设置
DIST1CA();
DIST1CB();
DIST0IE();
DIST1IE();
//ADC设置
ENADC();
ADCCK(ADCCK128);
ADC_CH(ADCMIN_CH);
ENADCIE();
START_ADC();
sei();
}
void init_port(void)
{
cli();
//A口设置
#if !tra_data
DDRA=(1<<DDA7)|(1<<DDA6);
PORTA=null;
#else
DDRA=(1<<DDA6);
PORTA=NULL;
#endif
//B口设置
DDRB=FULL;
PORTB=0XC0;
}
void init_mem(void)
{
int i;
i=0x60;
for(i=0x60;i<0xdd;i++)
MEM_IO(i)=0x00;
adccount=0X00;
adc_chnum=ADCMIN_CH;
ADC_FINISHED=false;
low_v=false;
first_tem=false;
over_tem=false;
solar_ch=null;
load_nmv=null;
cycle_num=low_cycle;
load_nmv=null;
}
//-------------------------------------
//
void start_up_timer0(void)
{
ENT0IE();
TCNT0=0x82; //125=7D FF-7D=82;1MHzMCUKC时,
//125个64分频为8毫秒,处理125次为 1秒
//12个小时误差:5.76分钟。
T064CK();
timer_cn=null;
timer_tc=null;
timer_th=null;
}
void start_up_timer1(void)
{
ENT1IE();
//CTROC1A();
//CTROC1B();
//PWMOC1A();
//PWMOC1B();
STOPT1CK();
OC1A_V(NULL);
OC1B_V(null);
OC1C_V(NULL);
}
void program_start()
{
int bt;
int bt1=null;
int bt2=null;
char dis=null;
while(1)
{
if(ADC_FINISHED)
{
feed_dog();
switch(adc_chnum)
{
//dis=null;
case ADCCH0://太阳能板检测
feed_dog();
bt=adc_result_op();
solar_nmv=(2*bt)/5;//如果bt*4,则solar_nmv将会精确到10mV
//与外接电阻有关 150ohm+10ohm
if(solar_nmv<=SLMIN)
sunup=false;
if(solar_nmv>=SLMAX)
sunup=true;
break;
//%%%%%%%%%%%%%%%%%%%%%%%%%%%
case ADCCH1://电池检测
feed_dog();
bt=adc_result_op();
#if tra_data
display(bt);
#endif
//---------过温 --------------//
if(over_tem)
break;
battery_nmv=(3*bt)/10;//如果bt*3,则battery_nmv将会精确到10mV
//与外接电阻有关120ohm+10ohm
//电池输出没有二极管就不用+7,7=0.7v
//battery_nmv+=7;//没有二极管,就不用+7
//---------12v过压------------//
low_v=false;
if(battery_nmv>=BATT12VMAX-10)
{
dis|=OVERCH_LED;
if(sunup)
{
turnoff_solar();//太阳出来,开启太阳能充电
}
bt2=null;
PORTB&=(~(1<<PORTB2));
break;
}
dis&=0XFE;
//----------12v欠压----------//
if(battery_nmv<=BATT12VMIN-10)
{
low_v=true;
if(battery_nmv>=BATT12VMIN-15)
{
bt2++;
if(bt2>=0x1f)
{bt2=00;
beep();
}
}
else
{
bt2=null;
PORTB&=(~(1<<PORTB2));
dis=null;
}
if(sunup)
{
turnon_solar(); //太阳出来,开启太阳能充电
if(solar_nmv<battery_nmv)
{
dis|=CHARGE_LED;
battery_chg(BATT12VMAX); //启动PWM充电
}
else
{
battery_chg(null);
}
}
break;
}
bt2=null;
PORTB&=(~(1<<PORTB2));
//---------12V正常 --------//
if((battery_nmv>BATT12VMIN+10)&&(battery_nmv<BATT12VMAX-10))
{
if(sunup)
{
turnon_solar(); //太阳出来,开启太阳能充电
if(battery_nmv>solar_nmv)
{
dis|=CHARGE_LED;
dis&=0xfe;
}
}else
turnoff_solar();
}
break;
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
case ADCCH2://电池温度检测
feed_dog();
bt=adc_result_op();
#if !tra_data
if(!first_tem)//记录环境温度
{
init_tem=bt;
first_tem=true;
//应该保存到EEPROM,以备
}
else
{
bt=bt-init_tem;
if(bt>=OVERTEM_BATTMAX)
{
over_tem=true;
turnoff_load();
turnoff_solar();
}
else
if(bt<OVERTEM_BATTMIN)
over_tem=false;
}
#endif
break;
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
case ADCCH3://定时检测
feed_dog();
bt=adc_result_op();
#if !tra_data
if(low_v||sunup)
break;
bt/=TIMERADC_SCALE;
if(bt!=null)
{
start_up_timer0();
bt*=TIMER_TMIN;
timer_tc=bt;
}
#endif
break;
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
case ADCCH4://负载电压检测
//无负载则会间隙工作
feed_dog();
bt=adc_result_op();
bt1=bt;
bt1*=12;//校正误差11.7%
bt1/=100;
bt+=bt1;
#if !tra_data
if(low_v||over_tem)
{
turnoff_load();
dis&=0xf9;
break;
}
turnon_load();
dis|=WORK_LED;
output_nmv=(2*bt)/5;//如果bt*4,则output_nmv将会精确到10mV
//与外接电阻有关150ohm+10ohm
#endif
break;
//%%%%%%%%%%%%%%%%%%%%%%%%
default:
feed_dog();
adc_chnum=ADCMIN_CH;
break;
}
ADC_FINISHED=false;
adc_chnum++;
ADC_CH(adc_chnum);
if(adc_chnum>ADCMAX_CH)
{
adc_chnum=ADCMIN_CH;
ADC_CH(ADCMIN_CH);
}
START_ADC();
#if !tra_data
display(dis);
#endif
}
}
}
void EN_wtdog(void)
{
WDTCR=0X18;
WDTCR=(1<<bit3)|(1<<bit1);
}
int main(void)
{
init_port();
init_mem();
init_register();
start_up_timer0();
start_up_timer1();
EN_wtdog();
program_start();
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -