|
设计功能如下:
(1)白天状态给电池充电。
1.1采用三段充电法,激活(5.0-5.8V),恒流(5.8-6.9V),涓流充电(6.9-7.2V)。
1.2充电状态红灯亮。
(2)黑天状态给电池给负载放电。
2.1开始放电全功放电。6个小时后,半功率放电。(实验板上地方不够,未做,下一版改进)
2.2电池放电保护电压5.2V 2.3温度补偿。(初版地方不够,未做)
(3)白-》黑天过渡状态大概5分钟,其间LEDG闪烁。
(4)按钮模拟黑天功能。
备注:昨晚(2013.07.14)测试了一下测试按钮,在充电状态下按下没问题,但是在绿灯闪烁和充电时电池开路情况下按下会对系统造成影响,已修改。 原理图有个地方画错了,Q3 E应该接Q5 S的,多亏huoyubing521发现了,谢谢~~ robin_chen559 2013.07.23
程序框图:
原理图:
修改记录:
更改项目
判断天黑绿灯闪烁时按钮按下时序混乱
充电电池开路,按钮按下后,天黑单片机掉电
原理图错误Q3 E应该接Q5 S端来着
源程序:
- /***********************************************************************************
- 项目:太阳能充放电控制器
- 功能:通过STC12C5410AD 的AD/PWM控制太阳能电池系统的充放电
- (1)白天状态给电池充电。
- 1.1采用三段充电法,激活(5.0-5.8V),恒流(5.8-6.9V),涓流充电(6.9-7.2V)。
- 1.2充电状态红灯亮。
- (2)黑天状态给电池给负载放电。
- 2.1开始放电全功放电。6个小时后,半功率放电。(实验板上地方不够,未做,下一版改进)
- 2.2电池放电保护电压5.2V
- (3)白-》黑天过渡状态大概5分钟,其间LEDG闪烁。
- (4)按钮模拟黑天功能。
- 设计:robin_chen559
- 日期:2013.07.09
- 备注:(1)晶振频率 11.059M (2)电池6V 2.5AH铅酸电池
- (3)太阳能电池板19V620MA 11W
- ***********************************************************************************/
- #include<STC12C5410AD.H>
- #include<intrins.h>
- #define uchar unsigned char
- #define uint unsigned int
- sbit LEDR = P1^7;
- sbit LEDG = P1^6;
- sbit LEDY = P1^5;
- sbit Bat_Sen_SW = P1^3;
- sbit Bat_DCH_SW = P3^5;
- sbit MUC_POWER = P3^3; //单片机供电
- sbit VINT0 = P3^2; //INT0端口
- bit Bat_CR = 0 ; //charge ready充电充满切换窗口
- bit Bat_OP = 0 ; //open 电池过冲切换窗口
- bit LEDG_Flash = 0 ; //判断天黑等待LEDG闪烁标志
- bit Bat_DCH_Bit = 0; //放电标志,防等待LEDG闪烁进入放电状态后还闪
- bit Bat_DCH_Wait = 0; //判断天黑等待放电标志
- bit SW_ON_Bit = 0 ; //按钮按下标志
-
- uchar Bat_CH_DCH = 0 ; //充放电转换标志 0充电,1放电,2按钮按下判断
- uchar T0_num = 0 ; //定时器1计时参数
- uint num = 0; //天黑判断延时计数参数
- //子程序声明
- void Delay_MS(uint MS);
- void init_AD(void);
- void Timer_init(void);
- int Get_AD(uchar channel);
- float AD_AV(uchar channel);
- void Power_Star(void);
- void Bat_Star(void);
- void Bat_CH(void);
- void init_PWM(uchar D_PWM);
- void Init_Inte(void);
- void Bat_DCH(void);
- void Power_OFF(void);
- void Bat_CH_DCH_Wait(void);
- void SW_ON_CHAR(void);
- void SW_OFF_CHAR(void);
- //子程序
- //延时子程序
- void Delay_MS(uint MS)
- {
- uint i,j;
- for(i=MS;i>0;i--)
- for(j=110;j>0;j--);
- }
- //定时器初始化子程序
- void Timer_init(void)
- {
- TMOD = 0x11; //0001 0001 定时器0/1 ,1模式16位计数
- EA = 1; //允许总中断发生
- ET0 = 1; //允许定时器0中断
- TR0 = 1; //定时器0开启
- TH0 = (65536-46080)/256; //高八位装值
- TL0 = (65536-46080)%256; //低八位装值
- }
- //定时器0中断子程序
- void Timer_0(void)interrupt 1
- {
- TH0 = (65536-46080)/256; //高八位装值
- TL0 = (65536-46080)%256 ; //低八位装值
-
- T0_num++;
- if(T0_num==10)
- {
- T0_num = 0; //计时清零
- if(LEDG_Flash == 1)
- {
- LEDG = ~LEDG; //LED_G闪烁
- }
- }
- }
- //AD初始化子程序
- void init_AD(void)
- {
- P1M0 = 0x11; //0001 0001
- P1M1 = 0xff; //1111 1111 AD4 /AD0开漏为AD输入,其余强推挽输出
- ADC_CONTR = 0xe0; //1110 0000
- Delay_MS(3);
- }
- //AD转换
- int Get_AD(uchar channel)
- {
- uchar AD_finished = 0; //设AD转换完成标志
- int result;
- ADC_CONTR|=channel; //选择AD转换通道
- ADC_CONTR|=0x08; // 开始ad转换
- while(AD_finished == 0) //等待AD转换完成
- {
- AD_finished=(ADC_CONTR&0x10);
- }
- result = ADC_DATA*4+ADC_LOW2; //读走AD转换结果
- ADC_CONTR&=0xe0; // 1110 0000 清除转换完成标志,关闭AD。
- return(result); //AD转换结果返回给函数
- }
-
- //AD转换结果运算子程序
- float AD_AV(uchar channel)
- {
- float VAL_AD = 0;
- uchar num ;
- for(num=100;num>0;num--)
- {
- VAL_AD+=Get_AD(channel); //100次AD转换结果相加
- }
- VAL_AD/=100.0; //100次AD转换平均值
- VAL_AD=VAL_AD*5/1024; //求十进制AD值
- return(VAL_AD); //返回十进制AD值
- }
- //开机外接电源判断子程序
- void Power_Star(void)
- {
-
- if(AD_AV(0)<3.0) //vin大于9V,市电加载
- {
- LEDG = 0; //外接电源正常,绿色LED亮
- LEDR = 1;
- init_PWM(0xff); //PWM D=0,关闭充电
- }
-
- }
- //太阳能电池板基本无输出,黑天
- void Power_OFF(void)
- {
-
- if(AD_AV(0)<1.0) //vin小于3V,太阳能电池板基本无输出
- {
-
- num++; //阳光不好太阳能供电不足,充电电路拉低太阳能 板输出电压
- Bat_DCH_Wait = 1; //判断天黑等待放电
- if(Bat_DCH_Bit == 0)
- {
- Bat_CH_DCH = 2; //充放电切换等待,天黑等待和放电状态判断条件相同
- LEDG_Flash = 1; //判断天黑等待LEDG闪烁
- }
- }
- if(AD_AV(0)>1.0) //vin大于3V,太阳能电池板有输出
- {
- num = 0;
- Bat_DCH_Bit = 0; //放电后重新充电
- Bat_CH_DCH = 0; //日食条件,时间大于5分钟,太阳能电池板重新上电
- LEDG_Flash = 0; //回复充电状态,LEDG禁止闪烁
- }
-
- if(num>1512) //太阳能电池板连续一段时间电压小于3V,252 对应10S;14652对应300秒(精度5S)
- {
-
- init_PWM(0xff); //PWM D=0,关闭充电
- Bat_CH_DCH = 1; //电池放电,改进板单片机供电和放电分开
-
- // num=0不合适,否则在放电过程中手欠按下按钮,系统重新进入黑天判断等待计数。
- }
- //如等待时间过长可考虑太阳能电池板意外,不能维持单片机判断黑天等待时间
-
- }
- //充放电切换等待子程序
- void Bat_CH_DCH_Wait(void)
- {
- LEDR = 1 ; //充电红灯关闭,避免等待过程中切充电红灯闪
- }
- //开机电池检测子程序
- void Bat_Star(void)
- {
-
- Bat_Sen_SW = 1 ; //打开电池电压检测三极管
-
- if(AD_AV(4)<1.5) //电池未接,黄灯亮
- {
- LEDY = 0 ;
- }
- if(AD_AV(4)>1.5) //电池挂载,红灯亮,充电
- {
- LEDR = 0 ;
- Bat_CH_DCH = 0 ; //进入充电程序
- }
-
- }
- //PWM子程序
- void init_PWM(uchar D_PWM )
- {
- CMOD = 0x00; //设置PWM定时器
- CL = 0x00;
- CH = 0x00;
- CCAPM0 = 0x42; //PWM0设置为PWM模式
- CCAP0L = 0x10 ; //PWM0设置
- CCAP0H = D_PWM ;
- CR = 1; //开始PWM定时器
- }
- //充电程序
- void Bat_CH(void)
- {
- bit Bit_RED_ON = 0 ;
- Bat_Sen_SW = 1; //允许电池电压检测
- Bat_DCH_SW = 0; //放电使能关闭
- Bat_DCH_Wait = 0; //判断天黑等待封禁
- MUC_POWER = 1; //防止电池开路时按钮按下,天黑放电失效
- if(AD_AV(4)<1.66) //电池断开,充电电路不通(0.5太低)
- {
- Bat_OP = 1; //电池给单片机供电PNP管漏电过去
- init_PWM(0xff);
- }
- if((AD_AV(4)>1.66)&(AD_AV(4)<2.05)) //电池挂载,电压范围5.0-5.8V,PWM D=0.3
- {
-
- init_PWM(0xb3); // PWM D=0.3 0xb3 (D=0.1驱不动,表上无电流)
- Bat_CR = 0; //防冲完电后换电池
- Bat_OP = 0; // 清除电池开路标志
- }
- //电池挂载,电压范围5.8-6.9V,PWM D=0.9/0.6
- if((AD_AV(4)>=2.05)&(AD_AV(4)<=2.42))
- {
-
-
- init_PWM(0x19); //PWM D=0.9 0x19
-
- Bat_OP = 0; // 清除电池开路标志
- if(AD_AV(4)<2.27) // Vbat 6.5V,窗口下端,放电至6.5V以下,充电红灯才会重新亮
- {
- Bit_RED_ON = 1; //红灯亮置“1”
- }
- if(Bit_RED_ON == 1)
- {
- Bat_CR = 0; //防冲完电后换电池
- }
- }
- //电池挂载,电压范围6.9-8.0V,PWM D=0.3
- if((AD_AV(4)>2.42)&(AD_AV(4)<=2.80))
-
- { //窗口比较,用7.0判6.9V
- Delay_MS(10);
- if (AD_AV(4)>2.35) //确定电池基本充到6.7V(窗口)
- {
-
- Bat_OP = 0; // 清除电池开路标志
- init_PWM(0xb3); //PWM D=0.3,绢流充电(电池老化后,维持电压)
- }
- if (AD_AV(4)>2.40) //确定电池基本充到7.0V(窗口)
- {
-
- Bat_OP = 0; // 清除电池开路标志
- Bit_RED_ON = 1;
- }
- if(Bit_RED_ON == 1)
- {
- Bat_CR = 1; //充电完毕,红色指示灯关闭
- }
- if(AD_AV(4)>2.52)
- {
- init_PWM(0xff); //Vbat 7.2V PWM D=0 (电池老化后,小电流仍会使电压虚高电压)
- }
-
- }
- if(AD_AV(4)>2.80) //电池开路,电压范围8V,PWM D=0.75
- {
-
- if ( AD_AV(4)>2.80)
- {
- Bat_OP = 1; //电池开路标志置 ‘1’
- init_PWM(0x40); //PWM 0x40 D=0.75
- }
- }
- //状态指示灯
-
- LEDG = 0 ; //主电绿灯亮
- if (Bat_CR == 0) //充电未完成
- {
- LEDR = 0; // 指示红灯亮
- LEDY = 1; //指示黄灯灭
- }
- if(Bat_CR == 1) //充电完成
- {
- LEDR = 1; // 指示红灯灭
- LEDY = 0; //指示黄灯亮
- }
- if (Bat_OP == 0) //电池开路
- {
- LEDY = 1; //指示黄灯灭
- }
- if (Bat_OP == 1) //电池开路
- {
- LEDR = 1; // 指示红灯灭
- LEDY = 0; //指示黄灯亮
- }
-
- }
-
- //中断初始化
- void Init_Inte(void) //中断初始化
- {
- EA = 1; //开总中断
- IT0 = 1; //下降沿触发中断
- EX0 = 1; //开外部0中断
- }
- //中断0响应
- void Inter0(void) interrupt 0 //外部中断0程序
- {
- SW_ON_Bit = 1 ; //开关按下标志置“1”
- }
- //按键按下判断
- void SW_ON_CHAR(void)
- {
-
- if( SW_ON_Bit == 1) //按钮确定按下
- {
- VINT0 = 1; //端口置“1”好判断
- _nop_();
- _nop_();
- _nop_(); //三个空周期,待电平稳定
- if(VINT0 == 0) //按钮按下
- {
- Delay_MS(10);
- if(VINT0 == 0) //确定按钮按下
- {
- Bat_CH_DCH = 1; //放电标志置“1”
- }
- }
- }
- }
- //按钮松开判断
- void SW_OFF_CHAR(void)
- {
-
- if( SW_ON_Bit == 1) //确定之前有开关按下
- {
- VINT0 = 1; //端口置“1”好判断
- _nop_();
- _nop_();
- _nop_(); //三个空周期,待电平稳定
- if(VINT0 == 1) //INT0电平为高
- {
- Delay_MS(10);
- if(VINT0 == 1) //确定按钮松开,放电标志置"0"
- {
- SW_ON_Bit = 0; //按钮按下标志清除
- if(Bat_DCH_Wait == 0) //防止判断天黑绿灯闪烁时按钮按下时序混乱
- {
- Bat_CH_DCH = 0;
- }
- }
- }
- }
- }
- //放电子程序
- void Bat_DCH(void)
- {
- float VCC_DCH; //设定放电基准电压
- float DCH_AD_AV4; //放电电池采样电压
- Bat_Sen_SW = 1; //允许电池电压检测
- Bat_DCH_SW = 1; //电池放电开关开启
- Bat_DCH_Bit = 1; //放电标志置“1”
- init_PWM(0xff); //设置PWM后端口输出0不好使了,避免按钮测试放电电流有差异
- LEDG_Flash = 0; //等待状态切换到放电状态,禁止LEDG闪烁
- LEDR = 1; //三色指示灯全灭
- LEDG = 1;
- LEDY = 1;
-
- //放电保护
- VCC_DCH = (1024*2.5)/AD_AV(2); //计算放电基准电压
- DCH_AD_AV4 = AD_AV(4)*VCC_DCH/1024; //放电基准电压下电池电压
-
- if(DCH_AD_AV4<1.82) //电池电压小于5.2V
- {
- Bat_DCH_SW = 0; //电池放电开关关闭,电池停止放电
- MUC_POWER = 0; //否则检测太阳能板无电,还是继续进入放电状态
- }
-
- }
- //主程序
- void main(void)
- {
- init_AD(); //AD初始化
- Timer_init(); //定时器初始化
- Init_Inte(); //中断初始化
- Power_Star(); //开机检测外接电源
- Bat_Star(); //开机电池检测
-
- MUC_POWER = 1; //中断响应,电池来不及供电
- P3M0 = 0x00; // 0000 0000
- P3M1 = 0xfb; // 1111 1011
- while(1)
- {
-
- Power_OFF(); //判断是否黑天
- SW_ON_CHAR(); //判断按钮是否按下
- SW_OFF_CHAR(); //判断按钮是否松开
- if(Bat_CH_DCH==0)
- {
- Bat_CH(); //电池充电
- }
- if(Bat_CH_DCH==1)
- {
- Bat_DCH(); //电池放电
- }
- if(Bat_CH_DCH==2)
- {
- Bat_CH_DCH_Wait(); //充放电切换等待
- }
- }
复制代码
全部完整代码:
SOFT.rar
(47.09 KB, 下载次数: 308)
|
评分
-
查看全部评分
|