| 
高级会员 主题
回帖0
积分3383
阅读权限30
注册时间2012-12-18
最后登录1970-1-1
在线时间 小时
 
 | 
 
| 本帖最后由 SengChuary 于 2013-4-9 18:47 编辑 
 
   
 
   主程序:
 18B20程序:LCD12864程序:复制代码#include <reg52.h>
#include <lcd12864.h>//lcd12864相关控制
#include <DS18B20.h>
#include <math.h>
 
sbit CTRL_UP=P2^0;
sbit CTRL_DOWN=P2^1;
 
sbit ADCOE=P2^6;
sbit ADCSTART=P2^7;
sbit ADCALE=P2^5;
sbit ADCA=P2^4;
sbit ADCB=P2^3;
sbit POWERKK=P1^4;
#define ADCDATE P0
 
sbit KEY1=P3^7;
sbit KEY2=P3^5;
sbit KEY3=P3^6;
 
void InitSys();//初始化系统
void InitInt();//初始化外部中断
void InitTimer();//初始化定时器,串口中断
void SendSerialData();//启动并发送一组串口数据
void StartADC();//选择通道n,开始转换
void ShowAllTime();//显示完整的时间
 
unsigned char g_myPar[15],g_CurSend;
//g_t10,g_t11,g_t20,g_t21,g_t30,g_t31,g_n,g_U0,g_U1p,g_U1f,g_U2,g_U3,g_Th,g_Tm,g_Ts;参数顺序
bit bSerialSending;
unsigned char g_time[6];
unsigned char g_CurIn;
unsigned char code g_adda[]={0,1,1,0,1};
unsigned char code g_addb[]={1,0,0,0,1};
unsigned char code g_ctrlu[]={1,1,1,0,0};
unsigned char code g_ctrld[]={0,1,0,1,1};
unsigned char g_tt10,g_tt11,g_tt20,g_tt21,g_tt30,g_tt31;
unsigned char CutState;
bit CurTR0,Curctrlu,Curctrld;
float SqrtDuty;
unsigned char g_Percent;
 
void main()
{
//DelayMs(10);
//Delay4us(10);
InitSys();
DelayMs(1200);
InitLCD();
InitLCDshow(0);
InitInt();//初始化外部中断0
InitTimer();//初始化定时器0,串口中断
bSerialSending = 0;
//     bLinking = 0;
 
//WriteLCD(0,0x80);
//DspNumber(123);
StartADC();
while(1)
{
if(KEY1==0)//充电
 
{
TR1 = 0;
CutState = 0;
POWERKK = 1;
InitLCDshow(0);
TR0 = 1;
g_myPar[0]=g_tt10;
g_myPar[1]=g_tt11;
g_myPar[2]=g_tt20;
g_myPar[3]=g_tt21;
g_myPar[4]=g_tt10;
g_myPar[5]=g_tt11;
//SqrtDuty = sqrt((float)g_myPar[1]/(g_myPar[0]+g_myPar[1]));
//Duty=g_myPar[0]*100/(g_myPar[0]+g_myPar[1]);
TR1 = 1;
StartADC();
ShowAllTime();
DelayMs(100);
}
else if(KEY2==0)//放电
{
TR1 = 0;
CutState = 1;
POWERKK = 1;
InitLCDshow(1);
TR0 = 0;
g_CurIn = 0;
CTRL_UP = 1;
CTRL_DOWN = 0;
TR1 = 1;
StartADC();
ShowAllTime();
DelayMs(100);
}
else if(KEY3==0)//维护
{
TR1 = 0;
POWERKK = 0;
CutState = 2;
InitLCDshow(2);
TR0 = 1;
g_myPar[0]=0xff;
g_myPar[1]=0xf0;
g_myPar[2]=0xfe;
g_myPar[3]=0x74;
g_myPar[4]=0xff;
g_myPar[5]=0xf2;
//SqrtDuty = sqrt((float)g_myPar[1]/(g_myPar[0]+g_myPar[1]));
//Duty=g_myPar[0]*100/(g_myPar[0]+g_myPar[1]);
TR1 = 1;
StartADC();
ShowAllTime();
DelayMs(100);
}
}
}
 
