找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 8395|回复: 21
打印 上一主题 下一主题
收起左侧

电池容量测试仪 Labview与STC单片机的结合(山山工作室)

  [复制链接]
跳转到指定楼层
楼主
在这个论坛上很久第一次发帖子,之前在数码之家发表过,17做的东西 先分享给大家共同讨论
前一段时间开源了一个智能小车,小车需要锂电池供电,家里一大堆电池,当使用的时候才发现好久没有容量大减,正好最近在研究labview,所以就做了1个来测试一下电池容量,其实原理非常简单,用单片机就能轻松搞定,为了高大上而且能为了能看到电池充电和放电的曲线所以就需要上位软件了,第一次用labview编程程序写的非常烂高手见谅了
功能:

上位机 labview  负责采集数据计时显示设置充放电截止电压和电池曲线图
下位机 stc125a60s2 负责ad检测电压电流串口通信
1.增加1602液晶,方便没有电脑的时候也可以测量电池容量
2.使用labview工作,电压电流同时显示在1602上面
1秒钟刷新一次电压,电流,容量,时间


由于手底下没有mos管所以暂时使用317进行横流放电
充电采用锂电池专用模块
通信 串口发送字符串
检测电压电流 Work_v_ad
充电    Work_v_cd
放电    Work_v_fd
关闭    Work_voff

电脑和单片机通信采用一个usb ttl下载器进行
ad采集为了准确,采用Tl431做标准基准源,还算比较准确的

电路图

没有上位软件也能显示容量,只不过没有曲线










