万年历时钟芯片代码

合集下载

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

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

数字钟、万年历制作(基于单片机)电路原理图:程序://********************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语言)

#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万年历 时钟显示

//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();}}}。

  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: 初始时间地址。

相关文档
最新文档