基于51单片机的DS1302+LCD12864+DS18B20小综合.docx
《基于51单片机的DS1302+LCD12864+DS18B20小综合.docx》由会员分享,可在线阅读,更多相关《基于51单片机的DS1302+LCD12864+DS18B20小综合.docx(32页珍藏版)》请在冰豆网上搜索。
![基于51单片机的DS1302+LCD12864+DS18B20小综合.docx](https://file1.bdocx.com/fileroot1/2023-2/10/1687d8b2-143e-4d25-851d-c1ee6db485a0/1687d8b2-143e-4d25-851d-c1ee6db485a01.gif)
基于51单片机的DS1302+LCD12864+DS18B20小综合
#include
#include
#defineuintunsignedint
#defineucharunsignedchar
#definefirst_line0x80
#definesecond_line0x90
#definethird_line0x88
#defineforth_line0x98
#definesec_addr_pos0x04
#definemin_addr_pos0x02
#definehor_addr_pos0x00
#defineday_addr_pos0x05
#definemon_addr_pos0x03
#defineyer_addr_pos0x01
#definewek_addr_pos0x02
#definesbl_addr_pos0x04
#defineTep_addr_pos0x05
#defineTmp_addr_pos0x06
ucharcodeline_one[]="2016年10月31日";
ucharcodeline_two[]="14:
22:
45";
ucharcodeline_three[]="星期五-23℃";
ucharstr_wek[]="一二三四五六日℃";
charsecond,minute,hour,day,week,month,year;
ucharkey_flag,mode_cnt;
uinttemperature,symbol;//用于存储DS18B20采集的整个数据
ucharDS18B20_H;//用于存储DS18B20数据采集的整数部分
ucharDS18B20_L;//用于存储DS18B20数据采集的小数部分
ucharinit_18B20_fail;
sfrLCD_DATA=0x80;
sbitLCD_EN=P2^7;
sbitLCD_RS=P2^6;
sbitLCD_RW=P2^5;
sbitDS_CLK=P3^6;
sbitDS_RST=P3^5;
sbitDS_IO=P3^4;
sbitACC0=ACC^0;
sbitACC7=ACC^7;
sbitkey_1=P2^4;
sbitkey_2=P2^3;
sbitkey_3=P2^2;
sbitDQ=P3^7;
voiddelay_ms(uintms);
voiddelay_us(uintus);
bitbusy(void);
voidwrite_command(ucharcommand);
voidwrite_data(uchardat);
voidlcd_pos(ucharx,uchary);
voidLCD_init(void);
voidInput_1byte(ucharTD);
ucharOutput_1byte(void);
ucharRead_DS1302(ucharDS_ADD);
voidwrite_DS1302(ucharDS_ADD,ucharDS_DATE);
voidwrite_time(ucharaddr,ucharnum);
ucharBCD_to_Dec(ucharnum);
voidwrite_week(ucharnum);
voidwrite_date(ucharaddr,ucharnum);
ucharreadsecond(void);
ucharreadminute(void);
ucharreadhour(void);
ucharreadday(void);
ucharreadmonth(void);
ucharreadweek(void);
ucharreadyear(void);
voidreadtime(void);
voidDS1302_init(void);
voidkey_scan(void);
ucharDS18B20_read_byte(void);
voidDS18B20_write_byte(ucharbyte);
ucharDS18B20_Init(void);
uintread_temperature(void);
voidwrite_temp(uchartemp_h);
voidwrite_symbol(ucharaddr,ucharsymbol);
voiddisplay_18B20_err(void);
voidmain(void)
{
key_flag=0;
second=20;
minute=30;
hour=10;
day=31;
week=3;
month=12;
year=16;
LCD_init();
/*while
(1){
write_date(day_addr_pos,day);
write_date(mon_addr_pos,month);
write_date(yer_addr_pos,year);
write_time(sec_addr_pos,second);
write_time(min_addr_pos,minute);
write_time(hor_addr_pos,hour);
write_week(week);
}*/
if(!
(Read_DS1302(0x8E)&0x80)){
DS1302_init();
}
while
(1){
key_scan();
if(key_flag==0){
second=Read_DS1302(0x81);
write_time(sec_addr_pos,BCD_to_Dec(second));
minute=Read_DS1302(0x83);
write_time(min_addr_pos,BCD_to_Dec(minute));
hour=Read_DS1302(0x85);
write_time(hor_addr_pos,BCD_to_Dec(hour));
week=Read_DS1302(0x8B);
write_week(week);
day=Read_DS1302(0x87);
write_date(day_addr_pos,BCD_to_Dec(day));
month=Read_DS1302(0x89);
write_date(mon_addr_pos,BCD_to_Dec(month));
year=Read_DS1302(0x8D);
write_date(yer_addr_pos,BCD_to_Dec(year));
readtime();//读出十进制数,提供给按键进行数据的+/-的处理
temperature=read_temperature();
init_18B20_fail=DS18B20_Init();
if(init_18B20_fail==0){
//temperature=read_temperature();
if((temperature&0x8000)==0x8000)//判断读取的温度是正温度还是负温度
{
symbol=0x2D;
//write_symbol(0x0A,0x2C);//显示负号
temperature=~temperature+1;//负温度时处理,原数取反再加1
}else{
symbol=0xfe;
//write_symbol(0x0A,0xfe);//不显示正号
}
//write_symbol(0x0A,symbol);
DS18B20_H=(temperature>>4)&0x7f;//取温度读数的整数部分
DS18B20_L=temperature&0x0f;//取温度读数的小数部分
write_symbol(sbl_addr_pos,symbol);
write_temp(DS18B20_H);
}else{
display_18B20_err();
}
}
}
}
voiddelay_us(uintus)
{
while(us--);
}
voiddelay_ms(uintms)
{
uchari;
while(ms--){
for(i=250;i>0;i--){
_nop_();
_nop_();
_nop_();
_nop_();
}
}
}
bitbusy(void)
{
bitresult;
LCD_RS=0;
LCD_RW=1;
LCD_EN=1;
result=(bit)(LCD_DATA&0x80);
LCD_EN=0;
returnresult;
}
voidwrite_command(ucharcommand)
{
while(busy());
LCD_RS=0;
LCD_RW=0;
LCD_EN=1;
delay_us
(1);
LCD_DATA=command;
delay_us
(1);
LCD_EN=0;
}
voidwrite_data(uchardat)
{
while(busy());
LCD_RS=1;
LCD_RW=0;
LCD_EN=1;
delay_us
(1);
LCD_DATA=dat;
delay_us
(1);
LCD_EN=0;
}
voidlcd_pos(ucharx,uchary)
{
ucharpos;
if(x==0){
x=0x80;
}elseif(x==1){
x=0x90;
}elseif(x==2){
x=0x88;
}elseif(x==3){
x=0x98;
}
pos=x+y;
write_command(pos);
}
voidLCD_init(void)
{
uchari;
write_command(0x30);
delay_ms
(1);
write_command(0x30);
delay_ms
(1);
write_command(0x0C);
delay_ms
(1);
write_command(0x01);
delay_ms
(1);
write_command(0x06);
delay_ms
(1);
write_command(first_line);
for(i=0;i<16;i++){
write_data(line_one[i]);
}
write_command(second_line);
for(i=0;i<16;i++){
write_data(line_two[i]);
}
write_command(third_line);
for(i=0;i<16;i++){
write_data(line_three[i]);
}
}
voidInput_1byte(ucharTD)
{
uchari;
ACC=TD;
for(i=8;i>0;i--){
DS_IO=ACC0;
DS_CLK=1;
DS_CLK=0;
ACC=ACC>>1;
}
}
ucharOutput_1byte(void)
{
uchari;
for(i=8;i>0;i--)
{
ACC=ACC>>1;
ACC7=DS_IO;
DS_CLK=1;
DS_CLK=0;
}
return(ACC);
}
ucharRead_DS1302(ucharDS_ADD)
{
ucharDS_INF;
DS_RST=0;
DS_CLK=0;
DS_RST=1;
Input_1byte(DS_ADD);
DS_INF=Output_1byte();
DS_CLK=1;
DS_RST=0;
return(DS_INF);
}
voidwrite_DS1302(ucharDS_ADD,ucharDS_DATE)
{
DS_RST=0;
DS_CLK=0;
DS_RST=1;
Input_1byte(DS_ADD);
Input_1byte(DS_DATE);
DS_CLK=1;
DS_RST=0;
}
voidDS1302_init(void)
{
second=57;
minute=59;
hour=23;
day=30;
month=3;
week=5;
year=16;
write_DS1302(0x8E,0x00);//NWP
write_DS1302(0x80,(second/10)<<4|(second%10));
write_DS1302(0x82,(minute/10)<<4|(minute%10));
write_DS1302(0x84,(hour/10)<<4|(hour%10));
write_DS1302(0x86,(day/10)<<4|(day%10));
write_DS1302(0x88,(month/10)<<4|(month%10));
write_DS1302(0x8A,(week/10)<<4|(week%10));
write_DS1302(0x8C,(year/10)<<4|(year%10));
write_DS1302(0x8E,0x01);//WP
}
voidwrite_time(ucharaddr,ucharnum)
{
write_command(second_line+addr);
delay_ms(5);
write_data(0x30+num/10);
delay_ms(5);
write_data(0x30+num%10);
delay_ms(5);
}
ucharBCD_to_Dec(ucharnum)
{
ucharNUM_H,NUM_L,NUM;
NUM_H=num>>4;
NUM_L=num&0x0f;
NUM=((NUM_H*10))+NUM_L;
returnNUM;
}
voidwrite_week(ucharnum)
{
uchari;
switch(num){
case1:
write_command(third_line+wek_addr_pos);
for(i=0;i<2;i++){
write_data(str_wek[i]);
delay_ms(5);
}
break;
case2:
write_command(third_line+wek_addr_pos);
for(i=2;i<4;i++){
write_data(str_wek[i]);
delay_ms(5);
}
break;
case3:
write_command(third_line+wek_addr_pos);
for(i=4;i<6;i++){
write_data(str_wek[i]);
delay_ms(5);
}
break;
case4:
write_command(third_line+wek_addr_pos);
for(i=6;i<8;i++){
write_data(str_wek[i]);
delay_ms(5);
}
break;
case5:
write_command(third_line+wek_addr_pos);
for(i=8;i<10;i++){
write_data(str_wek[i]);
delay_ms(5);
}
break;
case6:
write_command(third_line+wek_addr_pos);
for(i=10;i<12;i++){
write_data(str_wek[i]);
delay_ms(5);
}
break;
case7:
write_command(third_line+wek_addr_pos);
for(i=12;i<14;i++){
write_data(str_wek[i]);
delay_ms(5);
}
break;
}
}
voidwrite_date(ucharaddr,ucharnum)
{
write_command(first_line+addr);
delay_ms(5);
write_data(0x30+num/10);
delay_ms(5);
write_data(0x30+num%10);
delay_ms(5);
}
/************************读出所有时间**********************/
voidreadtime(void)
{
readsecond();
readminute();
readhour();
readday();
readmonth();
readweek();
readyear();
}
/*****************读出秒的十进制数***************************/
ucharreadsecond(void)
{
uchardat;
dat=Read_DS1302(0x81);
second=((dat&0x70)>>4)*10+(dat&0x0f);
returnsecond;
}
/*****************读出分的十进制数***************************/
ucharreadminute(void)
{
uchardat;
dat=Read_DS1302(0x83);
minute=((dat&0x70)>>4)*10+(dat&0x0f);
returnminute;
}
/*****************读出小时的十进制数***************************/
ucharreadhour(void)
{
uchardat;
dat=Read_DS1302(0x85);
hour=((dat&0x70)>>4)*10+(dat&0x0f);
returnhour;
}
/*****************读出天的十进制数***************************/
ucharreadday(void)
{
uchardat;
dat=Read_DS1302(0x87);
day=((dat&0x70)>>4)*10+(dat&0x0f);
returnday;
}
/*****************读出月的十进制数***************************/
ucharreadmonth(void)
{
uchardat;
dat=Read_DS1302(0x89);
month=((dat&0x70)>>4)*10+(dat&0x0f);
returnmonth;
}
/*****************读出周的十进制数***************************/
ucharreadweek(void)
{
uchardat;
dat=Read_DS1302(0x8b);
week=((dat&0x70)>>4)*10+(dat&0x0f);
returnweek;
}
/*****************读出年的十进制数***************************/
ucharreadyear(void)
{
uchardat;
dat=Read_DS1302(0x8d);
year=((dat&0xf0)>>4)*10+(dat&0x0f);
returnyear;
}
voidkey_scan(void)
{
if(key_1==0){
delay_ms(5);
if(key_1==0){
while(!
key_1);
mode_cnt++;
key_flag=1;
write_DS1302(0x8E,0x00);
write_DS1302(0x80,0x80);
write_DS1302(0x8E,0x80);
if(mode_cnt==8){
key_flag=0;
mode_cnt=0;
write_command(0x0C);
write_DS1302(0x8E,0x00);
write_DS1302(0x80,0x00);
write_DS1302(0x80,(second/10)<<4|(second%10));
write_DS1302(0x82,(minute/10)<<4|(minute%10));
write_DS1302(0x84,(hour/10)<<4|(hour%10));
write_DS1302(0x86,(day/10)<<4|(day%10));
write_DS1302(0x88,(month/10)<<4|(month%10));
write_DS1302(0x8A,(week/10)<<4|(week%10));
write_DS1302(0x8C,(year/10)<<4|(year%10));
//write_DS1302(0x80,0x00);
write_DS1302(0x8E,0x80);
}
switch(mode_cnt){
case7:
write_