找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 9979|回復(fù): 21
打印 上一主題 下一主題
收起左側(cè)

電池容量測(cè)試儀 Labview與STC單片機(jī)的結(jié)合(山山工作室)

  [復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
#
ID:63042 發(fā)表于 2018-7-19 14:23 | 只看該作者 |只看大圖 回帖獎(jiǎng)勵(lì) |正序?yàn)g覽 |閱讀模式
在這個(gè)論壇上很久第一次發(fā)帖子,之前在數(shù)碼之家發(fā)表過,17做的東西 先分享給大家共同討論
前一段時(shí)間開源了一個(gè)智能小車,小車需要鋰電池供電,家里一大堆電池,當(dāng)使用的時(shí)候才發(fā)現(xiàn)好久沒有容量大減,正好最近在研究labview,所以就做了1個(gè)來測(cè)試一下電池容量,其實(shí)原理非常簡(jiǎn)單,用單片機(jī)就能輕松搞定,為了高大上而且能為了能看到電池充電和放電的曲線所以就需要上位軟件了,第一次用labview編程程序?qū)懙姆浅高手見諒了
功能:

上位機(jī) labview  負(fù)責(zé)采集數(shù)據(jù)計(jì)時(shí)顯示設(shè)置充放電截止電壓和電池曲線圖
下位機(jī) stc125a60s2 負(fù)責(zé)ad檢測(cè)電壓電流串口通信
1.增加1602液晶,方便沒有電腦的時(shí)候也可以測(cè)量電池容量
2.使用labview工作,電壓電流同時(shí)顯示在1602上面
1秒鐘刷新一次電壓,電流,容量,時(shí)間


由于手底下沒有mos管所以暫時(shí)使用317進(jìn)行橫流放電
充電采用鋰電池專用模塊
通信 串口發(fā)送字符串
檢測(cè)電壓電流 Work_v_ad
充電    Work_v_cd
放電    Work_v_fd
關(guān)閉    Work_voff

電腦和單片機(jī)通信采用一個(gè)usb ttl下載器進(jìn)行
ad采集為了準(zhǔn)確,采用Tl431做標(biāo)準(zhǔn)基準(zhǔn)源,還算比較準(zhǔn)確的

電路圖

沒有上位軟件也能顯示容量,只不過沒有曲線










程序
  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]; //暫存數(shù)組,可以將10改為你需要的數(shù)值
  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); //延時(shí)約1ms
  33. void UART_init(void);               //初始化函數(shù)
  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)               //初始化函數(shù)
  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;                       //關(guān)串口中斷
  63.     TI = 0;                       //將串口發(fā)送完成中斷請(qǐng)求標(biāo)志清零
  64.     SBUF = dat;                //寫數(shù)據(jù)到發(fā)送緩沖區(qū)
  65.     while(!TI);                   //等待發(fā)送完成
  66.     TI = 0;                       //將串口發(fā)送完成中斷請(qǐng)求標(biāo)志清零
  67.     ES = 1;                   //將串口發(fā)送完成中斷請(qǐng)求標(biāo)志清零
  68. }
  69. /* ***************************************************** */


  70. // 函數(shù)名稱:UART_SendString()
  71. // 函數(shù)功能:發(fā)送字符串
  72. // 入口參數(shù):待發(fā)送的字符串(*upStr)
  73. // 出口參數(shù):無
  74. /* ***************************************************** *
  75. void uart_sendstring(uchar *upStr)
  76. {
  77.     while(*upStr)                    // 檢測(cè)是否發(fā)送完畢
  78.     {
  79.         senddata(*upStr++);   
  80.         // 調(diào)用UART_SendOneByte函數(shù)一個(gè)字節(jié)一個(gè)字節(jié)發(fā)送數(shù)據(jù)
  81.     }
  82. }
  83. /* ***************************************************** */      




  84. void delay(unsigned int a) //延時(shí)約1ms
  85. {
  86.         unsigned int i;
  87.         while (--a!=0)
  88.         for(i=600;i>0;i--);   //1T單片機(jī)i=600,若是12T單片機(jī)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;   //清零轉(zhuǎn)換結(jié)果寄存器高8位
  126.         ADC_RESL=0; //清零轉(zhuǎn)換結(jié)果寄存器低2位
  127.         ADC_CONTR=0x80;//開啟AD電源
  128.         delay(2);   //等待1ms,讓AD電源穩(wěn)定
  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;     //定義處理后的數(shù)值A(chǔ)D_val為浮點(diǎn)數(shù)
  228. //        unsigned char i;
  229. //        for(i=0;i<100;i++)
  230. //        AD_val+=AD_get(channel); //轉(zhuǎn)換100次求平均值(提高精度)
  231. //        AD_val/=100;
  232. //    //    AD_val=(AD_val*2.5)/1024; //AD的參考電壓是單片機(jī)上的5v,所以乘5即為實(shí)際電壓值
  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;    //關(guān)串口中斷
  336.    
  337.           table[i]=SBUF;//命令存到命令數(shù)組
  338.             if(table[0]=='W')
  339.             i++;
  340.             else
  341.             i=0;
  342.             RI=0; //軟件清除接收中斷
  343.             ES=1;//開串口中斷
  344.         if(i>8)      //如果接受字節(jié)大于8個(gè)開始檢測(cè)接受字節(jié)后六位數(shù)據(jù)  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. }
復(fù)制代碼

程序?qū)懙谋容^爛,大家參考一下吧

