久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 17286|回復: 8
打印 上一主題 下一主題
收起左側

自制18650電池容量檢測器

  [復制鏈接]
跳轉到指定樓層
樓主
ID:161768 發表于 2017-5-24 03:06 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
本文原作者為wosiyabo 版權歸作者所有
根據電池容量的mAh,可以計算電池的持續放電時間的電流數去確定電池的容量。以下用了一個STC12C5608AD去做檢測電池放電400mA的時間,再以公式400mA*時間=mAh

(注意,有保護板的測不到因為低于2.86V會斷電)


     
誰也沒想到德力普的2500mAh的電池竟然實測只有1860mAh........ 原理圖忘記加12MHz晶振了。。。請各位后期制作加上去吧。。單片機定時器1內用PWM輸出控制在~400mA以內,電壓降低時PWM提升幅度。已經調得很準了,不過溫漂會有少少誤差。
(剛開始時用電阻做負載,后來發現電壓降到3.3V左右時電流變成300幾毫安,后來才改成PWM模式保持電流在2.83V都可以400mA)

單片機源程序:
  1. #include "reg51.h"
  2. //#include
  3. #include "intrins.h"
  4. #define uchar unsigned char
  5. #define uint unsigned int
  6. #define ulong unsigned long
  7. #define ADC_POWER   0x80            //ADC電源控制位
  8. #define ADC_FLAG    0x10            //ADC完成標志
  9. #define ADC_START   0x08            //ADC起始控制位
  10. #define ADC_SPEEDLL 0x00            //540個時鐘
  11. #define ADC_SPEEDL  0x20            //360個時鐘
  12. #define ADC_SPEEDH  0x40            //180個時鐘
  13. #define ADC_SPEEDHH 0x60            //90個時鐘

  14. sfr CCON        =   0xD8;           //PCA control register
  15. sbit CCF0       =   CCON^0;         //PCA module-0 interrupt flag
  16. sbit CCF1       =   CCON^1;         //PCA module-1 interrupt flag
  17. sbit CR         =   CCON^6;         //PCA timer run control bit
  18. sbit CF         =   CCON^7;         //PCA timer overflow flag
  19. sfr CMOD        =   0xD9;           //PCA mode register
  20. sfr CL          =   0xE9;           //PCA base timer LOW
  21. sfr CH          =   0xF9;           //PCA base timer HIGH
  22. sfr CCAPM0      =   0xDA;           //PCA module-0 mode register
  23. sfr CCAP0L      =   0xEA;           //PCA module-0 capture register LOW
  24. sfr CCAP0H      =   0xFA;           //PCA module-0 capture register HIGH
  25. sfr PCAPWM0     =   0xF2;



  26. sfr AUXR        =   0x8e;               //輔助寄存器
  27. sfr P1ASF       =   0x9D;           //P1口第2功能控制寄存器
  28. sfr ADC_RES     =   0xBD;           //ADC高8位結果
  29. sfr ADC_CONTR  = 0xc5;
  30. sfr ADC_DATA   = 0xc6;
  31. sfr ADC_LOW2   = 0xbe;

  32. sfr P0M0  = 0x93;
  33. sfr P0M1  = 0x94;
  34. sfr P1M0  = 0x91;
  35. sfr P1M1  = 0x92;
  36. sfr P2M0  = 0x95;
  37. sfr P2M1  = 0x96;
  38. sfr P3M0  = 0xb1;
  39. sfr P3M1  = 0xb2;  

  40. typedef unsigned char BYTE;

  41. uchar code table[]="0123456789BatTime:V.mAh_";
  42. uchar time1,time2,time3,pwm1;
  43. uint fen=0,ad1=138,ad0;

  44. sbit P12 = P1^2;
  45. sbit P13 = P1^3;
  46. sbit LED = P3^2;  //背光腳H亮
  47. sbit  rs = P3^3;  //
  48. sbit POW = P3^7;  //PWM
  49. sbit  en = P3^5;  //
  50. sbit SPK = P3^4;  //蜂鳴器

  51. void InitADC();
  52. uint GetADCResult(BYTE ch);
  53. void Delayus(uint us);
  54. void Delayms(unsigned int ms);
  55. void write_com(uchar com);
  56. void write_dat(uchar dat);
  57. void init();
  58. void Timer0Init(void);

  59. /*----------------------------
  60. 讀取ADC結果
  61. ----------------------------*/
  62. uint GetADCResult(BYTE ch)
  63. {
  64.     ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ch | ADC_START;
  65.     _nop_();                        //等待4個NOP
  66.     _nop_();
  67.     _nop_();
  68.     _nop_();
  69.     while (!(ADC_CONTR & ADC_FLAG));//等待ADC轉換完成
  70.     ADC_CONTR &= ~ADC_FLAG;         //Close ADC
  71.         return (ADC_DATA*4+ADC_LOW2);        //adc_data*4的意思是左移兩位,4 = 2的2次方。
  72.                                     //然后左移后加上adc_low的值,這個值應該是adc轉換的低兩位。  

  73. //        ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ch | ADC_START;
  74.    // _nop_();                        //Must wait before inquiry
  75.    // _nop_();
  76.   // _nop_();
  77.    // _nop_();
  78.    // while (!(ADC_CONTR & ADC_FLAG));//Wait complete flag
  79.    // ADC_CONTR &= ~ADC_FLAG;         //Close ADC
  80.     //return ADC_DATA;                //Return ADC result         */

  81. }

  82. /*----------------------------
  83. 初始化ADC
  84. ----------------------------*/
  85. void InitADC()
  86. {
  87.     P1 = P1M0 = P1M1 = 0x03;        //Set all P1 as Open-Drain mode
  88.         ADC_RES = 0;
  89.     ADC_DATA = 0;                   //Clear previous result
  90.         ADC_LOW2 = 0;
  91.     ADC_CONTR = ADC_POWER | ADC_SPEEDLL;
  92.     Delayms(2);                       //ADC上電并延時
  93. }

  94. void Delayus(uint us)                //@12.000MHz
  95. {
  96.    while(--us)
  97.    {
  98.                 _nop_();
  99.                 _nop_();
  100.                 _nop_();
  101.                 _nop_();
  102.    }
  103. }
  104. void Delayms(unsigned int ms)                //@12.000MHz
  105. {
  106.         unsigned char i, j;
  107.         while(--ms)
  108.         {
  109.                 i = 12;
  110.                 j = 169;
  111.                 do
  112.                 {
  113.                         while (--j);
  114.                 } while (--i);
  115.         }
  116. }
  117. void write_com(uchar com)
  118. {
  119.         rs=0;
  120.         en=0;
  121.         P2=com;
  122.         Delayms(2);
  123.         en=1;
  124.         Delayms(2);
  125.         en=0;
  126. }
  127. void write_dat(uchar dat)
  128. {
  129.         rs=1;
  130.         en=0;
  131.         P2=dat;
  132.         Delayms(2);
  133.         en=1;
  134.         Delayms(2);
  135.         en=0;
  136. }
  137. void init()
  138. {
  139.         Delayms(15);
  140.         write_com(0x38); //寫指令38H(不檢測忙信號)
  141.         Delayms(5);
  142.         write_com(0x38); //寫指令38H(不檢測忙信號)
  143.         Delayms(5);
  144.         write_com(0x38); //寫指令38H(不檢測忙信號)
  145.         write_com(0x08); //寫指令08H:顯示關閉
  146.         write_com(0x01); //寫指令01H:顯示清屏
  147.       
  148.         write_com(0x06); //寫指令06H:顯示光標移動設置
  149.         write_com(0x0C); //寫指令0CH:顯示開及光標設置
  150. }

  151. void Timer0Init(void)                //2毫秒@12.000MHz
  152. {
  153.         AUXR &= 0x7F;                //定時器時鐘12T模式
  154.         TMOD &= 0xF0;                //設置定時器模式
  155.         TMOD |= 0x01;                //設置定時器模式
  156.         TL0 = 0x30;                //設置定時初值
  157.         TH0 = 0xF8;                //設置定時初值
  158.         TF0 = 0;                //清除TF0標志
  159.         TR0 = 0;                //定時器0開始計時
  160. }


  161. void Timer1Init(void)                //5毫秒@12.000MHz
  162. {
  163.         AUXR &= 0xBF;                //定時器時鐘12T模式
  164.         TMOD &= 0x0F;                //設置定時器模式
  165.         TMOD |= 0x10;                //設置定時器模式
  166.         TL1 = 0x78;                //設置定時初值
  167.         TH1 = 0xEC;                //設置定時初值
  168.         TF1 = 0;                //清除TF1標志
  169.         TR1 = 1;                //定時器1開始計時
  170. }


  171. void main()
  172. {      
  173.    bit q1=0,q2=0,q3=0;
  174.         uchar k1;
  175.         ulong ww=1667;
  176.         P0M0 = P0M1 = 0x00;
  177.         //P1M0 = 0x00;
  178.         //P1M1 = 0x00;
  179.         P2M0 = P2M1 = 0x00;
  180.         P3M1 = 0x94;
  181.         P3M0 = 0x00;
  182.         POW=0;
  183.         LED=1;
  184.         SPK=0;
  185.         init();
  186.         InitADC();
  187.         Timer0Init();
  188.         Timer1Init();
  189.         TR0 = 1;                        //timer0 start running
  190.     ET0 = 1;                        //enable timer0 interrupt
  191.     //TR1 = 1;                        //timer1 start running
  192.     //ET1 = 1;                        //enable timer1 interrupt
  193.     EA = 1;                         //open global interrupt switch
  194.                   
  195.         for(k1=255;k1>0;k1--)
  196.            {
  197.                    SPK=~SPK;
  198.                 Delayus(k1);
  199.            }   
  200.            SPK=0;

  201.           write_com(0x80); //80為上排第一個
  202.           write_dat(table[10]);
  203.           write_dat(table[11]);
  204.           write_dat(table[12]);
  205.           write_dat(table[12]);
  206.           write_dat(table[17]);
  207.           write_com(0xC0); //C0為下排第一個
  208.           write_dat(table[13]);
  209.           write_dat(table[14]);
  210.           write_dat(table[15]);
  211.           write_dat(table[16]);
  212.           write_dat(table[17]);
  213.           write_com(0xC0+6);
  214.           write_dat(table[0]);
  215.           write_dat(table[0]);
  216.           write_dat(table[17]);
  217.           write_dat(table[0]);
  218.           write_dat(table[0]);
  219.           write_dat(table[17]);
  220.           write_dat(table[0]);
  221.           write_dat(table[0]);
  222.         while(1)
  223.         {


  224.           while(1)
  225.           {

  226.            if(EA==1)
  227.               {
  228.                         write_com(0xC0+13);
  229.                         write_dat(table[time1%10/1]);
  230.                         write_com(0xC0+12);
  231.                         write_dat(table[time1%100/10]);
  232.                         write_com(0xC0+10);
  233.                         write_dat(table[time2%10/1]);
  234.                         write_com(0xC0+9);
  235.                         write_dat(table[time2%100/10]);
  236.                         write_com(0xC0+7);
  237.                         write_dat(table[time3%10/1]);
  238.                         write_com(0xC0+6);
  239.                         write_dat(table[time3%100/10]);
  240.               }


  241.          
  242.          
  243.           if(q1==0&time1==2)
  244.              {
  245.                         write_com(0x85);
  246.                         write_dat(table[ad0%1000/100]);
  247.                         write_com(0x86);
  248.                         write_dat(table[19]);
  249.                         write_com(0x87);
  250.                         write_dat(table[ad0%100/10]);
  251.                         write_com(0x88);
  252.                         write_dat(table[ad0%10/1]);
  253.                         write_com(0x89);
  254.                         write_dat(table[18]);
  255.                         q1=1;                              

  256.                                    for(k1=0;k1<255;k1++)
  257.                            {
  258.                                    SPK=~SPK;
  259.                                 Delayus(150);
  260.                            }
  261.                                 Delayms(100);
  262.                                    for(k1=0;k1<255;k1++)
  263.                            {
  264.                                    SPK=~SPK;
  265.                                 Delayus(150);
  266.                            }
  267.                             SPK=0;
  268.                                 CCON = 0;                       //Initial PCA control register
  269.                                                                 //PCA timer stop running
  270.                                                                 //Clear CF flag
  271.                                                                 //Clear all module interrupt flag
  272.                                 CL = 0;                         //Reset PCA base timer
  273.                                 CH = 0;
  274.                                 CMOD = 0x02;                    //Set PCA timer clock source as Fosc/2
  275.                                                                 //Disable PCA timer overflow interrupt
  276.                                 CCAP0H = CCAP0L = 0xFF;         //PWM0 port output 50% duty cycle square wave
  277.                                 CCAPM0 = 0x42;                  //PCA module-0 work in 8-bit PWM mode and no PCA interrupt
  278.                               
  279.                                 CR = 1;                         //PCA timer start run
  280.                             TR0 = 1;
  281.                                 ET1 = 1;
  282.                }      

  283.                         write_com(0x8B);
  284.                         write_dat(table[ad0%1000/100]);
  285.                         write_com(0x8C);
  286.                         write_dat(table[19]);
  287.                         write_com(0x8D);
  288.                         write_dat(table[ad0%100/10]);
  289.                         write_com(0x8E);
  290.                         write_dat(table[ad0%10/1]);
  291.                         write_com(0x8F);
  292.                         write_dat(table[18]);

  293.           if(fen>=1)LED=0;
  294.           if(ad0<=286)q3=1;
  295.            while(q3==1)
  296.            {
  297.                         for(k1=0;k1<100;k1++)
  298.                            {
  299.                                    SPK=~SPK;
  300.                                 Delayus(110);
  301.                            }
  302.                                 SPK=0;                        
  303.                                 LED=~LED;
  304.                                 CCAP0H = CCAP0L = 0xFF;
  305.                                 POW=0;
  306.                                 EA=0;
  307.                                 Delayms(500);
  308.                         ad0=GetADCResult(0);
  309.                         write_com(0x8B);
  310.                         write_dat(table[ad0%1000/100]);
  311.                         write_com(0x8C);
  312.                         write_dat(table[19]);
  313.                         write_com(0x8D);
  314.                         write_dat(table[ad0%100/10]);
  315.                         write_com(0x8E);
  316.                         write_dat(table[ad0%10/1]);
  317.                         write_com(0x8F);
  318.                         write_dat(table[18]);
  319.                  if(!q2)
  320.                  {      
  321.                    ww*=fen;
  322.                    ww*=4;
  323.                     write_com(0xC0+0);
  324.                         write_dat(table[23]);
  325.                         write_com(0xC0+1);
  326.                         write_dat(table[23]);
  327.                     write_com(0xC0+2);
  328.                         write_dat(table[23]);
  329.                     write_com(0xC0+3);
  330.                         write_dat(table[23]);
  331.                     write_com(0xC0+4);
  332.                         write_dat(table[23]);
  333.                     write_com(0xC0+5);
  334.                         write_dat(table[23]);
  335.                         write_com(0xC0+6);
  336.                         write_dat(table[23]);
  337.                         write_com(0xC0+7);
  338.                         write_dat(table[ww%100000000/10000000]);
  339.                         write_com(0xC0+8);
  340.                         write_dat(table[ww%10000000/1000000]);
  341.                         write_com(0xC0+9);
  342.                         write_dat(table[ww%1000000/100000]);
  343.                         write_com(0xC0+10);
  344.                         write_dat(table[ww%100000/10000]);
  345.                         write_com(0xC0+11);
  346.                         write_dat(table[ww%10000/1000]);
  347.                         write_com(0xC0+12);
  348.                         write_dat(table[20]);
  349.                         write_com(0xC0+13);
  350.                         write_dat(table[21]);
  351.                         write_com(0xC0+14);
  352.                         write_dat(table[22]);
  353.                         Delayms(1000);
  354.                 q2=1;
  355.                  }
  356.            }

  357.                  
  358.           }

  359.         }  
  360. }
  361. void tm0_isr() interrupt 1 using 1
  362. {
  363.   static uchar i1,i2;
  364.         TL0 = 0x30;                //設置定時初值
  365.         TH0 = 0xF8;                //設置定時初值
  366.         i1++;
  367.         if(i1>=50)
  368.         {
  369.           i1=0;
  370.           i2++;
  371.           if(i2>=10)
  372.                   {
  373.                    i2=0;
  374.                    time1++;
  375.                   if(time1>=60)
  376.                          {
  377.                            time1=0;
  378.                            time2++;
  379.                            fen++;
  380.                           if(time2>=60)
  381.                                   {
  382.                                     time2=0;
  383.                                         time3++;
  384.                                         if(time3>=24)time3=0;
  385.                                   }
  386.                           }
  387.                           }
  388.         }
  389.    ad0=GetADCResult(0);      
  390. }

  391. void tm1_isr() interrupt 3 using 1
  392. {
  393.         TL1 = 0x78;                //設置定時初值
  394.         TH1 = 0xEC;                //設置定時初值
  395.         if(ad0>=428)CCAP0H = CCAP0L = 142;
  396.         if(ad0<=427&&ad0>424)CCAP0H = CCAP0L = 142;
  397.         if(ad0<=424&&ad0>420)CCAP0H = CCAP0L = 141;
  398.         if(ad0<=420&&ad0>416)CCAP0H = CCAP0L = 140;
  399.         if(ad0<=416&&ad0>412)CCAP0H = CCAP0L = 139;
  400.         if(ad0<=412&&ad0>408)CCAP0H = CCAP0L = 138;
  401.         if(ad0<=408&&ad0>404)CCAP0H = CCAP0L = 137;
  402.         if(ad0<=404&&ad0>400)CCAP0H = CCAP0L = 136;
  403.         if(ad0<=400&&ad0>396)CCAP0H = CCAP0L = 135;
  404.         if(ad0<=396&&ad0>392)CCAP0H = CCAP0L = 134;
  405.         if(ad0<=392&&ad0>388)CCAP0H = CCAP0L = 132;//
  406.         if(ad0<=388&&ad0>384)CCAP0H = CCAP0L = 131;
  407.         if(ad0<=384&&ad0>380)CCAP0H = CCAP0L = 129;
  408.         if(ad0<=380&&ad0>376)CCAP0H = CCAP0L = 128;
  409.         if(ad0<=376&&ad0>372)CCAP0H = CCAP0L = 127;
  410.         if(ad0<=372&&ad0>368)CCAP0H = CCAP0L = 126;//
  411.         if(ad0<=368&&ad0>364)CCAP0H = CCAP0L = 125;
  412.         if(ad0<=364&&ad0>360)CCAP0H = CCAP0L = 123;
  413.         if(ad0<=360&&ad0>356)CCAP0H = CCAP0L = 122;
  414.         if(ad0<=356&&ad0>352)CCAP0H = CCAP0L = 120;
  415.         if(ad0<=352&&ad0>348)CCAP0H = CCAP0L = 119;
  416.         if(ad0<=348&&ad0>344)CCAP0H = CCAP0L = 117;
  417.         if(ad0<=344&&ad0>340)CCAP0H = CCAP0L = 116;
  418.         if(ad0<=340&&ad0>336)CCAP0H = CCAP0L = 114;
  419.         if(ad0<=336&&ad0>332)CCAP0H = CCAP0L = 113;
  420.         if(ad0<=332&&ad0>328)CCAP0H = CCAP0L = 111;
  421.         if(ad0<=328&&ad0>324)CCAP0H = CCAP0L = 109;
  422.         if(ad0<=324&&ad0>320)CCAP0H = CCAP0L = 108;
  423.         if(ad0<=320&&ad0>316)CCAP0H = CCAP0L = 106;
  424.         if(ad0<=316&&ad0>312)CCAP0H = CCAP0L = 105;
  425.         if(ad0<=312&&ad0>308)CCAP0H = CCAP0L = 103;
  426.         if(ad0<=304&&ad0>300)CCAP0H = CCAP0L = 100;
  427.         if(ad0<=300&&ad0>296)CCAP0H = CCAP0L = 98;
  428.         if(ad0<=296&&ad0>292)CCAP0H = CCAP0L = 97;
  429.         if(ad0<=292&&ad0>288)CCAP0H = CCAP0L = 94;
  430.         if(ad0<=288&&ad0>284)CCAP0H = CCAP0L = 91;
  431.         if(ad0<=284)CCAP0H = CCAP0L = 0xFF;
  432.       
  433.         //CCAPM0 = 0x42;
  434. }
