单片机c语言电子万年历完整程序.pdf
单单片片机机 c c 语语言言电电子子万万年年历历完完整整程程序序公司内部编号:(GOOD-TMMT-MMUT-UUPTY-UUYY-DTTI-该程序为51单片机c语言电子万年历#includereg52.h/#include#define uchar unsigned char#define uint unsigned intsbit lcden=P34;sbit lcdrs=P35;sbit DATA=P07;sbit RST=P05;sbit SCLK=P06;sbit menu=P30;/菜单sbit add=P31;/加一sbit dec=P37;/减一sbit led0=P10;sbit led1=P11;sbit led2=P12;sbit led3=P13;sbit ds=P32;/sbit beep=P33;uint temp;float f_temp;uint warn_l1=270;uint warn_l2=250;uint warn_h1=300;uint warn_h2=320;uint get_temp();void delayms(uint x);void write_com(uchar com);void write_data(uchar date);void init();void dis_temp(uint t);void Write1302(uchar dat);void WriteSet1302(uchar Cmd,uchar dat);uchar Read1302(void);uchar ReadSet1302(uchar Cmd);void Init_DS1302(void);void DisplaySecond(uchar x);void DisplayMinute(uchar x);void DisplayHour(uchar x);void DisplayDay(uchar x);void DisplayMonth(uchar x);void DisplayYear(uchar x);void DisplayWeek(uchar x);void dis_temp(uint t);void read_date(void);void turn_val(char newval,uchar flag,uchar newaddr,uchar s1num);void key_scan(void);uchar code table2=TUEWESTHUFRISATSUNMON;uchar second,minute,hour,day,month,year,week,count=0;uchar ReadValue,num,time;void delayms(uint x)uint i,j;for(i=x;i0;i-)for(j=110;j0;j-);/void write_com(uchar com)lcdrs=0;P2=com;delayms(5);lcden=1;delayms(5);lcden=0;void write_data(uchar date)lcdrs=1;P2=date;delayms(5);lcden=1;delayms(5);lcden=0;void init()lcden=0;write_com(0 x38);write_com(0 x0c);write_com(0 x06);write_com(0 x01);/void Write1302(uchar dat)uchar i;SCLK=0;/拉低 SCLK,为脉冲上升沿写入数据做好准备 delayms(2);/稍微等待,使硬件做好准备 for(i=0;i=1;/将 dat 的各数据位右移 1 位,准备写入下一个数据位 void WriteSet1302(uchar Cmd,uchar dat)RST=0;/禁止数据传递 SCLK=0;/确保写数居前 SCLK 被拉低 RST=1;/启动数据传输 delayms(2);/稍微等待,使硬件做好准备 Write1302(Cmd);/写入命令字 Write1302(dat);/写数据 SCLK=1;/将时钟电平置于已知状态 RST=0;/禁止数据传递 uchar Read1302(void)uchar i,dat;delayms(2);/稍微等待,使硬件做好准备 for(i=0;i=1;/将 dat 的各数据位右移 1 位,因为先读出的是字节的最低位 if(DATA=1)/如果读出的数据是 1 dat|=0 x80;/将 1 取出,写在 dat 的最高位 SCLK=1;/将 SCLK 置于高电平,为下降沿读出 delayms(2);/稍微等待 SCLK=0;/拉低 SCLK,形成脉冲下降沿 delayms(2);/稍微等待 return dat;/将读出的数据返回 uchar ReadSet1302(uchar Cmd)uchar dat;RST=0;/拉低 RST SCLK=0;/确保写数居前 SCLK 被拉低 RST=1;/启动数据传输 Write1302(Cmd);/写入命令字 dat=Read1302();/读出数据 SCLK=1;/将时钟电平置于已知状态 RST=0;/禁止数据传递 return dat;/将读出的数据返回void Init_DS1302(void)WriteSet1302(0 x8E,0 x00);/根据写状态寄存器命令字,写入不保护指令 WriteSet1302(0 x80,(0/10)4|(0%10);/根据写秒寄存器命令字,写入秒的初始值 WriteSet1302(0 x82,(59/10)4|(59%10);/根据写分寄存器命令字,写入分的初始值 WriteSet1302(0 x84,(23/10)4|(23%10);/根据写小时寄存器命令字,写入小时的初始值 WriteSet1302(0 x86,(28/10)4|(28%10);/根据写日寄存器命令字,写入日的初始值 WriteSet1302(0 x88,(2/10)4|(2%10);/根据写月寄存器命令字,写入月的初始值 WriteSet1302(0 x8c,(14/10)4|(14%10);/nian/WriteSet1302(0 x8a,(4/10)4)*10+(ReadValue&0 x0F);i=x/10;j=x%10;write_com(0 x80+0 x46);write_data(i+0 x30);write_com(0 x80+0 x47);write_data(j+0 x30);void DisplayMinute(uchar x)uchar i,j;i=x/10;j=x%10;write_com(0 x80+0 x43);write_data(i+0 x30);write_com(0 x80+0 x44);write_data(j+0 x30);write_com(0 x80+0 x45);write_data(:);void DisplayHour(uchar x)uchar i,j;i=x/10;j=x%10;write_com(0 x80+0 x40);write_data(i+0 x30);write_com(0 x80+0 x41);write_data(j+0 x30);write_com(0 x80+0 x42);write_data(:);void DisplayDay(uchar x)uchar i,j;i=x/10;j=x%10;write_com(0 x89);write_data(i+0 x30);write_com(0 x8a);write_data(j+0 x30);void DisplayMonth(uchar x)uchar i,j;i=x/10;j=x%10;write_com(0 x86);write_data(i+0 x30);write_com(0 x87);write_data(j+0 x30);write_com(0 x88);write_data(/);void DisplayYear(uchar x)uchar i,j;i=x/10;j=x%10;write_com(0 x81);write_data(2+0 x30);write_com(0 x82);write_data(0+0 x30);write_com(0 x83);write_data(i+0 x30);write_com(0 x84);write_data(j+0 x30);write_com(0 x85);write_data(/);void DisplayWeek(uchar x)uchar i;x=x*3;/write_com(0 x8c);write_data(table2x);/write_com(0 x8d);write_data(table2x+1);/write_com(0 x8e);write_data(table2x+2);write_com(0 x8c);for(i=0;i4)*10+(ReadValue&0 x0F);ReadValue=ReadSet1302(0 x83);minute=(ReadValue&0 x70)4)*10+(ReadValue&0 x0F);ReadValue=ReadSet1302(0 x85);hour=(ReadValue&0 x70)4)*10+(ReadValue&0 x0F);ReadValue=ReadSet1302(0 x87);day=(ReadValue&0 x70)4)*10+(ReadValue&0 x0F);ReadValue=ReadSet1302(0 x89);month=(ReadValue&0 x70)4)*10+(ReadValue&0 x0F);ReadValue=ReadSet1302(0 x8d);year=(ReadValue&0 x70)4)*10+(ReadValue&0 x0F);ReadValue=ReadSet1302(0 x8b);/读星期 week=ReadValue&0 x07;DisplayYear(year);DisplayMonth(month);DisplayDay(day);DisplayWeek(week);DisplayHour(hour);DisplayMinute(minute);DisplaySecond(second);dis_temp(get_temp();/温度显示 key_scan();/按键检测void turn_val(char newval,uchar flag,uchar newaddr,uchar s1num)newval=ReadSet1302(newaddr);/读取当前时间 newval=(newval&0 x70)4)*10+(newval&0 x0f);/将 bcd 码转换成十进制 if(flag)/判断是加一还是减一 newval+;switch(s1num)case 1:if(newval99)newval=0;DisplayYear(newval);break;case 2:if(newval12)newval=1;DisplayMonth(newval);break;case 3:if(newval31)newval=1;DisplayDay(newval);break;case 4:if(newval6)newval=0;DisplayWeek(newval);break;case 5:if(newval23)newval=0;DisplayHour(newval);break;case 6:if(newval59)newval=0;DisplayMinute(newval);break;case 7:if(newval59)newval=0;DisplaySecond(newval);break;default:break;else newval-;switch(s1num)case 1:if(newval=0)newval=99;DisplayYear(newval);break;case 2:if(newval=0)newval=12;DisplayMonth(newval);break;case 3:if(newval=0)newval=31;DisplayDay(newval);break;case 4:if(newval0)newval=6;DisplayWeek(newval);break;case 5:if(newval0)newval=23;DisplayHour(newval);break;case 6:if(newval0)newval=59;DisplayMinute(newval);break;case 7:if(newval0)newval=59;DisplaySecond(newval);break;default:break;WriteSet1302(newaddr-1),(newval/10)0)i-;ds=1;i=4;while(i0)i-;bit tempreadbit(void)uint i;bit dat;ds=0;i+;ds=1;i+;i+;dat=ds;i=8;while(i0)i-;return(dat);uchar tempread(void)uchar i,j,dat;dat=0;for(i=1;i=8;i+)j=tempreadbit();dat=(j1);return(dat);void tempwritebyte(uchar dat)uint i;uchar j;bit testb;for(j=1;j1;if(testb)ds=0;i+;i+;ds=1;i=8;while(i0)i-;else ds=0;i=8;while(i0)i-;ds=1;i+;i+;void tempchange(void)dsreset();delayms(1);tempwritebyte(0 xcc);tempwritebyte(0 x44);key_scan();/按键函数uint get_temp()uchar a,b;tempchange();/温度函数 dsreset();delayms(1);tempwritebyte(0 xcc);tempwritebyte(0 xbe);a=tempread();b=tempread();temp=b;tempwarn_l2)&(t=warn_l1)warn(40,0 x01);else if(t=warn_l2)warn(10,0 x03);else if(t=warn_h1)warn(40,0 x04);else if(t=warn_h2)warn(10,0 x0c);else i=40;while(i-)dis_temp(get_temp();DisSecond(second);/void main()init();Init_DS1302();while(1)tempchange();read_date();deal(temp);key_scan();/*void key_scan(void)/uchar miao,s1num=0;uchar s1num=0;if(menu=0)delayms(5);if(menu=0)while(!menu);s1num+;while(1)if(menu=0)delayms(5);if(menu=0)while(!menu);s1num+;/miao=ReadSet1302(0 x81);/second=miao;/WriteSet1302(0 x80,miao|0 x80);write_com(0 x0f);/光标闪射if(s1num=1)/year=ReadSet1302(0 x8d);write_com(0 x80+4);/年光标 if(add=0)delayms(3);if(add=0)while(!add);turn_val(year,1,0 x8d,1);if(dec=0)delayms(3);if(dec=0)while(!dec);turn_val(year,0,0 x8d,1);if(s1num=2)/month=ReadSet1302(0 x89);write_com(0 x80+7);/月光标 if(add=0)delayms(3);if(add=0)while(!add);turn_val(month,1,0 x89,2);if(dec=0)delayms(3);if(dec=0)while(!dec);turn_val(month,0,0 x89,2);if(s1num=3)/day=ReadSet1302(0 x87);write_com(0 x80+10);/日光标if(add=0)delayms(3);if(add=0)while(!add);turn_val(day,1,0 x87,3);if(dec=0)delayms(3);if(dec=0)while(!dec);turn_val(day,0,0 x87,3);/写入日寄存器 if(s1num=4)/week=ReadSet1302(0 x8b);write_com(0 x80+14);/星期光标 if(add=0)delayms(3);if(add=0)while(!add);turn_val(week,1,0 x8b,4);if(dec=0)delayms(3);if(dec=0)while(!dec);turn_val(week,0,0 x8b,4);if(s1num=5)/hour=ReadSet1302(0 x85)write_com(0 x80+0 x40+1);/时光标 if(add=0)delayms(3);if(add=0)while(!add);turn_val(hour,1,0 x85,5);if(dec=0)delayms(3);if(dec=0)while(!dec);turn_val(hour,0,0 x85,5);if(s1num=6)/调时间分/minute=ReadSet1302(0 x83);write_com(0 x80+0 x40+4);if(add=0)delayms(5);if(add=0)while(!add);turn_val(minute,1,0 x83,6);/写入分寄存器 if(dec=0)delayms(3);if(dec=0)while(!dec);turn_val(minute,0,0 x83,6);/写入分寄存器 if(s1num=7)/调时间秒/second=ReadSet1302(0 x81);write_com(0 x80+0 x40+7);/秒光标if(add=0)delayms(3);if(add=0)while(!add);if(second=0 x60)second=0 x00;turn_val(second,1,0 x81,7);if(dec=0)delayms(3);if(dec=0)while(!dec);turn_val(second,0,0 x81,7);if(s1num=8)/miao=ReadSet1302(0 x81);/second=miao;/WriteSet1302(0 x80,second&0 x7f);s1num=0;/s1num 清零/write_com(0 x0c);/光标不闪烁/break;