76_774325_8b85ba80d92f6fb.jpg (266.12 KB, 下載次數(shù): 126)

76_774325_8b85ba80d92f6fb.jpg

76_774325_9e899116f435b88.jpg (187.92 KB, 下載次數(shù): 107)

76_774325_9e899116f435b88.jpg

76_774325_6299be69059ff6d.jpg (88.42 KB, 下載次數(shù): 117)

76_774325_6299be69059ff6d.jpg

76_774325_a2193f9123c21dc.jpg (171.31 KB, 下載次數(shù): 107)

76_774325_a2193f9123c21dc.jpg

評(píng)分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎(jiǎng)勵(lì)!

查看全部評(píng)分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏11 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

21#
ID:434366 發(fā)表于 2019-11-26 18:18 | 只看該作者
學(xué)習(xí)了  挺好
回復(fù)

使用道具 舉報(bào)

20#
ID:242941 發(fā)表于 2019-10-23 17:28 | 只看該作者
C程序編譯不通過,好多報(bào)錯(cuò)
回復(fù)

使用道具 舉報(bào)

19#
ID:599807 發(fā)表于 2019-8-28 11:13 | 只看該作者
大神 上位機(jī)軟件可以發(fā)一個(gè)嗎
回復(fù)

使用道具 舉報(bào)

18#
ID:210588 發(fā)表于 2019-6-21 08:07 | 只看該作者
樓主可以提供下原理圖和上位機(jī)程序嗎?
回復(fù)

使用道具 舉報(bào)

17#
ID:452731 發(fā)表于 2019-6-18 00:09 | 只看該作者
這個(gè)上位機(jī)蠻不錯(cuò)的
回復(fù)

使用道具 舉報(bào)

16#
ID:92810 發(fā)表于 2019-5-29 14:35 | 只看該作者
這個(gè)挺好玩的。。。!
回復(fù)

使用道具 舉報(bào)

15#
ID:467275 發(fā)表于 2019-5-28 22:07 | 只看該作者

可以上傳一下上位機(jī)嗎
回復(fù)

使用道具 舉報(bào)

14#
ID:471632 發(fā)表于 2019-3-31 19:00 | 只看該作者
樓主不要謙虛了,程序再爛,只要實(shí)現(xiàn)功能就行了。當(dāng)然,有空間可以提高的,世界上沒有完美無缺的事情,微軟的補(bǔ)丁不也是滿天飛嗎?
回復(fù)

使用道具 舉報(bào)

13#
ID:168431 發(fā)表于 2019-3-30 12:54 來自手機(jī) | 只看該作者
可以上傳一下上位機(jī)嗎
回復(fù)

使用道具 舉報(bào)

12#
ID:335688 發(fā)表于 2018-12-27 08:20 | 只看該作者
謝謝樓主共享!求上位機(jī)軟件,想學(xué)習(xí)一下~
回復(fù)

使用道具 舉報(bào)

11#
ID:65956 發(fā)表于 2018-11-15 13:37 | 只看該作者
你的程序在串口中斷中作太多事,可能會(huì)影響到效率,另外能否提供上位機(jī)的具體協(xié)議
回復(fù)

使用道具 舉報(bào)

10#
ID:65956 發(fā)表于 2018-11-7 13:20 | 只看該作者
很不錯(cuò),學(xué)習(xí)了,有資料可下載參考嗎
回復(fù)

使用道具 舉報(bào)

9#
ID:303334 發(fā)表于 2018-11-6 09:47 | 只看該作者
這個(gè)好好學(xué)習(xí)一下。相當(dāng)不錯(cuò)的資料
回復(fù)

使用道具 舉報(bào)

8#
ID:125719 發(fā)表于 2018-11-6 08:20 | 只看該作者
這個(gè)很厲害啊,值得學(xué)習(xí)
回復(fù)

使用道具 舉報(bào)

7#
ID:357599 發(fā)表于 2018-11-2 21:57 | 只看該作者
樓主上位機(jī)軟件給一個(gè)吧,想學(xué)習(xí)一下!
回復(fù)

使用道具 舉報(bào)

6#
ID:357599 發(fā)表于 2018-11-2 21:56 | 只看該作者
大神!膜拜!求上位機(jī)的源程序。
回復(fù)

使用道具 舉報(bào)

5#
ID:150982 發(fā)表于 2018-9-12 16:35 | 只看該作者
有沒有上位機(jī)的軟件。留個(gè)qq聯(lián)系你
回復(fù)

使用道具 舉報(bào)

地板
ID:63042 發(fā)表于 2018-7-30 14:44 | 只看該作者
wandier1 發(fā)表于 2018-7-29 09:52
樓主有電路圖和元器件清單嗎,也想做一個(gè)

帖子第一張圖片就是電路圖,沒幾個(gè)元器件都在上面了
回復(fù)

使用道具 舉報(bào)

板凳
ID:292069 發(fā)表于 2018-7-29 09:52 | 只看該作者
樓主有電路圖和元器件清單嗎,也想做一個(gè)
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:373684 發(fā)表于 2018-7-19 20:19 | 只看該作者
樓主這么厲害,,,單片機(jī)和Labview都懂。這2個(gè)我都在學(xué)。
回復(fù)

使用道具 舉報(bào)

樓主
ID:63042 發(fā)表于 2018-7-19 14:27 | 只看該作者
寫錯(cuò)1個(gè)字 是17年作的
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表