復制代碼
本文原作者為:wosiyabo 版權歸作者所有
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏14 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:204108 發表于 2017-5-24 06:36 | 只看該作者
樓主大神,我想自己動手焊接一個,能將所需的電子原件和加完晶振的電路圖告訴我嗎,不勝感激。!
回復

使用道具 舉報

板凳
ID:191195 發表于 2017-5-24 07:00 來自手機 | 只看該作者
好資料呀,支持一下。
回復

使用道具 舉報

地板
ID:140980 發表于 2017-5-27 08:18 | 只看該作者
沒有電流檢測電路,怎么保證電流的準確.
回復

使用道具 舉報

5#
ID:67537 發表于 2018-12-30 22:31 | 只看該作者
如果是一次性的鋰電池,有什么辦法測量容量
回復

使用道具 舉報

6#
ID:358930 發表于 2018-12-31 09:45 來自手機 | 只看該作者
yyhhgg 發表于 2018-12-30 22:31
如果是一次性的鋰電池,有什么辦法測量容量

好像是算內阻值的,電動車不是有那種短路一樣的容量表嗎?你去修車那看看就知道了
回復

使用道具 舉報

7#
ID:412684 發表于 2019-3-20 17:55 | 只看該作者
czvsgd 發表于 2017-5-24 06:36
**** 作者被禁止或刪除 內容自動屏蔽 ****