//初始化系统
void InitSys()
{
unsigned char i;
 
for(i=0;i<6;i++)
{
 
g_time[i] =;
}
ADCOE = 1;
ADCALE = 0;
ADCSTART = 0;
 
POWERKK = 1;
g_myPar[0]=0xff;//0x30
g_myPar[1]=0x30;
g_myPar[2]=0xff;
g_myPar[3]=0x30;//0x30
g_myPar[4]=0xff;
g_myPar[5]=0x30;
g_tt10 = 0xff;
g_tt11 = 0x30;
g_tt20 = 0xff;
g_tt21 = 0x30;
/*g_myPar[0] = 0x80;//g_TH1
g_myPar[1] = 0x00;//g_TH2
g_myPar[2] = 0x00;//g_TH3*/
g_myPar[6] = 6;
SqrtDuty = sqrt(0.5);
//Duty=g_myPar[0]*100/(g_myPar[0]+g_myPar[1]);
}
 
//初始化外部中断
void InitInt()
{
IT0 = 1;// 0/1 低电平/下跳变
PX0 = 1;// 中断优先级
//EX0 = 1;
//EA = 1;
}
 
 
//初始化定时器,串口中断
void InitTimer()
{
TMOD = 0x11;// 使用高4位 0/1/2/3  13位/16位/8位自动重载/双8位
 
TH0 = (65536 - 49235) / 256;
TL0 = (65536 - 49235) % 256;
PT0 = 1;
TR0 = 1;//开启定时器0
ET0 = 1;
 
TH1 = (65536 - 49235) / 256;
TL1 = (65536 - 49235) % 256;
TR1 = 1;//开启定时器1
ET1 = 1;
 
TCLK=1;
RCLK=1;
 
TH2=0xFF;  //19200bps  22.1184MHz的时钟频率
TL2=0xDC;
RCAP2H=0xFF;  //方式1和方式3的波特率=fosc/(32-(65535-(RCAP2H,RCAP2L))
RCAP2L=0xDC;
 
TR2=1;
//ET2=1;
 
SCON = 0x50;//串口方式1,允许接收
PCON = 0x00;//关闭波特率加倍
 
PS = 1;//设置串口中断为高优先级
ES = 1;//开串口中断
//TH1 = 0xfd;//串口通信使用定时器1,设定波特率9600
//TH1 = 0xf3;//串口通信使用定时器1,设定波特率2400
 
EA = 1;
}
 
//开始发送串口数据
void SendSerialData()
{
if(!bSerialSending)
{
bSerialSending = 1;
g_CurSend = 0;
SBUF = g_myPar[g_CurSend];
g_CurSend++;
}
}
 
//开始ADC转换
void StartADC()
{
CurTR0 = TR0;
TR0 = 0;
g_CurIn=0;
ADCA = g_adda[g_CurIn];
ADCB = g_addb[g_CurIn];
CTRL_UP = g_ctrlu[g_CurIn];
CTRL_DOWN = g_ctrld[g_CurIn];
Curctrlu = CTRL_UP;
Curctrld = CTRL_DOWN;
ADCALE = 1;
ADCALE = 0;
ADCSTART = 1;
ADCSTART = 0;
EX0 = 1;
 
}
 
//倒序转换
unsigned char Reverse(unsigned char num)
{
unsigned char i,rtTmp;
rtTmp = 0x00;
for(i=0; i<8; i++)
{
rtTmp <<=1;
rtTmp |= num & 0x01;
num >>= 1;
}
return rtTmp;
}
 
//显示完整的时间
void ShowAllTime()
{
WriteLCD(0,0x98+4);
WriteLCD(1,g_time[0]);//时
WriteLCD(1,g_time[1]);
WriteLCD(1,:);
WriteLCD(1,g_time[2]);//分
WriteLCD(1,g_time[3]);
WriteLCD(1,:);
 
WriteLCD(1,g_time[4]);
WriteLCD(1,g_time[5]);
}
 
