|
/*根據(jù)電池容量的mAh,可以計(jì)算電池的持續(xù)放電時(shí)間的電流數(shù)去確定電池的容量。
以下用了stc8051U去做檢測(cè)電池放電400mA的時(shí)間,再以公式400mA*時(shí)間=mAh
*/
#include "stc8051U.h"
#include "intrins.h"
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
#define ADCTIM (*(unsigned char volatile xdata *)0xfea8)
#define VREFH_ADDR CHIPID7
#define VREFL_ADDR CHIPID8
uint BGV; //內(nèi)部1.19V參考信號(hào)源值存放在idata中
typedef unsigned char BYTE;
uchar time1,time2,time3,pwm1;
uint fen=0,ad1=138,ad0;
sbit LED1 = P1^7;
sbit LED = P3^6; //背光腳H亮
sbit rw = P2^5;
sbit rs = P2^6; //
sbit en = P2^7; //
sbit cs1 = P3^2;
sbit cs2 = P3^3;
sbit rst = P3^4;
sbit SPK = P3^5; //蜂鳴器
sbit POW = P3^7; //PWM
void InitADC();
uint GetADCResult(BYTE ch);
void Delayus(uint us);
void Delay(uchar ms);
void lcdstate();
void write_command(uchar command);
void write_data(uchar datas);
void lcdinit();
void clearScreen();
void init();
void Timer0Init(void);
void Timer1Init(void);
void dyADC();
void hz_display16(unsigned char pag, unsigned char col, unsigned char code *hzk);
unsigned char code SZ[][16]=
{/*-- 文字: 0 --*/
/*-- 楷體_GB231212; 此字體下對(duì)應(yīng)的點(diǎn)陣為:寬x高=8x16 --*/
0x00,0x00,0xF0,0x08,0x08,0x18,0xE0,0x00,0x00,0x00,0x0F,0x10,0x20,0x10,0x0F,0x00,
/*-- 文字: 1 --*/
/*-- 楷體_GB231212; 此字體下對(duì)應(yīng)的點(diǎn)陣為:寬x高=8x16 --*/
0x00,0x00,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x10,0x00,0x00,0x00,
/*-- 文字: 2 --*/
/*-- 楷體_GB231212; 此字體下對(duì)應(yīng)的點(diǎn)陣為:寬x高=8x16 --*/
0x00,0x30,0x08,0x08,0x08,0xF8,0x00,0x00,0x00,0x00,0x18,0x14,0x13,0x10,0x08,0x00,
/*-- 文字: 3 --*/
/*-- 楷體_GB231212; 此字體下對(duì)應(yīng)的點(diǎn)陣為:寬x高=8x16 --*/
0x00,0x00,0x10,0x08,0x88,0x78,0x00,0x00,0x00,0x00,0x10,0x20,0x20,0x11,0x0E,0x00,
/*-- 文字: 4 --*/
/*-- 楷體_GB231212; 此字體下對(duì)應(yīng)的點(diǎn)陣為:寬x高=8x16 --*/
0x00,0x00,0xC0,0x20,0x10,0xF8,0x00,0x00,0x00,0x03,0x02,0x02,0x02,0x1F,0x02,0x00,
/*-- 文字: 5 --*/
/*-- 楷體_GB231212; 此字體下對(duì)應(yīng)的點(diǎn)陣為:寬x高=8x16 --*/
0x00,0x00,0x70,0x48,0xC8,0x88,0x00,0x00,0x00,0x10,0x10,0x20,0x10,0x0F,0x00,0x00,
/*-- 文字: 6 --*/
/*-- 楷體_GB231212; 此字體下對(duì)應(yīng)的點(diǎn)陣為:寬x高=8x16 --*/
0x00,0x00,0xE0,0x90,0x88,0x80,0x00,0x00,0x00,0x07,0x18,0x20,0x20,0x19,0x06,0x00,
/*-- 文字: 7 --*/
/*-- 楷體_GB231212; 此字體下對(duì)應(yīng)的點(diǎn)陣為:寬x高=8x16 --*/
0x00,0x10,0x08,0x08,0x88,0x78,0x00,0x00,0x00,0x00,0x00,0x18,0x07,0x00,0x00,0x00,
/*-- 文字: 8 --*/
/*-- 楷體_GB231212; 此字體下對(duì)應(yīng)的點(diǎn)陣為:寬x高=8x16 --*/
0x00,0x00,0x78,0x88,0x88,0x78,0x00,0x00,0x00,0x0C,0x12,0x21,0x21,0x1E,0x00,0x00,
/*-- 文字: 9 --*/
/*-- 楷體_GB231212; 此字體下對(duì)應(yīng)的點(diǎn)陣為:寬x高=8x16 --*/
0x00,0x60,0x98,0x08,0x08,0xF8,0xC0,0x00,0x00,0x00,0x21,0x12,0x09,0x07,0x00,0x00,
/*-- 文字: : --*/
/*-- 楷體_GB231212; 此字體下對(duì)應(yīng)的點(diǎn)陣為:寬x高=8x16 --*/
0x00,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0xC,0xC,0x00,0x00,0x00,0x00,0x00,
/*-- 文字: B --*/
/*-- 宋體12; 此字體下對(duì)應(yīng)的點(diǎn)陣為:寬x高=8x16 --*/
0x08,0xF8,0x88,0x88,0x88,0x70,0x00,0x00,0x20,0x3F,0x20,0x20,0x20,0x11,0x0E,0x00,
/*-- 文字: a --*/
/*-- 宋體12; 此字體下對(duì)應(yīng)的點(diǎn)陣為:寬x高=8x16 --*/
0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x19,0x24,0x22,0x22,0x22,0x3F,0x20,
/*-- 文字: t --*/
/*-- 宋體12; 此字體下對(duì)應(yīng)的點(diǎn)陣為:寬x高=8x16 --*/
0x00,0x80,0x80,0xE0,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x1F,0x20,0x20,0x00,0x00,
/*-- 文字: T --*/
/*-- 宋體12; 此字體下對(duì)應(yīng)的點(diǎn)陣為:寬x高=8x16 --*/
0x18,0x08,0x08,0xF8,0x08,0x08,0x18,0x00,0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00,
/*-- 文字: i --*/
/*-- 宋體12; 此字體下對(duì)應(yīng)的點(diǎn)陣為:寬x高=8x16 --*/
0x00,0x80,0x98,0x98,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,
/*-- 文字: m --*/
/*-- 宋體12; 此字體下對(duì)應(yīng)的點(diǎn)陣為:寬x高=8x16 --*/
0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x20,0x3F,0x20,0x00,0x3F,0x20,0x00,0x3F,
/*-- 文字: e --*/
/*-- 宋體12; 此字體下對(duì)應(yīng)的點(diǎn)陣為:寬x高=8x16 --*/
0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x1F,0x22,0x22,0x22,0x22,0x13,0x00,
/*-- 文字: V --*/
/*-- 宋體12; 此字體下對(duì)應(yīng)的點(diǎn)陣為:寬x高=8x16 --*/
0x08,0x78,0x88,0x00,0x00,0xC8,0x38,0x08,0x00,0x00,0x07,0x38,0x0E,0x01,0x00,0x00,
/*-- 文字: A --*/
/*-- 宋體12; 此字體下對(duì)應(yīng)的點(diǎn)陣為:寬x高=8x16 --*/
0x00,0x00,0xC0,0x38,0xE0,0x00,0x00,0x00,0x20,0x3C,0x23,0x02,0x02,0x27,0x38,0x20,
/*-- 文字: h --*/
/*-- 宋體12; 此字體下對(duì)應(yīng)的點(diǎn)陣為:寬x高=8x16 --*/
0x08,0xF8,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20,
/*-- 文字: 一 --*/
/*-- 宋體12; 此字體下對(duì)應(yīng)的點(diǎn)陣為:寬x高=16x16 --*/
0x00,0x00,0x0,0x0,0x0,0x0,0x00,0x00,0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x00,
/*-- 文字: . --*/
/*-- 楷體_GB231212; 此字體下對(duì)應(yīng)的點(diǎn)陣為:寬x高=8x16 --*/
0x00,0x0,0x0,0x00,0x00,0x00,0x00,0x00,0x00,0xC,0x0,0x00,0x00,0x00,0x00,0x00,
};
/*----------------------------
讀取ADC結(jié)果
----------------------------*/
uint GetADCResult(BYTE channel)
{
ADC_RES = 0;
ADC_RESL = 0;
ADC_CONTR = (ADC_CONTR & 0xF0) | 0x40 | channel; //啟動(dòng) AD 轉(zhuǎn)換
_nop_(); //等待4個(gè)NOP
_nop_();
_nop_();
_nop_();
while (!(ADC_CONTR & 0x20)); //查詢ADC完成標(biāo)志
ADC_CONTR &= ~0x20;
return (((int)ADC_RES << 8) | ADC_RESL); //adc_data*4的意思是左移兩位,4 = 2的2次方。
//然后左移后加上adc_low的值,這個(gè)值應(yīng)該是adc轉(zhuǎn)換的低兩位。
}
/*----------------------------
初始化ADC
----------------------------*/
void InitADC()
{
P_SW2 |= 0x80; //擴(kuò)展 RAM 區(qū)特殊功能寄存器(XFR)訪問(wèn)控制寄存器
ADCTIM = 0x3f; //ADC時(shí)序控制寄存器3f=00111111
P_SW2 &= 0x7f;
ADCCFG = 0x2f; //設(shè)置ADC時(shí)鐘為系統(tǒng)時(shí)鐘/2/16
ADC_CONTR = 0x80; //使能ADC模塊,并選擇第15通道 8f=10001111 //ADC上電并延時(shí)
}
void lcdstate() //讀狀態(tài)指令
{
uchar lcd=0x00; /*設(shè)置初值為0,全部為低,方便后面的判忙*/
rs=0; /*根據(jù)時(shí)序圖拉低,選擇寫(xiě)指令*/
rw=1; /*根據(jù)時(shí)序圖拉低,選擇寫(xiě)模式*/
do
{
en=1; /*使能,使液晶輸出信號(hào),檢查是否忙*/
_nop_();_nop_();_nop_();_nop_();/*延時(shí)4US*/
lcd=P0; /*把P0口的狀態(tài)值讀回來(lái)給lcd*/
en=0; /*使能端跳變*/;
}while(lcd&0x80); /*結(jié)果的高位保留,如果高位DB7為一,則表示忙*/
}
void Delayus(uint us) //@12.000MHz
{
while(--us)
{
_nop_();
_nop_();
_nop_();
_nop_();
}
}
void delay(uchar ms)
{ uchar i;
uchar j;
for(i=0;i<100;i++)
for(j=0;j<ms;j++);
}
void write_command(uchar command)
{
lcdstate();
rs=0; //RS=0;為往MCU進(jìn)行指令操作
rw=0; //RW=0;為往MCU寫(xiě)入操作
en=0;
_nop_();_nop_();_nop_();_nop_();/*延時(shí)4US*/
en=1;
_nop_();_nop_();_nop_();_nop_();/*延時(shí)4US*/
P0=command;
_nop_();_nop_();_nop_();_nop_();/*延時(shí)4US*/
en=0;
}
void write_data(uchar datas)
{
lcdstate();
rs=1;
rw=0;
en=0;
_nop_();_nop_();_nop_();_nop_();/*延時(shí)4US*/
en=1;
_nop_();_nop_();_nop_();_nop_();/*延時(shí)4US*/
P0=datas;
_nop_();_nop_();_nop_();_nop_();/*延時(shí)4US*/
en=0;
}
void lcdinit()
{
delay(100); //
cs1=1;
cs2=1;
delay(100);
lcdstate(); //
write_command(0x3e); //
write_command(0xb8+0); //
write_command(0xc0+0); //
write_command(0x40+0); //
write_command(0x3f);
}
void clearScreen( )
{ uchar i,j;
lcdstate();
cs1=1;
cs2=1;
write_command(0x3f); //設(shè)置顯示開(kāi)
write_command(0xb8); //Y 設(shè)置第0頁(yè);
write_command(0x40); // 設(shè)置第0列
for(i=0;i<8;i++)
{
write_command(0xb8+i);
for(j=0;j<64;j++)
{
//write_command(0x40+j);
write_data(0x00);
}
}
}
void Timer0Init(void) //2毫秒@12.000MHz 時(shí)間
{
AUXR &= 0x7F; //定時(shí)器時(shí)鐘12T模式
TMOD &= 0xF0; //設(shè)置定時(shí)器模式
TMOD |= 0x01; //設(shè)置定時(shí)器模式
TL0 = 0x30; //設(shè)置定時(shí)初值
TH0 = 0xF8; //設(shè)置定時(shí)初值
TF0 = 0; //清除TF0標(biāo)志
TR0 = 0; //定時(shí)器0開(kāi)始計(jì)時(shí)
}
void Timer1Init(void) //5毫秒@12.000MHz
{
AUXR &= 0xBF; //定時(shí)器時(shí)鐘12T模式
TMOD &= 0x0F; //設(shè)置定時(shí)器模式
TMOD |= 0x10; //設(shè)置定時(shí)器模式
TL0 = 0xB0; //設(shè)置定時(shí)初始值
TH0 = 0x3C; //設(shè)置定時(shí)初值
TF1 = 0; //清除TF1標(biāo)志
TR1 = 0; //定時(shí)器1開(kāi)始計(jì)時(shí)
}
void hz_display8(unsigned char pag, unsigned char col, unsigned char zi)
{
uchar j=0;
uchar i=0;
for(j=0;j<2;j++) //這里寫(xiě)四頁(yè)
{
write_command(0xb8+pag+j); //page在這里就是從page表示的這頁(yè)開(kāi)始寫(xiě)起。
write_command(0x40+col); //從列為col表示的列開(kāi)始
for(i=0;i<8;i++) //這里寫(xiě)32列
write_data(SZ[zi][8*j+i]); //J為頁(yè),I,為第J行第I個(gè)數(shù)
}
}
void dyADC()
{
int res,ad1;
int xes;
GetADCResult(15);
GetADCResult(15);
res=GetADCResult(15);//讀內(nèi)部基準(zhǔn)ADC, 讀15通道
GetADCResult(0);
GetADCResult(0);
xes=GetADCResult(0);//讀p1.1外部電壓ADC
ad1=(int)((long)xes* BGV / res); //計(jì)算p1.1外部電壓, vcc為1.19V,
ad0=ad1/10;
}
void main()
{
bit q1=0,q2=0,q3=0;
// uchar k1;
ulong ww=1667;
P_SW2 = 0X80; //使能訪問(wèn) XFR,沒(méi)有沖突不用關(guān)閉
CKCON = 0x00; //設(shè)置外部數(shù)據(jù)總線速度為最快
WTST = 0x00;
P0M0 = 0x00; //00上拉準(zhǔn)雙向口/10浮空輸入
P0M1 = 0x00; //11開(kāi)漏輸出/01推挽輸出
P1M0 = 0x00;
P1M1 = 0x01; //設(shè)置P1.0為ADC
P2M0 = 0x00;
P2M1 = 0x00;
P3M0 = 0x00; //00上拉準(zhǔn)雙向口/10浮空輸入
P3M1 = 0x00; //11開(kāi)漏輸出/01推挽輸出
P4M0 = 0x00;
P4M1 = 0x00;
P5M0 = 0x00;
P5M1 = 0x00;
BGV = (VREFH_ADDR << 8) + VREFL_ADDR; //從 CHIPID 中讀取內(nèi)部參考電壓值
POW=1;
LED1=1;
SPK=0;
lcdinit();
clearScreen();
InitADC();
Timer0Init();
Timer1Init();
TR0 = 1; //timer0 時(shí)間
ET0 = 1; // 時(shí)間
// TR1 = 1; //timer1 start running
// ET1 = 1; //enable timer1 interrupt
EA = 1; //open global interrupt switch
cs1=1;
cs2=0;
hz_display8(0,0,11); //Batt:
hz_display8(0,8,12);
hz_display8(0,16,13);
hz_display8(0,24,13);
hz_display8(0,32,10);
hz_display8(6,0,14); //time:
hz_display8(6,8,15);
hz_display8(6,16,16);
hz_display8(6,24,17);
hz_display8(6,32,10);
while(1)
{
while(1)
{
if(EA==1)
{
cs1=1;
cs2=0;
hz_display8(6,40,(time3%100/10)); //時(shí)
hz_display8(6,48,(time3%10/1));
hz_display8(6,56,10); //:
cs1=0;
cs2=1;
hz_display8(6,0,(time2%100/10)); //分
hz_display8(6,8,(time2%10/1));
hz_display8(6,16,10); //:
hz_display8(6,24,(time1%100/10)); //秒
hz_display8(6,32,(time1%10/1));
}
if(q1==0&time1==2) //q1=0 time1=2 才執(zhí)行括號(hào)里的程序
{
dyADC();
cs1=1;
cs2=0;
hz_display8(0,40,(ad0/100));
hz_display8(0,48,22);
hz_display8(0,56,(ad0%100/10));
cs1=0;
cs2=1;
hz_display8(0,0,(ad0%10));
hz_display8(0,8,18); //v
q1=1;
CCON = 0; //PCA控制寄存器CCON
CMOD = 0x08; //工作模式寄存器CMOD
CL = 0; //PCA的16位計(jì)數(shù)器 — 低8位CL和高8位CH
CH = 0;
CCAPM1 = 0x42; //PCA比較/捕獲寄存器CCAPMn (n=0,1,2,3) PCA interrupt
PCA_PWM1 = 0x40; //Disable PCA timer overflow interrupt
CCAP1H = CCAP1L = 0x01; //模塊0的捕捉/比較寄存器用來(lái)控制輸出的占?比
CCON |= CR; //PCA計(jì)數(shù)器陣列, 運(yùn)行控制位
// while(1);
TR1 = 1; // 時(shí)間
ET1 = 1;
}
dyADC();
//ad0=GetADCResult(0);
cs1=0;
cs2=1;
hz_display8(0,16,(ad0/100));
hz_display8(0,24,22);
hz_display8(0,32,(ad0%100/10));
hz_display8(0,40,(ad0%10));
hz_display8(0,48,18); //v
if(fen>=1)LED=0;
if(ad0<=286)q3=1;
while(q3==1)
{
LED=~LED;
// CCAP1H = CCAP1L = 0x00;
POW=0;
EA=0;
Delay(500);
Delay(500);
Delay(500);
Delay(500);
Delay(500);
Delay(500);
Delay(500);
Delay(500);
Delay(500);
dyADC();
// ad0=GetADCResult(0);
cs1=0;
cs2=1;
hz_display8(0,16,(ad0/100));
hz_display8(0,24,22);
hz_display8(0,32,(ad0%100/10));
hz_display8(0,40,(ad0%10));
hz_display8(0,48,18); //v
if(!q2)
{
ww*=fen;
ww*=4;
cs1=1;
cs2=2;
hz_display8(6,0,21); //-------
hz_display8(6,8,21);
hz_display8(6,16,21);
hz_display8(6,24,21);
hz_display8(6,32,21);
hz_display8(6,40,21);
hz_display8(6,48,21);
hz_display8(6,56,21);
cs1=0;
cs2=1;
hz_display8(6,0,(ww%100000000/10000000));
hz_display8(6,8,(ww%10000000/1000000));
hz_display8(6,16,(ww%1000000/100000));
hz_display8(6,24,(ww%100000/10000));
hz_display8(6,32,(ww%10000/1000));
hz_display8(6,40,16); //mah
hz_display8(6,48,19);
hz_display8(6,56,20);
Delay(1000);
q2=1;
}
}
}
}
}
void tm0_isr() interrupt 1 using 1
{
static uchar i1,i2;
TL0 = 0x30; //設(shè)置定時(shí)初值 2ms
TH0 = 0xF8; //設(shè)置定時(shí)初值
i1++;
if(i1>=50)
{
i1=0;
i2++;
if(i2>=10)
{
i2=0;
time1++;
if(time1>=60)
{
time1=0;
time2++;
fen++;
if(time2>=60)
{
time2=0;
time3++;
if(time3>=24)time3=0;
}
}
}
}
//dyADC();
//ad0=GetADCResult(0);
}
void tm1_isr() interrupt 3 using 1
{
TL0 = 0xB0; //設(shè)置定時(shí)初始值
TH0 = 0x3C; //設(shè)置定時(shí)初值
//dyADC();
if(ad0>=428)CCAP1H = CCAP1L = 142; //模塊0的捕捉/比較寄存器用來(lái)控制輸出的占?比
if(ad0<=427&&ad0>424)CCAP1H = CCAP1L = 142;
if(ad0<=424&&ad0>420)CCAP1H = CCAP1L = 141;
if(ad0<=420&&ad0>416)CCAP1H = CCAP1L = 140;
if(ad0<=416&&ad0>412)CCAP1H = CCAP1L = 139;
if(ad0<=412&&ad0>408)CCAP1H = CCAP1L = 138;
if(ad0<=408&&ad0>404)CCAP1H = CCAP1L = 137;
if(ad0<=404&&ad0>400)CCAP1H = CCAP1L = 136;
if(ad0<=400&&ad0>396)CCAP1H = CCAP1L = 135;
if(ad0<=396&&ad0>392)CCAP1H = CCAP1L = 134;
if(ad0<=392&&ad0>388)CCAP1H = CCAP1L = 132;//
if(ad0<=388&&ad0>384)CCAP1H = CCAP1L = 131;
if(ad0<=384&&ad0>380)CCAP1H = CCAP1L = 129;
if(ad0<=380&&ad0>376)CCAP1H = CCAP1L = 128;
if(ad0<=376&&ad0>372)CCAP1H = CCAP1L = 127;
if(ad0<=372&&ad0>368)CCAP1H = CCAP1L = 126;//
if(ad0<=368&&ad0>364)CCAP1H = CCAP1L = 125;
if(ad0<=364&&ad0>360)CCAP1H = CCAP1L = 123;
if(ad0<=360&&ad0>356)CCAP1H = CCAP1L = 122;
if(ad0<=356&&ad0>352)CCAP1H = CCAP1L = 120;
if(ad0<=352&&ad0>348)CCAP1H = CCAP1L = 119;
if(ad0<=348&&ad0>344)CCAP1H = CCAP1L = 117;
if(ad0<=344&&ad0>340)CCAP1H = CCAP1L = 116;
if(ad0<=340&&ad0>336)CCAP1H = CCAP1L = 114;
if(ad0<=336&&ad0>332)CCAP1H = CCAP1L = 113;
if(ad0<=332&&ad0>328)CCAP1H = CCAP1L = 111;
if(ad0<=328&&ad0>324)CCAP1H = CCAP1L = 109;
if(ad0<=324&&ad0>320)CCAP1H = CCAP1L = 108;
if(ad0<=320&&ad0>316)CCAP1H = CCAP1L = 106;
if(ad0<=316&&ad0>312)CCAP1H = CCAP1L = 105;
if(ad0<=312&&ad0>308)CCAP1H = CCAP1L = 103;
if(ad0<=304&&ad0>300)CCAP1H = CCAP1L = 100;
if(ad0<=300&&ad0>296)CCAP1H = CCAP1L = 98;
if(ad0<=296&&ad0>292)CCAP1H = CCAP1L = 97;
if(ad0<=292&&ad0>288)CCAP1H = CCAP1L = 94;
if(ad0<=288&&ad0>284)CCAP1H = CCAP1L = 91;
if(ad0<=284)CCAP1H = CCAP1L = 0xFF;
}
|
|