程序
  1. #include<stc12c5a60s2.h>
  2. #include"stdio.h"
  3. #include"intrins.h"


  4. #define uint unsigned int
  5. #define uchar unsigned char


  6. sbit v_cd=P2^0;
  7. sbit v_fd=P2^1;
  8. sbit key=P2^2;
  9. sbit lcdrs=P2^3;
  10. sbit lcden=P2^4;


  11. int volt,aolt,curr,mah;
  12. uchar key_flag=1;
  13. uchar num;
  14. uchar v_shi,v_ge,v_xiao1,v_xiao2;
  15. uchar a_shi,a_ge,a_xiao1,a_xiao2;
  16. uchar h_shi,h_ge,h_xiao1,h_xiao2;
  17. uchar t_shi,t_ge,t_xiao1,t_xiao2;
  18. uchar s,g,x1,x2;
  19. uchar data table[12]; //暂存数组,可以将10改为你需要的数值
  20. uint i=0;
  21. uchar code table1[]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39};
  22. bit com_flag;
  23. uint time;
  24. uint num1,num2;
  25. bit time_flag;
  26. bit shan_flag;
  27. bit lcd_flag;




  28. void AD_init();
  29. unsigned int AD_get(unsigned char channel);
  30. float AD_work(unsigned char channel);
  31. void delayms(uint z);
  32. void delay(unsigned int a); //延时约1ms
  33. void UART_init(void);               //初始化函数
  34. void senddata(uchar dat);
  35. //void uart_sendstring(uchar *upStr);
  36. void write_com(uchar com)    ;
  37. void write_data(uchar date);
  38. void lcd_init();
  39. void time_init();






  40. void delayms(uint z)
  41. {
  42.         uint x,y;
  43.         for(x=z;x>0;x--)
  44.             for(y=110;y>0;y--);
  45. }      


  46. /**********************************************************/


  47. void UART_init(void)               //初始化函数
  48. {
  49.     SCON = 0x50;
  50.     TMOD = 0x21;
  51.     TH1  = 0xFD;                  //波特率9600
  52.     TL1  = 0xFD;
  53.     TR1  = 1;
  54.     ES   = 1;
  55.     EA   = 1;
  56. //    TI   =0;
  57. //    REN = 1;


  58. }
  59. /**********************************************************/


  60. void senddata(uchar dat)
  61. {               


  62.     ES = 0;                       //关串口中断
  63.     TI = 0;                       //将串口发送完成中断请求标志清零
  64.     SBUF = dat;                //写数据到发送缓冲区
  65.     while(!TI);                   //等待发送完成
  66.     TI = 0;                       //将串口发送完成中断请求标志清零
  67.     ES = 1;                   //将串口发送完成中断请求标志清零
  68. }
  69. /* ***************************************************** */


  70. // 函数名称:UART_SendString()
  71. // 函数功能:发送字符串
  72. // 入口参数:待发送的字符串(*upStr)
  73. // 出口参数:无
  74. /* ***************************************************** *
  75. void uart_sendstring(uchar *upStr)
  76. {
  77.     while(*upStr)                    // 检测是否发送完毕
  78.     {
  79.         senddata(*upStr++);   
  80.         // 调用UART_SendOneByte函数一个字节一个字节发送数据
  81.     }
  82. }
  83. /* ***************************************************** */      




  84. void delay(unsigned int a) //延时约1ms
  85. {
  86.         unsigned int i;
  87.         while (--a!=0)
  88.         for(i=600;i>0;i--);   //1T单片机i=600,若是12T单片机i=125
  89. }


  90. /*************************************************************/
  91. void write_com(uchar com)            //1602 lcd
  92. {
  93.     lcdrs=0;
  94.     lcden=1;
  95.     P0=com;
  96.     delayms(5);
  97.     lcden=0;
  98. }
  99. /**********************************************************/
  100. void write_data(uchar date)        //1602 lcd
  101. {
  102.     lcdrs=1;
  103.     lcden=1;
  104.     P0=date;
  105.     delayms(5);
  106.     lcden=0;
  107. }


  108. /**********************************************************/
  109. void lcd_init()    //lcd初始化
  110. {
  111.      write_com(0x38);
  112.      delayms(20);
  113.      write_com(0x38);
  114.      delayms(20);
  115.             write_com(0x0c);
  116.      delayms(20);
  117.             write_com(0x06);
  118.      delayms(20);
  119.             write_com(0x01);
  120.      delayms(20);
  121. }




  122. void AD_init()
  123. {
  124.         P1ASF=0xff; //P1口全部作为模拟功能AD使用
  125.         ADC_RES=0;   //清零转换结果寄存器高8位
  126.         ADC_RESL=0; //清零转换结果寄存器低2位
  127.         ADC_CONTR=0x80;//开启AD电源
  128.         delay(2);   //等待1ms,让AD电源稳定
  129. }




  130. void time_init()
  131. {   
  132.         TH0=(65536-45872)/256;
  133.         TL0=(65536-45872)%256;
  134.         EA=1;
  135.         ET0=1;
  136.         TR0=1;
  137.         
  138. }
  139. void lcd_display()
  140. {
  141.         
  142.         volt=((AD_get(0)*2.5)/AD_get(7))*2*1000;
  143.         v_shi=volt/1000;
  144.         v_ge=volt%1000/100;
  145.         v_xiao1=volt%100/10;
  146.         v_xiao2=volt%10;
  147.         
  148.         write_com(0x82);
  149.         write_data(table1[v_shi]);
  150.         write_com(0x83);
  151.         write_data('.');
  152.         write_com(0x84);
  153.         write_data(table1[v_ge]);
  154.         write_com(0x85);
  155.         write_data(table1[v_xiao1]);
  156.         write_com(0x86);
  157.         write_data(table1[v_xiao2]);
  158.         write_com(0x87);
  159.         write_data('V');
  160.    
  161.         aolt=(AD_get(2)*0.002)*1000;
  162.         a_shi=aolt/1000;
  163.         a_ge=aolt%1000/100;
  164.         a_xiao1=aolt%100/10;
  165.         a_xiao2=aolt%10;
  166.         
  167.         write_com(0x89);
  168.         write_data(table1[a_shi]);
  169.         write_com(0x8a);
  170.         write_data('.');
  171.         write_com(0x8b);
  172.         write_data(table1[a_ge]);
  173.         write_com(0x8c);
  174.         write_data(table1[a_xiao1]);
  175.         write_com(0x8d);
  176.         write_data(table1[a_xiao2]);
  177.         write_com(0x8e);
  178.         write_data('A');   
  179.         
  180.         write_com(0xC0);   
  181.         write_data(' ');
  182.         
  183.         h_shi=mah/1000;
  184.         h_ge=mah%1000/100;
  185.         h_xiao1=mah%100/10;
  186.         h_xiao2=mah%10;
  187.    
  188.         write_com(0xc1);
  189.         write_data(table1[h_shi]);
  190.         write_com(0xc2);
  191.         write_data(table1[h_ge]);
  192.         write_com(0xc3);
  193.         write_data(table1[h_xiao1]);
  194.         write_com(0xc4);
  195.         write_data(table1[h_xiao2]);
  196.         
  197.         write_com(0xc5);
  198.         write_data('M');
  199.         write_com(0xc6);
  200.         write_data('A');
  201.         write_com(0xc7);
  202.         write_data('H');
  203.         
  204.         write_com(0xc8);
  205.         write_data(' ');
  206.         write_com(0xc9);
  207.         write_data('T');
  208.         write_com(0xca);
  209.         write_data('=');
  210.         
  211.         t_shi=time/100;
  212.         t_ge=time%100/10;
  213.         t_xiao1=time%10;
  214.         write_com(0xcb);
  215.         write_data(table1[t_shi]);
  216.         write_com(0xcc);
  217.         write_data(table1[t_ge]);
  218.         write_com(0xcd);
  219.         write_data(table1[t_xiao1]);
  220.         write_com(0xce);
  221.         write_data('M');


  222.         
  223. }


  224.    
  225. //    float AD_work(unsigned char channel)
  226. //    {
  227. //        float AD_val;     //定义处理后的数值AD_val为浮点数
  228. //        unsigned char i;
  229. //        for(i=0;i<100;i++)
  230. //        AD_val+=AD_get(channel); //转换100次求平均值(提高精度)
  231. //        AD_val/=100;
  232. //    //    AD_val=(AD_val*2.5)/1024; //AD的参考电压是单片机上的5v,所以乘5即为实际电压值
  233. //        return AD_val;
  234. //    }




  235. void keysean()
  236. {
  237.         if(key==0)
  238.         {
  239.                 delayms(500);
  240.                 if(key==0)
  241.                 {
  242.                         key_flag++;
  243.                         if(key_flag>3)
  244.                             key_flag=1;
  245.                 }
  246.                 while(!key);
  247.         }
  248.         
  249.             if(key_flag==1)
  250.             {
  251.                     v_fd=1;
  252.                     v_cd=1;
  253.                     write_com(0x80);
  254.                     write_data(' ');
  255.                     num1=0;
  256.                     time_flag=0;
  257.             }
  258.             
  259.             if(key_flag==2)
  260.             {
  261.                     v_fd=1;
  262.                     v_cd=0;
  263.                     time=0;
  264.                     mah=0;
  265.                
  266.                 write_com(0x80);
  267.                 write_data('C');
  268.                 write_com(0x81);
  269.                 write_data(' ');
  270.                
  271.             }
  272.             
  273.             if(key_flag==3)
  274.             {
  275.                     v_cd=1;
  276.                     v_fd=0;
  277.                     time_flag=1;
  278.                     if(shan_flag==0)
  279.                     {
  280.                             write_com(0x80);
  281.                             write_data('F');
  282.                     }
  283.                     else
  284.                     {
  285.                             write_com(0x80);
  286.                             write_data(' ');


  287.                     }
  288.                     
  289.                     volt=((AD_get(0)*2.5)/AD_get(7))*2*1000;
  290.                     v_shi=volt/1000;
  291.                     v_ge=volt%1000/100;
  292.                
  293.                     if(v_shi==2)
  294.                     {
  295.                             v_fd=1;
  296.                             v_cd=1;
  297.                             time_flag=0;
  298.                             key_flag=1;
  299.                     }        
  300.                
  301.             }
  302.             
  303. }




  304. void main()
  305. {   
  306.         AD_init();
  307.         UART_init();
  308.         lcd_init();
  309.         time_init();   
  310.         v_cd=1;
  311.         v_fd=1;
  312.         
  313.         while(1)
  314.         {
  315.                 if(com_flag==0)
  316.                 keysean();
  317.                 if(lcd_flag==1)
  318.                 {
  319.                     lcd_display();
  320.                     lcd_flag=0;
  321.                 }
  322. //                senddata(table1[v_shi]);
  323. //                    senddata('-');
  324. //                    senddata(table1[key_flag]);
  325. //                    senddata(0x0d);
  326. //                    senddata(0x0a);
  327.                
  328.             
  329.         }
  330. }


  331. /**********************************************************/


  332. void interrupt_uart() interrupt 4
  333. {


  334.      
  335.           ES=0;    //关串口中断
  336.    
  337.           table[i]=SBUF;//命令存到命令数组
  338.             if(table[0]=='W')
  339.             i++;
  340.             else
  341.             i=0;
  342.             RI=0; //软件清除接收中断
  343.             ES=1;//开串口中断
  344.         if(i>8)      //如果接受字节大于8个开始检测接受字节后六位数据  Work_v_ad
  345.     {
  346.                 if(table[5]=='v'&&table[6]=='_'&&table[7]=='a'&&table[8]=='d')
  347.         {  
  348.                         volt=((AD_get(0)*2.5)/AD_get(7))*2*1000;
  349.                         v_shi=volt/1000;
  350.                         v_ge=volt%1000/100;
  351.                         v_xiao1=volt%100/10;
  352.                         v_xiao2=volt%10;
  353.                     
  354.                         senddata(table1[v_shi]);
  355.                         senddata('.');
  356.                         senddata(table1[v_ge]);
  357.                         senddata(table1[v_xiao1]);
  358.                         senddata(table1[v_xiao2]);
  359.                         
  360.                         aolt=(AD_get(2)*0.002)*1000;
  361.                         a_shi=aolt/1000;
  362.                         a_ge=aolt%1000/100;
  363.                         a_xiao1=aolt%100/10;
  364.                         a_xiao2=aolt%10;
  365.                     
  366.                         senddata('_');
  367.                         if(a_shi>0)
  368.                         senddata(table1[a_shi]);
  369.                         senddata(table1[a_ge]);
  370.                         senddata(table1[a_xiao1]);
  371.                         senddata(table1[a_xiao2]);
  372.                         senddata(0x0d);
  373.                         senddata(0x0a);
  374.                         com_flag=1;
  375.                     
  376.                 }
  377.                 if(table[5]=='v'&&table[6]=='_'&&table[7]=='a'&&table[8]=='a')
  378.         {  
  379.                         aolt=(AD_get(2)*0.002)*1000;
  380.                         a_shi=aolt/1000;
  381.                         a_ge=aolt%1000/100;
  382.                         a_xiao1=aolt%100/10;
  383.                         a_xiao2=aolt%10;
  384.                     
  385.                         senddata(table1[a_shi]);
  386.                         //senddata('.');
  387.                         senddata(table1[a_ge]);
  388.                         senddata(table1[a_xiao1]);
  389.                         senddata(table1[a_xiao2]);
  390.                         senddata(0x0d);
  391.                         senddata(0x0a);
  392.                         com_flag=1;
  393.                         
  394.                 }
  395.                 if(table[5]=='v'&&table[6]=='_'&&table[7]=='c'&&table[8]=='d')
  396.         {
  397.                             com_flag=1;
  398.                             v_fd=1;
  399.                             v_cd=0;
  400.                 }
  401.                
  402.                 if(table[5]=='v'&&table[6]=='_'&&table[7]=='f'&&table[8]=='d')
  403.         {
  404.                             com_flag=1;
  405.                             v_cd=1;
  406.                             v_fd=0;
  407.                 }
  408.                
  409.                 if(table[5]=='v'&&table[6]=='o'&&table[7]=='f'&&table[8]=='f')
  410.         {
  411.                             com_flag=1;
  412.                             v_cd=1;
  413.                             v_fd=1;
  414.                            
  415.                 }
  416.                 i=0;   
  417.         }
  418.             
  419. }

  420. void T0_time() interrupt 1
  421. {
  422.         TH0=(65536-45872)/256;
  423.         TL0=(65536-45872)%256;
  424.         num2++;
  425.         if(num2==20)
  426.             {
  427.                     num2=0;
  428.                     shan_flag=~shan_flag;
  429.                     lcd_flag=1;
  430.             }
  431.         
  432.         if(time_flag==1)
  433.         {
  434.                 num1++;
  435.                 if(num1==1200)
  436.                 {
  437.                         num1=0;
  438.                         time++;
  439.                         if(time==1000)
  440.                             time=0;
  441.                         mah=(AD_get(2)*0.002)*1000*time/60;
  442.                         
  443.                 }
  444.         }
  445.         
  446.    
  447. }