//外部中断0服务程序
void Int0() interrupt 0
{
g_myPar[7+g_CurIn] = ADCDATE;
g_CurIn++;
if(g_CurIn<5)
{
ADCA = g_adda[g_CurIn];
ADCB = g_addb[g_CurIn];
CTRL_UP = g_ctrlu[g_CurIn];
CTRL_DOWN = g_ctrld[g_CurIn];
ADCALE = 1;
ADCALE = 0;
ADCSTART = 1;
ADCSTART = 0;
}
else
{
TR0 = CurTR0;
EX0 = 0;
CTRL_UP = Curctrlu;
CTRL_DOWN = Curctrld;
}
}
 
//定时器0中断服务程序
void Timer0() interrupt 1
{
static unsigned char i;
static bit j;
if(j)
{
j = 0;
i++;
if(i>g_myPar[6])
{
i = 0;
CTRL_UP = 1;
CTRL_DOWN = 0;
TH0 = g_myPar[4];
TL0 = g_myPar[5];
}
else
{
CTRL_UP = 1;
CTRL_DOWN = 1;
TH0 = g_myPar[2];
TL0 = g_myPar[3];
}
}
else
{
j = 1;
CTRL_UP = 0;
CTRL_DOWN = 1;
TH0 = g_myPar[0];
TL0 = g_myPar[1];
}
}
 
 
//定时器1中断服务程序
void Timer1() interrupt 3
{
static unsigned char i,j;
unsigned char temp_data[2];
unsigned char presence,k;
 
TH1 = (65536 - 60730) / 256;
TL1 = (65536 - 60730) % 256;
i++;
if(i>24)//时间显示
{
i=0;
g_time[5]++;
g_myPar[14]++;
if(g_time[5] > 0x39)//秒个位
{
g_time[5] = 0x30;
g_time[4]++;
if(g_time[4] > 0x35)//秒十位
{
g_time[4] = 0x30;
g_time[3]++;
g_myPar[14] = 0;
g_myPar[13]++;
if(g_time[3] > 0x39)//分个位
{
g_time[3] = 0x30;
g_time[2]++;
if(g_time[2] > 0x35)//分十位
{
g_time[2] = 0x30;
g_time[1]++;
g_myPar[13] = 0;
g_myPar[12]++;
if(g_time[1] > 0x33)//时个位
{
g_time[1] = 0x30;
g_time[0]++;
if(g_time[0] > 0x39)//时十位
{
g_time[0] = 0x30;
g_myPar[12]=0;
}//时十位
}//时个位
WriteLCD(0,0x98+4);
WriteLCD(1,g_time[0]);
WriteLCD(1,g_time[1]);
}//分十位
WriteLCD(0,0x98+5);
WriteLCD(1,:);
WriteLCD(1,g_time[2]);
}//分个位
WriteLCD(0,0x98+6);
WriteLCD(1,g_time[3]);
}//秒十位
}//秒个位
WriteLCD(0,0x98+7);
WriteLCD(1,g_time[4]);
WriteLCD(1,g_time[5]);
 
//显示充/放电状态
j++;
switch(j)
 
{
case 1:
WriteLCD(0,0x98+2);
WriteLCD(1, );
WriteLCD(1, );
WriteLCD(1, );
StartADC();
break;
case 2:
WriteLCD(0,0x98+2);
WriteLCD(1,.);
break;
case 3:
WriteLCD(0,0x98+2);
WriteLCD(1,.);
WriteLCD(1,.);
break;
case 4:
WriteLCD(0,0x98+3);
WriteLCD(1,.);
j = 0;
break;
default:
j = 0;
}
 
presence = Init_DS18B20();
if(presence==0)
{
WriteOneChar(0xCC); //跳过ROM匹配操作
Delay4us(10);
WriteOneChar(0x44); //启动温度转换
}
presence = Init_DS18B20();
if(presence==0)
{
WriteOneChar(0xCC); //跳过ROM匹配操作
Delay4us(10);
WriteOneChar(0xBE); //读取温度寄存器
Delay4us(10);
temp_data[0] = ReadOneChar(); //温度低8位
Delay4us(10);
temp_data[1] = ReadOneChar(); //温度高8位
if(presence==0)
{
if(temp_data[1]==0xff) presence=1;
}
}
 
if(g_CurIn == 5)
{
for(k=0;k<5;k++)
{
g_myPar[7+k] = Reverse(g_myPar[7+k]);
}
 
g_Percent = g_myPar[7+2]*1.56-48;//(U1f-4.8)/10*100
if(g_Percent>100) g_Percent = 0;
if(CutState==0)//充电模式
{
g_tt10 = (65536-5*(105-g_Percent))/256;
g_tt11 = (65536-5*(105-g_Percent))%256;
g_tt20 = (65536-5*(5+g_Percent))/256;
g_tt21 = (65536-5*(5+g_Percent))%256;
 
g_myPar[0]=g_tt10;
g_myPar[1]=g_tt11;
g_myPar[2]=g_tt20;
g_myPar[3]=g_tt21;
g_myPar[4]=g_tt10;
g_myPar[5]=g_tt11;
}
SqrtDuty = sqrt(1-g_Percent/100.0);
//Duty=g_myPar[0]*100/(g_myPar[0]+g_myPar[1]);
g_CurIn = 0;
}
 
if(CutState==2)//维护
{
WriteLCD(0,0x90);
DspNumber(g_myPar[7+2]*156);//电池电压
WriteLCD(1,V);
//g_Percent = g_myPar[4+2]*1.56-48;
DspPercent(g_Percent);
if(presence==0)
{
WriteLCD(0,0x90+5);
DspTemp(temp_data[1],temp_data[0]);
}
}
else if(CutState==1)//放电
{
//显示参数g_U0,g_U1p,g_U1f,g_U2,g_U3,
WriteLCD(0,0x90);
DspNumber(g_myPar[7+2]*156);//电池电压
WriteLCD(1,V);
//g_Percent = g_myPar[4+2]*1.56-48;
DspPercent(g_Percent);
WriteLCD(0,0x88+4);
WriteLCD(1,:);
DspNumber((g_myPar[7+2]-g_myPar[7])*31);//放电电流
if(presence==0)
{
WriteLCD(0,0x90+5);
DspTemp(temp_data[1],temp_data[0]);
}
}
else//充电
{
//显示参数g_U0,g_U1p,g_U1f,g_U2,g_U3,
WriteLCD(0,0x80);
DspNumber(g_myPar[7+2]*156);//电池电压
WriteLCD(1,V);
//g_Percent = g_myPar[4+2]*1.56-48;
DspPercent(g_Percent);
WriteLCD(0,0x90+4);
WriteLCD(1,:);
DspNumber(((g_myPar[7+4]-g_myPar[7+3])*78)*SqrtDuty);//充电电流
WriteLCD(0,0x88+4);
WriteLCD(1,:);
DspNumber(g_myPar[7+4]*156*SqrtDuty);//充电电压
if(presence==0)
{
WriteLCD(0,0x80+5);
DspTemp(temp_data[1],temp_data[0]);
}
}
}
 
 
}
 
