万年历时钟芯片代码

合集下载

单片机制作数字钟(含万年历、秒表功能)

单片机制作数字钟(含万年历、秒表功能)

数字钟、万年历制作(基于单片机)电路原理图:程序://********************20131206****数字钟程序#pragma SMALL#include <reg51.h>#include <absacc.h>#include <intrins.h>//********************************************************* *********编译预处理void display(unsigned char *p); //显示函数,P为显示数据首地址unsigned char keytest(); //按键检测函数unsigned char search(); //按键识别函数void alarm(); //闹钟判断启动函数void ftion0(); //始终修改函数void ftion1(); //闹钟修改函数void ftion3(); //日期修改函数void cum(); //加1修改函数void minus(); //减1修改函数void jinzhi(); //进制修改函数void riqi(); //日期void stopwatch(); //秒表函数//********************************************************* *******函数声明sbit P2_7=P2^7;//********************************************************* *******端口定义unsigned char clockbuf[3]={0,0,0};unsigned char bellbuf[3]={0,0,0};unsigned char date[3]={1,1,1}; //日期存放数组unsigned char stop[3]={0,0,0};unsigned char msec1,msec2;unsigned char timdata,rtimdata,dtimdata;unsigned char count;unsigned char *dis_p;unsigned char or; //12进制控制标志unsigned char ri; //日期显示控制标志位unsigned char mb; //秒表控制标志位bit arm,rtim,rhour,rmin,hour,min,sec,day,mon,year; //定义位变量//********************************************************* *****全局变量定义void main(){unsigned char a;or=0; //12进制修改标志清零ri=0;mb=0;P2_7=0;arm=0;msec1=0;msec2=0;timdata=0;rtimdata=0;count=0;TMOD=0x12;TL0=0x06;TH0=0x06;TH1=(65536-10000)/256;TL1=(65536-10000)%256;EA=1;ET0=1;ET1=1;TR0=1;TR1=0;dis_p=clockbuf;while(1){a=keytest();if(a==0x78) //判断是否有键按下{display(dis_p);if(arm==1) alarm();}else{display(dis_p);a=keytest();if(a!=0x78){a=search();switch(a){case 0x00:ftion0();break;case 0x01:ftion1();break;case 0x02:cum();break;case 0x06:jinzhi();break;case 0x03:riqi();break;case 0x04:ftion3();break;case 0x05:minus();break;case 0x07:stopwatch();break;case 0x09:TR1=1;break;case 0x0a:TR1=0;break;case 0x0b:stop[0]=0;stop[1]=0;stop[2]=0;break;default:break;}}}}}//********************************************主函数【完】void display(unsigned char *p){unsigned char buffer[]={0,0,0,0,0,0};unsigned char k,i,j,m,temp;unsigned char led[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};buffer[0]=p[0]/10;buffer[1]=p[0]%10;buffer[2]=p[1]/10;buffer[3]=p[1]%10;buffer[4]=p[2]/10;buffer[5]=p[2]%10;if((sec==0)&&(min==0)&&(hour==0)&&(rmin==0)&&(rhour==0)&&( day==0)&&(mon==0)&&(year==0)) //没有修改标志,正常显示{for(k=0;k<3;k++){temp=0x01;for(i=0;i<6;i++){P0=0x00; //段选端口j=buffer[i];P0=led[j];P1=~temp; //位选端口temp<<=1;for(m=0;m<200;m++);}}}else //若有修改标志,则按以下标志分别显示{if(sec==1||day==1){P1=0x1f;i=buffer[5];P0=led[i];for(m=0;m<200;m++);P1=0x2f;j=buffer[4];P0=led[j];for(m=0;m<200;m++);}if(min==1||rmin==1||mon==1){P1=0x3b;i=buffer[2];P0=led[i];for(m=0;m<200;m++);P1=0x37;j=buffer[3];P0=led[j];for(m=0;m<200;m++);}if(hour==1||rhour==1||year==1) {P1=0x3e;i=buffer[0];P0=led[i];for(m=0;m<200;m++);P1=0x3d;j=buffer[1];P0=led[j];for(m=0;m<200;m++);}}}//**********************************LED显示函数【完】unsigned char keytest(){unsigned char c;P2=0x78; //检测是否有键按下c=P2;c=c&0x78;return(c);}//******************************************键盘检测函数【完】unsigned char search(){unsigned char a,b,c,d,e;c=0x3f;a=0; //行号while(1){P2=c;d=P2;d=d&0x07;if(d==0x03){b=0;break;} //列号else if(d==0x05){b=1;break;}else if(d==0x06){b=2;break;}a++;c>>=1;if(a==5){a=0;c=0x3f;}}e=a*3+b;do{display(dis_p);}while((d=keytest())!=0x78);return(e);}//***********************************************查键值函数【完】void alarm(){if((clockbuf[0]==bellbuf[0])&&(clockbuf[1]==bellbuf[1])){P2_7=1;rtim=1;if(count==10){count=0;P2_7=0;arm=0;rtim=0;}}}//****************************************闹钟判断启动函数【完】void ftion0(){TR0=0;rhour=0;rmin=0;dis_p=clockbuf;rtimdata=0;timdata++;switch(timdata){case 0x01:sec=1;break;case 0x02:sec=0;min=1;break;case 0x03:min=0;hour=1;break;case 0x04:timdata=0;hour=0;TR0=1;break;default:break;}}//*********************************************时钟设置函数【完】void ftion1(){if(TR0==0) TR0=1;sec=0;min=0;hour=0;dis_p=bellbuf;timdata=0;rtimdata++;switch(rtimdata){case 0x01:rmin=1;break;case 0x02:rmin=0;rhour=1;break;case 0x03:rtimdata=0;rhour=0;arm=1;dis_p=clockbuf;break;default:break;}}//*********************************************闹钟设置函数【完】void ftion3(){if(TR0==0) TR0=1;day=0;mon=0;year=0;dis_p=date;timdata=0;rtimdata=0;dtimdata++;switch(dtimdata){case 0x01:day=1;break;case 0x02:day=0;mon=1;break;case 0x03:mon=0;year=1;break;case 0x04:dtimdata=0;year=0;dis_p=clockbuf;break;default:break;}}//*************************************************日期修改函数【完】void minus(){if(sec==1){if(0==clockbuf[2]) clockbuf[2]=59;else clockbuf[2]--;}else if(min==1){if(0==clockbuf[1]) clockbuf[1]=59;else clockbuf[1]--;}else if(hour==1){if(or==0) //判断进制{if(0==clockbuf[0]) clockbuf[0]=23;else clockbuf[0]--;}if(or==1){if(1==clockbuf[0]) clockbuf[0]=12;else clockbuf[0]--;}}else if(rmin==1){if(bellbuf[1]==0) bellbuf[1]=59;else bellbuf[1]--;}else if(rhour==1){if(or==0){if(bellbuf[0]==0) bellbuf[0]=23;else bellbuf[0]--;}if(or==1){if(bellbuf[0]==1) bellbuf[0]=12;else bellbuf[0]--;}}else if(day==1){if(date[2]==1) date[2]=31;else date[2]--;}else if(mon==1){if(date[1]==1) date[1]=12;else date[1]--;}else if(year==1){if(date[0]==1) date[0]=99;else date[0]--;}}//*************************************减1修改功能函数【完】void cum(){if(sec==1){if(59==clockbuf[2]) clockbuf[2]=0;else clockbuf[2]++;}else if(min==1){if(59==clockbuf[1]) clockbuf[1]=0;else clockbuf[1]++;}else if(hour==1){if(or==0) //判断进制{if(23==clockbuf[0]) clockbuf[0]=0;else clockbuf[0]++;}if(or==1){if(12==clockbuf[0]) clockbuf[0]=1;else clockbuf[0]++;}}else if(rmin==1){if(bellbuf[1]==59) bellbuf[1]=0;else bellbuf[1]++;}else if(rhour==1){if(or==0){if(bellbuf[0]==23) bellbuf[0]=0;else bellbuf[0]++;}if(or==1){if(bellbuf[0]==12) bellbuf[0]=1;else bellbuf[0]++;}}else if(day==1){if(date[2]==31) date[2]=1;else date[2]++;}else if(mon==1){if(date[1]==12) date[1]=1;else date[1]++;}else if(year==1){if(date[0]==99) date[0]=0;else date[0]++;}}//*************************************加1修改功能函数【完】void jinzhi(){if(or==0) or=1;else or=0;}//***********************************进制修改控制函数【完】void riqi(){if(ri==0){dis_p=date;}if(ri==1){dis_p=clockbuf;}ri++;if(ri==2) ri=0;}//********************************日期控显示函数【完】void stopwatch(){if(mb==0){dis_p=stop;mb=1;}else{mb=0;dis_p=clockbuf;}}//************秒表**********秒表**********秒表函数【完】void clock() interrupt 1{EA=0;if(msec1!=0x14) msec1++; //6MHz晶振定时10mselse{msec1=0;if(msec2!=100) msec2++; //定时1selse{if(rtim==1) count++; //闹钟启动标志计时10smsec2=0;if(clockbuf[2]!=59) clockbuf[2]++;else{clockbuf[2]=0;if(clockbuf[1]!=59) clockbuf[1]++;else{clockbuf[1]=0;if(or==0){if(clockbuf[0]!=23) clockbuf[0]++;else{clockbuf[0]=0;if((date[1]==1)||(date[1]==1)||(date[1]==1)||(date[1]==3)||(date[ 1]==5)||(date[1]==7)||(date[1]==8)||(date[1]==10)||(date[1]==12)){if(date[2]!=30) date[2]++;else{date[2]=1;if(date[1]!=11) date[1]++;else{date[1]=1;date[0]++;}}}if((date[1]==4)||(date[1]==6)||(date[1]==9)||(date[1]==11)){if(date[2]!=29) date[2]++;else{date[2]=1;if(date[1]!=11) date[1]++;else{date[1]=1;date[0]++;}}}if(date[1]==2){if((((date[0]%4==0)&&(date[0]%100!=0))||(date[0]%400==0))){if(date[2]!=28) date[2]++;else{date[2]=1;if(date[1]!=11) date[1]++;else{date[1]=1;date[0]++;}}}else{if(date[2]!=27) date[2]++;else{date[2]=1;if(date[1]!=11) date[1]++;else{date[1]=1;date[0]++;}}}}}}if(or==1){if(clockbuf[0]!=12) clockbuf[0]++;else{clockbuf[0]=0;if((date[1]==1)||(date[1]==1)||(date[1]==1)||(date[1]==3)||(date[ 1]==5)||(date[1]==7)||(date[1]==8)||(date[1]==10)||(date[1]==12)){if(date[2]!=30) date[2]++;else{date[2]=1;if(date[1]!=11) date[1]++;else{date[1]=1;date[0]++;}}}if((date[1]==4)||(date[1]==6)||(date[1]==9)||(date[1]==11)){if(date[2]!=29) date[2]++;else{date[2]=1;if(date[1]!=11) date[1]++;else{date[1]=1;date[0]++;}}}if(date[1]==2){if((((date[0]%4==0)&&(date[0]%100!=0))||(date[0]%400==0))){if(date[2]!=28) date[2]++;else{date[2]=1;if(date[1]!=11) date[1]++;else{date[1]=1;date[0]++;}}}else{if(date[2]!=27) date[2]++;else{date[2]=1;if(date[1]!=11) date[1]++;else{date[1]=1;date[0]++;}}}}}}}}}}EA=1;}//*******************************定时器0中断函数【完】void miaobiao() interrupt 3{TH1=(65536-10000)/256;TL1=(65536-10000)%256;if(stop[2]!=99) stop[2]++;else{stop[2]=0;if(stop[1]!=59) stop[1]++;else{stop[1]=0;if(stop[0]!=59) stop[0]++;else stop[0]=0;}}}//***********************************定时器1中断函数【完】。

单片机万年历程序带农历和闹钟

单片机万年历程序带农历和闹钟

#include < character.h >#include < lcd.h >#include < clock.h >#include < sensor.h>#include < calendar.h >#include < key.h >/*****************************预概念**************************************/#define uchar unsigned char#define uint unsigned int/****************************************************************************/ sbit bell = P2 ^ 0; //概念蜂鸣器端口sbit in = P2 ^ 7; //概念红外检测端口/***************************************************************************** * 名称: Timer0_Service() inturrupt 1* 功能: 中断效劳程序整点报时3声嘟嘟的声音* 入口参数:* 出口参数:*****************************************************************************/ void Timer0_Service() interrupt 1{static uchar count = 0;static uchar flag = 0; //记录鸣叫的次数count = 0;TR0 = 0; //关闭Timer0TH0 = 0x3c;TL0 = 0XB0; //延时50 msTR0 = 1 ; //启动Timer0count ++;if( count == 20 ) //鸣叫1 秒{bell = ~ bell;count = 0;flag ++;}if( flag == 6 ){flag = 0;TR0 = 0; //关闭Timer0}}/****************************************************************************** 名称: Timer2_Servie() interrupt 5* 功能: 中断效劳程序整点报时一分钟* 入口参数:* 出口参数:*****************************************************************************/ void Timer3_Service() interrupt 5{static uchar count;TF2 = 0; //软件清除中断标志count ++;if( in == 1 ){count = 0; //计算清0TR2 = 0; //关闭Timer2bell = 1; //关闭蜂鸣器}if( count == 120 ) // 一分钟后关闭报警{count = 0; //计算清0TR2 = 0; //关闭Timer2bell = 1; //关闭蜂鸣器}}/****************************************************************************** * 函数名称:main()* 功能:* 入口参数:* 出口参数:******************************************************************************* */void main( void ){uchar clock_time[7] = { 0x00, 0x17, 0x12, 0x14, 0x12, 0x08 }; //概念时刻变量秒分时日月年uchar alarm_time[2] = { 0, 0}; //闹钟设置alarm_time[0]: 分钟alarm_time[1] :小时uchar temperature[2]; //概念温度变量temperature[0] 低8位temperature[1] 高8位Lcd_Initial(); //LCD初始化Clock_Initial( clock_time ); //时钟初试化/***********************中断初始化***************************/EA = 1; //开总中断ET0 = 1; //Timer0 开中断ET2 = 1; //Timer2 开中断TMOD = 0x01 ; //Timer0 工作方式1RCAP2H = 0x3c;RCAP2L = 0xb0; //Timer2 延时50 mswhile( 1 ){switch( Key_Scan() ){case up_array: //{Key_Idle();}break;case down_array:{Key_Idle();}break;case clear_array:{Key_Idle();}break;case function_array:{Key_Function( clock_time, alarm_time );}case null:{Clock_Fresh( clock_time ); //时刻刷新Lcd_Clock( clock_time ); //时刻显示Sensor_Fresh( temperature ); //温度更新Lcd_Temperture( temperature ); //温度显示Calendar_Convert( 0 , clock_time );Week_Convert( 0, clock_time );//整点报时if( ( * clock_time == 0x59 ) && ( * ( clock_time + 1 ) == 0x59 ) ){bell = 0;TR2 = 1; //启动Timer2}//闹钟报警if( * alarm_time == * ( clock_time + 1 ) ) //分钟相吻合if( * ( alarm_time + 1 ) == *( clock_time + 2 ) ) //小时相吻合{bell = 0;TR2 = 1; //启动Timer2}}break;}}}#ifndef _SUN_MOON#define _SUN_MOON/*************************************************************************/#define uchar unsigned char#define uint unsigned int/****************************************************************************** *** 名称: get_moon_day(uchar month_p,uint table_addr)* 功能: 读取数据表中农历的大月或小月,若是大月返回1, 小月返回0* 入口参数:* 出口参数:******************************************************************************* **/bit get_moon_day( uchar month_p,uint calendar_address ){uchar temp;switch(month_p){case 1: { temp = year_code[calendar_address] & 0x08; if(temp==0) return(0); else return(1); }case 2: { temp = year_code[calendar_address] & 0x04; if(temp==0) return(0); else return(1); }case 3: { temp = year_code[calendar_address] & 0x02; if(temp==0) return(0); else return(1); }case 4: { temp = year_code[calendar_address] & 0x01; if(temp==0) return(0); else return(1); }case 5: { temp = year_code[calendar_address + 1] & 0x80; if(temp==0) return(0); else return(1); }case 6: { temp = year_code[calendar_address + 1] & 0x40; if(temp==0) return(0); else return(1); }case 7: { temp = year_code[calendar_address + 1] & 0x20; if(temp==0) return(0); else return(1); }case 8: { temp = year_code[calendar_address + 1] & 0x10; if(temp==0) return(0); else return(1); }case 9: { temp = year_code[calendar_address + 1] & 0x08; if(temp==0) return(0); else return(1); }case 10: { temp = year_code[calendar_address + 1] & 0x04; if(temp==0) return(0); else return(1); }case 11: { temp = year_code[calendar_address + 1] & 0x02; if(temp==0) return(0); else return(1); }case 12: { temp = year_code[calendar_address + 1] & 0x01; if(temp==0) return(0); else return(1); }case 13: { temp = year_code[calendar_address + 2] & 0x80; if(temp==0) return(0); else return(1); }}}/*************************************************************************** 名称: void Calendar_Convert( uchar * clock_time )* 功能: 输入BCD的阳历数据,输出BCD阴历数据( 1901 - 2099 )* 入口参数: c_flag:阳历的世纪标志clock_time: 时钟地址* 出口参数: 无* 说明: c_flag = 0 :21世纪c_flag = 1 :19世纪*****************************************************************************/ void Calendar_Convert( uchar c_flag, uchar * clock_time ){bit flag_month, flag_year;uchar year, month, day, month_point; //概念年月天uchar temp1, temp2, temp3;uint calendar_address; //概念农历地址uint day_number;uchar clock_moon[3]; //概念阴历clock_time += 3; //指向日day = ( * clock_time >> 4 ) * 10 + ( *clock_time & 0x0f ); //BCD转换十进制clock_time ++; //指向月month = ( * clock_time >> 4 ) * 10 + ( * clock_time & 0x0f ); //BCD转换十进制clock_time ++; //指向年year = ( * clock_time >> 4 ) * 10 + ( * clock_time & 0x0f ); //BCD转换十进制//定位日历地址if( c_flag == 0 )calendar_address = ( year + 99 ) * 3;elsecalendar_address = ( year - 1 ) * 3;//春节(正月初一)所在的阳历月份temp1 = year_code[ calendar_address + 2 ] & 0x60; //Bit6~~Bit5:春节所在的阳历月份temp1 >>= 5 ;//春节(正月初一)所在的阳历日期temp2 = year_code[ calendar_address + 2 ] & 0x1f; //Bit4~~Bit0:春节所在的阳历日期//计算春节(正月初一)离昔时元旦{ 1月1日(阳历) }的天数;春节只会在阳历的1月或2月if( temp1 == 1 )temp3 = temp2 - 1;elsetemp3 = temp2 + 31 - 1;//计算阳历月离昔时元旦{ 1月1日(阳历) }的天数if( month < 10 )day_number = day_code1[ month - 1 ] + day - 1;elseday_number = day_code2[ month - 10 ] + day - 1;//若是阳历的月大于2 且该年的2月为闰月,天数加1//闰年指的确实是阳历有闰日或阴历有闰月的一年;//阳历四年一闰,在二月加一天,这一天叫做闰日://农历三年一闰,五年两闰,十九年七闰,每逢闰年所加的一个月叫做闰月。

DS1302万年历芯片

DS1302万年历芯片

DS1302时钟时间芯片#include<reg52.h>#include<INTRINS.H>/************************************************************/#define uchar unsigned char#define uint unsigned int#define write_second 0x80 //秒开始数存储,修改用(下同)#define write_minute 0x82 //分开始数存储#define write_hour 0x84 //时开始数存储,12小时计时,从0开始要写入0x80(12小时要判断上下午)。