复制代码

程序写的比较烂,大家参考一下吧

76_774325_8b85ba80d92f6fb.jpg (266.12 KB, 下载次数: 85)

76_774325_8b85ba80d92f6fb.jpg

76_774325_9e899116f435b88.jpg (187.92 KB, 下载次数: 68)

76_774325_9e899116f435b88.jpg

76_774325_6299be69059ff6d.jpg (88.42 KB, 下载次数: 70)

76_774325_6299be69059ff6d.jpg

76_774325_a2193f9123c21dc.jpg (171.31 KB, 下载次数: 66)

76_774325_a2193f9123c21dc.jpg

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏11 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:63042 发表于 2018-7-19 14:27 | 只看该作者
写错1个字 是17年作的
回复

使用道具 举报

板凳
ID:373684 发表于 2018-7-19 20:19 | 只看该作者
楼主这么厉害,,,单片机和Labview都懂。这2个我都在学。
回复

使用道具 举报

地板
ID:292069 发表于 2018-7-29 09:52 | 只看该作者
楼主有电路图和元器件清单吗,也想做一个
回复

使用道具 举报

5#
ID:63042 发表于 2018-7-30 14:44 | 只看该作者
wandier1 发表于 2018-7-29 09:52
楼主有电路图和元器件清单吗,也想做一个