//串口中断服务程序
void Serial() interrupt 4
{
if(RI)
{
RI = 0;
bSerialSending = 0;
if(SBUF == 5)
{
SBUF = 6;
 
}
else if(SBUF == 6)
{
SendSerialData();
}
else
{
SBUF = 0xff;
}
}
else
{
TI = 0;
if(bSerialSending)
{
if(g_CurSend<15)
{
SBUF = g_myPar[g_CurSend];
g_CurSend++;
 
}
else
{
bSerialSending = 0;
}
}
}
}
复制代码#include <lcd12864.h>//lcd12864相关控制
 
unsigned char code date[3][64]={" 0.000V  0%  0.0"
"充电电流: 0.000A"
"充电电压: 0.000V"
"充电... 00:00:00",
"正在测试电池性能"
" 0.000V  0%  0.0"
"放电电流: 0.000A"
"放电... 00:00:00",
"正在维护电池    "
" 0.000V  0%  0.0"
"电池健康度   0% "
"维护... 00:00:00"};
//毫秒延时
void Delay4us(unsigned char us)
{
while(us--);
}
 
//毫秒延时
void DelayMs(unsigned int ms)
{
unsigned char i;
while(ms--)
{
for(i=228; i>0; i--);
}
}
 
//初始化LCD显示
void InitLCDshow(unsigned char n)
{
unsigned char i;
WriteLCD(0,0x80); for(i=0;i<16;i++)  WriteLCD(1,date[n][i]);
WriteLCD(0,0x90); for(i=0;i<16;i++)  WriteLCD(1,date[n][i+16]);
WriteLCD(0,0x88); for(i=0;i<16;i++)  WriteLCD(1,date[n][i+32]);
WriteLCD(0,0x98); for(i=0;i<16;i++)  WriteLCD(1,date[n][i+48]);
}
 