#define read_second 0x81 //秒,显示要读这个存储器#define read_minute 0x83 //分,显示要读这个存储器#define read_hour 0x85 //时,显示要读这个存储器#define write_day 0x86#define read_day 0x87#define write_month 0x88#define read_month 0x89#define write_week 0x8A#define read_week 0x8B#define write_year 0x8C#define read_year 0x8D#define write_protect 0x8E/************************************************************/ sbit ACC_7=ACC^7;sbit SCLK =P1^2;sbit DIO =P1^3;sbit CE =P1^4; //protus软件中的RES脚/********************************/uchar dd[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};void delay(char us){char m,n;while(us--){for(m=0;m<40;m++)for(n=0;n<50;n++);}}/**********/void write1302(unsigned char addr,dat){unsigned char i,temp; CE=0;SCLK=0;CE=1;for(i=0;i<8;i++){SCLK=0;temp=addr;if(temp&0x01==0x01) DIO=1;elseDIO=0;addr>>=1;SCLK=1;}for(i=0;i<8;i++){SCLK=0;temp=dat;if(temp&0x01==0x01) DIO=1;elsedat>>=1;SCLK=1;}}unsigned char read1302(unsigned char addr) {unsigned char i,temp,dat1,dat2;CE=0;SCLK=0;CE=1;for(i=8;i>0;i--)//дÈë¶ÁÊý¾ÝµØÖ·{SCLK =0;temp =addr;if(temp&0x01==0x01)DIO=1;elseDIO=0;addr>>=1;SCLK=1;for(i=8;i>0;i--)//¶ÁÊý¾Ý{ACC_7=DIO;SCLK=1;ACC>>=1;SCLK=0; //下降沿读出数据 }CE=0;dat1=ACC;dat2=dat1/16;dat1=dat1%16;dat1=dat1+dat2*10;return(ACC);}///////////////////////////////////// void Initial(void){write1302(write_protect,0x00); write1302(write_second,0x56); write1302(write_minute,0x34);write1302(write_hour,0x12);write1302(write_protect,0x80);}/////////////////////void main(void){unsigned char tt1,tt2,hour;Initial();write1302(write_second,0x55); //秒从55开始write1302(write_minute,0x59); //分从59开始write1302(write_hour,0x8B); //赋值0x80,为12小时计时,但低五位为计时为,所以,显示只显示低五位,小时从11开始write1302(write_year,0x0f); //15年write1302(write_week,0x03);//周三write1302(write_month,0x0a);//10月while(1){tt1=read1302(read_second);tt2=read1302(read_hour) & 0x1f; //取出低五位if(read1302(read_hour) & 0x20==0x20) //12小时计时判断上下午hour="pm "; // afternoonelsehour="am ";//morningP0=dd[tt1/10];P2=0xfe;delay(2);P2=0xff;P0=dd[tt1%10];P2=0xfd;delay(2);P2=0xff;P0=dd[tt2/10];P2=0xf7;delay(2);P2=0xff;P0=dd[tt2%10];P2=0xfb;delay(2);P2=0xff;}}。

基于PCF8563时钟芯片的万年历制作

基于PCF8563时钟芯片的万年历制作

万年历是一种能够显示日期、星期和时间的工具,它不仅能够告诉我们当天是几号,还能显示星期几和当前时间。

在这个项目中,我们将使用PCF8563时钟芯片来制作一个基于PCF8563的万年历。

PCF8563是一种CMOS实时时钟和日历芯片,它可以提供年、月、日、星期和小时、分钟、秒的数据。

它具有电源管理功能,可以通过一个电源低于2V脉冲输入来切换系统电源供电方式。

为了制作这个基于PCF8563的万年历,我们需要以下材料和工具:1. Arduino主控板2.PCF8563时钟芯片3.16x2液晶显示屏4.面包板5.杜邦线6.10k电阻接下来,我们将按照以下步骤来制作基于PCF8563的万年历:第一步:连接电路首先,将Arduino主控板插入面包板。

接着,连接PCF8563时钟芯片到Arduino主控板上的I2C总线。

将SDA引脚连接到A4引脚,将SCL引脚连接到A5引脚。

此外,还需要使用10k电阻将VCC引脚连接到VCC引脚上。

接下来,将16x2液晶显示屏连接到面包板。

连接液晶屏的RS引脚到Arduino主控板的D12引脚,RW引脚到GND引脚,和E引脚到D11引脚。

将液晶屏的D4到D7引脚连接到Arduino主控板的D5到D2引脚。

第二步:编写代码打开Arduino IDE并创建一个新的项目。

然后,编写以下代码:#include <Wire.h>#include <LiquidCrystal_I2C.h>//定义PCF8563的地址#define PCF8563_ADDR 0x51//定义显示屏的尺寸#define LCD_COLUMNS 16#define LCD_ROWS 2LiquidCrystal_I2C lcd(0x27, LCD_COLUMNS, LCD_ROWS);void setup//初始化I2C总线Wire.begin(;//设置时钟芯片为24小时模式Wire.beginTransmission(PCF8563_ADDR);Wire.write(0x02);Wire.write(0x00);Wire.endTransmission(;//初始化液晶显示屏lcd.begin(LCD_COLUMNS, LCD_ROWS);lcd.setCursor(0, 0);lcd.print("Date: ");lcd.setCursor(0, 1);lcd.print("Time: ");void loop//读取PCF8563的日期和时间Wire.beginTransmission(PCF8563_ADDR); Wire.write(0x02);Wire.endTransmission(;Wire.requestFrom(PCF8563_ADDR, 7);int second = bcdToDec(Wire.read( & 0x7F); int minute = bcdToDec(Wire.read();int hour = bcdToDec(Wire.read( & 0x3F); int dayOfWeek = bcdToDec(Wire.read();int dayOfMonth = bcdToDec(Wire.read();int month = bcdToDec(Wire.read( & 0x1F); int year = bcdToDec(Wire.read();//显示日期和时间lcd.setCursor(6, 0); printWithLeadingZero(dayOfMonth);lcd.print("/");printWithLeadingZero(month);lcd.print("/");lcd.print(2000 + year);lcd.setCursor(6, 1); printWithLeadingZero(hour);lcd.print(":");printWithLeadingZero(minute);lcd.print(":");printWithLeadingZero(second);delay(1000);//将BCD码转换为十进制int bcdToDec(int bcd)return (bcd / 16 * 10) + (bcd % 16);//打印带有前导零的数字void printWithLeadingZero(int number)if (number < 10)lcd.print('0');}lcd.print(number);第三步:上传代码将Arduino主控板连接到电脑,并根据需要选择正确的端口和板类型。

(完整word版)万年历(DS1302+LCD1602【程序、仿真、完整】)

(完整word版)万年历(DS1302+LCD1602【程序、仿真、完整】)

基于52单片机的万年历显示(采用实时芯片DS1302芯片+LCD1602液晶显示)仿真图:/************************************************************-- THE LCD1602 DISPLAY LIB -—COPYRIGHT (C) 2014 BY LLH-— ALL RIGHTS RESERVED —-ATTENTION:延时不能过长,否则无法与DS1302同步(最好小于1ms)*************************************************************/#ifndef __LCD1602_DIS_H__#define __LCD1602_DIS_H__#define uint unsigned int#define uchar unsigned charsbit lcd_rs=P2^0;sbit lcd_rw=P2^1;sbit lcd_en=P2^2;/**********延时子程序************/void delay(uint z){uint x,y;for(x=z;x〉0;x—-)for(y=65;y〉0;y--);//60刚好和DS1302同步}/***********写命令子程序**********/void write_com(uchar com){lcd_rs=0;lcd_rw=0;P0=com;delay(1);lcd_en=1;delay(1);lcd_en=0;}/***********写数据子程序**********/void write_data(uchar date){lcd_rs=1;lcd_rw=0;P0=date;delay(1);lcd_en=1;delay(1);lcd_en=0;}/**********初始化子程序************/void init_LCD1602(){lcd_en=0;write_com(0x38); //显示模式设置:16*2显示,5*7点阵,8位数据接口write_com(0x0c); //开显示,不显示光标write_com(0x06); //指针、光标自动加一,整屏不移动write_com(0x80); //初始位置设置}/*********显示子程序***********/void display(uchar *str){while(*str!='\0’){write_data(*str);str++;}}#endifDS1302的H文件:/******************************************************************—— THE DS1302 REAL_TIME LIB —-COPYRIGHT (C) 2014 BY LLH-- ALL RIGHTS RESERVED ——ATTENTION:不能使用(i=0;i<8;i++),否则,液晶无法显示确切的时间(???);星期的显示多了一天(???)********************************************************************/#ifndef __DS1302_REAL_TIME_H__#define __DS1302_REAL_TIME_H__#define uint unsigned int#define uchar unsigned charsbit DS1302_RST=P1^5;sbit DS1302_SCLK=P1^6;sbit DS1302_IO=P1^7;sbit ACC0=ACC^0;sbit ACC7=ACC^7;typedef struct{uchar second;uchar minute;uchar hour;uchar week;uchar day;uchar month;uchar year;uchar date_str[11];uchar time_str[9];}date_time;/**************写数据定义*****************/#define DS1302_SECOND 0x80#define DS1302_MINUTE 0x82#define DS1302_HOUR 0x84#define DS1302_WEEK 0x8A#define DS1302_DAY 0x86#define DS1302_MONTH 0x88#define DS1302_YEAR 0x8C#define ST 0x00/*************单字节写数据子程序**************/void single_byte_write(uchar date){uchar i;ACC=date;for(i=8;i〉0;i--) //不能使用(i=0;i〈8;i++),否则,液晶只显示00000{DS1302_IO=ACC0;DS1302_SCLK=1;DS1302_SCLK=0;ACC=ACC>>1;}}/*************单字节读数据子程序**************/uchar single_byte_read( ){uchar i;for(i=8;i>0;i--){ACC=ACC>〉1;ACC7=DS1302_IO;DS1302_SCLK=1;DS1302_SCLK=0;}return ACC;}/**************控制字的写入****************/void write_command(uchar addr,uchar dat){DS1302_SCLK=0;DS1302_RST=0;DS1302_RST=1;single_byte_write(addr);single_byte_write(dat);DS1302_SCLK=1;DS1302_RST=0;}/**************读取芯片内部的数据****************/uchar read_data(uchar address){uchar r_data;DS1302_SCLK=0;DS1302_RST=0;DS1302_RST=1;single_byte_write(address|0x01);//若没加(或0x01)ds1302和lcd1602都无法正常显示(?)r_data=single_byte_read();DS1302_SCLK=1;DS1302_RST=0;return r_data;}/************初始化子程序************/void init_DS1302(){uchar temp;temp=read_data(DS1302_SECOND);if(temp&0x80){write_command(0x8e,0x00); //启动读写write_command(0x84,0x00);//设置24小时模式write_command(DS1302_SECOND,ST); //写入当前时间数据}}/*************读取时间、并实现BCD和十进制间的转化***************//****************************************************************十进制转8421编码:32/10 = 3*16= 48(十进制)= 30(16进制)32%10 = 230+2 = 32 * 16 + 32 % 10 = 32(8421编码)(即:a/10*10+a%10)8421编码转十进制:51 / 16 = 5 * 10(16进制) = 50(十进制)51 % 16 = 150 + 1 = 51 / 16 + 51 % 16 = 51(十进制)(即:a/16*10+a%16)*****************************************************************/void get_time(date_time *Time){uchar value;value=read_data(DS1302_SECOND);Time—〉second=(value/16)*10+(value%16);value=read_data(DS1302_MINUTE);Time—〉minute=(value/16)*10+(value%16);value=read_data(DS1302_HOUR);(完整word版)万年历(DS1302+LCD1602【程序、仿真、完整】) Time-〉hour=(value/16)*10+(value%16);value=read_data(DS1302_WEEK);Time—〉week=(value/16)*10+(value%16-1);//星期的显示数值比正确值多一value=read_data(DS1302_DAY);Time-〉day=(value/16)*10+(value%16);value=read_data(DS1302_MONTH);Time—>month=(value/16)*10+(value%16);value=read_data(DS1302_YEAR);Time-〉year=(value/16)*10+(value%16);}/**************年-月-日-星期“字符”显示***************/void date_to_str(date_time *Time){Time-〉date_str[0]=Time-〉year/10+’0’; //加’0’转化成字符Time—〉date_str[1]=Time—〉year%10+’0';Time->date_str[2]='—’;Time->date_str[3]=Time->month/10+'0';Time->date_str[4]=Time-〉month%10+'0’;Time—>date_str[5]=’—’;Time-〉date_str[6]=Time-〉day/10+'0';Time—>date_str[7]=Time—>day%10+’0’;Time-〉date_str[8]=’-’;Time->date_str[9]=Time—〉week%10+’0’;Time-〉date_str[10]='\0';}/**************时-分-秒“字符”显示***************/void time_to_str(date_time *Time){Time—>time_str[0]=Time->hour/10+’0';Time-〉time_str[1]=Time—〉hour%10+’0';Time—>time_str[2]=’-';Time—>time_str[3]=Time—>minute/10+'0’;Time—>time_str[4]=Time—>minute%10+'0’;Time->time_str[5]='—';Time->time_str[6]=Time->second/10+'0';Time->time_str[7]=Time—>second%10+'0';Time-〉time_str[8]=’\0';}#endif万年历C文件:/********************************************************* TITLE: 实时时钟FUNCTION: DS1302+LCD1602显示实时时钟WRITER: LINLIANHUO(完整word版)万年历(DS1302+LCD1602【程序、仿真、完整】) TIME: 2014-07-30REMARK: matters need attention**********************************************************/#include 〈reg51.h〉#include <string.h〉#include ”DS1302。

PIC单片机-多功能万年历电子钟

PIC单片机-多功能万年历电子钟

