- /**********************************************
- * 功能:LED顯示鋰電池容量檢測
- * 編程:ztzp
- * 日期:2020-04-14
- * P0 段碼控制
- * P2 位碼控制
- * P1 5位撥碼開關(guān),決定放電電流。
- **********************************************/
- #include <reg52.h>
- #define uchar unsigned char
- #define uint unsigned int
- #define ulong unsigned long
- sfr T2MOD = 0xC9; //使用定時器2必須定義,T2MOD的地址。
- float Iout; //放電電流,與預(yù)設(shè)值相關(guān)。
- float Sum; //放電量累加值
- ulong S; //放電量四舍五入后轉(zhuǎn)換為整數(shù)
- uchar S1; //第一位
- uchar S2; //第二位
- uchar S3; //第三位
- uint i; //1秒鐘計時變量
- uint State = 0; //計數(shù)狀態(tài),0開始計數(shù);1停止計數(shù)。此值由外部中斷0控制。
- sbit LED_R = P3^6; //紅色LED,表示正在放電,低電平有效。
- sbit LED_G = P3^7; //綠色LED,表示停止放電,低電平有效。
- void init(); //系統(tǒng)初始化
- void init_int0(); //外部中斷初始化
- void init_Time2(); //定時器2初始化
- void Show(); //LED數(shù)碼管顯示放電量
- //共陽LED數(shù)碼管位碼(從左到右:1、2、3、4、5、6、7、8)
- //用PNP管驅(qū)動
- code uchar WEI_CODE [] =
- {
- 0xFE, //1 11111110
- 0xFD, //2 11111101
- 0xFB, //3 11111011
- 0xF7, //4 11110111
- 0xEF, //5 11101111
- 0xDF, //6 11011111
- 0xBF, //7 10111111
- 0x7F //8 01111111
- };
- //共陽LED數(shù)碼管段碼(帶小數(shù)點)
- code uchar DSY_CODE [] =
- {
- 0x40, //0
- 0x79, //1
- 0x24, //2
- 0x30, //3
- 0x19, //4
- 0x12, //5
- 0x02, //6
- 0x78, //7
- 0x00, //8
- 0x10 //9
- };
- // 延時 xms(晶振:11.0592MHz,)
- void DelayMS(uint x)
- {
- uchar i;
- while( x-- )
- {
- for( i=0; i<111; i++ );
- }
- }
- //主程序
- void main()
- {
- init(); //系統(tǒng)初始化
- init_int0(); //外部中斷初始化
- init_Time2(); //定時器2初始化
- while(1)
- {
- Show(); //顯示
- }
- }
- //LED數(shù)碼管顯示放電量(從左到右)
- void Show()
- {
- //第1位
- S = Sum + 0.5; //四舍五入
- S1 = S/10000000;
- if (S1 != 0)
- {
- P2 = WEI_CODE[0];
- P0 = DSY_CODE[S1] + 0x80; //無小數(shù)點
- DelayMS(1);
- P2 = 0xFF;
- P0 = 0xFF;
- DelayMS(1);
- }
- //第2位
- S = Sum + 0.5;
- S2 = S%10000000/1000000;
- if (S2 != 0 || S1 != 0) //當(dāng)?shù)谝晃徊坏扔?時,第二位必須顯示
- {
- P2 = WEI_CODE[1];
- P0 = DSY_CODE[S2] + 0x80;
- DelayMS(1);
- P2 = 0xFF;
- P0 = 0xFF;
- DelayMS(1);
- }
- //第3位
- S = Sum + 0.5;
- S3 = S%1000000/100000;
- if (S3 != 0 || S2 != 0 || S1 != 0) //當(dāng)?shù)诙唬ɑ蛘叩谝晃唬┎坏扔?時,第三位必須顯示。
- {
- P2 = WEI_CODE[2];
- P0 = DSY_CODE[S3] + 0x80;
- DelayMS(1);
- P2 = 0xFF;
- P0 = 0xFF;
- DelayMS(1);
- }
- //第4位(個位)
- S = Sum + 0.5;
- S = S%100000/10000;
- P2 = WEI_CODE[3];
- P0 = DSY_CODE[S]; //有小數(shù)點
- DelayMS(1);
- P2 = 0xFF;
- P0 = 0xFF;
- DelayMS(1);
- //第5位
- S = Sum + 0.5;
- S = S%10000/1000;
- P2 = WEI_CODE[4];
- P0 = DSY_CODE[S]+0x80;
- DelayMS(1);
- P2 = 0xFF;
- P0 = 0xFF;
- DelayMS(1);
- //第6位
- S = Sum + 0.5;
- S = S % 1000 /100;
- P2 = WEI_CODE[5];
- P0 = DSY_CODE[S]+0x80;
- DelayMS(1);
- P2 = 0xFF;
- P0 = 0xFF;
- DelayMS(1);
- //第7位
- S = Sum + 0.5;
- S = S % 100/10;
- P2 = WEI_CODE[6];
- P0 = DSY_CODE[S]+0x80;
- DelayMS(1);
- P2 = 0xFF;
- P0 = 0xFF;
- DelayMS(1);
- //第8位
- S = Sum + 0.5;
- S = S % 10;
- P2 = WEI_CODE[7];
- P0 = DSY_CODE[S]+0x80;
- DelayMS(1);
- P2 = 0xFF;
- P0 = 0xFF;
- DelayMS(1);
- }
- //系統(tǒng)初始化
- //根據(jù)讀入P1的撥碼開關(guān)狀態(tài)值,決定放電電流。
- void init()
- {
- LED_R = 0; //紅燈亮
- LED_G = 1; //綠燈滅
- switch( P1 )
- {
- case 0XFE: //50mA
- Iout = 500.0/3.6;
- break;
- case 0XFD: //100mA
- Iout = 1000.0/3.6;
- break;
- case 0XFC: //150mA
- Iout = 1.5*1000.0/3.6;
- break;
- case 0XFB: //200mA
- Iout = 2.0*1000.0/3.6;
- break;
- case 0XFA: //250mA
- Iout = 2.5*1000.0/3.6;
- break;
- case 0XF9: //300mA
- Iout = 3.0*1000.0/3.6;
- break;
- case 0XF8: //350mA
- Iout = 3.5*1000.0/3.6;
- break;
- case 0XF7: //400mA
- Iout = 4.0*1000.0/3.6;
- break;
- case 0XF6: //450mA
- Iout = 4.5*1000.0/3.6;
- break;
- case 0XF5: //500mA
- Iout = 5.0*1000.0/3.6;
- break;
- case 0XF4: //550mA
- Iout = 5.5*1000.0/3.6;
- break;
- case 0XF3: //600mA
- Iout = 6.0*1000.0/3.6;
- break;
- case 0XF2: //650mA
- Iout = 6.5*1000.0/3.6;
- break;
- case 0XF1: //700mA
- Iout = 7.0*1000.0/3.6;
- break;
- case 0XF0: //750mA
- Iout = 7.5*1000.0/3.6;
- break;
- case 0XEF: //800mA
- Iout = 8.0*1000.0/3.6;
- break;
- case 0XEE: //850mA
- Iout = 8.5*1000.0/3.6;
- break;
- case 0XED: //900mA
- Iout = 9.0*1000.0/3.6;
- break;
- case 0XEC: //950mA
- Iout = 9.5*1000.0/3.6;
- break;
- case 0XEB: //1000mA
- Iout = 10.0*1000.0/3.6;
- break;
- case 0XEA: //1050mA
- Iout = 10.5*1000.0/3.6;
- break;
- case 0XE9: //1100mA
- Iout = 11.0*1000.0/3.6;
- break;
- case 0XE8: //1150mA
- Iout = 11.5*1000.0/3.6;
- break;
- case 0XE7: //1200mA
- Iout = 12.0*1000.0/3.6;
- break;
- case 0XE6: //1250mA
- Iout = 12.5*1000.0/3.6;
- break;
- case 0XE5: //1300mA
- Iout = 13.0*1000.0/3.6;
- break;
- case 0XE4: //1350mA
- Iout = 13.5*1000.0/3.6;
- break;
- case 0XE3: //1400mA
- Iout = 14.0*1000.0/3.6;
- break;
- case 0XE2: //1450mA
- Iout = 14.5*1000.0/3.6;
- break;
- case 0XE1: //1500mA
- Iout = 15.0*1000.0/3.6;
- break;
- case 0XE0: //1550mA
- Iout = 15.5*1000.0/3.6;
- break;
- }
- }
- //外部中斷初始化
- void init_int0()
- {
- PX0 = 1; //設(shè)置外部中斷0為最高優(yōu)先級
- IT0 = 1; //1:設(shè)置下降沿觸發(fā)方式;0:低電平觸發(fā)方式
- EA = 1; //開總中斷
- EX0 = 1; //開外部中斷0
- }
- //定時器2初始化
- void init_Time2()
- {
- T2MOD = 0;
- T2CON = 0;
- RCAP2H = (65536 - 50000)/256; //12M晶振,50ms產(chǎn)生一次中斷
- RCAP2L = (65536 - 50000)%256;
- ET2 = 1; //允許T2中斷
- TR2 = 1; //啟動T2中斷
- }
- //外部中斷0,用于停止放電計數(shù)。
- void Int0() interrupt 0
- {
- LED_R = 1; //紅燈滅
- LED_G = 0; //綠燈亮
- State = 1; //停止放電計數(shù)
- // EX0 = 0; //停止外部中斷
- }
- //定時器2中斷服務(wù)程序
- void Time2() interrupt 5
- {
- TF2 = 0; //定時器2必須由軟件對溢出標(biāo)志位清零!
- if (i > 20 && State == 0) //每1秒累加一次放電量
- {
- Sum += Iout; //以100mA放電,1秒鐘的放電量。
- i = 0;
- }
- i++;
- }
復(fù)制代碼
|