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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

用STC89C52制作的“鋰電池容量檢測器”

[復制鏈接]
跳轉到指定樓層
樓主
本帖最后由 ztzp 于 2025-7-6 12:07 編輯

初步設想,使用STC89C52單片機控制,利用該單片機T2的16位自動裝填初值功能,得到精確的1秒時鐘,每隔1秒累計所放電量(Q=It),放電負載使用自制的2A電子負載儀,放電電流由負載儀設定(先以100mA為準),則每1秒所放的電量為:

每隔1秒就以上述公式計算電量進行累計。
放電電流的設定可以用跳線(或撥碼開關)將某個I/O口的各位分別對地短路來實現。
在P1口外接5位撥碼開關(也可以在PCB板上焊兩排排針,用短路帽來短接),設置放電電流(圖中電流為50mA):

由于有5檔開關,所以能夠預置的放電電流種類為:

開關1~5分別設置電流強度為:50mA、100mA、200mA、400mA、800mA。
各檔位組合設置的充電電流(以50mA遞增)如下表:

當電池電壓達到3V時終止放電,這個可以用繼電器來控制負載儀,并接通蜂鳴器報警。
3V電壓的檢測可以用一個電壓比較器(LM339)構成的“施密特觸發器”來完成,基準電壓源由一個TL431構成。
部分元件參數及封裝:

電路原理:模擬部分(放電進行時):

電路原理:模擬部分(放電停止):

TL431分壓原理:

其中R1是1、3腳間電阻;R2是1、2腳間電阻。
電路原理:數字部分:

單片機部分供電由78L05三端穩壓器提供,實測單片機部分工作電流不大于20mA,所以78L05在不加散熱片的情況下也能正常工作。

前面的電路(主要是模擬部分),由于電池有負載時的端電壓小于空載時的電壓,所以如果用繼電器的開關控制電池放電的話,則在電池電壓低于臨界值時,繼電器觸點斷開電池的瞬間,負載消失,導致電池電壓又會高于臨界值,這時繼電器觸點又會重新閉合,如此重復,繼電器的觸點就會不停的抖動,這個過程會長達幾個小時不停,我第一個繼電器就是這樣損壞的。
所以在電路中取消了用繼電器觸點控制電池,在電路中只讓觸點控制單片機“中斷”、蜂鳴器。
控制“中斷”,在中斷函數中停止累加器工作,LED顯示最后的電量,這就是電池的容量
控制蜂鳴器報警,提醒人,放電結束了。
在關閉電路以前,電池繼續通過負載儀放電也無所謂,因為電池都有保護芯片,放到一定的時候它會自動斷電的。

目前采用如下電路結構:
模擬部分:

數字部分:

電路最大的改變是放電截止時不再用繼電器斷開電池,以免造成繼電器觸點頻繁抖動。
繼電器采用雙刀雙擲,當放電截止時,一個觸點控制單片機的INT0,使累計停止;另一個觸點接通蜂鳴器,用聲音提醒放電已經結束了。
用面包板搭建的測試電路:



電路調試成功后,用洞洞板焊接而成的最終作品:





工作狀態:

這是自制的“2A負載儀”在放電過程中的工作狀態:
開始放電時(100mA放電電流):

放電結束時(100mA放電電流):

經過對手中幾片鋰電池進行測量,數據如下:



評分

參與人數 1黑幣 +100 收起 理由
admin + 100 共享資料的獎勵!

查看全部評分

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

使用道具 舉報

