找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 22332|回复: 22
收起左侧

AD_PWM太阳能电池充放电控制器,原理图/源程序,测试通过

  [复制链接]
ID:140725 发表于 2016-10-12 13:32 | 显示全部楼层 |阅读模式

设计功能如下:
       (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
       0.png 0.png
程序框图:
0.png
原理图:
0.png


修改记录:
更改项目
判断天黑绿灯闪烁时按钮按下时序混乱
充电电池开路,按钮按下后,天黑单片机掉电
原理图错误Q3 E应该接Q5 S端来着

源程序:
  1. /***********************************************************************************
  2. 项目:太阳能充放电控制器
  3. 功能:通过STC12C5410AD 的AD/PWM控制太阳能电池系统的充放电
  4.       (1)白天状态给电池充电。
  5.              1.1采用三段充电法,激活(5.0-5.8V),恒流(5.8-6.9V),涓流充电(6.9-7.2V)。
  6.                  1.2充电状态红灯亮。
  7.           (2)黑天状态给电池给负载放电。
  8.              2.1开始放电全功放电。6个小时后,半功率放电。(实验板上地方不够,未做,下一版改进)
  9.                  2.2电池放电保护电压5.2V
  10.           (3)白-》黑天过渡状态大概5分钟,其间LEDG闪烁。
  11.           (4)按钮模拟黑天功能。

  12. 设计:robin_chen559
  13. 日期:2013.07.09
  14. 备注:(1)晶振频率 11.059M (2)电池6V 2.5AH铅酸电池
  15.       (3)太阳能电池板19V620MA 11W
  16. ***********************************************************************************/
  17. #include<STC12C5410AD.H>
  18. #include<intrins.h>

  19. #define uchar unsigned char
  20. #define uint  unsigned int

  21. sbit LEDR = P1^7;
  22. sbit LEDG = P1^6;
  23. sbit LEDY = P1^5;

  24. sbit Bat_Sen_SW = P1^3;


  25. sbit Bat_DCH_SW = P3^5;
  26. sbit MUC_POWER = P3^3;                                          //单片机供电
  27. sbit VINT0 = P3^2;                       //INT0端口  

  28. bit Bat_CR = 0 ;                         //charge ready充电充满切换窗口
  29. bit Bat_OP = 0 ;                                                  //open 电池过冲切换窗口
  30. bit LEDG_Flash = 0 ;                                          //判断天黑等待LEDG闪烁标志
  31. bit Bat_DCH_Bit = 0;                     //放电标志,防等待LEDG闪烁进入放电状态后还闪
  32. bit Bat_DCH_Wait = 0;                                          //判断天黑等待放电标志
  33. bit SW_ON_Bit = 0 ;                      //按钮按下标志



  34. uchar Bat_CH_DCH = 0 ;                                      //充放电转换标志 0充电,1放电,2按钮按下判断
  35. uchar T0_num = 0 ;                                                  //定时器1计时参数
  36. uint num = 0;                                                  //天黑判断延时计数参数

  37. //子程序声明
  38. void Delay_MS(uint MS);
  39. void init_AD(void);
  40. void Timer_init(void);

  41. int Get_AD(uchar channel);
  42. float AD_AV(uchar channel);

  43. void Power_Star(void);
  44. void Bat_Star(void);
  45. void Bat_CH(void);
  46. void init_PWM(uchar D_PWM);
  47. void Init_Inte(void);               
  48. void Bat_DCH(void);
  49. void Power_OFF(void);
  50. void Bat_CH_DCH_Wait(void);
  51. void SW_ON_CHAR(void);
  52. void SW_OFF_CHAR(void);
  53. //子程序

  54. //延时子程序
  55. void Delay_MS(uint MS)
  56. {
  57.   uint i,j;
  58.   for(i=MS;i>0;i--)
  59.      for(j=110;j>0;j--);
  60. }

  61. //定时器初始化子程序
  62. void Timer_init(void)
  63. {
  64.    TMOD = 0x11;                   //0001 0001 定时器0/1 ,1模式16位计数
  65.    EA  = 1;                                                  //允许总中断发生
  66.    ET0 = 1;                                          //允许定时器0中断
  67.    TR0 = 1;                                                  //定时器0开启

  68.    TH0 = (65536-46080)/256;       //高八位装值
  69.    TL0 = (65536-46080)%256;       //低八位装值
  70. }
  71. //定时器0中断子程序
  72. void Timer_0(void)interrupt 1
  73. {
  74.    TH0 = (65536-46080)/256;       //高八位装值
  75.    TL0 = (65536-46080)%256 ;       //低八位装值
  76.    
  77.    T0_num++;
  78.    if(T0_num==10)
  79.    {
  80.         T0_num = 0;                   //计时清零
  81.         if(LEDG_Flash == 1)
  82.         {
  83.          LEDG = ~LEDG;                 //LED_G闪烁
  84.         }
  85.    }
  86. }

  87. //AD初始化子程序
  88.   void init_AD(void)
  89.   {
  90.    P1M0 = 0x11;                    //0001 0001
  91.    P1M1 = 0xff;                    //1111 1111  AD4 /AD0开漏为AD输入,其余强推挽输出
  92.    ADC_CONTR = 0xe0;               //1110 0000
  93.    Delay_MS(3);   
  94.   }

  95. //AD转换
  96. int Get_AD(uchar channel)
  97. {
  98.   uchar AD_finished = 0;           //设AD转换完成标志
  99.   int result;
  100.   ADC_CONTR|=channel;              //选择AD转换通道
  101.   ADC_CONTR|=0x08;                 // 开始ad转换
  102.   while(AD_finished == 0)                   //等待AD转换完成
  103.   {
  104.    AD_finished=(ADC_CONTR&0x10);
  105.   }
  106.   result = ADC_DATA*4+ADC_LOW2;    //读走AD转换结果
  107.   ADC_CONTR&=0xe0;                 // 1110 0000 清除转换完成标志,关闭AD。
  108.   return(result);                  //AD转换结果返回给函数
  109. }

  110. //AD转换结果运算子程序

  111. float AD_AV(uchar channel)
  112. {
  113.    float VAL_AD = 0;
  114.    uchar num ;
  115.    for(num=100;num>0;num--)
  116.    {
  117.     VAL_AD+=Get_AD(channel);         //100次AD转换结果相加
  118.    }
  119.    VAL_AD/=100.0;                                         //100次AD转换平均值
  120.    VAL_AD=VAL_AD*5/1024;                         //求十进制AD值
  121.    return(VAL_AD);                                         //返回十进制AD值
  122. }

  123. //开机外接电源判断子程序
  124. void Power_Star(void)
  125. {
  126.                                                                   
  127.   if(AD_AV(0)<3.0)                                         //vin大于9V,市电加载
  128.   {
  129.    LEDG = 0;                         //外接电源正常,绿色LED亮
  130.    LEDR = 1;

  131.    init_PWM(0xff);                                     //PWM D=0,关闭充电
  132.   }
  133.   
  134. }
  135. //太阳能电池板基本无输出,黑天
  136. void Power_OFF(void)
  137. {
  138.   
  139.   if(AD_AV(0)<1.0)                                         //vin小于3V,太阳能电池板基本无输出
  140.   {
  141.    
  142.    num++;                                                         //阳光不好太阳能供电不足,充电电路拉低太阳能 板输出电压
  143.    Bat_DCH_Wait = 1;                 //判断天黑等待放电
  144.    if(Bat_DCH_Bit == 0)
  145.    {
  146.      Bat_CH_DCH = 2;                             //充放电切换等待,天黑等待和放电状态判断条件相同
  147.      LEDG_Flash = 1;                 //判断天黑等待LEDG闪烁
  148.    }
  149.   }                                                                        


  150.   if(AD_AV(0)>1.0)                                         //vin大于3V,太阳能电池板有输出
  151.    {
  152.    num = 0;
  153.    Bat_DCH_Bit = 0;                  //放电后重新充电
  154.    Bat_CH_DCH  = 0;                                     //日食条件,时间大于5分钟,太阳能电池板重新上电
  155.    LEDG_Flash  = 0;                  //回复充电状态,LEDG禁止闪烁
  156.    }
  157.   
  158.    if(num>1512)                                         //太阳能电池板连续一段时间电压小于3V,252 对应10S;14652对应300秒(精度5S)
  159.    {
  160.    
  161.    init_PWM(0xff);                                     //PWM D=0,关闭充电

  162.    Bat_CH_DCH = 1;                   //电池放电,改进板单片机供电和放电分开
  163.    
  164.                                                           //        num=0不合适,否则在放电过程中手欠按下按钮,系统重新进入黑天判断等待计数。

  165.    }
  166.                                      //如等待时间过长可考虑太阳能电池板意外,不能维持单片机判断黑天等待时间
  167.   
  168. }

  169. //充放电切换等待子程序
  170. void Bat_CH_DCH_Wait(void)
  171. {
  172.   LEDR = 1 ;                         //充电红灯关闭,避免等待过程中切充电红灯闪
  173. }

  174. //开机电池检测子程序
  175. void Bat_Star(void)
  176. {

  177.   Bat_Sen_SW = 1 ;                  //打开电池电压检测三极管               


  178. if(AD_AV(4)<1.5)                                         //电池未接,黄灯亮
  179. {
  180.   LEDY = 0 ;
  181. }

  182. if(AD_AV(4)>1.5)                                         //电池挂载,红灯亮,充电
  183. {
  184.   LEDR = 0 ;
  185.   Bat_CH_DCH = 0 ;                                     //进入充电程序
  186. }


  187. }

  188. //PWM子程序
  189. void init_PWM(uchar D_PWM )
  190. {
  191. CMOD = 0x00;                    //设置PWM定时器
  192. CL   = 0x00;
  193. CH   = 0x00;

  194. CCAPM0 = 0x42;                                     //PWM0设置为PWM模式

  195. CCAP0L = 0x10 ;                                 //PWM0设置
  196. CCAP0H = D_PWM ;

  197. CR = 1;                         //开始PWM定时器
  198. }

  199. //充电程序
  200. void Bat_CH(void)
  201. {

  202. bit Bit_RED_ON = 0 ;

  203. Bat_Sen_SW = 1;                     //允许电池电压检测

  204. Bat_DCH_SW = 0;                     //放电使能关闭

  205. Bat_DCH_Wait = 0;                   //判断天黑等待封禁

  206. MUC_POWER = 1;                                                 //防止电池开路时按钮按下,天黑放电失效

  207. if(AD_AV(4)<1.66)                                         //电池断开,充电电路不通(0.5太低)
  208.   {
  209.    Bat_OP = 1;                                                 //电池给单片机供电PNP管漏电过去
  210.    init_PWM(0xff);
  211.   }

  212. if((AD_AV(4)>1.66)&(AD_AV(4)<2.05)) //电池挂载,电压范围5.0-5.8V,PWM D=0.3
  213.   {
  214.    
  215.    init_PWM(0xb3);                                         //        PWM D=0.3 0xb3 (D=0.1驱不动,表上无电流)
  216.    Bat_CR = 0;                                         //防冲完电后换电池
  217.    Bat_OP = 0;                                                 // 清除电池开路标志
  218.   }

  219.   //电池挂载,电压范围5.8-6.9V,PWM D=0.9/0.6
  220.   if((AD_AV(4)>=2.05)&(AD_AV(4)<=2.42))
  221.   {
  222.         
  223.         
  224.      init_PWM(0x19);                                          //PWM D=0.9  0x19
  225.    
  226.      Bat_OP = 0;                                                  // 清除电池开路标志

  227.          if(AD_AV(4)<2.27)                                              // Vbat  6.5V,窗口下端,放电至6.5V以下,充电红灯才会重新亮
  228.          {
  229.           Bit_RED_ON = 1;                         //红灯亮置“1”
  230.          }

  231.          if(Bit_RED_ON == 1)
  232.          {
  233.          Bat_CR = 0;                                              //防冲完电后换电池
  234.          }

  235.   }

  236. //电池挂载,电压范围6.9-8.0V,PWM D=0.3
  237.   if((AD_AV(4)>2.42)&(AD_AV(4)<=2.80))  
  238.    
  239.    {                                                                  //窗口比较,用7.0判6.9V
  240.         Delay_MS(10);

  241.     if (AD_AV(4)>2.35)                          //确定电池基本充到6.7V(窗口)
  242.      {
  243.    
  244.          Bat_OP = 0;                                          // 清除电池开路标志

  245.          init_PWM(0xb3);                                   //PWM D=0.3,绢流充电(电池老化后,维持电压)
  246.      }

  247.           if (AD_AV(4)>2.40)                       //确定电池基本充到7.0V(窗口)
  248.      {
  249.    
  250.          Bat_OP = 0;                                          // 清除电池开路标志
  251.      Bit_RED_ON = 1;
  252.      }
  253.          if(Bit_RED_ON == 1)
  254.          {
  255.           Bat_CR = 1;                     //充电完毕,红色指示灯关闭
  256.          }

  257.           if(AD_AV(4)>2.52)
  258.           {
  259.            init_PWM(0xff);                                   //Vbat 7.2V PWM D=0  (电池老化后,小电流仍会使电压虚高电压)
  260.           }
  261.    
  262.         }

  263.   if(AD_AV(4)>2.80)                   //电池开路,电压范围8V,PWM D=0.75
  264.     {
  265.      
  266.            if        ( AD_AV(4)>2.80)
  267.           {
  268.            Bat_OP = 1;                                      //电池开路标志置 ‘1’
  269.        init_PWM(0x40);                              //PWM 0x40 D=0.75
  270.           }

  271.      }

  272.   //状态指示灯


  273.   LEDG = 0 ;                          //主电绿灯亮   

  274.   if (Bat_CR == 0)                                      //充电未完成
  275.     {
  276.             LEDR = 0;                                              // 指示红灯亮
  277.      LEDY = 1;                                              //指示黄灯灭  
  278.     }

  279.   if(Bat_CR == 1)                                    //充电完成
  280.     {
  281.            LEDR = 1;                                            // 指示红灯灭
  282.      LEDY = 0;                                                //指示黄灯亮  
  283.     }
  284.   if (Bat_OP == 0)                                           //电池开路
  285.     {
  286.      LEDY = 1;                                                //指示黄灯灭
  287.     }
  288.   if (Bat_OP == 1)                                           //电池开路
  289.     {
  290.      LEDR = 1;                                            // 指示红灯灭
  291.      LEDY = 0;                                                //指示黄灯亮
  292.     }



  293. }

  294. //中断初始化
  295. void Init_Inte(void)                //中断初始化
  296. {
  297. EA  = 1;                           //开总中断
  298. IT0 = 1;                           //下降沿触发中断
  299. EX0 = 1;                           //开外部0中断
  300. }


  301. //中断0响应
  302. void Inter0(void) interrupt 0         //外部中断0程序
  303. {
  304. SW_ON_Bit = 1 ;                      //开关按下标志置“1”                    
  305. }

  306. //按键按下判断
  307. void SW_ON_CHAR(void)
  308. {

  309. if( SW_ON_Bit == 1)                                 //按钮确定按下
  310. {
  311.    VINT0 = 1;                        //端口置“1”好判断
  312.    _nop_();
  313.    _nop_();
  314.    _nop_();                                                        //三个空周期,待电平稳定

  315. if(VINT0 == 0)                                            //按钮按下
  316.   {
  317.   Delay_MS(10);

  318.   if(VINT0 == 0)                                        //确定按钮按下
  319.   {
  320.    Bat_CH_DCH = 1;                  //放电标志置“1”
  321.   }
  322.   }
  323. }
  324. }
  325. //按钮松开判断
  326. void SW_OFF_CHAR(void)
  327. {

  328. if( SW_ON_Bit == 1)                            //确定之前有开关按下
  329. {
  330.    VINT0 = 1;                       //端口置“1”好判断
  331.    _nop_();
  332.    _nop_();
  333.    _nop_();                                                        //三个空周期,待电平稳定

  334. if(VINT0 == 1)                                                //INT0电平为高
  335.   {
  336.   Delay_MS(10);
  337.   if(VINT0 == 1)                                        //确定按钮松开,放电标志置"0"
  338.    {
  339.      SW_ON_Bit = 0;                                        //按钮按下标志清除

  340.      if(Bat_DCH_Wait == 0)                    //防止判断天黑绿灯闪烁时按钮按下时序混乱
  341.            {
  342.              Bat_CH_DCH = 0;
  343.        }                     
  344.    }         
  345.   }
  346. }
  347. }


  348. //放电子程序
  349. void Bat_DCH(void)
  350. {
  351.   float VCC_DCH;                          //设定放电基准电压
  352.   float DCH_AD_AV4;                                      //放电电池采样电压

  353.   Bat_Sen_SW = 1;                  //允许电池电压检测
  354.   Bat_DCH_SW = 1;                  //电池放电开关开启

  355.   Bat_DCH_Bit = 1;                 //放电标志置“1”

  356.   init_PWM(0xff);                                   //设置PWM后端口输出0不好使了,避免按钮测试放电电流有差异
  357.   LEDG_Flash = 0;                  //等待状态切换到放电状态,禁止LEDG闪烁

  358.   LEDR = 1;                                                   //三色指示灯全灭
  359.   LEDG = 1;
  360.   LEDY = 1;   
  361.   
  362.   //放电保护

  363.   VCC_DCH = (1024*2.5)/AD_AV(2);          //计算放电基准电压
  364.   DCH_AD_AV4 = AD_AV(4)*VCC_DCH/1024;     //放电基准电压下电池电压

  365.   if(DCH_AD_AV4<1.82)                                      //电池电压小于5.2V
  366.          {
  367.       Bat_DCH_SW = 0;                     //电池放电开关关闭,电池停止放电
  368.           MUC_POWER  = 0;                                          //否则检测太阳能板无电,还是继续进入放电状态
  369.          }
  370.                                  
  371. }


  372. //主程序
  373. void main(void)
  374. {
  375. init_AD();                         //AD初始化
  376. Timer_init();                                                //定时器初始化
  377. Init_Inte();                                                //中断初始化

  378. Power_Star();                      //开机检测外接电源
  379. Bat_Star();                                                //开机电池检测

  380. MUC_POWER = 1;                     //中断响应,电池来不及供电

  381. P3M0 = 0x00;                                            // 0000 0000
  382. P3M1 = 0xfb;                                       // 1111 1011

  383. while(1)
  384. {

  385.    Power_OFF();                                            //判断是否黑天
  386.    SW_ON_CHAR();                                         //判断按钮是否按下
  387.    SW_OFF_CHAR();                                         //判断按钮是否松开

  388.    if(Bat_CH_DCH==0)
  389.    {
  390.     Bat_CH();                                                //电池充电
  391.    }

  392.    if(Bat_CH_DCH==1)
  393.    {
  394.     Bat_DCH();                                                //电池放电
  395.    }

  396.    if(Bat_CH_DCH==2)                        
  397.    {                                                        
  398.      Bat_CH_DCH_Wait();                                //充放电切换等待
  399.    }

  400. }
复制代码

全部完整代码: SOFT.rar (47.09 KB, 下载次数: 308)

评分

参与人数 2黑币 +20 收起 理由
tieq1952 + 10 很给力!
练氏 + 10

查看全部评分

回复

使用道具 举报

ID:141494 发表于 2016-10-14 22:35 | 显示全部楼层
谢谢分享!!收藏!!
回复

使用道具 举报

ID:140183 发表于 2017-8-3 20:07 | 显示全部楼层
谢谢啦!!!!!!!!!
回复

使用道具 举报

ID:224560 发表于 2017-8-3 23:57 | 显示全部楼层
学习了。。。。。。。。
回复

使用道具 举报

ID:241976 发表于 2017-10-23 00:34 | 显示全部楼层
学习了。。。。。。。。
回复

使用道具 举报

ID:249545 发表于 2017-12-27 09:57 | 显示全部楼层
光电池板是充6V铅畜电池的,感觉老师制做的作品相当不错,有图有真相有源代码,是HEI坛良心作品!
但是鄙人私下也认为外围元件有些复杂,对DIY爱好者来讲有些望而生畏,恐难成功DIY.请教老师升级一下外围,能不能做简洁一些.
回复

使用道具 举报

ID:159977 发表于 2018-1-13 11:12 | 显示全部楼层
谢谢楼主分享
回复

使用道具 举报

ID:253767 发表于 2018-1-14 08:21 | 显示全部楼层
谢谢分享,学习了
回复

使用道具 举报

ID:312332 发表于 2018-4-20 13:13 | 显示全部楼层
顶贴,谢谢楼主
回复

使用道具 举报

ID:162514 发表于 2018-4-22 20:45 | 显示全部楼层
收了,谢谢!
回复

使用道具 举报

ID:271166 发表于 2018-5-12 16:30 | 显示全部楼层
谢谢楼主分享
回复

使用道具 举报

ID:313725 发表于 2018-5-16 14:51 | 显示全部楼层
谢谢楼主分享
回复

使用道具 举报

ID:271166 发表于 2018-5-19 15:59 | 显示全部楼层
谢谢分享!!收藏!!
回复

使用道具 举报

ID:254251 发表于 2018-5-22 13:28 | 显示全部楼层
谢谢分享要充12V电瓶应改哪里啊
回复

使用道具 举报

ID:389836 发表于 2018-8-25 08:49 | 显示全部楼层
楼主,有MPPT的吗
回复

使用道具 举报

ID:140183 发表于 2019-2-20 14:11 | 显示全部楼层
谢谢分享!下载学习学习.
回复

使用道具 举报

ID:490264 发表于 2019-3-16 16:29 | 显示全部楼层
为什么SOFT里边的代码不能打开
回复

使用道具 举报

ID:490264 发表于 2019-3-16 16:37 | 显示全部楼层
太阳能充放电控制器  这个C文件 用什么打开哇
回复

使用道具 举报

ID:71807 发表于 2019-7-13 08:31 | 显示全部楼层
厉害了!
回复

使用道具 举报

ID:429789 发表于 2019-11-21 18:10 | 显示全部楼层
感谢分享
回复

使用道具 举报

ID:610295 发表于 2021-7-23 17:03 | 显示全部楼层
没有充电电流检测,电压检测这部分没有看懂。
回复

使用道具 举报

ID:557411 发表于 2021-7-28 16:54 | 显示全部楼层
非常好的学习案例,感谢分享!
回复

使用道具 举报

ID:1050999 发表于 2023-3-21 12:58 来自手机 | 显示全部楼层
改后的原理图是怎么样的
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表