很給力
回復

使用道具 舉報

8#
ID:322197 發表于 2025-1-23 21:30 | 只看該作者
根據樓主程序改成STC8051U lcd12864,可以顯示,不能用

新建文本文檔.7z

4.44 KB, 下載次數: 0, 下載積分: 黑幣 -5

回復

使用道具 舉報

9#
ID:72088 發表于 2025-1-24 09:26 | 只看該作者
運放搭建個橫流放電,程序簡單了,測量也更準確了,
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 久久久久久免费毛片精品 | 在线一区视频 | 欧美日韩福利视频 | 色吧色综合 | 国产乱码高清区二区三区在线 | 久久久av | 亚洲男人天堂网 | 国产黄色网址在线观看 | 久久婷婷国产麻豆91 | 在线精品一区二区三区 | 夜夜操天天艹 | 成人欧美一区二区三区在线播放 | 日韩高清三区 | 亚洲欧美一区二区三区视频 | 亚洲综合婷婷 | 欧美精品在线播放 | 一区二区播放 | 精品国产乱码久久久久久丨区2区 | 久久亚洲欧美日韩精品专区 | 久久免费香蕉视频 | 免费一级毛片 | 国产欧美一区二区三区日本久久久 | 国产亚洲一区二区三区 | 天天插日日操 | 一区二区三区中文字幕 | 日本视频在线播放 | 精品久久久久一区二区国产 | 国产精品高清在线 | av网站在线播放 | 岛国毛片在线观看 | 天堂影院av | 国产精华一区 | 日韩精品一区二区不卡 | 国产高清久久久 | 91直接看| 天天爽夜夜骑 | 成人教育av | 国产精品久久久久aaaa | 亚洲国产精品区 | 欧美乱码精品一区二区三区 | 国产一区二区三区免费 |