PIC单片机-多功能万年历电子钟;*********************************************************************************LIST P=PIC16F72#INCLUDE<P16F72.INC>;********************************************************************************#DEFINE DIO_A PORTA ;RA端口寄存器#DEFINE DIO_B PORTB ;RB端口寄存器#DEFINE DIO_C PORTC ;RC端口寄存器#DEFINE SIO_A TRISA ;RA端口输入、输出设定#DEFINE SIO_B TRISB ;RB端口输入、输出设定#DEFINE SIO_C TRISC ;RC端口输入、输出设定;===============数码管共脚位定义=============================#DEFINE HOUH_LED PORTB,3 ;数码管位选#DEFINE HOUL_LED PORTB,2 ;数码管位选#DEFINE MINH_LED PORTB,1 ;数码管位选#DEFINE MINL_LED PORTB,0 ;数码管位选#DEFINE SEC_LED PORTB,4 ;LED位选;===============按键脚位定义=================================#DEFINE SETUP_KEY PORTA,3 ;时钟设置键#DEFINE INCREASE_KEY PORTA,4 ;时间加键#DEFINE DECREASE_KEY PORTA,5 ;时间减键;============== DS1302引脚定义==============================#DEFINE T_CLK PORTA,0 ;1302时钟->7#DEFINE T_IO PORTA,1 ;1302数据输入/输出->6#DEFINE T_RST PORTA,2 ;1302使能位->5#DEFINE SET_IO TRISA,1 ;设定1302I_O;========================================================================== #DEFINE FLAG_10S FLAG,7 ;#DEFINE FLAG_SETUP FLAG,6 ;#DEFINE FLAG_500MS FLAG,5 ;#DEFINE FLAG_250MS FLAG,4 ;#DEFINE FLAG_MINUTE FLAG,3 ;#DEFINE FLAG_HOUR FLAG,2 ;#DEFINE FLAG_TIME FLAG,1 ;#DEFINE FLAG_DATE FLAG,0 ;;========================================================================== #DEFINE FLAG_YEAR FLAG1,7 ;#DEFINE FLAG_DAY FLAG1,6 ;#DEFINE FLAG_DATA FLAG1,5 ;;*********************寄存器定义***************************ID_TEMP EQU 72HW_TEMP EQU 73HSTATUS_TEMP EQU 74HPCLATH_TEMP EQU 75HERRORLEVEL -302CBLOCK 020HSEC ;秒寄存器MINUTE ;分寄存器HOUR ;小时寄存器DATE ;日寄存器MONTH ;月寄存器DAY ;星期寄存器YEAR ;年寄存器WRITE_ENABLED ;写使能寄存器DS1302_RX ;保存接受的1个数据DS1302_TX ;准备写入到DS1302的一个数据BYTE_COUNT ;字节数寄存器BIT_COUNT ;BIT数寄存器TEMP1 ;转换进制用TIMER0 ;\TIMER1 ;定时用TIMER2 ;/;-------------------------------------FLAGFLAG1FSR_TEMPCOUNTCOUNT1 ;显示数据位数COUNT2 ;显示数据表中位置COUNT3 ;显示位置COUNT4CNTCNT0CNT1CNT2SHOW_MINSHOW_HOUDATA_INCDATEPC1 ;C2 ;C3 ;ENDC;*******************宏定义********************************* BANK1 MACRO ;体1BSR STATUS,RP0BCR STATUS,RP1ENDMBANK0 MACRO ;体0BCR STATUS,RP0BCR STATUS,RP1ENDM;-------------------------------------------------------------------;子程序名:;功能:中断服务主程序入口;功能说明:;----------------------------------------------------------------- INTERMIT_SERVE:;---------现场保护-----------------------STWR W_TEMP ;SWAPR STATUS,W ;CLRR STATUS ;STWR STATUS_TEMP ;LDR PCLATH,W ;STWR PCLATH_TEMP ;CLRR PCLATH ;;-------中断服务-------------------------INCR TIMER0,F ;\LDWI .100 ;\XORWR TIMER0,W ;判断是否到250MSBTSS STATUS,Z ;/LJUMP AAA ;ON,LDWI B'00010000' ;\每到250MS取反一次标志位1 XORWR FLAG,F ;/CLRR TIMER0INCR TIMER1,F ;\LDWI .2 ;\XORWR TIMER1,W ;判断是否到500MSBTSS STATUS,Z ;/LJUMP AAA ;ON,LDWI B'00100000' ;\每到500MS取反一次标志位1 XORWR FLAG,F ;/CLRR TIMER1 ;YES,INCR TIMER2,F ;\LDWI .20 ;\XORWR TIMER2,W ;判断是否到5SBTSS STATUS,Z ;/LJUMP $+3 ;/CLRR TIMER2 ;YES,BSR FLAG_10S ;DP_SECLCALL PLAY_SECANDWI 0F0HSTWR DIO_BCLRR DIO_CINCR COUNT,FLDWI 01H ;;;;;;;;;;;;;;;;;XORWR COUNT,WBTSC STATUS,ZLCALL PLAY_HOUR_H ;LDWI 02H ;;;;;;;;;;;;;;;;;;;XORWR COUNT,WBTSC STATUS,ZLCALL PLAY_HOUR_L ;LDWI 03H ;;;;;;;;;;;;;;;;;;XORWR COUNT,WBTSC STATUS,ZLCALL PLAY_MINUTE_H ;LDWI 04H ;;;;;;;;;;;;;;;;XORWR COUNT,WBTSS STATUS,ZLJUMP $+3CLRR COUNTLCALL PLAY_MINUTE_L ;LDWI 0D9H ;\STWR TMR0 ;/写入TMR0初始值BCR INTCON,T0IF ;清TMR0中断标志;-------恢复现场-------------------LDR PCLATH_TEMP,W ;STWR PCLATH ;SWAPR STATUS_TEMP,F ;STWR STATUS ;SWAPR W_TEMP,F ;SWAPR W_TEMP,W ;RTFI ;中断返回;............................................................. ;子程序名:;功能:清寄存器;功能说明: ;................................................................CLR_RAM:LDWI 20HSTWR FSRCLRR INDFINCR FSR,FLJUMP $-3RTIW 00H;--------------------------------------------------------------------------;子程序名:;功能:查表子程序;功能说明:用于显示0-9时钟数据字型码,共阳LED无小数点;--------------------------------------------------------------------------- TABLE:ADDWR PCL,FRTIW B'11001111' ;0RTIW B'00000101' ;1RTIW B'11011100' ;2RTIW B'10011101' ;3RTIW B'00010111' ;4RTIW B'10011011' ;5RTIW B'11011011' ;6RTIW B'00001101' ;7RTIW B'11011111' ;8RTIW B'10011111' ;9;...........Program Initialization........................................;子程序名: 单片机复位进入点;功能:;功能说明: ;............................................................................PORT_INIT:CLRR INTCON ;清除中断BANK1 ;\LDWI B'00000000' ;\STWR SIO_C ;\RC口设为输出LDWI B'11100000' ;\STWR SIO_B ;/RB口设为输入LDWI B'11111000' ;\STWR SIO_A ;LDWI 06H ;STWR ADCON1 ;A口配置为普通数字I/OLDWI B'10000101' ;\ 设TMR0分频1:64STWR OPTION_REG ;/RB口同时输入、出时不能上拉BANK0 ;;----------------------------------CLRR DIO_A ;清控制位CLRR DIO_BCLRR DIO_C ;\关闭显示LDWI 0DAH ;\写入TMR0初始值STWR TMR0 ;/2.5MS中断一次LDWI B'10100000' ;\开TMR0中断使能位STWR INTCON ;/LCALL CLR_RAM ;->清寄存器LCALL DS1302_INIT ;->初始化DS1302LCALL READ_DS1302 ;;CALL DATE_INIT ;\;CALL WRITE_DS1302 ;/写数据LCALL QINDON_INITMOVFW DATESTWR DATEP ;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ;程序名:;功能:;功能说明: ;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% MAIN_PROGRAM:BTSC FLAG_SETUPLJUMP $+3;NOP;NOPLCALL DELAY250MSLCALL READ_DS1302 ;BTSS FLAG_10S ;检测是否到5SLJUMP $+3 ;CLRR FLAG ;3S到,退出校正时间状态CLRR FLAG1 ;MOVFW DATEXORWR DATEP,WBTSC STATUS,ZLJUMP TEST_KEYLDWI 030HSUBWR SEC,WBTSS STATUS,ZLJUMP TEST_KEY ;->检测按键LDWI 005HSUBWR SEC,FLCALL WRITE_DS1302 ;写入设置的数据MOVFW DATESTWR DATEPLJUMP MAIN_PROGRAM ;循环;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% TEST_KEY:NOP ;\LDR DIO_A,W ;\ANDWI B'00111000' ;\XORWI B'00111000' ;检测是否有按键按下?BTSC STATUS,Z ;/LJUMP MAIN_PROGRAM ;/BCR FLAG_10S ;YES,重新启动5S到标记CLRR TIMER2 ;/;------------------------------------------------------BTSC FLAG_DATA ;显示日期时禁止调整LJUMP MAIN_PROGRAM ;/BTSS SETUP_KEY ;检测是否按时间设置键?LJUMP SETUP ;YES,跳设置键处理程序BTSS INCREASE_KEY ;检测是否按增键?LJUMP INCREASE ;YES,BTSS DECREASE_KEY ;检测是否按减键?LJUMP DECREASE ;YES,LJUMP MAIN_PROGRAM ;;时间设置键处理--------------------SETUP:LCALL DELAY_10MS ;\BTSS SETUP_KEY ;检测设置键是否松开?LJUMP $-2 ;/LCALL DELAY_10MS ;LDWI SHOW_HOU ;STWR FSR ;第一个调整单元LDWI 24HSTWR DATA_INC ;调整最大值BSR FLAG_SETUPBSR FLAG_HOURBSR FLAG_TIMELJUMP TEST_KEYDEC_MIN:INCR COUNT2,FLDWI 01H ;;;;;;;;;;;;;;;;;;;;;;;XORWR COUNT2,WBTSS STATUS,ZLJUMP DEC_MON ;02HLDWI SHOW_MINSTWR FSR ;调整单元地址LDWI 60HSTWR DATA_INC ;调整最大值BSR FLAG_MINUTEBCR FLAG_HOURDEC_MONXORWR COUNT2,WBTSS STATUS,ZLJUMP DEC_DATE ;03HBSR FLAG_HOURBCR FLAG_MINUTEBSR FLAG_DATEBCR FLAG_TIMEDEC_DATELDWI 03H ;;;;;;;;;;;;;;;;;;;XORWR COUNT2,WBTSS STATUS,ZLJUMP DEC_YEAR ;04HLDWI SHOW_MINSTWR FSR ;调整单元地址LDWI 32HSTWR DATA_INC ;调整最大值BSR FLAG_MINUTEBCR FLAG_HOURDEC_YEARLDWI 04H ;;;;;;;;;;;;;;;;;;XORWR COUNT2,WBTSS STATUS,ZLJUMP DEC_DAY ;05HMOVFW SHOW_HOUSTWR MONTHMOVFW SHOW_MINBCR FLAG_MINUTEBSR FLAG_YEARBCR FLAG_DATEDEC_DAYLDWI 05H ;;;;;;;;;;;;;;;;;;;XORWR COUNT2,WBTSS STATUS,ZLJUMP DEC_END ;06HLDWI SHOW_MINSTWR FSR ;调整单元地址LDWI 08HSTWR DATA_INC ;调整最大值BSR FLAG_MINUTEBCR FLAG_HOURBSR FLAG_DAYBCR FLAG_YEARDEC_ENDXORWR COUNT2,WBTSS STATUS,ZLJUMP DEC1 ;MOVFW SHOW_HOUSTWR YEARMOVFW SHOW_MINSTWR DAYCLRR COUNT2 ;清BCR FLAG_SETUP ;清标示BCR FLAG_DAYBCR FLAG_MINUTELCALL WRITE_DS1302 ;写入设置的数据DEC1LJUMP TEST_KEY ;;增加键处理++++++++++++++++++++++++++++++++++++++++++++++++ INCREASE:LCALL DELAY_10MS ;\BTSS INCREASE_KEY ; 检测是否松开加键?LJUMP $-2 ;/LCALL DELAY_10MS ;BTSS FLAG_SETUP ;检测是否已进入设置状态?LJUMP $+8 ;YES,处理数据调整LCALL BCD_B ;先BCD数据转换成2进制,INCR INDF,F ;当前地址数据加1LCALL B_BCD ;再将2进制数据转换成BCD码,写如该单元;判断调整到上限?MOVFW DATA_INC ;\XORWR INDF,W ;\判断当前地址数据变量大小BTSC STATUS,Z ;/CLRR INDF ;/LJUMP MAIN_PROGRAM ;/;减少键处理================================================= DECREASE:LCALL DELAY_10MS ;\BTSS DECREASE_KEY ;检测是否松开减键?LJUMP $-2 ;/LCALL DELAY_10MS ;BTSS FLAG_SETUP ;检测是否已进入设置状态?LJUMP $+7 ;YES,处理数据调整LCALL BCD_B ;BCD码转2进制LDR INDF,W ;\BTSC STATUS,Z ;判断下限减到0?LJUMP MAIN_PROGRAM ;/DECR INDF,F ;LCALL B_BCD ;2进制转BCD码LJUMP MAIN_PROGRAM ;返回主程序;...........Program Initialization........................................;子程序名:;功能:启动DS1302开始计时;功能说明: ;............................................................................QINDON_INITBCR T_CLK ;\BCR T_RST ;先禁止LDWI B'10000000' ;发送写使能寄存器命令STWR DS1302_TX ;;B7必须为1BSR T_RST ;LCALL SEND_BYTE ;->发送一个字节数据BCR SEC,7MOVFW SEC ;\允许写使能命令STWR DS1302_TX ;/LCALL SEND_BYTE ;->发送一个字节的数据BCR T_RST ;->DS1302复位RET ;;...........Program Initialization........................................;子程序名:;功能:写DS1302初始数据;功能说明:写入10年09月19日10时05分00秒;............................................................................DATE_INIT:LDWI B'00000000' ;\B7=0表示启动时钟震荡,B7=1表示暂停时钟震荡STWR SEC ;/B6~B4表示秒十位,B3-B0表示秒个位;秒寄存器,BCD码格式,初始00秒LDWI 05H ;\STWR MINUTE ;/;分钟寄存器,BCD码格式,00-59LDWI B'00010000' ;B7=0表示24小时方式,B7=1表示12小时方式,当选12小时方式下STWR HOUR ;B6=未用,B5=1表示下午B5=0表示上午,B4=小时高位B3-B0小时低位;小时寄存器,BCD码格式,00-59LDWI 19HSTWR DATE ;日;日期寄存器,BCD码格式,00-31LDWI 09HSTWR MONTH ;月;月份寄存器,BCD码格式,00-12LDWI 07H;星期寄存器,BCD码格式,0-7LDWI 10H ;STWR YEAR ;年;年寄存器,BCD码格式,00-99RET;----------------------------------------------------------------------;子程序名::DS1302_INI;功能:初始化1302,先禁止RST,允许写使能;功能说明:;---------------------------------------------------------------------------DS1302_INIT:BCR T_CLK ;\BCR T_RST ;先禁止LDWI B'10001110' ;发送写使能寄存器命令STWR DS1302_TX ;;B7必须为1,B6=1表示对RAM进行操作B6=0表示读写时钟/日历数据;;B5~B1为寄存器地址位,B0为0表示写,为1表示读BSR T_RST ;LCALL SEND_BYTE ;->发送一个字节数据LDWI B'00000000' ;\允许写使能命令STWR DS1302_TX ;/;B7=1为写保护,B7=0为写允许,B0~B6=0固定为0LCALL SEND_BYTE ;->发送一个字节的数据BCR T_RST ;->DS1302复位;------------------------------LDWI B'10010000' ;\90H设定充电方式命令STWR DS1302_TX ;写入缓冲BSR T_RST ;->允许操作DS1302LCALL SEND_BYTE ;BCR T_RST ;->DS1302复位RET ;;----------------------------------------------------------------------;子程序名:SEND_BYTE;功能:调用一次发送一个字节的数据;功能说明:数据从低位开始发送,用于发送1302的控制命令或发送一个数据;---------------------------------------------------------------------------SEND_BYTE:LDWI D'8' ;\写入BIT数STWR BIT_COUNT ;/SEND_LOOP:BCR T_IO ;BCR T_CLK ;\->BIT数在T_CLK低电平时变化BTSC DS1302_TX,0 ;检测发送缓冲寄存器位0,是1就发1.是0就发0RRR DS1302_TX,F ;向右移1位,为发送下一个BIT准备BSR T_CLK ;确定发送有效DECRSZ BIT_COUNT,F ;检测是否发送完8个BIT?LJUMP SEND_LOOP ;<否>继续发送下一位BCR T_CLK ;<是>返回RTIW 00H ;发送完8BIT数返回;----------------------------------------------------------------------;子程序名:READ_BYTE;功能:调用一次读出一个字节的数据;功能说明:数据从低位开始发送,用于发送1302的控制命令或发送一个数据;---------------------------------------------------------------------------READ_BYTE:BANK1BSR SET_IO ;I_O 设置为输入BANK0NOPLDWI D'8' ;\读8个BIT数据STWR BIT_COUNT ;/READ_LOOP:BCR T_CLK ;下降沿读取BCR STATUS,C ;\BTSC T_IO ;接收一个BITBSR STATUS,C ;/RRR DS1302_RX,FBSR T_CLK ;恢复高电平DECRSZ BIT_COUNT,F ;检测是否读完8BIT?LJUMP READ_LOOP ;-><否>循环读出BANK1BCR SET_IO ;I_O恢复为输出BANK0BCR T_CLKRETNOP;**********************************************************;子程序名:READ_DS1302;功能:突发模式读DS1302;说明:1.FLAG_RAM=1 读RAM14个字节定时数据; 2.FLAG_RAM=0 读7个字节日历/时钟数据;**********************************************************READ_DS1302:BSR T_RST ;-启动DS1302LDWI B'10111111' ;->ON,读日历/时钟突发模式命令多字节STWR DS1302_TX ;->写入发送寄存器LCALL SEND_BYTE ;->发送LDWI SEC ;->ON,准备接收DS1302时钟数据的首地址STWR FSR ;写入间接寻址寄存器LDWI D'7' ;->,ON,1次读出7个字节日历/时钟数据STWR BYTE_COUNT ;->写入字节计数器READ_BITLCALL READ_BYTELDR DS1302_RX,W ;\<是>将8BIT数据写入数据保存处STWR INDF ;/INCR FSR,F ;数据保存处地址加1,为下一个数据提供地址DECRSZ BYTE_COUNT,F ;检测是否读完数据?LJUMP READ_BIT ;->否,循环BCR T_RST ;->DS1302复位,禁止操作RET ;读完7个日历/时钟数据,返回;**********************************************************;子程序名:WRITE_DS1302;功能:突发模式写DS1302;说明:1.定时标志FLAG_TIMER=1 写14个字节定时数据->RAM; 2.定时标志FLAG_TIMER=0 写7个字节日历/时钟数据/写使能命令;**********************************************************WRITE_DS1302:LDWI B'10111110' ;->ON,写时钟多字节命令STWR DS1302_TX ;\BSR T_RST ; 发送突发模式写时钟命令LCALL SEND_BYTE ;/;--------------------------------;BCF T_CLK ;;BCF T_IO ;LDWI SEC ;->ON,准备写时钟/日历数据首地址STWR FSR ;LDWI D'8' ;->ON,准备写时钟的字节数STWR BYTE_COUNT ;/WRITE_BYTE:LDR INDF,W ;\拷贝地址数据内容到发送缓冲STWR DS1302_TX ;/LCALL SEND_BYTEINCR FSR,F ;->数据发送地址加1,为下一个数据提供地址DECRSZ BYTE_COUNT,F ;检测是否写完数据?LJUMP WRITE_BYTE ;BCR T_RST ;->DS1302复位,禁止操作RET ;写完数据,返回;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ;子程序名:显示LED;功能:;功能说明: ;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%% PLAY_SEC:;显示秒闪烁~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~BTSS FLAG_500MS ;检测闪烁频率LJUMP $+3 ;/BSR SEC_LED ;RETBCR SEC_LED ;RET;====================================;显示分L位MLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMMLMLMLMLMPLAY_MINUTE_L:BSR MINL_LED ;BTSS FLAG_MINUTE ;->检测是否要闪烁当前单元?LJUMP $+3 ;BTSS FLAG_250MS ;检测闪烁频率LJUMP $+0AH ;/LDR SHOW_MIN,W ;ANDWI 0FH ;LCALL TABLE ;STWR DIO_C ;ADDWR DIO_C,FRETBTSS FLAG_DAY ;指示灯不跟着闪烁LJUMP $+4MOVFW DIO_CXORWI B'00100000'STWR DIO_CRET;显示分H位MHMHMHMHMHMHMHMHMHMHMHMHMHMHMHPLAY_MINUTE_H:BSR MINH_LED ;BTSS FLAG_MINUTE ;->检测是否要闪烁当前单元?LJUMP $+3 ;BTSS FLAG_250MS ;检测闪烁频率LJUMP $+0AH ;/SWAPR SHOW_MIN,W ;ANDWI 0FH ;LCALL TABLE ;STWR DIO_C ;BTSS FLAG_YEARBTSS FLAG_YEARLJUMP $+4MOVFW DIO_CXORWI B'00100000'STWR DIO_CRET;显示时L位HLHLHLHLHLHLHLHLHLHLHLHLHLHLHLHLHLHLHLHLHLHLPLAY_HOUR_L:BSR HOUL_LED ;BTSS FLAG_HOUR ;->检测是否要闪烁当前单元?LJUMP $+3 ;BTSS FLAG_250MS ;检测闪烁频率LJUMP $+0AH ;/LDR SHOW_HOU,WANDWI 0FH ;LCALL TABLE ;STWR DIO_C ;MOVFW DIO_CXORWI B'00100000'STWR DIO_CRET;显示时H位HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH PLAY_HOUR_H:BSR HOUH_LED ;BTSS FLAG_HOUR ;->检测是否要闪烁当前单元?LJUMP $+3 ;BTSS FLAG_250MS ;检测闪烁频率LJUMP $+0AH ;/SWAPR SHOW_HOU,W ;ANDWI 0FH ;LCALL TABLE ;STWR DIO_C ;MOVFW DIO_CXORWI B'00100000'STWR DIO_CRETEND。

单片机万年历时钟

单片机万年历时钟

#include<reg52.h> //用定时器实现电子时钟#include<delay.h>#define uint unsigned int#define uchar unsigned charsbit wela = P2^7;sbit dula = P2^6;sbit lcdrs = P1^0;sbit lcdrw = P1^1;sbit lcden = P2^5;sbit beep = P2^3;uchar lcd1[] = "2014-07-22 TUE";uchar lcd2[] = "00-00-00";uchar num;uchar hour = 23,min = 59,sec = 50;uchar i;//循环时用到i计数uchar month = 7,day = 22;uint year = 2014, week = 3; //时间初始化,可自己定义void write_com(uchar com) //写命令{lcdrs = 0;lcden = 0;P0 = com;delayms(3);lcden = 1;delayms(3);lcden = 0;}void write_data(uchar dat) //写数据{lcdrs = 1;lcden = 0;P0 = dat;delayms(5);lcden = 1;delayms(5);lcden = 0;}void init()//液晶初始化,包括第一次的显示{dula = 0;wela = 0;lcden = 0;lcdrw = 0;write_com(0x38);//设置16*2显示,5*7点阵,8位数据口//delayms(5); //确保程序安全写入,程序小的情况下write_com(0x0c); //设置开显示,不显示光标//delayms(5);write_com(0x06);//写一个字符后地址指针加一//delayms(5);write_com(0x01);//显示清零,数据指针清零//delayms(5);write_com(0x80); //从第一行第一个光标开始//delayms(5);for(i=0;i<14;i++){write_data(lcd1[i]);delayms(1);}write_com(0x80+0x43); //从第二行第三个开始显示for(i=0;i<8;i++){write_data(lcd2[i]) ;delayms(1);}TMOD = 0x01; //定时器中断0初始化TH0 = (65536-45872)/256;TL0 = (65536-45872)%256;EA = 1;TR0 = 1;ET0 = 1;}void display_sfm(uchar add,uchar date){uchar shi,ge;shi = date/10;ge = date%10;write_com(0x80+0x40+add); //找到位write_data(0x30+shi);//写数据,0x30是16进制,在液晶中代表0,加几代表写几write_data(0x30+ge ) ;// 写数据依次来的}void display_week(uchar a )//显示星期几{switch(a){case 1: write_com(0x80+11);//星期一write_data(0x40);write_data(0x4f);write_data(0x4e);break;case 2: write_com(0x80+11);write_data(0x54);write_data(0x55);write_data(0x45);break;case 3: write_com(0x80+11);write_data(0x57);write_data(0x45);write_data(0x44);break;case 4: write_com(0x80+11);write_data(0x54);write_data(0x48);write_data(0x55);break;case 5: write_com(0x80+11);write_data(0x46);write_data(0x52);write_data(0x49);break;case 6: write_com(0x80+11);write_data(0x54);write_data(0x48);write_data(0x55);break;case 7: write_com(0x80+11);write_data(0x53);write_data(0x55);write_data(0x4e);break;}}void display_yue_ri(uchar add,uchar date) {uchar shi,ge;shi = date/10;ge = date%10;write_com(0x80+add); //找到位write_data(0x30+shi);//写数据,0x30是16进制,在液晶中代表0,加几代表写几write_data(0x30+ge);// 写数据依次来的}void display_year(uint year)//注意数据之间的传输不要出现错误{uchar a,b,c,d;a = year/1000;b = year/100%10;c = year/10%10;d = year%10;write_com(0x80);//控制指针write_data(0x30+a);//控制显示什么数字write_data(0x30+b);write_data(0x30+c);write_data(0x30+d);}void main()//主程序内越精简越好{init();while(1){if(num==20){num = 0;sec++;if(sec==60){sec = 0;min++;if(min==60){min = 0;hour++;if(hour==24){hour = 0;day++;display_week(week);//显示星期几week++;if(week==8)week = 0;if(((year/4==0&&year/100!=0)||(year/400==0)&&(month==2))&&(day==29))//闰年2月判断{day = 0;month++;}if(((month==1)||(month==3)||(month==5)||(month==7)||(month==8)||(month==10)||(month==12))&&(day==31))//1.3.5.7.8.10.12月份{day = 0;month++;}if(((month==4)||(month==6)||(month==9)||(month==11))&&(day==30))//4.6.9.11月份{day = 0;month++;}if((!(year/4==0&&year/100!=0)||(year/400==0))&&(month==2)&&(day==28))//非闰年2月判断{day = 0;month++;}if(month==12){month = 1;year++;}}}}display_sfm(9,sec);//显示display_sfm(6,min);display_sfm(3,hour);display_year(year);display_yue_ri(5,month);display_yue_ri(8,day);}}}void T0_timer() interrupt 1{TH0 = (65536-45872)/256;TL0 = (65536-45872)%256;num++;}。