//发送一个字节
void SendByteLCD(unsigned char bbyte)
{
unsigned char i;
for(i=0;i<8;i++)
{
SID=bbyte&0x80; //取出最高位
SCLK=1;
SCLK=0;
bbyte<<=1; //左移
}
}
 
//写指令或数据
//#pragma disable
void WriteLCD(unsigned char cmd, unsigned char num)//reentrant
{
if(cmd==0)
{
//start_num=0xf8;  //写指令
SendByteLCD(0xf8);     //发送起始信号
 
}
else
{
//start_num=0xfa;  //写数据
SendByteLCD(0xfa);     //发送起始信号
}
DelayMs(5);                        //延时是必须的
SendByteLCD(num & 0xf0);        //发送高四位
DelayMs(1);                        //延时是必须的
SendByteLCD((num<<4) & 0xf0);              //发送低四位
DelayMs(1);                        //延时是必须的
}
 
//显示一个数
void DspNumber(unsigned int num)
{
unsigned char i,dsp[5];
for(i=0;i<4;i++)
{
dsp[i] = num % 10;
dsp[i] += 0x30;
num /= 10;
}
if(num)
{
dsp[4] = num + 0x30;
}
else
{
dsp[4] = ;
}
WriteLCD(1,dsp[4]);
WriteLCD(1,dsp[3]);
WriteLCD(1,.);
WriteLCD(1,dsp[2]);
WriteLCD(1,dsp[1]);
WriteLCD(1,dsp[0]);
}
 
 
void DspPercent(unsigned char per)
{
unsigned char i;
i = per / 100;
per %= 100;
i += 0x30;
if(i==)i= ;
WriteLCD(1,i);
i = per / 10;
per %= 10;
i += 0x30;
if(i==)i= ;
WriteLCD(1,i);
per += 0x30;
WriteLCD(1,per);
}
//显示温度
void DspTemp(unsigned char num1,unsigned char num2)
{
unsigned char i;
num1 = num1<<4 | num2>>4;
num2 &= 0x0f;
num2 /= 1.6;
i = num1 / 100;
 
num1 %= 100;
WriteLCD(1, \%);
if(i)
{
WriteLCD(1, i+0x30);
i = num1 / 10;
num1 %= 10;
WriteLCD(1, i+0x30);
WriteLCD(1, num1+0x30);
}
else
{
WriteLCD(1, );
i = num1 / 10;
num1 %= 10;
if(i)
{
WriteLCD(1, i+0x30);
}
else
{
WriteLCD(1, );
}
WriteLCD(1, num1+0x30);
}
WriteLCD(1, .);
WriteLCD(1, num2+0x30);
/*    i = (num >> 4) + 0x30;
if(i>9)i+=7;
WriteLCD(1, i);
i = (num & 0x0f) + 0x30;
if(i>9)i+=7;
WriteLCD(1,i);*/
}
 
//初始化LCD
void InitLCD(void)
{
//PSB=0; ;     //串口驱动模式
DelayMs(10); //启动等待,等LCM讲入工作状态
 
RESET=0; DelayMs(1); RESET=1; // 复位LCD
CS=1;
WriteLCD(0,0x30);  //8 位介面,基本指令集
WriteLCD(0,0x0c);  //显示打开,光标关,反白关
WriteLCD(0,0x01);  //清屏,将DDRAM的地址计数器归零
}
 | 
 
12864, ARM , 电池 , 原理图 , ARM , ARM , ARM , ARM , ARM , ARM , ARM , ARM , ARM , ARM , ARM |