帖子第一张图片就是电路图,没几个元器件都在上面了
回复

使用道具 举报

6#
ID:150982 发表于 2018-9-12 16:35 | 只看该作者
有没有上位机的软件。留个qq联系你
回复

使用道具 举报

7#
ID:357599 发表于 2018-11-2 21:56 | 只看该作者
大神啊!膜拜!求上位机的源程序。
回复

使用道具 举报

8#
ID:357599 发表于 2018-11-2 21:57 | 只看该作者
楼主上位机软件给一个吧,想学习一下!
回复

使用道具 举报

9#
ID:125719 发表于 2018-11-6 08:20 | 只看该作者
这个很厉害啊,值得学习
回复

使用道具 举报

10#
ID:303334 发表于 2018-11-6 09:47 | 只看该作者
这个好好学习一下。相当不错的资料
回复

使用道具 举报

11#
ID:65956 发表于 2018-11-7 13:20 | 只看该作者
很不错,学习了,有资料可下载参考吗
回复

使用道具 举报

12#
ID:65956 发表于 2018-11-15 13:37 | 只看该作者
你的程序在串口中断中作太多事,可能会影响到效率,另外能否提供上位机的具体协议
回复

使用道具 举报

13#
ID:335688 发表于 2018-12-27 08:20 | 只看该作者
谢谢楼主共享!求上位机软件,想学习一下~
回复