单片机数字钟万年历(c语言)

单片机数字钟万年历(c语言)

#include <REGX51.H>#include <ABSACC.h>#define Font_code XBYTE[0xefff] //字符码写地址#define reg_code XBYTE[0xdfff] //字位码写地址#define s_1_con_key P3_2#define m_1_con_key P3_3#define h_1_con_key P3_4#define w_1_con_key P3_5#define p1 P1sbit BELL=P1^0;//sbit p10=P1^0;//sbit p20=P1^1;//sbit p30=P1^2;//sbit p40=P1^3;//sbit p50=P1^4;//sbit p60=P1^5;//sbit p70=P1^6;//sbit p80=P1^7;//字型码const unsigned char seg_design[11]={0x3F,/*0*/0x06,/*1*/0x5B,/*2*/0x4F,/*3*/0x66,/*4*/0x6D,/*5*/0x7D,/*6*/0x07,/*7*/0x7F,/*8*/0x6F,/*9*/0x40,/*-*/};//字位码const unsigned char bit_design[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};code unsigned char sszymmh[]={ 6,2,3, 5,2,1, 3,2,2, 5,2,2, 1,3,2, 6,2,1, 5,2,1,6,2,4, 3,2,2, 5,2,1, 6,2,1, 5,2,2, 3,2,2, 1,2,1,6,1,1, 5,2,1, 3,2,1, 2,2,4, 2,2,3, 3,2,1, 5,2,2,5,2,1, 6,2,1, 3,2,2, 2,2,2, 1,2,4, 5,2,3,3,2,1,2,2,1, 1,2,1, 6,1,1, 1,2,1, 5,1,6, 0,0,0} ;// 音阶频率表高八位code unsigned char FREQH[]={0xF2,0xF3,0xF5,0xF5,0xF6,0xF7,0xF8,0xF9,0xF9,0xFA,0xFA,0xFB,0xFB,0xFC,0xFC,//1,2,3,4,5,6,7,8,i0xFC,0xFD,0xFD,0xFD,0xFD,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFF,} ;// 音阶频率表低八位code unsigned char FREQL[]={0x42,0xC1,0x17,0xB6,0xD0,0xD1,0xB6,0x21,0xE1,0x8C,0xD8,0x68,0xE9,0x5B,0x8F,//1,2,3,4,5,6,7,8,i0xEE,0x44, 0x6B,0xB4,0xF4,0x2D,0x47,0x77,0xA2,0xB6,0xDA,0xFA,0x16,};unsigned char bit_con;unsigned int ms_1_con; //毫秒计数器unsigned char s_1_con; //秒计数器unsigned char m_1_con; //分计数器unsigned char h_1_con=12;//时计数器unsigned char w_1_con=6; //周计时器unsigned char d_1_con=1;unsigned char mon_1_con=1;unsigned int y_1_con=2011;unsigned char s1; //秒计数器unsigned char m1; //分计数器unsigned char h1; //时计数器unsigned char Display_Buffer[8]; //显示缓冲区unsigned int k1=0;unsigned int k2=0;unsigned char timer0h,timer0l,time,led=1,j=0;unsigned char flagd=0;void delay_nms(unsigned int n);void Calculation_display(void);void time_set(void);void time_set1(void);void time_set2(void);void InitTimer0(void){TMOD = 0x01; // 方式1,16位计数器方式TH0 = 0xFC; //定时初值=65536-n n=1000,定时周期是1ms TL0 = 0x18;EA = 1; //开总中断使能ET0 = 1; //允许定时器T0溢出中断TR0 = 1; //T0 运行}void delay(unsigned char t){unsigned char t1;unsigned long t2;for(t1=0;t1<t;t1++){for(t2=0;t2<4000;t2++){;}}TR0=0;}void song(){TH0=timer0h;TL0=timer0l;TR0=1;delay(time);}void sing(){unsigned char k,i=0;time=1;while(time){if(k1==0) break;InitTimer0();Calculation_display();if(k2==0)time_set();else if(k2==1)time_set1();elsetime_set2();p1=~seg_design[8];k=sszymmh[i]+7*sszymmh[i+1]-1;timer0h=FREQH[k];timer0l=FREQL[k];time=sszymmh[i+2];i=i+3;song();}}void main(void){InitTimer0();while(1){Calculation_display();delay_nms(100);if(k2==0)time_set();else if(k2==1)time_set1();elsetime_set2();sing();k1=0;InitTimer0();}}void Timer0Interrupt(void) interrupt 1 using 1 {TH0 = 0xFC;TL0 = 0x18;ms_1_con++;//采用定时扫描方式bit_con++;if(bit_con > 7) bit_con = 0;reg_code = 0x00; //先消隐显示Font_code = Display_Buffer[bit_con];reg_code = bit_design[bit_con];if(k1==1){TR0=0;BELL=!BELL;TH0=timer0h;TL0=timer0l;TR0=1;}}void delay_nms(unsigned int n) //延时N ms{unsigned char a,b;unsigned int c;for(c=n;c>0;c--)for(b=142;b>0;b--)for(a=2;a>0;a--);}void Calculation_display(void){unsigned char day;if(ms_1_con > 999) //1000ms定时到{ms_1_con = 0;s_1_con++;if(s_1_con > 59){s_1_con = 0;m_1_con++;if(m_1_con > 59){m_1_con = 0;h_1_con++;k1=1;if(h_1_con > 23){h_1_con = 0;w_1_con++;if(w_1_con>7)w_1_con=1;switch(mon_1_con){case 1:case 3:case 5:case 7:case 8:case 10:case 12:day=31;break;case 2:day=28;break;case 4:case 6:case 9:case 11:day=30;break;}d_1_con++;if(d_1_con>day){mon_1_con++;d_1_con=1;if(mon_1_con>12){y_1_con++;mon_1_con=1;}}}}}}p1=~seg_design[w_1_con];if(k2==0){if(ms_1_con<500){Display_Buffer[2] = seg_design[10];Display_Buffer[5] = seg_design[10];}else{Display_Buffer[2] = !seg_design[10];Display_Buffer[5] = !seg_design[10];}Display_Buffer[6] = seg_design[s_1_con/10];//秒十位Display_Buffer[7] = seg_design[s_1_con%10]; //秒个位Display_Buffer[3] = seg_design[m_1_con/10]; //分十位Display_Buffer[4] = seg_design[m_1_con%10]; //分个位Display_Buffer[0] = seg_design[h_1_con/10]; //时十位Display_Buffer[1] = seg_design[h_1_con%10]; //时个位}if(k2==1){Display_Buffer[3] = seg_design[y_1_con%10]; //年个位Display_Buffer[2] = seg_design[(y_1_con/10)%10]; //年十位Display_Buffer[1] = seg_design[((y_1_con/100)%10)]; //年百位Display_Buffer[0] = seg_design[y_1_con/1000]; //年千位Display_Buffer[6] = seg_design[d_1_con/10]; //日十位Display_Buffer[7] = seg_design[d_1_con%10]; //日个位Display_Buffer[4] = seg_design[mon_1_con/10]; //月十位Display_Buffer[5] = seg_design[mon_1_con%10]; //月个位}if(k2==2){Display_Buffer[2] = seg_design[10];Display_Buffer[5] = seg_design[10];Display_Buffer[6] = seg_design[s1/10]; //秒十位Display_Buffer[7] = seg_design[s1%10]; //秒个位Display_Buffer[3] = seg_design[m1/10]; //分十位Display_Buffer[4] = seg_design[m1%10]; //分个位Display_Buffer[0] = seg_design[h1/10]; //时十位Display_Buffer[1] = seg_design[h1%10]; //时个位}if(s1==s_1_con&&m1==m_1_con&&h1==h_1_con)k1=1;}void time_set(void){unsigned char day;if(!s_1_con_key){s_1_con++;if(s_1_con > 59){s_1_con = 0;m_1_con++;if(m_1_con > 59){m_1_con = 0;h_1_con++;if(h_1_con > 23){h_1_con = 0;w_1_con++;if(w_1_con>7)w_1_con=1;d_1_con++;switch(mon_1_con){case 1:case 3:case 5:case 7:case 8:case 10:case 12:day=31;break;case 2:day=28;break;case 4:case 6:case 9:case 11:day=30;break;}if(d_1_con>day){mon_1_con++;d_1_con=1;if(mon_1_con>12){y_1_con++;mon_1_con=1;}}}}}}if(!m_1_con_key){m_1_con++;if(m_1_con > 59){m_1_con = 0;h_1_con++;if(h_1_con > 23){h_1_con = 0;w_1_con++;if(w_1_con>7)w_1_con=1;d_1_con++;switch(mon_1_con){case 1:case 3:case 5:case 7:case 8:case 10:case 12:day=31;break;case 2:day=28;break;case 4:case 6:case 9:case 11:day=30;break;}if(d_1_con>day){mon_1_con++;d_1_con=1;if(mon_1_con>12){y_1_con++;mon_1_con=1;}}}}}if(!h_1_con_key){h_1_con++;if(h_1_con > 23){h_1_con = 0;w_1_con++;if(w_1_con>7)w_1_con=1;d_1_con++;switch(mon_1_con){case 1:case 3:case 5:case 7:case 8:case 10:case 12:day=31;break;case 2:day=28;break;case 4:case 6:case 9:case 11:day=30;break;}if(d_1_con>day){mon_1_con++;d_1_con=1;if(mon_1_con>12){y_1_con++;mon_1_con=1;}}}}if(!w_1_con_key){k2=1;}}void time_set1(void){unsigned char day;switch(mon_1_con){case 1:case 3:case 5:case 7:case 8:case 10:case 12:day=31;break;case 2:day=28;break;case 4:case 6:case 9:case 11:day=30;break;}if(!s_1_con_key){d_1_con++;w_1_con++;if(w_1_con>7)w_1_con=1;if(d_1_con>day){mon_1_con++;d_1_con=1;if(mon_1_con>12){y_1_con++;mon_1_con=1;}}}if(!m_1_con_key){mon_1_con++;w_1_con=(w_1_con+day%7)%7;if(mon_1_con>12){y_1_con++;mon_1_con=1;}}if(!h_1_con_key){y_1_con++;if(y_1_con>9999){w_1_con=(w_1_con+365%7)%7;y_1_con=0;}}if(!w_1_con_key){k2=2;}}void time_set2(void){if(!s_1_con_key){s1++;if(s1>59)s1=0;}if(!m_1_con_key){m1++;if(m1>59)m1=0;}if(!h_1_con_key){h1++;if(h1>23)h1=0;}if(!w_1_con_key){k2=0;}}。

51单片机 ds1302万年历 时钟显示

51单片机 ds1302万年历 时钟显示

//DS1302时钟芯片程序#include <reg52.h>#define uchar unsigned char#define uint unsigned intsbit CLK=P2^3; //定义口sbit IO=P2^4;sbit RST=P2^5;sbit ACC7=ACC^7;sbit ACC0=ACC^0;uchar a[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}, //定义数码管显示码b[8]={0x00,0x00,0x12,0x23,0x11,0x07,0x08,0xbe},//写入时钟数据,最后be突发访问c[7],s,s1,ml1,mh1,ml2,mh2,ml3,mh3; //c存放读.出时钟数据void delay(uint z) // 延时{uint i;uchar j;for(i=z;i>0;i--)for(j=200;j>0;j++);}// 显示子程序void display(uchar mh1,uchar ml1,uchar mh2,uchar ml2,uchar mh3,uchar ml3){uchar x,k,r;for(k=0;k<80;k++){for(r=0;r<8;r++){x=P2&0XF8;P2=x+r ;if(r==2||r==5){ P0=0XBF;delay(3);}//------秒-------if(r==0){P0=a[ml1] ;delay(3) ;}if(r==1){P0=a[mh1] ;delay(3) ;}//------fen---------if(r==3){P0=a[ml2] ;delay(3) ;}if(r==4){P0=a[mh2] ;delay(3) ;}//-----shi---------if(r==6){P0=a[ml3] ;delay(3) ;}if(r==7){P0=a[mh3] ;delay(3) ;}delay(3);}}}//********DS1302读写程序************void w(uchar u) //写入1位字节{uchar i;ACC = u;for(i=8; i>0; i--){IO = ACC0;CLK = 1;CLK = 0;ACC = ACC >> 1;}}uchar r(void) //读出1位字节{uchar i;for(i=8; i>0; i--){ACC = ACC >>1;ACC7 = IO;CLK = 1;CLK = 0;}return(ACC);}void W1302(uchar ucAddr, uchar ucDa){RST = 0;CLK = 0;RST = 1;w(ucAddr); // 地址,命令w(ucDa); //写1Byte数据CLK = 1;RST = 0;}void wclock(uchar *p) //写入时钟多字节数据{uchar i;// W1302(0x80,0x00); //停止时钟W1302(0x8e,0x00); // 允许写RST=0;CLK=0;RST=1;w(0xbe); //写多字节命令for(i=8;i>0;i--){w(*p); //按数组指针逐个写入,写入数据在主函数调用时指向b数组p++;}W1302(0x00,0x50); //启动定时器CLK=1;RST=0;}void rclock(uchar *p) //读出时钟多字节数据{uchar i;RST=0;CLK=0;RST=1;w(0xbf);for(i=7;i>0;i--){*p=r();p++;}CLK=1;RST=0;}void main(void){uchar mh,ml,fh,fl,sh,sl,z,v,q,e,y,t,k;wclock(b);while(1){rclock(c);mh=(c[0]&0xf0)>>4;ml=c[0]&0x0f;fh=(c[1]&0xf0)>>4;fl=c[1]&0x0f;sh=(c[2]&0xf0)>>4;sl=c[2]&0x0f;display(mh,ml,fh,fl,sh,sl);if(mh==3&&ml==0){ for(k=0;k<3;k++){z=(c[3]&0xf0)>>4;v=c[3]&0x0f;q=(c[4]&0xf0)>>4;e=c[4]&0x0f;y=(c[6]&0xf0)>>4;t=c[6]&0x0f;display(z,v,q,e,y,t);}}}}。

万年历初始源程序

万年历初始源程序