沙發
ID:97023 發表于 2025-7-6 13:24 | 只看該作者
  1. /**********************************************
  2. * 功能:LED顯示鋰電池容量檢測
  3. * 編程:ztzp
  4. * 日期:2020-04-14
  5. * P0        段碼控制
  6. * P2        位碼控制
  7. * P1        5位撥碼開關,決定放電電流。
  8. **********************************************/
  9. #include <reg52.h>

  10. #define uchar unsigned char
  11. #define uint unsigned int
  12. #define ulong unsigned long

  13. sfr T2MOD = 0xC9;        //使用定時器2必須定義,T2MOD的地址。
  14. float Iout;                //放電電流,與預設值相關。
  15. float Sum;                //放電量累加值
  16. ulong S;                //放電量四舍五入后轉換為整數
  17. uchar S1;                //第一位
  18. uchar S2;                //第二位
  19. uchar S3;                //第三位
  20. uint i;                        //1秒鐘計時變量
  21. uint State = 0;        //計數狀態,0開始計數;1停止計數。此值由外部中斷0控制。

  22. sbit LED_R = P3^6;        //紅色LED,表示正在放電,低電平有效。
  23. sbit LED_G = P3^7;        //綠色LED,表示停止放電,低電平有效。

  24. void init();                //系統初始化
  25. void init_int0();        //外部中斷初始化
  26. void init_Time2();        //定時器2初始化
  27. void Show();                //LED數碼管顯示放電量

  28. //共陽LED數碼管位碼(從左到右:1、2、3、4、5、6、7、8)
  29. //用PNP管驅動
  30. code uchar WEI_CODE [] =
  31. {
  32.         0xFE,                //1          11111110
  33.         0xFD,                //2          11111101
  34.         0xFB,                //3          11111011
  35.         0xF7,                //4          11110111
  36.         0xEF,                //5          11101111
  37.         0xDF,                //6          11011111
  38.         0xBF,                //7          10111111
  39.         0x7F                //8   01111111
  40. };

  41. //共陽LED數碼管段碼(帶小數點)
  42. code uchar DSY_CODE [] =
  43. {
  44.         0x40,                //0
  45.         0x79,                //1
  46.         0x24,                //2
  47.         0x30,                //3
  48.         0x19,                //4
  49.         0x12,                //5
  50.         0x02,                //6
  51.         0x78,                //7
  52.         0x00,                //8
  53.         0x10                //9
  54. };

  55. // 延時 xms(晶振:11.0592MHz,)
  56. void DelayMS(uint x)
  57. {
  58.         uchar i;
  59.         while( x-- )
  60.         {
  61.                 for( i=0; i<111; i++ );
  62.         }
  63. }

  64. //主程序
  65. void main()
  66. {
  67.         init();                        //系統初始化
  68.         init_int0();        //外部中斷初始化
  69.         init_Time2();        //定時器2初始化
  70.         while(1)
  71.         {
  72.                 Show();                //顯示
  73.         }
  74. }

  75. //LED數碼管顯示放電量(從左到右)
  76. void Show()
  77. {
  78.         //第1位
  79.         S = Sum + 0.5;        //四舍五入
  80.         S1 = S/10000000;
  81.         if (S1 != 0)
  82.         {
  83.                 P2 = WEI_CODE[0];
  84.                 P0 = DSY_CODE[S1] + 0x80;        //無小數點
  85.                 DelayMS(1);
  86.                 P2 = 0xFF;
  87.                 P0 = 0xFF;
  88.                 DelayMS(1);
  89.         }

  90.         //第2位
  91.         S = Sum + 0.5;
  92.         S2 = S%10000000/1000000;
  93.         if (S2 != 0 || S1 != 0)                //當第一位不等于0時,第二位必須顯示
  94.         {
  95.                 P2 = WEI_CODE[1];
  96.                 P0 = DSY_CODE[S2] + 0x80;
  97.                 DelayMS(1);
  98.                 P2 = 0xFF;
  99.                 P0 = 0xFF;
  100.                 DelayMS(1);
  101.         }

  102.         //第3位
  103.         S = Sum + 0.5;
  104.         S3 = S%1000000/100000;
  105.         if (S3 != 0 || S2 != 0 || S1 != 0)                //當第二位(或者第一位)不等于0時,第三位必須顯示。
  106.         {
  107.                 P2 = WEI_CODE[2];
  108.                 P0 = DSY_CODE[S3] + 0x80;
  109.                 DelayMS(1);
  110.                 P2 = 0xFF;
  111.                 P0 = 0xFF;
  112.                 DelayMS(1);
  113.         }

  114.         //第4位(個位)
  115.         S = Sum + 0.5;
  116.         S = S%100000/10000;
  117.         P2 = WEI_CODE[3];
  118.         P0 = DSY_CODE[S];        //有小數點
  119.         DelayMS(1);
  120.         P2 = 0xFF;
  121.         P0 = 0xFF;
  122.         DelayMS(1);

  123.         //第5位
  124.         S = Sum + 0.5;
  125.         S = S%10000/1000;
  126.         P2 = WEI_CODE[4];
  127.         P0 = DSY_CODE[S]+0x80;
  128.         DelayMS(1);
  129.         P2 = 0xFF;
  130.         P0 = 0xFF;
  131.         DelayMS(1);

  132.         //第6位
  133.         S = Sum + 0.5;
  134.         S = S % 1000 /100;
  135.         P2 = WEI_CODE[5];
  136.         P0 = DSY_CODE[S]+0x80;
  137.         DelayMS(1);
  138.         P2 = 0xFF;
  139.         P0 = 0xFF;
  140.         DelayMS(1);

  141.         //第7位
  142.         S = Sum + 0.5;
  143.         S = S % 100/10;
  144.         P2 = WEI_CODE[6];
  145.         P0 = DSY_CODE[S]+0x80;
  146.         DelayMS(1);
  147.         P2 = 0xFF;
  148.         P0 = 0xFF;
  149.         DelayMS(1);

  150.         //第8位
  151.         S = Sum + 0.5;
  152.         S = S % 10;
  153.         P2 = WEI_CODE[7];
  154.         P0 = DSY_CODE[S]+0x80;
  155.         DelayMS(1);
  156.         P2 = 0xFF;
  157.         P0 = 0xFF;
  158.         DelayMS(1);
  159. }

  160. //系統初始化
  161. //根據讀入P1的撥碼開關狀態值,決定放電電流。
  162. void init()
  163. {
  164.         LED_R = 0;        //紅燈亮
  165.         LED_G = 1;        //綠燈滅

  166.         switch( P1 )
  167.         {
  168.                 case 0XFE:        //50mA
  169.                         Iout = 500.0/3.6;
  170.                         break;
  171.                 case 0XFD:        //100mA
  172.                         Iout = 1000.0/3.6;
  173.                         break;
  174.                 case 0XFC:        //150mA
  175.                         Iout = 1.5*1000.0/3.6;
  176.                         break;
  177.                 case 0XFB:        //200mA
  178.                         Iout = 2.0*1000.0/3.6;
  179.                         break;
  180.                 case 0XFA:        //250mA
  181.                         Iout = 2.5*1000.0/3.6;
  182.                         break;
  183.                 case 0XF9:        //300mA
  184.                         Iout = 3.0*1000.0/3.6;
  185.                         break;
  186.                 case 0XF8:        //350mA
  187.                         Iout = 3.5*1000.0/3.6;
  188.                         break;
  189.                 case 0XF7:        //400mA
  190.                         Iout = 4.0*1000.0/3.6;
  191.                         break;
  192.                 case 0XF6:        //450mA
  193.                         Iout = 4.5*1000.0/3.6;
  194.                         break;
  195.                 case 0XF5:        //500mA
  196.                         Iout = 5.0*1000.0/3.6;
  197.                         break;
  198.                 case 0XF4:        //550mA
  199.                         Iout = 5.5*1000.0/3.6;
  200.                         break;
  201.                 case 0XF3:        //600mA
  202.                         Iout = 6.0*1000.0/3.6;
  203.                         break;
  204.                 case 0XF2:        //650mA
  205.                         Iout = 6.5*1000.0/3.6;
  206.                         break;
  207.                 case 0XF1:        //700mA
  208.                         Iout = 7.0*1000.0/3.6;
  209.                         break;
  210.                 case 0XF0:        //750mA
  211.                         Iout = 7.5*1000.0/3.6;
  212.                         break;
  213.                 case 0XEF:        //800mA
  214.                         Iout = 8.0*1000.0/3.6;
  215.                         break;
  216.                 case 0XEE:        //850mA
  217.                         Iout = 8.5*1000.0/3.6;
  218.                         break;
  219.                 case 0XED:        //900mA
  220.                         Iout = 9.0*1000.0/3.6;
  221.                         break;
  222.                 case 0XEC:        //950mA
  223.                         Iout = 9.5*1000.0/3.6;
  224.                         break;
  225.                 case 0XEB:        //1000mA
  226.                         Iout = 10.0*1000.0/3.6;
  227.                         break;
  228.                 case 0XEA:        //1050mA
  229.                         Iout = 10.5*1000.0/3.6;
  230.                         break;
  231.                 case 0XE9:        //1100mA
  232.                         Iout = 11.0*1000.0/3.6;
  233.                         break;
  234.                 case 0XE8:        //1150mA
  235.                         Iout = 11.5*1000.0/3.6;
  236.                         break;
  237.                 case 0XE7:        //1200mA
  238.                         Iout = 12.0*1000.0/3.6;
  239.                         break;
  240.                 case 0XE6:        //1250mA
  241.                         Iout = 12.5*1000.0/3.6;
  242.                         break;
  243.                 case 0XE5:        //1300mA
  244.                         Iout = 13.0*1000.0/3.6;
  245.                         break;
  246.                 case 0XE4:        //1350mA
  247.                         Iout = 13.5*1000.0/3.6;
  248.                         break;
  249.                 case 0XE3:        //1400mA
  250.                         Iout = 14.0*1000.0/3.6;
  251.                         break;
  252.                 case 0XE2:        //1450mA
  253.                         Iout = 14.5*1000.0/3.6;
  254.                         break;
  255.                 case 0XE1:        //1500mA
  256.                         Iout = 15.0*1000.0/3.6;
  257.                         break;
  258.                 case 0XE0:        //1550mA
  259.                         Iout = 15.5*1000.0/3.6;
  260.                         break;
  261.         }
  262. }

  263. //外部中斷初始化
  264. void init_int0()
  265. {
  266.         PX0 = 1;        //設置外部中斷0為最高優先級
  267.         IT0 = 1;        //1:設置下降沿觸發方式;0:低電平觸發方式
  268.         EA = 1;                //開總中斷
  269.         EX0 = 1;        //開外部中斷0
  270. }

  271. //定時器2初始化
  272. void init_Time2()
  273. {
  274.         T2MOD = 0;
  275.         T2CON = 0;
  276.         RCAP2H = (65536 - 50000)/256;                //12M晶振,50ms產生一次中斷
  277.         RCAP2L = (65536 - 50000)%256;
  278.         ET2 = 1;        //允許T2中斷
  279.         TR2 = 1;        //啟動T2中斷
  280. }

  281. //外部中斷0,用于停止放電計數。
  282. void Int0() interrupt 0
  283. {
  284.         LED_R = 1;        //紅燈滅
  285.         LED_G = 0;        //綠燈亮
  286.         State = 1;        //停止放電計數
  287. //        EX0 = 0;        //停止外部中斷
  288. }

  289. //定時器2中斷服務程序
  290. void Time2() interrupt 5
  291. {
  292.         TF2 = 0;        //定時器2必須由軟件對溢出標志位清零!
  293.         if (i > 20 && State == 0)        //每1秒累加一次放電量
  294.         {
  295.                 Sum += Iout;                //以100mA放電,1秒鐘的放電量。
  296.                 i = 0;
  297.         }
  298.         i++;
  299. }
