当前位置:文档之家› 单片机万年历DS12C887实现程序

单片机万年历DS12C887实现程序

#include <REG51.H>#include "1602.h"#include"ds12cr887.h"#define uchar unsigned char#define uint unsigned intsbit lcdrs=P3^7 ;sbit lcdrw=P3^6 ;sbit lcden=P3^5 ;sbit dscs=P1^4;sbit dsas=P1^5;sbit dsrw=P1^6;sbit dsds=P1^7;sbit dsirq=P3^3;/**************键盘引脚定义******************/sbit key_1 = P1^0; //设置格式sbit key_2 = P1^1; //+sbit key_3 = P1^2; //-sbit key_4 = P1^3; //定时设置sbit buzzer= P3^1; //蜂鸣器sbit DQ = P3^0; //定义DS18B20/******************小点闪烁********************/bit at=0;/******************全局变量********************/uchar t0=0,second=0, min=0, hour=0,day=0,month=0,year=0,weekday=0,flag=0,temp=0,flag1=0; /******************初始化时间******************/uchar code table1[]=" 2009-05-12 MON ";uchar code table2[]="00:00:00 0000";/*******************字符表*********************/uchar code word[]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x20,0x2d}; uchar code week[][3]={"SUN","MON","TUE","WED","THU","FRI","SAT"};/************数据缓冲与键盘计数变量************/uchar databuffer[14],TempBuffer[4],count,t_value;uint num=0;/******************函数声明********************/void init();void lcd_write_com(uchar command); //1602液晶写命令void lcd_write_data(uchar date); //1602液晶写数据void delay(uint a);void newbuf(); //数据转换void keyboard(); //键盘子程序void disp(); //显示程序void write_ds(uchar add,uchar date);uchar read_ds(uchar add);void Init_DS18B20( );void delay_18B20(unsigned int i);uchar ReadOneChar(void );void WriteOneChar(uchar dat);void ReadTemp(void);void temp_to_str();/***********************主函数**********************/void main(){init(); //初始化Init_DS18B20( ); //DS18B20初始化lcd_write_com(0x80+0x00); //设置指针地址为首行for(num=0;num<15;num++) //将table字符串写入{lcd_write_data(table1[num]);delay(20);}lcd_write_com(0x80+0x40); //设置指针地址为第二行for(num=0;num<13;num++) //将table1字符串写入{lcd_write_data(table2[num]);delay(20);}while(1){uchar b;keyboard(); //调整时间ReadTemp(); //开启温度采集程序temp_to_str(); //温度数据转换成液晶字符lcd_write_com(0x80+0x40+9);delay(20);for(b=0;b<4;b++){lcd_write_data(TempBuffer[b]);delay(20);}if(flag==0){second=read_ds(0x00);min=read_ds(0x02);hour=read_ds(0x04);weekday=read_ds(0x06);day=read_ds(0x07);month=read_ds(0x08);year=read_ds(0x09);}if(hour==0){ flag1=1;if(flag1==1){buzzer=0;}}newbuf();disp();if(!at) //闪烁{databuffer[2]=10;databuffer[5]=10;}else{databuffer[2]=11;databuffer[5]=11;}disp();at=~at;}}/*************************初始化*************************/void init(){lcd_write_com(0x38); //设置显示模式lcd_write_com(0x0c); //光标闪烁lcd_write_com(0x06);lcd_write_com(0x01); //清屏write_ds(0x0a,0x20);write_ds(0x0b,0x26);read_ds(0x0c);buzzer=1;EA=1;EX1=1;;IT0=1;}/***********************LCD1602写命令************************/ void lcd_write_com(uchar command){ //液晶1602写命令lcdrs=0;lcdrw=0;P2=command;delay(5);lcden=1;delay(5);lcden=0;}/*************************LCD1602写数据************************/ void lcd_write_data(uchar date){lcdrs=1; //液晶1602写数据lcdrw=0;P2=date;delay(5);lcden=1;delay(5);lcden=0;}/***************************延时函数****************************/ void delay(uint a){uint x,y;for(x=a;x>0;x--)for(y=110;y>0;y--);}/******************************缓冲数据处理*************************/ void newbuf() //更新缓冲区子程序{databuffer[0]=second%10;databuffer[1]=second/10;databuffer[3]=min%10;databuffer[4]=min/10;databuffer[6]=hour%10;databuffer[7]=hour/10;databuffer[8]=day%10;databuffer[9]=day/10;databuffer[10]=month%10;databuffer[11]=month/10;databuffer[12]=year%10;databuffer[13]=year/10;}/**************************液晶数据显示**************************/ void disp() //显示程序{uchar j=0;lcd_write_com(0x80+0x40); //设置指针地址为第二行lcd_write_data(word[databuffer[7]]); //小时十位lcd_write_data(word[databuffer[6]]); //小时个位lcd_write_data(word[databuffer[5]]);lcd_write_data(word[databuffer[4]]); //分十位lcd_write_data(word[databuffer[3]]); //分个位lcd_write_data(word[databuffer[2]]);lcd_write_data(word[databuffer[1]]); //秒十位lcd_write_data(word[databuffer[0]]); //秒个位lcd_write_com(0x80+0x03); //设置指针地址为第一行lcd_write_data(word[databuffer[13]]); //年十位lcd_write_data(word[databuffer[12]]); //年个位lcd_write_data(word[12]);lcd_write_data(word[databuffer[11]]); //月十位lcd_write_data(word[databuffer[10]]); //月个位lcd_write_data(word[12]);lcd_write_data(word[databuffer[9]]); //日十位lcd_write_data(word[databuffer[8]]); //日个位lcd_write_com(0x80+0x0c);for(j=0;j<3;j++){lcd_write_data( week[weekday-1][j]);}}/******************************键盘扫描*****************************/ void keyboard(){if(key_1==0){delay(50);if(key_1==0){ count++; //按键计数,设置模式while(!key_1);flag=1;if(count==1) //key_1键摁一次{lcd_write_com(0x80+0x40+7); //设置光标为秒位置lcd_write_com(0x0f);}if(count==2) //key_1键摁两次{lcd_write_com(0x80+0x40+4); //设置光标为分位置}if(count==3) //key_1键摁三次{lcd_write_com(0x80+0x40+1); //设置光标为时位置}if(count==4) //key_1键摁四次{lcd_write_com(0x80+0x09); //设置光标为日位置}if(count==5) //key_1键摁五次{lcd_write_com(0x80+0x06); //设置光标为月位置}if(count==6) //key_1键摁六次{lcd_write_com(0x80+0x03); //设置光标为年位置}if(count==7) //key_1键摁七次{lcd_write_com(0x80+0x0c); //设置光标为年位置}if(count==8) //key_1键摁八次{count=0; //摁键次数清零lcd_write_com(0x0c); //光标不显示write_ds(0x00,second);write_ds(0x02,min);write_ds(0x04,hour);write_ds(0x06,weekday);write_ds(0x07,day);write_ds(0x08,month);write_ds(0x09,year);flag=0;}}}if(count!=0) //key_1键摁后处理{if(key_2==0) //key_2键摁下处理{delay(50);if(key_2==0){while(!key_2);if(count==1) //key_1键摁一次{second++; //秒加一if(second==60)second=0;newbuf();disp();lcd_write_com(0x80+0x40+7);}if(count==2) //key_1键摁两次{min++; //分加一if(min==60)min=0;newbuf();disp();lcd_write_com(0x80+0x40+4);}if(count==3) //key_1键摁三次{hour++; //时加一if(hour==24)hour=0;newbuf();disp();lcd_write_com(0x80+0x40+1);}if(count==4) //key_1键摁四次{day++; //日加一if(day==32)day=1;newbuf();disp();lcd_write_com(0x80+0x09);}if(count==5) //key_1键摁五次{month++; //月加一if(month==13)month=1;newbuf();disp();lcd_write_com(0x80+0x06);}if(count==6) //key_1键摁六次{year++; //年加一if(year==100)year=0;newbuf();disp();lcd_write_com(0x80+0x03);}if(count==7) //key_1键摁六次{weekday++; //年加一if(weekday==8)weekday=1;disp();lcd_write_com(0x80+0x0c);}}}if(key_3==0) //key_3键摁下处理{delay(50);if(key_3==0){while(!key_3);if(count==1) //key_1键摁一次{second--; //秒减一if(second==-1)second=59;newbuf();disp();lcd_write_com(0x80+0x40+7);}if(count==2) //key_1键摁两次{min--; //分减一if(min==-1)min=59;newbuf();disp();lcd_write_com(0x80+0x40+4); }if(count==3) //key_1键摁三次{hour--; //时减一if(hour==-1)hour=23;newbuf();disp();lcd_write_com(0x80+0x40+1); }if(count==4) //key_1键摁四次{day--; //日减一if(day==-1)day=31;newbuf();disp();lcd_write_com(0x80+0x09);}if(count==5) //key_1键摁五次{month--; //月减一if(month==-1)month=12;newbuf();disp();lcd_write_com(0x80+0x06);}if(count==6) //key_1键摁六次{year--; //年减一if(year==-1)year=99;newbuf();disp();lcd_write_com(0x80+0x03);}if(count==7) //key_1键摁六次{weekday--; //年减一if(weekday==0)weekday=7;disp();lcd_write_com(0x80+0x0c);}}}}if(key_4==0){delay(50);if(key_4==0){ count++; //按键计数,设置模式while(!key_4);flag=1;if(count==1) //key_1键摁一次{lcd_write_com(0x80+0x40+7); //设置光标为秒位置lcd_write_com(0x0f);}if(count==2) //key_1键摁两次{lcd_write_com(0x80+0x40+4); //设置光标为分位置}if(count==3) //key_1键摁三次{lcd_write_com(0x80+0x40+1); //设置光标为时位置}if(count==4) //key_1键摁四次{count=0; //摁键次数清零lcd_write_com(0x0c); //光标不显示write_ds(0x01,second);write_ds(0x03,min);write_ds(0x05,hour);flag=0;}}}}/**********************DS12887写数据*****************/void write_ds(uchar add,uchar date) //ds12887写数据{dscs=0;dsas=1;dsds=1;dsrw=1;delay(5);P0=add;dsas=0;dsrw=0;delay(5);P0=date;dsrw=1;dsas=1;dscs=1;}/*************************DS12887读数据********************/ uchar read_ds(uchar add) //ds12887读数据{uchar ds_date;dsas=1;dsds=1;dsrw=1;dscs=0;delay(5);P0=add;dsas=0;dsds=0;delay(5);P0=0xff;ds_date=P0;//问题之处dsds=1;dsas=1;dscs=1;return ds_date;}void timealarm() interrupt 2{uchar c;buzzer=0;c=read_ds(0x0c);}/***********ds18b20延迟子函数(晶振12MHz )********/void delay_18B20(unsigned int i){while(i--);}/**********ds18b20初始化函数**********************/void Init_DS18B20(void){unsigned char x=0;DQ = 1; //DQ复位delay_18B20(8); //稍做延时DQ = 0; //单片机将DQ拉低delay_18B20(80); //精确延时大于480usDQ = 1; //拉高总线delay_18B20(14);x=DQ; //稍做延时后如果x=0则初始化成功x=1则初始化失败delay_18B20(20);}/***********ds18b20读一个字节**************/uchar ReadOneChar(void){uchar y=0;uchar dat = 0;for (y=8;y>0;y--){DQ = 0; // 给脉冲信号dat>>=1;DQ = 1; // 给脉冲信号if(DQ)dat|=0x80;delay_18B20(4);}return(dat);}/*************ds18b20写一个字节****************/void WriteOneChar(uchar dat){unsigned char z=0;for (z=8; z>0; z--){DQ = 0;DQ = dat&0x01;delay_18B20(5);DQ = 1;dat>>=1;}}/**************读取ds18b20当前温度************/void ReadTemp(void){unsigned char a=0;unsigned char b=0;unsigned char t=0;Init_DS18B20();WriteOneChar(0xCC); // 跳过读序号列号的操作WriteOneChar(0x44); // 启动温度转换delay_18B20(100); // this message is wery importantInit_DS18B20();WriteOneChar(0xCC); //跳过读序号列号的操作WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器)前两个就是温度delay_18B20(100);a=ReadOneChar(); //读取温度值低位b=ReadOneChar(); //读取温度值高位t_value=b<<4;t_value+=(a&0xf0)>>4;}void temp_to_str() //温度数据转换成液晶字符显示{TempBuffer[0]=t_value/10+'0'; //十位TempBuffer[1]=t_value%10+'0'; //个位TempBuffer[2]=0xdf; //温度符号TempBuffer[3]='C';}。

相关主题