12864、DS1302制作的电子万年历代码如下:/********************************************************************名称:电子万年历功能:自动计时100年,节日、时间提醒作者:甘春生实验板:KX-1N/******************************************************************** #include<reg52.h>#define uint unsigned int#define uchar unsigned charsbit RS=P2^0;sbit RW=P2^1;sbit EN=P2^2;sbit FUN=P1^0;sbit OK=P1^1;sbit INC=P1^2;sbit DEC=P1^3;sbit RST=P2^5;sbit IO=P2^6;sbit SCLK=P2^7;uchar hour=10;uchar min=18;uchar sec=30;uchar year=10;uchar mon=1;uchar date=20;uchar day=3;uchar count=0;uchar flag=0;uchar num=0;uchar i=6;void delay(uint i){uint j;for(;i>0;i--)for(j=0;j<125;j++);}void Write_Ds1302_Byte(uchar temp){uchar i;for(i=0;i<8;i++)SCLK=0;IO=temp&0x01;//只传最后一位temp>>=1;SCL=1;}}void Write_Ds1302(uchar address,uchar dat) {RST=0;SCLK=0;RST=1;Write_Ds1302_Byte(address);Write_Ds1302_Byte(dat);SCLK=1;RST=0;}uchar Read_Ds1302(uchar address){uchar i,temp=0x00;RST=0;SCLK=0;RST=1;Write_Ds1302_Byte(address);for(i=0;i<8;i++){temp>>=1;SCLK=0;if(IO)temp=temp|0x80;SCLK=1;}RST=0;IO=0;return temp;}void Check_Busy(void){RW=1;//RW=1为读RS=0;//RS=0为指令EN=1;while(P2&0X80);}void Write_com(uchar com)Check_Busy();RW=0;RS=0;P2=com;EN=1;delay(1);EN=0;}void Write_dat(uchar dat){Check_Busy();RW=0;RS=1;P2=dat;EN=1;delay(1);EN=0;}void Lcd_Pos(uchar Xpos,uchar Ypos){uchar tmp;Xpos&=0x0f;Ypos&=0x03;tmp=Xpos;if(Ypos==0)tmp|=0x80;if(Ypos==1)tmp|=0x90;if(Ypos==2)tmp|=0x88;if(Ypos==3)tmp|=0x98;Write_com(tmp);}void Write_LCD_String(uchar x,uchar y,uchar *s) {Lcd_Pos(x,y);Lcd_Pos(x,y);while (*s!='\0'){Write_dat(*s);s++;delay(1);}void LCD_Rst(void){Write_com(0x30);Check_Busy();Write_com(0x01);Write_com(0x06);Write_com(0x0c);delay(5);}void Write_day(uchar Sel){switch (Sel){case 1:Write_LCD_String(6,1,"一");break;case 2:Write_LCD_String(6,1,"二");break;case 3:Lcd_Pos(6,1);Write_dat(0xc8);Write_dat(0xfd);break;case 4:Write_LCD_String(6,1,"四");break;case 5:Write_LCD_String(6,1,"五");break;case 6:Write_LCD_String(6,1,"六");break;case 7:Write_LCD_String(6,1,"日");break;default :break;}}void Updat_Time(void){Lcd_Pos(3,0);Write_dat(0x30+(year/10));Write_dat(0x30+(year%10)); Lcd_Pos(0,1);Write_dat(0x30+(mon/10));Write_dat(0x30+(mon%10)); Lcd_Pos(2,1);Write_dat(0x30+(date/10));Write_dat(0x30+(date%10)); Lcd_Pos(0,2);Write_dat(0x30+(hour/10));Write_dat(0x30+(hour%10)); Lcd_Pos(2,2);Write_dat(0x30+(min/10));Write_dat(0x30+(min%10)); Lcd_Pos(4,2);Write_dat(0x30+(sec/10));Write_dat(0x30+(sec%10)); Write_day(day);}void Write_Time(void){Write_Ds1302(0x8e,0x00);Write_Ds1302(0x8c,(year/10)*16+year%10);Write_Ds1302(0x88,(mon/10)*16+mon%10);Write_Ds1302(0x86,(date/10)*16+date%10);Write_Ds1302(0x84,(hour/10)*16+hour%10);Write_Ds1302(0x82,(min/10)*16+min%10);Write_Ds1302(0x80,(sec/10)*16+sec%10);Write_Ds1302(0x8a,(day/10)*16+day%10);Write_Ds1302(0x8e,0x80);}void Read_Time(void){year=(Read_Ds1302(0x8d)>>4)*10+Read_Ds1302(0x8d)%16; mon=(Read_Ds1302(0x89)>>4)*10+Read_Ds1302(0x89)%16; date=(Read_Ds1302(0x87)>>4)*10+Read_Ds1302(0x87)%16; hour=(Read_Ds1302(0x85)>>4)*10+Read_Ds1302(0x85)%16; min=(Read_Ds1302(0x83)>>4)*10+Read_Ds1302(0x83)%16; sec=(Read_Ds1302(0x81)>>4)*10+Read_Ds1302(0x81)%16; day=(Read_Ds1302(0x8b)>>4)*10+Read_Ds1302(0x8b)%16; Updat_Time();}void Set_Time(void){if(FUN==0){delay(10);if(FUN==0){while(!FUN);flag=1;num++;if(num==8)num=1;}}if(flag){if(num==1){Lcd_Pos(0,2);Write_com(0x0d);if(INC==0){delay(10);if(INC==0){while(!INC);hour++;if(hour==24)hour=0;}}if(DEC==0){delay(10);if(DEC==0){while(!DEC);hour--;if(hour==-1)hour=23;Updat_Time();}}}if(num==2){Lcd_Pos(2,2);Write_com(0x0d);if(INC==0){delay(10);if(INC==0){while(!INC);min++;if(min==60)min=0;Updat_Time();}}if(DEC==0){delay(10);if(DEC==0){while(!DEC);min--;if(min==-1)min=59;}}}if(num==3){Lcd_Pos(4,2);Write_com(0x0d);if(INC==0){delay(10);if(INC==0){while(!INC);sec++;if(sec==60)sec=0;Updat_Time();}}if(DEC==0){delay(10);if(DEC==0){while(!DEC);sec--;if(sec==-1)sec=59;Updat_Time();}}}if(num==4){Lcd_Pos(3,0);Write_com(0x0d);if(INC==0){delay(10);if(INC==0){while(!INC);year++;year=0;Updat_Time();}}if(DEC==0){delay(10);if(DEC==0){while(!DEC);year--;if(year==-1)sec=99;Updat_Time();}}}if(num==5){Lcd_Pos(0,1);Write_com(0x0d); if(INC==0){delay(10);if(INC==0){while(!INC);mon++;if(mon==13)mon=1;Updat_Time();}}if(DEC==0){delay(10);if(DEC==0){while(!DEC);mon--;if(mon==0)mon=12;Updat_Time();}}}if(num==6){Lcd_Pos(2,1);Write_com(0x0d); if(INC==0){delay(10);if(INC==0){while(!INC);date++;if(date==32)date=1;Updat_Time();}}if(DEC==0){delay(10);if(DEC==0){while(!DEC);date--;if(date==0)date=31;Updat_Time();}}}if(num==7){Lcd_Pos(6,1);Write_com(0x0d); if(INC==0){delay(10);if(INC==0){while(!INC);day++;if(day==8)day=1;Updat_Time();}}if(DEC==0){delay(10);if(DEC==0){while(!DEC);day--;if(day==0)day=7;Updat_Time();}}}}if(OK==0){delay(10);if(OK==0){while(!OK);flag=0;num=0;Write_com(0x0c);Write_Time();}}}void Festival(void){if (mon == 1 && date== 1 ) { Write_LCD_String(0,3,"Happy New Year!!"); } elseif (mon == 1 && date== 28 ) { Write_LCD_String(0,3," 世界麻风日"); } elseif (mon == 2 && date== 2 ) { Write_LCD_String(0,3," 世界湿地日"); } elseif (mon == 2 && date== 13 ) { Write_LCD_String(0,3," 明天情人节了"); } elseif (mon == 2 && date== 14 ) { Write_LCD_String(0,3," 今天是情人节"); } elseif (mon == 3 && date== 1 ) { Write_LCD_String(0,3," 国际海豹日"); }elseif (mon == 3 && date== 3 ) { Write_LCD_String(0,3," 全国爱耳日"); } elseif (mon == 3 && date== 8 ) { Write_LCD_String(0,3," 3.8妇女节"); } elseif (mon == 3 && date== 12 ) { Write_LCD_String(0,3," 植树节"); } elseif (mon == 3 && date== 14 ) { Write_LCD_String(0,3," 国际警察日"); } elseif (mon == 3 && date== 15 ) { Write_LCD_String(0,3," 消费者权益日"); } elseif (mon == 3 && date== 17 ) { Write_LCD_String(0,3," 国际航海日"); } elseif (mon == 3 && date== 21 ) { Write_LCD_String(0,3," 世界森林日"); } elseif (mon == 3 && date== 22 ) { Write_LCD_String(0,3," 世界水日"); } elseif (mon == 3 && date== 23 ) { Write_LCD_String(0,3," 世界气象日"); } elseif (mon == 3 && date== 24 ) { Write_LCD_String(0,3,"世界防治结核病日"); } elseif (mon == 4 && date== 1 ) { Write_LCD_String(0,3,"愚人节小心上当"); } elseif (mon == 4 && date== 7 ) { Write_LCD_String(0,3," 世界卫生日"); } elseif (mon == 4 && date== 8 ) { Write_LCD_String(0,3," 复活节"); } elseif (mon == 4 && date== 13 ) { Write_LCD_String(0,3," 黑色星期五"); } elseif (mon == 5 && date== 1 ) { Write_LCD_String(0,3," 劳动节放假"); } elseif (mon == 5 && date== 4 ) { Write_LCD_String(0,3," 青年节"); } elseif (mon == 5 && date== 8 ) { Write_LCD_String(0,3," 世界红十字日"); } elseif (mon == 5 && date== 12 ) { Write_LCD_String(0,3," 国际护士节"); } elseif (mon == 5 && date== 5 ) { Write_LCD_String(0,3,"近日注意母亲节"); } // &nb, , , , , sp;elseif (mon == 5 && date== 15 ) { Write_LCD_String(0,3," 国际家庭日"); } elseif (mon == 5 && date== 31 ) { Write_LCD_String(0,3," 世界无烟日"); } elseelseif (mon == 6 && date== 5 ) { Write_LCD_String(0,3," 世界环境日"); } elseif (mon == 6 && date== 26 ) { Write_LCD_String(0,3," 国际禁毒日"); } elseif (mon == 6 && date== 6 ) { Write_LCD_String(0,3," 全国爱眼日"); } elseif (mon == 6 && date== 13 ) { Write_LCD_String(0,3,"近日注意父亲节"); } elseif (mon == 6 && date== 15 ) { Write_LCD_String(0,3,"近日注意父亲节"); } elseif (mon == 7 && date== 1 ) { Write_LCD_String(0,3,"香港回归记念日"); } elseif (mon == 7 && date== 7 ) { Write_LCD_String(0,3,"抗日战争记念日"); } elseif (mon == 7 && date== 11 ) { Write_LCD_String(0,3," 世界人口日"); } elseif (mon == 8 && date== 1 ) { Write_LCD_String(0,3," 八一建军节"); } elseif (mon == 8 && date== 8 ) { Write_LCD_String(0,3," 中国男子节"); } elseif (mon == 8 && date== 15 ) { Write_LCD_String(0,3,"抗战胜利记念日"); } elseif (mon == 9 && date== 10 ) { Write_LCD_String(0,3," 中国教师节"); } elseif (mon == 9 && date== 18 ) { Write_LCD_String(0,3,"九·一八事变记念"); } elseif (mon == 9 && date== 20 ) { Write_LCD_String(0,3," 国际爱牙日"); } elseif (mon == 9 && date== 27 ) { Write_LCD_String(0,3," 世界旅游日"); } elseif (mon == 10 && date== 1 ) { Write_LCD_String(0,3," 中国国庆节"); } elseif (mon == 10 && date== 4 ) { Write_LCD_String(0,3," 世界动物日"); } elseif (mon == 10 && date== 24 ){ Write_LCD_String(0,3," 联合国日"); } elseif (mon == 10 && date== 12 ){ Write_LCD_String(0,3,"明天国际教师节"); } elseif (mon == 10 && date== 13 ){ Write_LCD_String(0,3," 国际教师节"); } elseif (mon == 11 && date== 10 ){ Write_LCD_String(0,3," 世界青年节"); } elseelseif (mon == 12 && date== 1 ) { Write_LCD_String(0,3," 世界艾滋病日"); } elseif (mon == 12 && date== 23 ){ Write_LCD_String(0,3," 明晚平安夜"); }elseif (mon == 12 && date== 24 ){ Write_LCD_String(0,3," 今晚平安夜"); }elseif (mon == 12 && date== 25 ){ Write_LCD_String(0,3," 圣诞快乐"); }elseif (mon == 12 && date== 31 ){ Write_LCD_String(0,3," 明日新年"); }else{if(hour >= 4 && hour< 6 ) { Write_LCD_String(0,3,"★★__▲▲__凌晨"); } if(hour >= 6 && hour< 8 ) { Write_LCD_String(0,3,"☆○__▲△__早晨"); } if(hour >= 8 && hour< 12 ) { Write_LCD_String(0,3,"__●__▲▲__上午"); } if(hour == 12) { Write_LCD_String(0,3,"____▲●▲__中午"); }if(hour >= 13 && hour< 18 ){ Write_LCD_String(0,3,"__▲▲__●__下午"); } if(hour >= 18 && hour< 22 ){ Write_LCD_String(0,3,"△▲__●☆__晚上"); } if(hour >= 22 && hour<= 23 ){ Write_LCD_String(0,3,"△▲__★☆__夜里"); } if(hour >= 0 && hour< 4 ) { Write_LCD_String(0,3,"__★▲▲★__深夜"); } }}void System_Init(void){LCD_Rst();Write_LCD_String(0,1,"系统初始化");Lcd_Pos(5,1);while(i--){Write_dat(0x3e);delay(300);}Write_com(0x01);Write_LCD_String(0,1,"您好!欢迎使用!");delay(1500);Write_com(0x01);Write_LCD_String(2,0,"2010年");Write_LCD_String(0,1,"01月18日星期一");Write_LCD_String(0,2,"10时17分30秒");}void main(void){System_Init();Write_Time(); while(1){Set_Time();if(!flag){Read_Time();Festival();}}}。

基于单片机的万年历源代码程序

基于单片机的万年历源代码程序

基于单片机的万年历源代码程序源程序代码如下:#include<reg52.h>#include<intrins.h>unsigned char code displaywelcome[]={" Welcome To My Lcd Timer"};//欢迎界面unsigned char code displaywish[]={" Happy Every Day ^_^"}; //欢迎界面unsigned char code overtemperature[]={"OVERTEMPERATURE!"};unsigned char code digit[]={"0123456789"}; //数字代码unsigned char mode,TH,TL,TN,TD,length,tempswitch,Maxtemp=40,amode,alarmmode,minutes,hours, minutea,seconds,houra=12;sbit SCLK=P1^0; //DS1302时钟输入sbit DATE=P1^1; //DS1302数据输入sbit REST=P1^2; //DS1302复位端口sbit SET=P1^4; //DS1302设置模式选择位sbit ADD=P1^5; //增加sbit RED=P1^6; //减小sbit CANL=P1^7;void delay1ms(int i)//1毫秒延时{int j,k;while(i--)for(j=76;j>1;j--);for(k=29;k>1;k--);}void delaynus(unsigned char n) //延时若干微秒{unsigned char i;for(i=0;i<n;i++);}/***********蜂鸣器模块************/sbit beep=P3^6; //位定义,定义P.6位fmpvoid dely500(void){unsigned char i;for(i=250;i>0;i--){_nop_();}}void baojing(unsigned char n){unsigned char x,i;while(n--){for(i=0;i<5;i++){for(x=0;x<200;x++){beep=~beep;dely500();}}for(i=0;i<3;i++){for(x=0;x<200;x++){beep=~beep;dely500();dely500();}}}}/*******DS1302模块*************/void Write1302(unsigned char date)//向1302写数据{unsigned char i;SCLK=0;delaynus(2);for(i=0;i<8;i++){DATE=date&0x01;SCLK=1;delaynus(2);SCLK=0;delaynus(2);date>>=1;}}void WriteSet1302(unsigned char cmd,unsigned char date) //根据相应的命令输入相应的数据{REST=0;SCLK=0;REST=1;Write1302(cmd);delaynus(5);Write1302(date);SCLK=1;REST=0;}unsigned char Read1302(void) //读取1302数据{unsigned char i,date;delaynus(2);for(i=0;i<8;i++){date>>=1;if(DATE==1)date|=0x80;SCLK=1;delaynus(2);SCLK=0;delaynus(2);}return date;}unsigned char ReadSet1302(unsigned char cmd)//根据命令读取1302相应的值{unsigned char date;REST=0;SCLK=0;REST=1;Write1302(cmd);delaynus(2);date=Read1302();SCLK=1;REST=0;return date;}void IntDS1302(void) //DS1302初始化{unsigned char flag;flag= ReadSet1302(0x81);if(flag&0x80) { //判断时钟芯片是否关闭WriteSet1302(0x8E,0x00); //根据写状态寄存器命令字,写入不保护指令WriteSet1302(0x80,((0/10)<<4|(0%10))); //根据写秒寄存器命令字,写入秒的初始值WriteSet1302(0x82,((0/10)<<4|(0%10))); //根据写分寄存器命令字,写入分的初始值WriteSet1302(0x84,((0/10)<<4|(0%10))); //根据写小时寄存器命令字,写入小时的初始值WriteSet1302(0x86,((0/10)<<4|(0%10))); //根据写日寄存器命令字,写入日的初始值WriteSet1302(0x88,((0/10)<<4|(0%10))); //根据写月寄存器命令字,写入月的初始值WriteSet1302(0x8c,((10/10)<<4|(10%10))); //根据写年寄存器命令字,写入年的初始值WriteSet1302(0x90,0xa5); //打开充电功能选择2K电阻充电方式WriteSet1302(0x8E,0x80); //根据写状态寄存器命令字,写入保护指令}}/***************液晶显示模块*****************/sbit RS=P2^5;sbit RW=P2^6;sbit E=P2^7;sbit BF=P0^7;/*液晶忙检测*/bit BusyTest(void){bit result;RS=0;RW=1;E=1;_nop_();_nop_();_nop_();result=BF;_nop_();_nop_();_nop_();E=0;return result;/*写指令*/void Write_com(unsigned char command) {while(BusyTest()!=0);RS=0;RW=0;E=0;_nop_();_nop_();_nop_();P0=command;_nop_();_nop_();_nop_();E=1;_nop_();_nop_();_nop_();E=0;}/*写地址*/void Write_Address(unsigned char address) {Write_com(address|0x80);delay1ms(1);}/*写数据*/void Write_Date(unsigned char date){RS=1;RW=0;E=0;_nop_();_nop_();_nop_();P0=date;_nop_();_nop_();_nop_();E=1;_nop_();_nop_();_nop_();E=0;delay1ms(1);}/*初始化*/void Lcd_Int(void){Write_com(0x38);delay1ms(1);Write_com(0x38);delay1ms(1);Write_com(0x06);delay1ms(1);Write_com(0x0c);delay1ms(1);Write_com(0x01);}void displaymainpart(void)//显示液晶主要部分(不变化部分){Write_Address(0x01);delay1ms(1);Write_Date('D');Write_Date('A');Write_Date('T');Write_Date('E');Write_Date(':');delay1ms(1);Write_Address(0x0A);delay1ms(1);Write_Date('-');Write_Address(0x0D);Write_Date('-');Write_Address(0x42);Write_Date('T');Write_Date('I');Write_Date('M');Write_Date('E');Write_Date(':');Write_Address(0x4A);Write_Date('-');Write_Address(0x4D);Write_Date('-');Write_Address(0x06);Write_Date('2');Write_Date('0');}void display_Second(unsigned char second) //在液晶上显示秒{unsigned char i,j;i=second/10;j=second%10;Write_Address(0x4E);Write_Date(digit[i]);Write_Date(digit[j]);delay1ms(1);}void display_Minute(unsigned char minute) //在液晶上显示分{unsigned char i,j;i=minute/10;j=minute%10;Write_Address(0x4B);Write_Date(digit[i]);Write_Date(digit[j]);delay1ms(1);}void display_Hour(unsigned char hour) //在液晶上显示时{unsigned char i,j;i=hour/10;j=hour%10;Write_Address(0x48);Write_Date(digit[i]);Write_Date(digit[j]);delay1ms(1);}void display_Day(unsigned char day) //在液晶上显示日{unsigned char i,j;i=day/10;j=day%10;Write_Address(0x0E);Write_Date(digit[i]);Write_Date(digit[j]);delay1ms(1);}void display_Month(unsigned char month) //在液晶上显示月{unsigned char i,j;i=month/10;j=month%10;Write_Address(0x0B);Write_Date(digit[i]);Write_Date(digit[j]);delay1ms(1);}void display_Year(unsigned char year) //在液晶上显示年{unsigned char i,j;i=year/10;j=year%10;Write_Address(0x08);Write_Date(digit[i]);Write_Date(digit[j]);delay1ms(1);}void display_houra(unsigned char x) //闹钟小时部分显示{unsigned char i,j;i=x/10;j=x%10;Write_Address(0x44);Write_Date(digit[i]);Write_Date(digit[j]);}void display_minutea(unsigned char x)//闹钟分钟部分显示{unsigned char i,j;i=x/10;j=x%10;Write_Address(0x47);Write_Date(digit[i]);Write_Date(digit[j]);}void display_Time(void) //显示实时时间{unsigned char value,day,month,year;Write_com(0x0c);value=ReadSet1302(0x81);seconds=(((value&0x70)>>4)*10+(value&0x0f));display_Second(seconds);value=ReadSet1302(0x83);minutes=(((value&0x70)>>4)*10+(value&0x0f));display_Minute(minutes);value=ReadSet1302(0x85);hours=(((value&0x70)>>4)*10+(value&0x0f));display_Hour(hours);value=ReadSet1302(0x87);day=(((value&0x70)>>4)*10+(value&0x0f));display_Day(day);value=ReadSet1302(0x89);month=(((value&0x70)>>4)*10+(value&0x0f));display_Month(month);value=ReadSet1302(0x8D);year=(((value&0xf0)>>4)*10+(value&0x0f));display_Year(year);}void displaystar(void) //显示欢迎界面{unsigned char i,j;Write_Address(0x0f);while(displaywelcome[i]!='\0'){Write_Date(displaywelcome[i]);i++;delay1ms(1);}i=0;Write_Address(0x4f);while(displaywish[i]!='\0'){Write_Date(displaywish[i]);i++;delay1ms(1);}j=40;while(j--){Write_com(0x18);//循环左移delay1ms(700);}Write_com(0x01);delay1ms(10);}void gbdisplay(unsigned char address) //时间调整时光标闪烁{Write_Address(address);delay1ms(5);Write_com(0x0f);delay1ms(5);}void displaymaxt(unsigned char x) //显示最大温度{unsigned char i,j,k;Write_com(0x0c);delay1ms(2);Write_Address(0x44);i=x/100;j=x/10;k=x%10;Write_Date(digit[i]);Write_Date(digit[j]);Write_Date(digit[k]);}/*****************时间调整部分*********************/void hourset(void) //调时{unsigned char timevalue,hour;delay1ms(500); //防止多次触发WriteSet1302(0x8e,0x00);//将写保护去掉,确保能正常将调整后的数值写入DS1302timevalue=ReadSet1302(0x85); //读取此时的数值hour=(((timevalue&0x70)>>4)*10+(timevalue&0x0f));while(1){if(ADD==0){delay1ms(50);if(ADD==0){hour++;delay1ms(300);while(ADD==0);}}if(RED==0){delay1ms(50);if(RED==0){hour--;delay1ms(300);if(hour==0) hour=23;while(RED==0);}}timevalue=(((hour)/10)<<4|(hour%10));WriteSet1302(0x84,timevalue);delay1ms(1);display_Hour(hour);Write_Address(0x49);delay1ms(5);if(hour>=24) hour=0;delay1ms(5);if(CANL==0){mode=0;Write_com(0x0c);break;}if(SET==0) break;}WriteSet1302(0x8e,0x80);}void minuteset(void) //调分{unsigned char timevalue,minute;delay1ms(500);WriteSet1302(0x8e,0x00);timevalue=ReadSet1302(0x83);minute=(((timevalue&0x70)>>4)*10+(timevalue&0x0f));while(1){if(ADD==0){delay1ms(10);if(ADD==0){minute++;if(minute>=60) timevalue=0;while(ADD==0);}}if(RED==0)delay1ms(10);if(RED==0){minute--;delay1ms(300);if(minute==0) minute=59;while(RED==0);}}timevalue=((minute/10)<<4|(minute%10));WriteSet1302(0x82,timevalue);delay1ms(1);display_Minute(minute);Write_Address(0x4c);delay1ms(5);if(minute>=60) minute=0;delay1ms(5);if(CANL==0){mode=0;Write_com(0x0c);break;}if(SET==0) break;}WriteSet1302(0x8e,0x80);}void secondset(void) //秒归零{unsigned char second;delay1ms(500);WriteSet1302(0x8e,0x00);while(1){if(ADD==0){delay1ms(10);if(ADD==0){second=0;WriteSet1302(0x80,0x00);while(ADD==0);}delay1ms(1);display_Second(second);Write_Address(0x4f);delay1ms(5);if(CANL==0){mode=0;Write_com(0x0c);break;}if(SET==0) break;}WriteSet1302(0x8e,0x80);}void yearset(void) //调年{unsigned char datevalue,year;delay1ms(500);WriteSet1302(0x8e,0x00);datevalue=ReadSet1302(0x8d);year=(((datevalue&0x70)>>4)*10+(datevalue&0x0f));while(1){if(ADD==0){delay1ms(10);if(ADD==0){year++;while(ADD==0);}}if(RED==0){delay1ms(10);if(RED==0){year--;delay1ms(300);while(RED==0);}}datevalue=((year/10)<<4|(year%10));WriteSet1302(0x8c,datevalue);delay1ms(5);display_Year(year);delay1ms(5);Write_Address(0x09);delay1ms(5);if(CANL==0){mode=0;Write_com(0x0c);break;}if(SET==0) break;}WriteSet1302(0x8e,0x80);}void monthset(void) //调月{unsigned char datevalue,month;delay1ms(500);WriteSet1302(0x8e,0x00);datevalue=ReadSet1302(0x89);month=(((datevalue&0x70)>>4)*10+(datevalue&0x0f));while(1){if(ADD==0){delay1ms(10);if(ADD==0){month++;if(month>12) month=1;while(ADD==0);}}if(RED==0){delay1ms(10);if(RED==0){month--;delay1ms(300);if(month==0) month=12;while(RED==0);}}datevalue=((month/10)<<4|(month%10));WriteSet1302(0x88,datevalue);delay1ms(1);display_Month(month);Write_Address(0x0c);delay1ms(5);if(CANL==0){mode=0;Write_com(0x0c);break;}if(SET==0) break;}WriteSet1302(0x8e,0x80);}void dayset(void) //调日{unsigned char datevalue,day;delay1ms(500);WriteSet1302(0x8e,0x00);datevalue=ReadSet1302(0x87);day=(((datevalue&0x70)>>4)*10+(datevalue&0x0f));while(1){if(ADD==0){delay1ms(10);if(ADD==0){day++;if(day>31) day=1;while(ADD==0);}}if(RED==0){delay1ms(10);if(RED==0){day--;delay1ms(300);if(day==0) day=31;while(RED==0);}}datevalue=((day/10)<<4|(day%10));WriteSet1302(0x86,datevalue);delay1ms(1);display_Day(day);Write_Address(0x0f);delay1ms(5);if(CANL==0){mode=0;Write_com(0x0c);break;}if(SET==0) break;}WriteSet1302(0x8e,0x80);}void alarmhourset(void) //闹钟小时调整{unsigned char value;value=houra;while(1){if(ADD==0){delay1ms(20);if(ADD==0){Write_com(0x0c);delay1ms(5);value++;if(value>23) value=0;while(ADD==0);}}if(RED==0){delay1ms(20);if(RED==0){value--;if(value==0) value=23;while(RED==0);}}houra=value;display_houra(houra);gbdisplay(0x45);if(CANL==0){delay1ms(500);break;}}}void alarmminuteset(void) //闹钟分钟调整{while(1){if(ADD==0){delay1ms(20);if(ADD==0){minutea++;if(minutea>59) minutea=0;while(ADD==0) ;}}if(RED==0){delay1ms(20);if(RED==0){minutea--;if(minutea==0) minutea=59;while(RED==0) ;}}display_minutea(minutea);gbdisplay(0x48);if(CANL==0){delay1ms(500);break;}}}void TimeSet(void) //时间调整函数{display_Time();if(SET==0){delay1ms(10);if(SET==0){mode++;delay1ms(20);switch(mode){case(1):{gbdisplay(0x48);hourset(); delay1ms(500);} break;case(2):{gbdisplay(0x4c);minuteset();delay1ms(500);} break;case(3):{gbdisplay(0x4f);secondset();delay1ms(500);} break;case(4):{gbdisplay(0x09);yearset();delay1ms(500);} break;case(5):{gbdisplay(0x0c);monthset();delay1ms(500);} break;case(6):{gbdisplay(0x0f);dayset();delay1ms(500);} break;}if(mode==7) mode=0;}}}/***************显示温度模块********************/unsigned char code displayexplain[]={"Digit thermometer"};unsigned char code displayerror[]={"DS18B20 ERROR"};unsigned char code displayerror1[]={"PLEASE CHECK "};unsigned char code displaypart1[]={"WenDu:"};unsigned char code displaypart2[]={"Cent"};unsigned char flag;/**********************操作DS18B20模块***************************/ sbit DQ=P3^3;unsigned char time;/**********************DS18B20初始化****************************/bit IntDS18B20(void){bit temp;DQ=1;for(time=0;time<2;time++);DQ=0;for(time=0;time<200;time++);DQ=1;for(time=0;time<10;time++);temp=DQ;for(time=0;time<200;time++);return temp;}/**************************读DS18B20**********************/unsigned char ReadDS18B20(void){unsigned char i;unsigned char dat;for(i=0;i<8;i++){DQ=1;_nop_();DQ=0;_nop_();DQ=1;for(time=0;time<2;time++);dat>>=1;if(DQ==1)dat=dat|0x80;elsedat=dat|0x00;for(time=0;time<10;time++);}return dat;}/*********************向DS18B20写数据**************************/ void WriteDS18B20(unsigned char date){unsigned char i;for(i=0;i<8;i++){DQ=1;_nop_();DQ=0;DQ=date&0x01;for(time=0;time<10;time++);DQ=1;for(time=0;time<1;time++);date>>=1;}for(time=0;time<4;time++);}/*******************为读取温度做好准备************************/ void ReadyreadDS18B20(void){IntDS18B20();WriteDS18B20(0XCC);WriteDS18B20(0X44);delay1ms(200);IntDS18B20();WriteDS18B20(0XCC);WriteDS18B20(0XBE);}/*************在1602液晶上显示相关信息模块**********************/ /****************当未检测到DS18B20时显示信息模块****************/ void Display_Error(void){unsigned char i=0;Write_Address(0x00);while(displayerror[i]!='\0'){Write_Date(displayerror[i]);i++;delay1ms(100);}delay1ms(5);i=0;Write_Address(0x40);while(displayerror1[i]!='\0'){Write_Date(displayerror1[i]);i++;delay1ms(100);}delay1ms(3000) ;}/*************温度显示模块****************/void Display_Explain(void){unsigned char i=0;Write_Address(0x00);delay1ms(5);while(displayexplain[i]!='\0'){Write_Date(displayexplain[i]);i++;delay1ms(5);}i=0;Write_Address(0x40);while(displaypart1[i]!='\0'){Write_Date(displaypart1[i]);i++;delay1ms(5);}i=0;Write_Address(0x4C);while(displaypart2[i]!='\0'){Write_Date(displaypart2[i]);i++;delay1ms(5);}Write_Address(0x49);Write_Date('.');delay1ms(5);}/*********************显示温度整数部分*************************/ void Display_Integer(unsigned char x){unsigned char i,j,k;i=x/100;j=x%100/10;k=x%10;Write_Address(0x46);if(flag==1) Write_Date('-');Write_Date(digit[i]);Write_Date(digit[j]);Write_Date(digit[k]);delay1ms(50) ;}/************显示温度小数部分*********************/ void Display_Decimal(unsigned char x){Write_Address(0x4A);delay1ms(5);Write_Date(digit[x]);delay1ms(50);}void displayovert(void){unsigned char i;Write_com(0x01);delay1ms(10);Write_Address(0x03);delay1ms(10);Write_Date('W');Write_Date('A');Write_Date('R');Write_Date('N');Write_Date('I');Write_Date('N');Write_Date('G');Write_Date('!');Write_Address(0x40);while(overtemperature[i]!='\0'){Write_Date(overtemperature[i]);i++;delay1ms(10);}}/*******************温度主函数********************/ void Temperature(void){unsigned char i;delay1ms(5);if(IntDS18B20()!=0) Display_Error();else{delay1ms(1);Write_com(0x01);delay1ms(5);Display_Explain();for(length=50;length>0;length--){for(i=0;i<6;i++){flag=0;ReadyreadDS18B20();TL=ReadDS18B20();TH=ReadDS18B20();if((TH&0XF8)!=0X00){flag=1;TL=~TL;TH=~TH;TL+=1;if(TL>255) TH+=1;TN=TH*16+TL/16;TD=(TL%16)*10/16;}TN=TH*16+TL/16;TD=(TL%16)*10/16;Display_Integer(TN);Display_Decimal(TD);delay1ms(10);}if(tempswitch==1){if(TN>=Maxtemp){Write_Address(0x03);delay1ms(5);displayovert();while(1){baojing(1);if(CANL==0){Write_com(0x01);delay1ms(5);break;}}}}if(CANL==0) break;}}}void tempset(void){if(ADD==0){delay1ms(10);if(ADD==0){Maxtemp++;while(ADD==0);}}if(RED==0){delay1ms(10);if(RED==0){Maxtemp--;while(RED==0);}}}void Maxtempset(void) //高温报警设置{Write_com(0x01);delay1ms(10);Write_Address(0x03);delay1ms(10);Write_Date('T');Write_Date('E');Write_Date('M');Write_Date('P');Write_Address(0x09);Write_Date('S');Write_Date('E');Write_Date('T');Write_Address(0x40);Write_Date('M');Write_Date('A');Write_Date('X');Write_Date(':');while(1){if(SET==0){delay1ms(20);if(SET==0){Write_Address(0x4e);Write_com(0x0f);while(1){if(ADD==0){delay1ms(20);if(ADD==0){Write_Address(0x4b);delay1ms(5);Write_Date('O');Write_Date('N');Write_Date(' ');tempswitch=1;}}if(RED==0){delay1ms(20);if(RED==0){Write_Address(0x4b);Write_Date('O');Write_Date('F');Write_Date('F');tempswitch=0;}}if(CANL==0){delay1ms(500);break;}}}}if(tempswitch==1){Write_Address(0x4b);Write_Date('O');Write_Date('N');Write_Date(' ');tempset();displaymaxt(Maxtemp);if(CANL==0){Write_com(0x01);displaymainpart();break;}}if(tempswitch==0){Write_com(0x0c);Write_Address(0x4b);Write_Date('O');Write_Date('F');Write_Date('F');}if(CANL==0){Write_com(0x01); displaymainpart();break;}}}void alarmswitchset(void){while(1){if(ADD==0){delay1ms(100);if(ADD==0){alarmmode=1;Write_Address(0x4c);Write_Date('O');Write_Date('N');Write_Date(' ');}}if(RED==0){alarmmode=0;Write_Address(0x4c);Write_Date('O');Write_Date('F');Write_Date('F');}if(CANL==0){delay1ms(500);break;}}}/**************** 设置模块 ******************/ void Set(void){if(SET==0){delay1ms(10);if(SET==0){Write_Address(0x40);Write_Date('T');Write_com(0x0f);delay1ms(1000);Write_com(0x0c);while(1){TimeSet();if(ADD==0){delay1ms(20);if(ADD==0){Write_com(0x01);Write_Address(0x00);delay1ms(5);Write_Date('S');delay1ms(10);Maxtempset();}}if(RED==0){delay1ms(20);if(RED==0){Write_com(0x01);delay1ms(5);Write_Address(0x02);Write_Date('A');Write_Date('L');Write_Date('A');Write_Date('R');Write_Date('M');Write_Address(0x09);Write_Date('S');Write_Date('E');Write_Date('T');Write_Address(0x46);Write_Date('-');display_houra(houra);display_minutea(minutea);if(alarmmode==1){Write_Address(0x4c);Write_Date('O');Write_Date('N');Write_Date(' ');}if(alarmmode==0){Write_Address(0x4c);Write_Date('O');Write_Date('F');Write_Date('F');}while(1){if(SET==0){delay1ms(100);if(SET==0){amode++;switch(amode){case(1):{gbdisplay(0x45);alarmhourset();Write_com(0x0c);delay1ms( 500);} break;case(2):{gbdisplay(0x48);alarmminuteset();Write_com(0x0c);delay1m s(500);} break;case(3):{gbdisplay(0x4c);alarmswitchset();Write_com(0x0c);delay1m s(500);} break;}if(amode==4) amode=0;}}if(CANL==0){Write_com(0x01);delay1ms(5);displaymainpart();break;}}}}if(CANL==0){Write_Address(0x40);Write_Date(' ');Write_com(0x0c);break;}}}}}/***************主函数**********************/void main(){IE=0X82; //打开定时中断TMOD=0X01; //选择定时器0工作在方式1TR0=0; //启动定时器0IntDS1302(); //初始化DS1302delay1ms(1);Lcd_Int(); //1602液晶初始化delay1ms(2);displaystar(); //显示欢迎界面displaymainpart(); //显示主要部分(不变化)while(1){display_Time( );Set( );if(ADD==0){Write_com(0x01);delay1ms(5);Temperature();Write_com(0x01);displaymainpart();}if((hours==houra)&&(minutes==minutea)&&(seconds==0)) {if(alarmmode==1){Write_com(0x01);delay1ms(5);Write_Address(0x03);Write_Date('T');Write_Date('I');Write_Date('M');Write_Date('E');Write_Address(0x08);Write_Date('U');Write_Date('P');Write_Date('!');delay1ms(5);while(1){baojing(1);if(CANL==0){Write_com(0x01);delay1ms(5);displaymainpart();break;}}}}}}。