復制代碼


回復

使用道具 舉報

板凳
ID:1136941 發表于 2025-7-6 15:09 | 只看該作者
請問撥碼開關是如何通過單片機控制放電電流的?
回復

使用道具 舉報

地板
ID:97023 發表于 2025-7-6 16:14 | 只看該作者
太陽雨ZW 發表于 2025-7-6 15:09
請問撥碼開關是如何通過單片機控制放電電流的?

初始化函數:
void init()
回復

使用道具 舉報

5#
ID:98396 發表于 2025-7-7 09:34 | 只看該作者
放電電流負載儀電路?
回復

使用道具 舉報

6#
ID:97023 發表于 2025-7-7 11:22 | 只看該作者
太陽雨ZW 發表于 2025-7-6 15:09
請問撥碼開關是如何通過單片機控制放電電流的?

我可能理解錯了你的意思,你可能是想問如何控制負載儀電流的,我是手動控制的。撥碼開關僅僅是告訴單片機這時的放電電流是多少,從而計算出每秒的放電電量并顯示。
回復

使用道具 舉報

7#
ID:97023 發表于 2025-7-7 12:31 | 只看該作者
tnovicet 發表于 2025-7-7 09:34
放電電流負載儀電路?

負載儀是另一個裝置,在這里把它看成一個可調電阻,是手動控制的,過幾天整理好以后我會發出來。
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 国产欧美日韩一区 | 国产精品一区二区av | 欧美国产亚洲一区二区 | 成人欧美一区二区三区在线播放 | 国产一区二区精品自拍 | 国产午夜精品一区二区三区四区 | 久久久99国产精品免费 | 美女国内精品自产拍在线播放 | 国产精品网页 | 天天干天天想 | 不卡av在线 | 国产精品色一区二区三区 | 欧美日韩亚洲一区 | 国产三级大片 | 成人a视频在线观看 | 精区3d动漫一品二品精区 | 精品视频国产 | 日韩一区二区在线视频 | 美女久久久久 | 亚洲高清一区二区三区 | 日韩欧美在线观看 | 欧美在线亚洲 | 成人黄色电影在线播放 | 亚洲一区久久久 | 亚洲精品黄色 | 亚洲欧洲一区二区 | 国产精品夜色一区二区三区 | 亚洲国产精品激情在线观看 | 黄色日本视频 | 亚洲成人黄色 | 亚洲一区二区三区四区在线观看 | a级免费观看视频 | 男人的天堂视频网站 | 欧美日韩国产高清 | 精区3d动漫一品二品精区 | 久草视频在线看 | 亚洲精品九九 | 日本 欧美 国产 | 国产一区二区美女 | 国产视频二区在线观看 | 国产美女在线免费观看 |