高级会员
主题
帖子
积分3385
阅读权限30
注册时间2012-12-18
最后登录1970-1-1
在线时间 小时
|
本帖最后由 SengChuary 于 2013-4-9 18:47 编辑
主程序:- #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;
- }
- }
- }
- }
复制代码 18B20程序:LCD12864程序:- #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的地址计数器归零
- }
复制代码 |
|