万年历源代码

万年历源代码
LCD_Write(LCD_COMMAND, 0x04|InputMode); }
//初始化 LCD************************************************************
void LCD_Initial()
{
LcdEn=0; LCD_Write(LCD_COMMAND,0x38);
#define LCD_SHOW
0x04 //显示开
#define LCD_HIDE
0x00 //显示关
#define LCD_CURSOR #define LCD_NO_CURSOR
#define LCD_FLASH #define LCD_NO_FLASH
0x02 0x00
//显示光标 //无光标
{
Time->DateString[0] = '2';
Time->DateString[1] = '0';
Time->DateString[2] = Time->Year/10 + '0';
#include <REG52.H> #include <intrins.h> //#include "LCD1602.h" //#include "DS1302.h"
#define uint unsigned int #define uchar unsigned char sbit DS1302_CLK = P1^7; sbit DS1302_IO = P1^6; sbit DS1302_RST = P1^5;
0x01 0x00
//光标闪动 //光标不闪动

数字万年历简易C语言程序源代码

数字万年历简易C语言程序源代码

数字万年历简易C语言程序源代码#include"reg52.h"#define uchar unsigned char#define uint unsigned intsbit rs=P2^0; // lcd 控制端sbit en=P2^2; // lcd 控制端sbit all=P2^1; // lcd 控制端sbit s0=P1^5; //时间调节sbit s1=P1^6;sbit s2=P1^7;sbit voice=P2^7;int nt;sbit DQ=P2^6;sbit DS1302_CLK = P2^3; //实时时钟时钟线引脚sbit DS1302_IO = P2^4; //实时时钟数据线引脚sbit DS1302_RST = P2^5; //实时时钟复位线引脚sbit ACC0 = ACC^0;sbit ACC7 = ACC^7;unsigned char time;#define ads_y 0#define ads_mo 3#define ads_d 6#define ads_w 9#define ads_h 65#define ads_m 68#define ads_s 71#define DS1302_SECOND 0x80 //写入ds地址宏定义#define DS1302_MINUTE 0x82#define DS1302_HOUR 0x84#define DS1302_WEEK 0x8A#define DS1302_DAY0x86#define DS1302_MONTH 0x88#define DS1302_YEAR 0x8Cvoid delay1(unsigned int i) //ds 延时函数放在前边是为了让EP 两次存储之间延时可以调用{while(i--);}void init_ds() //ds 初始化函数{unsigned char x=0;DQ=1; //DQ复位delay1(8); //稍做延时DQ=0; //单片机将DQ拉低delay1(80); //精确延时大于480usDQ=1; //拉高总线delay1(10);x=DQ; //稍做延时后如果x=0则初始化成功x=1则初始化失败delay1(5);}unsigned char read_ds() ///ds 读一个字节{unsigned char i=0;unsigned char dat=0;for(i=8;i>0;i--){DQ=0; // 给脉冲信号dat>>=1;DQ=1; // 给脉冲信号if(DQ)dat|=0x80;delay1(5);}return(dat);}void write_ds(unsigned char dat) ///写一个字节{unsigned char i=0;for(i=8;i>0;i--){DQ=0;DQ=dat&0x01;delay1(5);DQ=1;dat>>=1;}delay1(5);}void get_nt() //获取温度{unsigned char a=0;unsigned char b=0;init_ds();write_ds(0xCC); // 跳过读序号列号的操作write_ds(0x44); // 启动温度转换delay1(10);init_ds();write_ds(0xCC); //跳过读序号列号的操作write_ds(0xBE); //读取温度寄存器等(共可读9个寄存器)前两个就是温度a=read_ds();b=read_ds();nt=0;nt=nt+b;nt=nt<<8;nt=nt+a;nt=nt*0.625; //此ds18b20 最低位为0.5 扩大十倍}void delay_1302(uint n) //按键长延时{while(n--);}void delay(uchar n) //lcd 延时子程序{uchar i,j;for(i=0;i<n;i++)< bdsfid="161" p=""></n;i++)<>for(j=0;j<10;j++);}void write_com(char com) //lcd comond in LCD控制字写入函数{en=0;P3=com;rs=0;delay(1);en=1;delay(2);en=0;delay(2);}void write_byte(char byte) //lcd data in LCD数据写入函数{en=0;P3=byte;rs=1;delay(1);en=1;delay(2);en=0;delay(2);}void init_lcd_com() //lcd init LCD初始化{all=0;write_com(0x38);write_com(0x0c);write_com(0x06);}void DS1302InputByte(unsigned char d) //实时时钟写入一字节(内部函数){unsigned char i;ACC = d;for(i=8; i>0; i--){DS1302_IO = ACC0; //相当于汇编中的RRCDS1302_CLK = 1;DS1302_CLK = 0;ACC = ACC >> 1;}}unsigned char DS1302OutputByte(void) //实时时钟读取一字节(内部函数){unsigned char i;for(i=8; i>0; i--){ACC = ACC >>1; //相当于汇编中的RRCACC7 = DS1302_IO;DS1302_CLK = 1;DS1302_CLK = 0;}return(ACC);}void Write1302(unsigned char ucAddr, unsigned char ucDa) //ucAddr: DS1302地址, ucData: 要写的数据DS1302_RST = 0;DS1302_CLK = 0;DS1302_RST = 1;DS1302InputByte(ucAddr); // 地址,命令DS1302InputByte(ucDa); // 写1Byte数据DS1302_CLK = 1;DS1302_RST = 0;}unsigned char Read1302(unsigned char ucAddr) //读取DS1302某地址的数据{unsigned char ucData;DS1302_RST = 0;DS1302_CLK = 0;DS1302_RST = 1;DS1302InputByte(ucAddr|0x01); // 地址,命令ucData = DS1302OutputByte(); // 读1Byte数据DS1302_CLK = 1;DS1302_RST = 0;return(ucData);}void DS1302_SetProtect(bit flag) //是否写保护{if(flag)Write1302(0x8E,0x10);elseWrite1302(0x8E,0x00);}void DS1302_SetTime(unsigned char Address, unsigned char V alue) // 关键函数向内写入时间{DS1302_SetProtect(0);Write1302(Address, ((V alue/10)<<4 | (V alue%10)));}void DS1302_GetTime(unsigned char xy) //关键函数向外读出时间{unsigned char ReadV alue;ReadV alue = Read1302(xy);time=((ReadV alue&0x70)>>4)*10+(ReadV alue&0x0F);}void display_nt(char ads,uchar t) //将读出时间显示char ge,shi;write_com(0x80+ads);shi=t%100/10;ge=t%10;write_byte(shi+'0');write_byte(ge+'0');}void display_nt2(char ads,uchar t) //将读出星期显示{ write_com(0x80+ads);write_byte(t+'0');}void get_dis() //获得时间并显示{DS1302_GetTime(DS1302_YEAR);display_nt(ads_y,time);DS1302_GetTime(DS1302_MONTH);display_nt(ads_mo,time);DS1302_GetTime(DS1302_DAY);display_nt(ads_d,time);DS1302_GetTime(DS1302_WEEK);display_nt2(ads_w,time);DS1302_GetTime(DS1302_HOUR);display_nt(ads_h,time);DS1302_GetTime(DS1302_MINUTE);display_nt(ads_m,time);DS1302_GetTime(DS1302_SECOND);display_nt(ads_s,time);}void set_time() //三按键设置时间{if(s0==0){write_com(0x0f); //开闪烁write_com(0x80+ads_m+1);while(s0==0);delay_1302(30000);while(s0==1){if(s1==0){DS1302_GetTime(DS1302_MINUTE); time++;DS1302_SetTime(DS1302_MINUTE,time); display_nt(ads_m,time);write_com(0x80+ads_m+1);delay_1302(30000);}if(s2==0){DS1302_GetTime(DS1302_MINUTE); time--;DS1302_SetTime(DS1302_MINUTE,time); display_nt(ads_m,time);write_com(0x80+ads_m+1);delay_1302(30000);}}write_com(0x80+ads_h+1);while(s0==0);delay_1302(30000);while(s0==1){if(s1==0){DS1302_GetTime(DS1302_HOUR); time++;DS1302_SetTime(DS1302_HOUR,time); display_nt(ads_h,time);write_com(0x80+ads_h+1);delay_1302(30000);}if(s2==0){DS1302_GetTime(DS1302_HOUR); time--;DS1302_SetTime(DS1302_HOUR,time); display_nt(ads_h,time);write_com(0x80+ads_h+1);delay_1302(30000);}}write_com(0x80+ads_w);while(s0==0);delay_1302(30000);while(s0==1){if(s1==0){DS1302_GetTime(DS1302_WEEK); time++;DS1302_SetTime(DS1302_WEEK,time); display_nt2(ads_w,time);write_com(0x80+ads_w);delay_1302(30000);}if(s2==0){DS1302_GetTime(DS1302_WEEK); time--;DS1302_SetTime(DS1302_WEEK,time); display_nt2(ads_w,time);write_com(0x80+ads_w);delay_1302(30000);}}write_com(0x80+ads_d+1);while(s0==0);delay_1302(30000);while(s0==1){if(s1==0){DS1302_GetTime(DS1302_DAY);time++;DS1302_SetTime(DS1302_DAY,time); display_nt(ads_d,time);write_com(0x80+ads_d+1);delay_1302(30000);}if(s2==0){DS1302_GetTime(DS1302_DAY);time--;DS1302_SetTime(DS1302_DAY,time);display_nt(ads_d,time);write_com(0x80+ads_d+1);delay_1302(30000);}}write_com(0x80+ads_mo+1);while(s0==0);delay_1302(30000);while(s0==1){if(s1==0){DS1302_GetTime(DS1302_MONTH); time++;DS1302_SetTime(DS1302_MONTH,time); display_nt(ads_mo,time);write_com(0x80+ads_mo+1);delay_1302(30000);}if(s2==0){DS1302_GetTime(DS1302_MONTH); time--;DS1302_SetTime(DS1302_MONTH,time); display_nt(ads_mo,time);write_com(0x80+ads_mo+1);delay_1302(30000);}}write_com(0x80+ads_y+1);while(s0==0);delay_1302(30000);while(s0==1){if(s1==0){DS1302_GetTime(DS1302_YEAR); time++;DS1302_SetTime(DS1302_YEAR,time); display_nt(ads_y,time);write_com(0x80+ads_y+1);delay_1302(30000);}if(s2==0){DS1302_GetTime(DS1302_YEAR); time--;DS1302_SetTime(DS1302_YEAR,time); display_nt(ads_y,time);write_com(0x80+ads_y+1);delay_1302(30000);}}write_com(0x0c);while(s0==0);delay_1302(30000);}}void init_lcd_dis() //显示初始化{write_com(0x80+2);write_byte('*');write_com(0x80+5);write_byte('*');write_com(0x80+8);write_byte('-');write_com(0x80+67);write_byte(':');write_com(0x80+70);write_byte(':');}void my() //右下角显示函数{char *pp;char i;code char p[]=" hou fei see a girl and say I LOVE YOU replay I LOVE YOU too ";pp=p;if(time<=60){write_com(0x80+74);for(i=0;i<=5;i++){write_byte(*(pp+time));pp++;}}}void display_nntt(int t) //当前温度显示{char ge,shi,bai;if(t<0){write_com(0x80+11);write_byte('-');t=-t;}else{write_com(0x80+11);write_byte('+');}bai=t/100;shi=t%100/10;ge=t%10;write_byte(bai+'0');write_byte(shi+'0');write_byte('.');write_byte(ge+'0');}void main(){init_lcd_com();init_lcd_dis();DS1302_SetTime(DS1302_SECOND,00); while(1){get_dis();set_time();get_nt();display_nntt(nt); my();}}。

单片机代码-DS1302万年历

单片机代码-DS1302万年历

#include<reg52.h>#include<intrins.h> //为了使用这个头文件中的_nop_()延时函数sbitsda=P2^0; //定义1302的数据线sbitscl=P2^1; //定义1302的时钟线sbitrst=P2^4; //定义1302的复位控制端,高电平时启动1302,低电平时关闭1302 sbit hc573_sg_le=P2^6; //对用于锁存段数据的573锁存LE端进行定义sbit hc573_bit_le=P2^7; //对用于锁存位选通数据的573锁存LE端进行定义sbitlcd_rs=P1^0; //1602数据/命令选择端,高电平执行数据操作,低电平执行命令操作sbitlcd_rw=P1^1; //1602读/写控制端高电平读,低电平写sbitlcd_en=P2^5; //1602读写控制使能信号,它为高脉冲信号才可执行读写操作sbit sta7=P0^7; //1602忙信号检测位,为1则忙,需等待,为0表示空闲unsigned char write_dat[8]={0x12,0x36,0x17,0x23,0x8,0x5,0x13,0x80}; //秒分时日月星期年和保护寄存器的初值unsigned char read_dat[8]; //用于接收从1302读到的寄存器当前值unsigned char code lcd_line1[]={" 20 - -"}; //定义第一行液晶显示的格式字符数组unsigned char code lcd_line2[]={"Week: : :"}; //定义第二行液晶显示的格式字符数组void lcd_busy_check(void) //1602忙信号检测,忙则等待{P0=0xff;do{lcd_rs=0; //读状态操作,为0lcd_rw=1; //读操作为1lcd_en=0;lcd_en=1; //读状态,需为高电平}while (sta7==1); //如果为1则忙,等待...直到为0lcd_en=0;}void lcd_write_cmd(unsigned char cmd) //液晶写命令函数{lcd_busy_check(); //每次操作之前都要进行忙信号检测lcd_rs=0; //执行命令操作,为0lcd_rw=0; //写操作,为0P0=cmd; //送指令到液晶数据端口P0,准备执行命令_nop_(); //这是一个延时函数,可延时一个机器周期,它在“intrins.h”中lcd_en=1; //高电平,指令送入液晶控制器_nop_(); //保持一会儿,使指令可靠地送入液晶控制器lcd_en=0; //低电平,执行命令}void lcd_write_data(unsigned char dat) //液晶写数据函数{lcd_busy_check(); //每次操作之前都要进行忙信号检测lcd_rs=1; //执行数据操作,为1lcd_rw=0; //写操作,为0P0=dat; //送数据到液晶数据端口P0,准备执行数据操作_nop_();lcd_en=1; //高电平,数据送入液晶液晶数据RAM_nop_(); //保持一会儿,使显示数据可靠地送入液晶数据RAM lcd_en=0; //低电平,显示数据}void lcd1602_init() //液晶显示初始化操作{P0=0x00;hc573_bit_le=0;hc573_sg_le=0; //关闭HC573使数码管不显示lcd_en=0; //为0,为实现高脉冲作准备lcd_write_cmd(0x38); //设置为5x7显示lcd_write_cmd(0x0c); // 打开显示-显示光标-光标闪烁lcd_write_cmd(0x6); //地址加一,光标右移,整屏显示不移动lcd_write_cmd(0x01); //清屏}/*--对1302进行写一个字节的函数--*/voidwrite_byte(unsigned char dat){unsigned char i;for(i=8;i>0;i--){sda=(bit)(dat&0x01);scl=0;scl=1;dat=dat>>1;}}/*--对1302进行读一个字节的函数--*/unsigned char read_byte(){unsigned char dat,i;for(i=8;i>0;i--){dat=dat>>1;scl=1;scl=0;if(sda==1)dat=(dat|0x80);}returndat;}/*--1302的初始化函数。

c51单片机万年历的c程序

c51单片机万年历的c程序

c51单片机万年历的c程序c51单片机万年历的c程序求一个单片机可以显示阳历的年、月、日、星期、小时.分.秒。

阴历也能显示,标明是否为闰年。

用LCD液晶显示,可以调整时间。

这有个数码管显示的程序以前做的,。

你可以在我这个程序上修改修改包括键盘扫描,还有动态显示。

【。

】#include <REG51.H>//常量参数#define TMODW 0x01;#define SCONW 0x00;#define xplay 0x04;//显示分频系数//显示位选unsigned char data stb;//键值缓存,0xFF无键命令unsigned char data keynum;//显示字型变量unsigned char data play[8];//工作参数unsigned char data l,m;//字型码unsigned char code BCDPC[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};//字位码unsigned char code STBCODE[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80 };//400Hz xplay分频计数unsigned char data cttime;//时钟参数unsigned char data hr,min,sec,sec100;//调整时钟参数(时钟“走”)void ct1(){sec100++;if (sec100==100){sec100=0;sec++;if (sec==60){sec=0;min++;if (min==60){min=0;hr++;if (hr==24) hr=0;}}}}//时钟参数→LED 显示缓存7段参数转换函数;void xcplay(){play[0]=BCDPC[hr/10];play[1]=BCDPC[hr%10];play[2]=BCDPC[min/10];play[3]=BCDPC[min%10];play[4]=BCDPC[sec/10];play[5]=BCDPC[sec%10];play[6]=BCDPC[sec100/10]; play[7]=BCDPC[sec100%10];}//显示扫描void cplay(){T0=1;//T0-高电平消隐T1=0;//T1-低电平准备发脉冲前沿TI=0;//?P1=0;//?SBUF=STBCODE[stb];while (TI==0){};TI=0;SBUF=play[stb];while (TI==0){};T1=1;T0=0;stb=++stb&0x07;}extern void cthl0();//定时器0中断处理程序void ct0(void) interrupt 1 using 1 {cthl0();cttime--;if (cttime==0){cttime=xplay;ct1();//调用时钟“走”函数xcplay();//调用时钟参数→Led显示缓存转换函数};cplay();}void w20ms(){for (l=0;l<41;l++){for (m=0;m<81;m++){}}}void tkey(){P1=0xF0;keynum=0xFF;if (P1!=0xF0){w20ms();P1=0xF0;if (P1!=0xF0){P1=0xFE;switch (P1){case 0xEE:keynum=0;break;case 0xDE:keynum=1;break;case 0xBE:keynum=2;break;case 0x7E:keynum=3;break;}P1=0xFD;switch (P1){case 0xED:keynum=4;break;case 0xDD:keynum=5;break;case 0xBD:keynum=6;break; case 0x7B:keynum=7;break; }P1=0xFB;switch (P1){case 0xEB:keynum=8;break; }};};P1=0x00;}void command(){switch (keynum){case 0:{hr=hr+1;if (hr==24)hr=0;}break;case 1:{min=min+1;if (min==60)min=0;}break;case 2:{sec=sec+1;if (sec==60)sec=0;}break;case 3:{sec100=0; }break;case 4:{while(!(P1=0xED)) {hr=0;min=0;sec=0;}}break;case 5:{hr=hr-1;if (hr==00)hr=24;}break;case 6:{min=min-1; if (min==00)min=59;}break;case 7:{sec=sec-1; if (sec==00)sec=0;}break;case 0xFF:break; }keynum=0xFF; }main (){ hr=8;min=5;sec=8;sec100=0; TMOD=TMODW; SCON=SCONW; ET0=1;TR0=1;EA=1;cttime=xplay; while (1){w20ms();tkey(); command();};}。

单片机万年历 代码

单片机万年历 代码

void DS1302_limit(void) //初始化{DS1302_WriteEnable();DS1302_OscEnable();for(ds1302_b=0;ds1302_b<7;ds1302_b++)DS1302_SendByte(ds_sec+2*ds1302_b,d1302[ds1302_b]); //赋值初始化}uchar DS1302_Read(uchar address) //读时钟{uchar dat;DS1302_WriteEnable();switch(address){case 0:dat=DS1302_ReceiveByte(ds_sec+1);break;case 1:dat=DS1302_ReceiveByte(ds_min+1);break;case 2:dat=DS1302_ReceiveByte(ds_hour+1);break;case 3:dat=DS1302_ReceiveByte(ds_day+1);break;case 4:dat=DS1302_ReceiveByte(ds_week+1);break;case 5:dat=DS1302_ReceiveByte(ds_month+1);break;case 6:dat=DS1302_ReceiveByte(ds_year+1);break;}DS1302_WriteDisable();return(dat);}void DS1302_Write(uchar address,uchar dat){DS1302_WriteEnable();switch(address){case 0:DS1302_SendByte(ds_sec,dat);break;case 1:DS1302_SendByte(ds_min,dat);break;case 2:DS1302_SendByte(ds_hour,dat);break;case 3:DS1302_SendByte(ds_day,dat);break;case 4:DS1302_SendByte(ds_week,dat);break;case 5:DS1302_SendByte(ds_month,dat);break;case 6:DS1302_SendByte(ds_year,dat);break;}DS1302_WriteDisable();}ds1302pro() //读出数据{nian01=DS1302_ReceiveByte(ds_year+1);yue01=DS1302_ReceiveByte(ds_month+1);ri01=DS1302_ReceiveByte(ds_day+1);xiaoshi01=DS1302_ReceiveByte(ds_hour+1);sec01=DS1302_ReceiveByte(ds_sec+1); //读秒信息min01=DS1302_ReceiveByte(ds_min+1); //读分信息zhouxingqi=DS1302_ReceiveByte(ds_week+1);d1302_transfer(); //数值处理提取出待显示的值}void DS1302_SendByte(uchar Command,uchar XmtDat) // 发送数据程序,发送1个字节给被控器DS1302{uchar i;RST=0;_nop_();SCLK=0;_nop_();RST=1;for(i=0;i<8;i++){IO_DATA= (bit)(Command&0x01);Command = Command >> 1;SCLK=1;_nop_();SCLK=0;}for(i=0;i<8;i++){IO_DATA= (bit)(XmtDat&0x01);XmtDat = XmtDat >> 1;SCLK=1;_nop_();SCLK=0;}RST=0;}uchar DS1302_ReceiveByte(uchar Command) // 接收数据程序;从被控器DS1302 接收1个字节数据{uchar i, RcvDat=0;RST=0;_nop_();SCLK=0;_nop_();RST=1;for(i=0;i<8;i++){IO_DATA= (bit)(Command&0x01);Command = Command >> 1;SCLK=1;_nop_();SCLK=0;}for(i=0;i<7;i++){if(IO_DATA)RcvDat|=0x80;RcvDat= RcvDat >> 1;SCLK=1;_nop_();SCLK=0;}if(IO_DATA)RcvDat|=0x80;RST=0;return RcvDat;}void DS1302_WriteEnable(void) //允许数据写入寄存器{DS1302_SendByte(ds_com,00);}void DS1302_WriteDisable(void) //禁止数据写入寄存器{DS1302_SendByte(ds_com,0x80);}void DS1302_OscEnable(void) //起动时钟操作{DS1302_SendByte(ds_sec,0x00);}void DS1302_OscDisable(void) //停止时钟操作{DS1302_SendByte(ds_sec,0x80);}void d1302_transfer(void) //数据转换函数{nian02=nian01&0x0f;nian01=nian01>>4;yue02=yue01&0x0f;yue01=yue01>>4;ri02=ri01&0x0f;ri01=ri01>>4;xiaoshi02=xiaoshi01&0x0f;xiaoshi01=xiaoshi01>>4;min02=min01&0x0f;min01=min01>>4;sec02=sec01&0x0f; //取miao信号的低四位 sec01=sec01>>4; //取高四位}void delay1302(int i) //延时函数{uchar x,j;for(x=0;x<i;x++){for(j=0;j<125;j++){;} }}。

万年历程序代码

万年历程序代码

/*****************************************************4字LED点阵屏+DS1302万年历电子钟C 程序*******************************************************DS1302 接线图Vcc2 CLK I/O /RST| | | |-------------------| 8 7 6 5 || DS1302 || || 1 2 3 4 |-------------------| | | |VCC1 GND1 脚接+5V 2,3脚32768HZ晶振4脚接地5脚接S51的P02 6脚接S51的P01 7接S51的P008脚接后备电源,可以接老计算机主板上的3.6V电池,也可以通过二级管隔离接一个大容量电解电容电压在2.5V以上即可维持595连级输出数据,138行驱动。

*///(本程序引用网上程序,有点BUG经过修改后可以使用,经过修改调整加上了温度显示功能,节日提醒功能和家人生日提醒功能。

//程序没有有效简化)07电气工程,付春平!//手动添加定时器2寄存器定义sfr T2CON = 0xC8;(special function register)sfr TL2 = 0xCC;sfr TH2 = 0xCD;sfr RCAP2L = 0xCA;sfr RCAP2H = 0xCB;sbit TF2 = T2CON^7;sbit EXF2 = T2CON^6;sbit RCLK = T2CON^5;sbit TCLK = T2CON^4;sbit EXEN2 = T2CON^3;sbit TR2 = T2CON^2;sbit C_T2 = T2CON^1;sbit CP_RL2= T2CON^0;//sbit ET2 =0xAD;#include<A T89x51.H>#include <intrins.h>#define uchar unsigned char#define uint unsigned intunsigned char irtime;//红外用全局变量bit irokk;unsigned char IRcord[2];unsigned char irdata[17];unsigned char data temp_data[2] = {0x00,0x00} ;void Ircordpro(void);uchar code hanzi[]; //汉字字模uchar code hanzi1[]; //汉字字模uchar code timer[18][16]; //0~9数字uchar code sw[]; //138驱动数据void Show_word(); //待机显示按三秒间隔分别显示年、月日、星期、时分秒。

万年历时钟芯片代码

万年历时钟芯片代码

万年历时钟芯片代码/******************************************************************** * 文件名: 时钟DS1302LCD.c* 描述: 该程序实现了用单片机来控制时钟芯片DS1302进行时钟的显示。

时钟会在1602上显示.* 创建人:东流,2012年2月7日* 版本号:1.0* 杜邦线接法:P3.5接J18的1端;J3.6接J18的2端;J3.7接J18的3端。

1602接到J17的排座上。

********************************************************************* **/#include&lt;reg52.h&gt;#include&lt;intrins.h&gt;#define uchar unsigned char#define uint unsigned intsbit ACC0 = ACC^0;sbit ACC7 = ACC^7;sbit T_CLK = P3^5; /*实时时钟时钟线引脚*/sbit T_IO = P3^6; /*实时时钟数据线引脚*/sbit T_RST = P3^7; /*实时时钟复位线引脚*///这三个引脚参考资料sbit E=P2^7;//1602使能引脚sbit RW=P2^6;//1602读写引脚sbit RS=P2^5;//1602数据/命令选择引脚/******************************************************************** * 名称: delay()* 功能: 延时,延时时间大概为5US。

* 输入: 无* 输出: 无********************************************************************* **/void delay(){_nop_();_nop_();_nop_();_nop_();}void Delay(uint i){uint x,j;for(j=0;j&lt;i;j++)for(x=0;x&lt;=148;x++);}/******************************************************************** * 名称: bit Busy(void)* 功能: 这个是一个读状态函数,读出函数是否处在忙状态* 输入: 输入的命令值* 输出: 无********************************************************************* **/bit Busy(void){bit busy_flag = 0;RS = 0;RW = 1;E = 1;delay();busy_flag = (bit)(P0 &amp; 0x80);E = 0;return busy_flag;}/******************************************************************** * 名称: wcmd(uchar del)* 功能: 1602命令函数* 输入: 输入的命令值* 输出: 无********************************************************************* **/void wcmd(uchar del){while(Busy());RS = 0;RW = 0;E = 0;delay();delay();E = 1;delay();E = 0;}/******************************************************************** * 名称: wdata(uchar del)* 功能: 1602写数据函数* 输入: 需要写入1602的数据* 输出: 无********************************************************************* **/void wdata(uchar del){while(Busy());RS = 1;RW = 0;E = 0;delay();P0 = del;delay();E = 1;delay();E = 0;}/******************************************************************** * 名称: L1602_init()* 功能: 1602初始化,请参考1602的资料* 输入: 无* 输出: 无********************************************************************* **/void L1602_init(void){wcmd(0x38);Delay(5);wcmd(0x38);Delay(5);wcmd(0x38);Delay(5);wcmd(0x38);wcmd(0x08);wcmd(0x0c);wcmd(0x04);wcmd(0x01);}/******************************************************************** * 名称: L1602_char(uchar hang,uchar lie,char sign)* 功能: 改变液晶中某位的值,如果要让第一行,第五个字符显示&quot;b&quot; ,调用该函数如下L1602_char(1,5,&#39;b&#39;)* 输入: 行,列,需要输入1602的数据* 输出: 无********************************************************************* **/void L1602_char(uchar hang,uchar lie,char sign){uchar a;if(hang == 1) a = 0x80;if(hang == 2) a = 0xc0;a = a + lie - 1;wcmd(a);wdata(sign);}/******************************************************************** * 名称: L1602_string(uchar hang,uchar lie,uchar *p)* 功能: 改变液晶中某位的值,如果要让第一行,第五个字符开始显示&quot;ab cd ef&quot; ,调用该函数如下L1602_string(1,5,&quot;ab cd ef;&quot;)* 输入: 行,列,需要输入1602的数据* 输出: 无********************************************************************* **/void L1602_string(uchar hang,uchar lie,uchar *p){uchar a,b=0;if(hang == 1) a = 0x80;if(hang == 2) a = 0xc0;a = a + lie - 1;while(1){wcmd(a++);if((*p == &#39;\0&#39;)||(b==16)) break;b++;wdata(*p);p++;}}/******************************************************************** * 名称: v_RTInputByte()* 功能: 往DS1302写入1Byte数据* 输入: ucDa 写入的数据* 输出: 无********************************************************************* **/void v_RTInputByte(uchar ucDa){uchar i;ACC = ucDa;T_RST = 1;for(i=8; i&gt;0; i--){T_IO = ACC0;T_CLK = 1;T_CLK = 0;ACC = ACC &gt;&gt; 1;}}/******************************************************************** * 名称: uc_RTOutputByte()* 功能: 从DS1302读取1Byte数据* 输入:无* 返回值: ACC********************************************************************* **/uchar uc_RTOutputByte(void){uchar i;T_RST = 1;for(i=8; i&gt;0; i--){ACC = ACC &gt;&gt;1;T_IO=1;ACC7 = T_IO;T_CLK = 1;T_CLK = 0;}return(ACC);}/******************************************************************** * 名称: v_W1302(uchar ucAddr, uchar ucDa)* 功能: 往DS1302写入数据* 输入: ucAddr: DS1302地址, ucDa: 要写的数据* 返回值: 无********************************************************************* **/void v_W1302(uchar ucAddr, uchar ucDa){T_RST = 0;T_CLK = 0;T_RST = 1;v_RTInputByte(ucAddr); // 写地址_nop_();_nop_();v_RTInputByte(ucDa); // 写1Byte数据T_CLK = 1;T_RST = 0;}/******************************************************************** * 名称: uc_R1302(uchar ucAddr)* 功能: 读取DS1302某地址的数据* 输入: ucAddr: DS1302地址* 返回值: ucDa :读取的数据********************************************************************* **/uchar uc_R1302(uchar ucAddr){uchar ucDa;T_RST = 0;T_CLK = 0;T_RST = 1;v_RTInputByte(ucAddr); //写地址,命令_nop_();_nop_();ucDa = uc_RTOutputByte(); //读1Byte数据T_CLK = 1;T_RST = 0;return(ucDa);}/******************************************************************** * 名称: v_BurstW1302T* 功能: 往DS1302写入时钟数据(多字节方式)* 输入: pSecDa: 时钟数据地址格式为: 秒分时日月星期年控制* 8Byte (BCD码) 1B 1B 1B 1B 1B 1B 1B 1B* 返回值: 无********************************************************************* **/void v_BurstW1302T(uchar *pSecDa){uchar i;v_W1302(0x8e, 0x00); //控制命令,WP=0,写操作T_RST = 0;T_CLK = 0;T_RST = 1;v_RTInputByte(0xbe); //0xbe:时钟多字节写命令for(i=8; i&gt;0; i--) //8Byte = 7Byte 时钟数据+ 1Byte 控制{v_RTInputByte(*pSecDa); //写1Byte数据pSecDa++;}T_CLK = 1;T_RST = 0;}/******************************************************************** * 名称: v_BurstR1302T(uchar *pSecDa)* 功能: 读取DS1302时钟数据* 输入: pSecDa: 时钟数据地址格式为: 秒分时日月星期年* 7Byte (BCD码) 1B 1B 1B 1B 1B 1B 1B* 返回值: ucDa :读取的数据***********************************************************************/void v_BurstR1302T(uchar *pSecDa){uchar i;T_RST = 0;T_CLK = 0;T_RST = 1;v_RTInputByte(0xbf); //0xbf:时钟多字节读命令for(i=8; i&gt;0; i--){*pSecDa = uc_RTOutputByte(); //读1Byte数据pSecDa++;}T_CLK = 1;T_RST = 0;}/******************************************************************** * 名称: v_BurstW1302R(uchar *pReDa)* 功能: 往DS1302寄存器数写入数据(多字节方式)* 输入: pReDa: 寄存器数据地址* 返回值: 无********************************************************************* **/void v_BurstW1302R(uchar *pReDa){uchar i;v_W1302(0x8e,0x00); //控制命令,WP=0,写操作T_RST = 0;T_CLK = 0;T_RST = 1;v_RTInputByte(0xfe); //0xbe:时钟多字节写命令for(i=31; i&gt;0; i--) //31Byte 寄存器数据{v_RTInputByte(*pReDa); //写1Byte数据pReDa++;}T_CLK = 1;T_RST = 0;}/******************************************************************** * 名称: v_BurstR1302R(uchar *pReDa)* 功能: 读取DS1302寄存器数据* 输入: pReDa: 寄存器数据地址* 返回值: 无********************************************************************* **/void v_BurstR1302R(uchar *pReDa){uchar i;T_RST = 0;T_CLK = 0;T_RST = 1;v_RTInputByte(0xff); //0xbf:时钟多字节读命令for(i=31; i&gt;0; i--) //31Byte 寄存器数据{*pReDa = uc_RTOutputByte(); //读1Byte数据pReDa++;}T_CLK = 1;T_RST = 0;}/********************************************************************* 名称: v_Set1302(uchar *pSecDa)* 功能: 设置初始时间* 输入: pSecDa: 初始时间地址。

万年历,STC,DS1302

万年历,STC,DS1302

}
}

{ } break; P0=0x00;
LS138++; if(LS138>0x07) { } SetTimer0(); LS138=0x00;
//定时器 1,初始化,用于控制按设置键后数码管闪烁的频率 voidTimer1Init(void) { } AUXR&=0xBF; TMOD&=0x0F; TL1=0xB0; TH1=0x3C; TF1=0; TR1=1; //定时器时钟 12T 模式 //设置定时器模式 //50 毫秒@12.000MHz
}
{ do { while(--k);
}while(--j);
}while(--i);
//设置时间、日期、星期 voidSetDateTime() { } voidSetTimer0()//用于控制 138 扫描数码管的时间 { } voidtm1_isr()interrupt3using1 { flashTime++; if(flashTime>50) TL0=0x78; TH0=0xCC; TF0=0; //设置定时初值 //设置定时初值 Set_RTC(write_rtc_address,l_tmpdate);
table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40,0x00};
codeunsignedcharwrite_rtc_address[7]={0x80,0x82,0x84,0x86,0x88,0x8a,0x8c};// 秒分时日月周年 最低位读写位 codeunsignedcharread_rtc_address[7]={0x81,0x83,0x85,0x87,0x89,0x8b,0x8d}; unsignedcharl_tmpdate[7]={30,43,21,15,12,2,14};//初始化 ds1302 的值 unsigned char Result[7]={0x00,0x00,0x00,0x00,0x00,0x00,0x00};//读取 ds1302 的结 果 unsigned char SetValue[7]={0x00,0x00,0x00,0x00,0x00,0x00,0x00};//存储已经设置好 的值,该值最后要写入 ds1302 unsignedcharLS138; unsigned char SetKey;//0x00 表示没有按设置键,0x01 设置年,0x02 设置月,0x03 设置 日,0x04 设置小时,0x05 设置分,0x06 设置秒 unsignedcharFlash,flashTime; unsignedcharHexYear; voidDelay250ms() { _nop_(); i=2; j=231; k=91; do unsignedchari,j,k; //@12.000MHz

单片机万年历程序代码

单片机万年历程序代码

单片机万年历程序代码以下是一个示例单片机万年历的程序代码:```c#include <reg51.h>typedef unsigned char uchar;typedef unsigned int uint;sbit K1 = P2^0; // 显示年份sbit K2 = P2^1; // 显示月份sbit K3 = P2^2; // 显示日期uchar code year_tab[] = {31,28,31,30,31,30,31,31,30,31,30,31}; uchar code week_tab[] = {0x06,0x07,0x01,0x02,0x03,0x04,0x05}; uchar year, month, day, week;void delay(uint ms){uint i, j;for(i=ms;i>0;i--)for(j=110;j>0;j--);}uchar getKey(){if(K1==0) {delay(5);if(K1==0)return 1;while(!K1);}if(K2==0) {delay(5);if(K2==0)return 2;while(!K2);}if(K3==0) {delay(5);if(K3==0)return 3;while(!K3);}return 0;}void display(uchar num) {P0 = num;delay(1);P0 = 0x00;}void init(){TMOD=0x01;TH0=0xFC;TL0=0x67;EA=1;ET0=1;TR0=1;}void main(){init();while(1) {uchar key = getKey();if(key == 1) {year++;if(year == 100)year = 0;}else if(key == 2) {month++;if(month == 13)month = 1;}else if(key == 3) {day++;if(day > year_tab[month-1]) { day = 1;}}display(year / 10);display(year % 10);display(month / 10);display(month % 10);display(day / 10);display(day % 10);display(week);}}void timer0() interrupt 1{TH0=0xFC;TL0=0x67;week++;if(week == 7)week = 0;}```该代码的主要思路是通过外部三个按键模拟年、月和日的调节,通过一个定时器不断更新星期的计数,然后将年、月、日和星期分别在数码管上显示出来。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

万年历时钟芯片代码/******************************************************************** * 文件名: 时钟DS1302LCD.c* 描述: 该程序实现了用单片机来控制时钟芯片DS1302进行时钟的显示。

时钟会在1602上显示.* 创建人:东流,2012年2月7日* 版本号:1.0* 杜邦线接法:P3.5接J18的1端;J3.6接J18的2端;J3.7接J18的3端。

1602接到J17的排座上。

********************************************************************* **/#include&lt;reg52.h&gt;#include&lt;intrins.h&gt;#define uchar unsigned char#define uint unsigned intsbit ACC0 = ACC^0;sbit ACC7 = ACC^7;sbit T_CLK = P3^5; /*实时时钟时钟线引脚*/sbit T_IO = P3^6; /*实时时钟数据线引脚*/sbit T_RST = P3^7; /*实时时钟复位线引脚*///这三个引脚参考资料sbit E=P2^7;//1602使能引脚sbit RW=P2^6;//1602读写引脚sbit RS=P2^5;//1602数据/命令选择引脚/******************************************************************** * 名称: delay()* 功能: 延时,延时时间大概为5US。

* 输入: 无* 输出: 无********************************************************************* **/void delay(){_nop_();_nop_();_nop_();_nop_();}void Delay(uint i){uint x,j;for(j=0;j&lt;i;j++)for(x=0;x&lt;=148;x++);}/******************************************************************** * 名称: bit Busy(void)* 功能: 这个是一个读状态函数,读出函数是否处在忙状态* 输入: 输入的命令值* 输出: 无********************************************************************* **/bit Busy(void){bit busy_flag = 0;RS = 0;RW = 1;E = 1;delay();busy_flag = (bit)(P0 &amp; 0x80);E = 0;return busy_flag;}/******************************************************************** * 名称: wcmd(uchar del)* 功能: 1602命令函数* 输入: 输入的命令值* 输出: 无********************************************************************* **/void wcmd(uchar del){while(Busy());RS = 0;RW = 0;E = 0;delay();delay();E = 1;delay();E = 0;}/******************************************************************** * 名称: wdata(uchar del)* 功能: 1602写数据函数* 输入: 需要写入1602的数据* 输出: 无********************************************************************* **/void wdata(uchar del){while(Busy());RS = 1;RW = 0;E = 0;delay();P0 = del;delay();E = 1;delay();E = 0;}/******************************************************************** * 名称: L1602_init()* 功能: 1602初始化,请参考1602的资料* 输入: 无* 输出: 无********************************************************************* **/void L1602_init(void){wcmd(0x38);Delay(5);wcmd(0x38);Delay(5);wcmd(0x38);Delay(5);wcmd(0x38);wcmd(0x08);wcmd(0x0c);wcmd(0x04);wcmd(0x01);}/******************************************************************** * 名称: L1602_char(uchar hang,uchar lie,char sign)* 功能: 改变液晶中某位的值,如果要让第一行,第五个字符显示&quot;b&quot; ,调用该函数如下L1602_char(1,5,&#39;b&#39;)* 输入: 行,列,需要输入1602的数据* 输出: 无********************************************************************* **/void L1602_char(uchar hang,uchar lie,char sign){uchar a;if(hang == 1) a = 0x80;if(hang == 2) a = 0xc0;a = a + lie - 1;wcmd(a);wdata(sign);}/******************************************************************** * 名称: L1602_string(uchar hang,uchar lie,uchar *p)* 功能: 改变液晶中某位的值,如果要让第一行,第五个字符开始显示&quot;ab cd ef&quot; ,调用该函数如下L1602_string(1,5,&quot;ab cd ef;&quot;)* 输入: 行,列,需要输入1602的数据* 输出: 无********************************************************************* **/void L1602_string(uchar hang,uchar lie,uchar *p){uchar a,b=0;if(hang == 1) a = 0x80;if(hang == 2) a = 0xc0;a = a + lie - 1;while(1){wcmd(a++);if((*p == &#39;\0&#39;)||(b==16)) break;b++;wdata(*p);p++;}}/******************************************************************** * 名称: v_RTInputByte()* 功能: 往DS1302写入1Byte数据* 输入: ucDa 写入的数据* 输出: 无********************************************************************* **/void v_RTInputByte(uchar ucDa){uchar i;ACC = ucDa;T_RST = 1;for(i=8; i&gt;0; i--){T_IO = ACC0;T_CLK = 1;T_CLK = 0;ACC = ACC &gt;&gt; 1;}}/******************************************************************** * 名称: uc_RTOutputByte()* 功能: 从DS1302读取1Byte数据* 输入:无* 返回值: ACC********************************************************************* **/uchar uc_RTOutputByte(void){uchar i;T_RST = 1;for(i=8; i&gt;0; i--){ACC = ACC &gt;&gt;1;T_IO=1;ACC7 = T_IO;T_CLK = 1;T_CLK = 0;}return(ACC);}/******************************************************************** * 名称: v_W1302(uchar ucAddr, uchar ucDa)* 功能: 往DS1302写入数据* 输入: ucAddr: DS1302地址, ucDa: 要写的数据* 返回值: 无********************************************************************* **/void v_W1302(uchar ucAddr, uchar ucDa){T_RST = 0;T_CLK = 0;T_RST = 1;v_RTInputByte(ucAddr); // 写地址_nop_();_nop_();v_RTInputByte(ucDa); // 写1Byte数据T_CLK = 1;T_RST = 0;}/******************************************************************** * 名称: uc_R1302(uchar ucAddr)* 功能: 读取DS1302某地址的数据* 输入: ucAddr: DS1302地址* 返回值: ucDa :读取的数据********************************************************************* **/uchar uc_R1302(uchar ucAddr){uchar ucDa;T_RST = 0;T_CLK = 0;T_RST = 1;v_RTInputByte(ucAddr); //写地址,命令_nop_();_nop_();ucDa = uc_RTOutputByte(); //读1Byte数据T_CLK = 1;T_RST = 0;return(ucDa);}/******************************************************************** * 名称: v_BurstW1302T* 功能: 往DS1302写入时钟数据(多字节方式)* 输入: pSecDa: 时钟数据地址格式为: 秒分时日月星期年控制* 8Byte (BCD码) 1B 1B 1B 1B 1B 1B 1B 1B* 返回值: 无********************************************************************* **/void v_BurstW1302T(uchar *pSecDa){uchar i;v_W1302(0x8e, 0x00); //控制命令,WP=0,写操作T_RST = 0;T_CLK = 0;T_RST = 1;v_RTInputByte(0xbe); //0xbe:时钟多字节写命令for(i=8; i&gt;0; i--) //8Byte = 7Byte 时钟数据+ 1Byte 控制{v_RTInputByte(*pSecDa); //写1Byte数据pSecDa++;}T_CLK = 1;T_RST = 0;}/******************************************************************** * 名称: v_BurstR1302T(uchar *pSecDa)* 功能: 读取DS1302时钟数据* 输入: pSecDa: 时钟数据地址格式为: 秒分时日月星期年* 7Byte (BCD码) 1B 1B 1B 1B 1B 1B 1B* 返回值: ucDa :读取的数据***********************************************************************/void v_BurstR1302T(uchar *pSecDa){uchar i;T_RST = 0;T_CLK = 0;T_RST = 1;v_RTInputByte(0xbf); //0xbf:时钟多字节读命令for(i=8; i&gt;0; i--){*pSecDa = uc_RTOutputByte(); //读1Byte数据pSecDa++;}T_CLK = 1;T_RST = 0;}/******************************************************************** * 名称: v_BurstW1302R(uchar *pReDa)* 功能: 往DS1302寄存器数写入数据(多字节方式)* 输入: pReDa: 寄存器数据地址* 返回值: 无********************************************************************* **/void v_BurstW1302R(uchar *pReDa){uchar i;v_W1302(0x8e,0x00); //控制命令,WP=0,写操作T_RST = 0;T_CLK = 0;T_RST = 1;v_RTInputByte(0xfe); //0xbe:时钟多字节写命令for(i=31; i&gt;0; i--) //31Byte 寄存器数据{v_RTInputByte(*pReDa); //写1Byte数据pReDa++;}T_CLK = 1;T_RST = 0;}/******************************************************************** * 名称: v_BurstR1302R(uchar *pReDa)* 功能: 读取DS1302寄存器数据* 输入: pReDa: 寄存器数据地址* 返回值: 无********************************************************************* **/void v_BurstR1302R(uchar *pReDa){uchar i;T_RST = 0;T_CLK = 0;T_RST = 1;v_RTInputByte(0xff); //0xbf:时钟多字节读命令for(i=31; i&gt;0; i--) //31Byte 寄存器数据{*pReDa = uc_RTOutputByte(); //读1Byte数据pReDa++;}T_CLK = 1;T_RST = 0;}/********************************************************************* 名称: v_Set1302(uchar *pSecDa)* 功能: 设置初始时间* 输入: pSecDa: 初始时间地址。

相关文档
最新文档