使用道具 举报

14#
ID:168431 发表于 2019-3-30 12:54 来自手机 | 只看该作者
可以上传一下上位机吗
回复

使用道具 举报

15#
ID:471632 发表于 2019-3-31 19:00 | 只看该作者
楼主不要谦虚了,程序再烂,只要实现功能就行了。当然,有空间可以提高的,世界上没有完美无缺的事情,微软的补丁不也是满天飞吗?
回复

使用道具 举报

16#
ID:467275 发表于 2019-5-28 22:07 | 只看该作者

可以上传一下上位机吗
回复

使用道具 举报

17#
ID:92810 发表于 2019-5-29 14:35 | 只看该作者
这个挺好玩的啊!!!!
回复

使用道具 举报

18#
ID:452731 发表于 2019-6-18 00:09 | 只看该作者
这个上位机蛮不错的
回复

使用道具 举报

19#
ID:210588 发表于 2019-6-21 08:07 | 只看该作者
楼主可以提供下原理图和上位机程序吗?
回复

使用道具 举报

20#
ID:599807 发表于 2019-8-28 11:13 | 只看该作者
大神 上位机软件可以发一个吗
回复

使用道具 举报

21#
ID:242941 发表于 2019-10-23 17:28 | 只看该作者
C程序编译不通过,好多报错
回复

使用道具 举报

22#
ID:434366 发表于 2019-11-26 18:18 | 只看该作者
学习了  挺好
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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