51单片机可调的ds1302时钟程序
51单片机+ds1302+DS18b20温度时钟(电路图+C语言程序)

时钟电路图:*■11PCB板:酱时井務ft是用诵m-pdfMerisi 口叵因Fjr 齐舱 C :s ® 工细理沖缶皿ndm - * TfS ' 4' 包田U i > 'ir ft ZS:MZ fH钟些fl是用说町-Pdf Wirrcf闻礒雜sbit dis_ bitlsbit dis_ bit2sbit dis_ bit3sbit dis_ bit4sbit dis_ bit5sbit dis_ bit6sbit ledl _bitsbit led2 ! bit=P2A7; II定义数码管控制口=P2A6; II定义数码管控制口=卩2八4; II定义数码管控制口=卩2八3; II定义数码管控制口=P2A1; II定义数码管控制口=P2A0; II定义数码管控制口=P2A2; II定时LED勺控制口=P2A5; II定时LED勺控制口单片机程序:/*===================================================================调试要求:1. MCU:AT89S52 芯片或AT89C522. 晶振:12MHz功能:多功能时钟+温度计/#inelude <reg52. h>#inelude vintrins . h>訂开始 LJ-雲匕®务如1痒3月计ttVl. •呈T』d"吐拠席射■ w耳pg文宇■[豹…SS时軽件思冃说#define uehar #define uint unsigned char unsigned intsbit s1_bit =P1A 0; // 定义S1 控制口 sbit s2_bit =P01; // 定义 S2控制口 sbit s3_bit =P02; // 定义 S3控制口 sbit dq_ds18b20 =P3A3;// 定义控制 DS18B20 sbit speak =P3A7; //定义蜂鸣器控制口sbit clk_ds1302 =P3A6; // 定义控制 DS1302勺时钟线 sbit io_ds1302 =P3A5;//定义控制DS1302勺串行数据 sbit rest_ds1302 =P3A4;#define smg_data P0 //定义数码管数据口void delay_3us(); //3US 的延时程序 void delay_8us(ui nt t);//8US 延时基准程序void delay_50us(ui nt t); //void display1(uchar dis_data); void display2(uchar dis_data); void display3(uchar dis_data); void display4(uchar dis_data); void display5(uchar dis_data); void display6(uchar dis_data);void init_t0(); //定时器0初始化函数 void dis_led(); //LED 处理函数 void judge_s1(); //S1 按键处理函数void judge_s2(); //S2 按键处理函数 void judge_s3(); //S3 按键处理函数void dis(uchar s6,uchar s5,uchar s4,uchar s3,uchar s2,uchar s1); 示子程序 void dis_sa n( uchar s6,uchar s5,uchar s4,uchar s3,uchar s1,uchar san); 〃闪烁显示子程序 void judge_dis(); //显示处理函数 void judge_clock(); // 显示处理函数 void set_ds1302(); // 设置时间void get_ds1302();// 读取当前时间void w_1byte_ds1302(uchar t); // 向 DS130写一个字节的数据 uchar r_1byte_ds1302(); // 从DS130读一个字节的数据//DS18B20测温函数定义延时50*T 微妙函数的声明//数码管1显示子程序 //数码管2显示子程序 //数码管3显示子程序 //数码管4显示子程序 //数码管5显示子程序 //数码管6显示子程序//显 s2,ucharvoid w_1byte_ds18b20(uchar value); // 向DS18B2写一个字节ucharr_1byte_ds18b20( void ); // 从DS18B2读取一个字节的数据voidrest_ds18b20( void ); //DS18B20复位程序void readtemp_ds18b20( void ); // 读取温度void dis_temp(); //温度显示函数//共阳数码管断码表const uchar tabl1[16] ={ 0xc0,0xf9,0xa4,0xb0,0x99,0x92,// 0 1 2 3 4 50x82,0xf8,0x80,0x90,0x86,0x87,0xFF,//6 7 8 9 E T B0xc6,0xbf,0xff };// C -const uchar tabl3[] ={ 0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09 };uchar t0_crycle;uchar hour_co un t, minu te_c oun t,sec on d_co un t,msec ond_count;uchar clock_hour,clock_m inu te;uchar coun tdow n_sec ond;uchar coun tdow n_hour,co un tdow n_min ute;uchar clock_en; //闹钟关闭和开启的标志,1开启,0关闭uchar flag1,sec on d_flag,za ncun 1,za ncun 2,za ncun3;uchar zancun4 ,za ncun 5,za ncun 6,za ncun7;uchar clock_flag,co un tdow n_flag;uchar msec on d_mi nute,msec on d_sec on d,mseco nd_mseco nd,mseco nd_flag; // 秒表相关参数uint speak_c ount;uchar templ,temph,temp_flag;uchar t_b,t_s,t_g,t_x,temp_flag2; //从左到右分别存储温度百位,十位,个位,小数位uchar tab23[3]; 〃二{0x40,0x59,0x23,0x28,0x11,0x06,0x09};// 上电时默认的时间//主程序void main(){P3 =0x00;flag1 =0;zancun3 =0;msecond_minute =0; //置秒表相关参数为0msecond_second =0;msec on d_msec ond =0;speak =1;//关闭蜂鸣器speak_co unt =0;clock_hour =0;clock_m inute =0;clock_flag =0;countdown_flag =0; //倒计时标志位为0clock_en =0;//开机时默认关闭闹钟ini t_t0();TRO =1;//// set_ds1302();〃设置DS1302勺初始时间//接下来开始编写让数码管显示的程序while (1){get_ds1302();judge_dis(); // 显示处理judge_s1();judge_s2();judge_s3();judge_clock(); //闹钟处理程序} _}void timerO() interrupt 1{TH0=(65536-50000)/256;TL0=(65536 - 50000)%256; t0_crycle ++;if (t0_crycle ==2) // 0.1 秒{t0_crycle =0;msec on d_flag =1;msec ond_count ++;if (msecond_count==10)//1 秒{ _msec on d_co unt =0;sec on d_flag =1;}}}//**************************************************//显示处理函数void judge_dis(){if (flag1 ==0){if (second_flag ==1){ _zancun7 ++;sec on d_flag =0;} _if (zancun7 <1){if (temp_flag2 ==1){ 一readtemp_ds18b20(); // 读取温度temp_flag2 =0;厂dis_temp(); //温度显示函数}if (zancun7 >=1){temp_flag2 =1;zancun4 =hour_count &0xf0;zancun4 >>=4;zancun5 =minute_count&0xf0;zancun5 >>=4;zancun6 =sec on d_co unt&0xf0;zancun6 >>=4;dis(za ncun4 ,hour_co unt &0x0f,za ncun5,minu te_co unt &0x0f,za ncun 6,sec ond_ cou nt &0x0f);dis_led();if (zancun7 ==5)zancun7 =0;}}if (flag1 !=0){switch (flag1){case 1:dis(5,10,11,1,12,12); // 显示SET1led1_bit =1;led2_bit =1;break;case 2:dis(5,10,11,2,12,12); // 显示SET2break;case 3:dis(5,10,11,3,12,12); // 显示SET3break;case 4:dis(5,10,11,4,12,12); // 显示SET4break;case 5:dis(5,10,11,5,12,12); // 显示SET5break;case 6:dis_san(zancun1 / 10,zancunl %10,zancun2/ 10,zancun2 %0,12,12,1); break;case 7:dis_san(zancun1 / 10,zancunl %10,zancun2/ 10,zancun2 %0,12,12,2); break;case 8:dis_san(zancun1 / 10,zancunl %10,zancun2/ 10,zancun2 %0,12,12,3); break;case 9: //进入修改时间,时间分位个位闪烁dis_san(zancun1 / 10,zancunl %10,zancun2/ 10,zancun2 %0,12,12,4); break;case 10: //进入修改闹钟,闹钟小时十位闪烁dis_san(zancunl / 10,zancunl %10,zancun2/ 10,zancun2 %0,12,zancun3,1); break;case 11://进入修改闹钟,闹钟小时个位闪烁dis_san(zancun1 / 10,zancunl %10,zancun2/ 10,zancun2%0,12,zancun3,2); break;case 12: //进入修改闹钟,闹钟小时十位闪烁dis_sa n(zan cu n1 / 10,za ncun1 %10,za ncun 2/ 10,za ncu n2%0,12,za ncun 3,3);break;case 13: //进入修改闹钟,闹钟小时个位闪烁dis_sa n(zan cu n1 / 10,za ncun1 %10,za ncun 2/ 10,za ncu n2%0,12,za ncun 3,4);break;case 14: //进入修改闹钟的开关dis_sa n(zan cu n1 / 10,za ncun1 %10,za ncun 2/ 10,za ncu n2%0,12,za ncun 3,6);break;case 15:dis_sa n(zancun1 / 10,za ncun1 %10,za ncun 2/ 10,za ncun 2%0,za ncun3/ 10,za ncun 3%10,1);break;case 16:dis_san(zancun1 / 10,zancunl %10,zancun2/10,zancun2%0,zancun3/ 10,zancun3%10,2);break;case 17:dis_san(zancun1 / 10,zancunl %10,zancun2/ 10,zancun2%0,zancun3/ 10,zancun 3%10,3);break;case 18:dis_sa n(zancun1 / 10,za ncun1 %10,za ncun 2/ 10,za ncun 2%0,za ncun3/ 10,za ncun 3%10,4);break;case 19:dis_sa n(zancun1 / 10,za ncun1 %10,za ncun 2/ 10,za ncun 2%0,za ncun3/ 10,za ncun 3%10,5);break;case 20:dis_sa n(zancun1 / 10,za ncun1 %10,za ncun 2/ 10,za ncun 2%0,za ncun3/ 10,za ncun 3%10,6);break;case 21:if (second_flag ==1){ _sec on d_flag =0;countdown_second --;if (countdown_second ==255){ _coun tdow n_sec ond =59;countdown_minute --;if (countdown_minute ==255){ _coun tdow n_min ute =59;countdown_hour --;if (countdown_hour ==255){flag1 =22;coun tdow n_min ute =0;coun tdow n_hour =0;coun tdow n_sec ond =0;coun tdow n_flag=1;_ } } } }dis(countdown_hour / 10,countdown_hour %10,countdown_minute / 10,countdown _minute%10,countdown_second/ 10,countdown_second%10); //break; case 22:{ speak =1;}dis(countdown_hour / 10,countdown_hour %10,countdown_minute / 10,countdown _minute%10,countdown_second/ 10,countdown_second%10); //break; case 23: dis(msecond_minute / 10,msecond_minute%10,msecond_second/ 10,msecond_sec on d%10,mseco nd_msec on d%0,12);break; case 24:if (msecond_flag ==1) { _msec on d_flag =0; msec on d_msec ond ++;if (msecond_msecon (==10){msec on d_msec ond =0; msec on d_sec ond ++;if (msecond_second==60) { _msecond_second =0; msec ond_minute ++;if (countdown_flag { _speak=0;if (second_flag { _sec on d_flag coun tdow n_flag} _ } else>0 &&countdown_flag <7)==1) =0; ++;if (msecond_minute==1OO) { _msec ond_minute =99;flagl =23;}}}}dis(msecond_minute / 10,msecond_minute%10,msecond_second/ 10,msecond_sec on d%10,mseco nd_msec on d%0,12);break;case 25:dis(zancun3 / 10,zancun3 %0,zancun2 / 10,zancun2 %10,zancun1 /10,zancun1 %0 );break;default :break;}}}//**************************************************〃S1按键处理函数void judge_s1(){ _s1_bit =1;//置IO为1,准备读入收据if (s1_bit ==0)//判断是否有按键按下{delay_50us(1); //延时,去除机械抖动if (s1_bit ==0){switch (flag1){case 0:case 1:case 2:case 3:case 4:case 6:case 7:case 8:case 10:case 11:case 12:case 13:case 15:case 16:case 17:case 18:case 19: flag1++;break;case 9: flag1=6;break;case 14: flag1=10;break;case 20: flag1=15;break;case 5:case 21:case 22:case 23: //系统从秒表状态复位case 24: //系统从秒表状态复位case 25: //系统从计数器复位flag1 =0;break;default :break;}while (s1_bit ==0){ _judge_dis();}〃等待按键释放}}}〃************************************************** 〃S2按键处理函数void judge_s2(){ _s2_bit =1; //置IO为1,准备读入收据if (s2_bit ==0)//判断是否有按键按下=0;{delay_50us(1); //延时,去除机械抖动 if (s2_bit ==0) { switch (flagl) { flag1 =6; zancun4 =hour_count &0xf0;zancun4 >>=4; zancun6 =hour_count &0x0f;zancun1=zancun4*10+zancun6; //zancun 1=hour_co unt; zancun5 =minute_count &0xf0; zancun5 >>=4; zancun6 =minute_count &0x0f; zancun2 =za ncun5* 10+za ncun6; case 1: //在显示SET 状态下按S2牛,进入修改时间 // zancun2=minu te_co unt; break; case 2: //在显示SET2犬态下按S2,进入设置闹钟 zancunl =clock_hour; zancun2 =clock_m inu te; flagl =10; break; case 6: //修改时钟小时十位状态下按 case 7: //修改时钟小时个位状态下按 case 8: //修改时钟分钟十位状态下按 case 9: //修改时钟分钟个位状态下按 〃zancun4=za ncun 1/10; 测S:SM tab23[2] =zancun1/10* 16+za ncu n1%10; tab23[1] hour_c ount minu te_c ount sec ond_co unt tab23[0]set_ds1302(); flag1//zancun 5=za ncun2&0 xf0; //zancun 5>>=4; =zancun2/10* 16+za ncu n2%10; =tab23[2]; =tab23[1]; =0; //设置DS130的初始时间 =0;break; case 10: //修改闹钟小时十位状态下按S2case 11: //修改闹钟小时个位状态下按S2case 12: //修改闹钟分钟十位状态下按S2 case 13: //修改闹钟分钟个位状态下按S2 case 14: //修改闹钟使能状态下按S2clock_hour clock_m inute clock_e n flag1=zancun1; =zancun2; =zancun3;=0;break;case 3:flagl =15;zancunl =co un tdow n_hour;zancun2 =co un tdow n_minu te;zancun3 =co un tdow n_sec ond;break;case 15:case 16:case 17:case 18:case 19:case 20:coun tdow n_hour =zancun1;coun tdow n_minute =za ncun2;coun tdow n_sec ond =za ncun3;flag1 =21;coun tdow n_flag =0;break;case 22:flag1 =21;break;case 21:flag1 =22;break;case 4:flag1 =23; //秒表暂停msec ond_minute =0;msecond_second =0;msec on d_msec ond =0;break;case 23:flag1 =24;break;case 24:flag1 =23;break;case 5:flagl =25;//进入计数器模式zancunl =0;zancun2 =0;zancun3 =0;break; default :break;}while (s2_bit ==0){ _judge_dis();}//等待按键释放}}}//**************************************************//S3按键处理函数void judge_s3(){ _s3_bit =1;//置IO为1,准备读入收据if (s3_bit ==0)//判断是否有按键按下{delay_50us(1); //延时,去除机械抖动if (s3_bit ==0){ _switch (flag1){case 6: //修改时间小时的十位数zancun1 +=10;if (zancun1 >=24)zancun1 =zancun 1%10;break;case 7: //修改时间小时的个位数za ncun1 =za ncu n1/10* 10+(za ncun1 %10+1) %10;if (zancun1 >=24)zancun1 =20;break;case 8: //修改时间分钟的十位数zancun2 +=10;if (zancun2 >=60)zancun2-=60;break;case 9: //修改时间分钟的个位数za ncun2 =za ncun2/10* 10+(za ncun2 %10+1) %10;break;case 10: //修改闹钟小时的十位数zancunl +=10;if (zancunl >=24)zancunl =zancun 1%10; break;case 11: //修改闹钟小时的个位数zancunl =za ncu n1/10* 10+(za ncun1 %10+1) %10;if (zancun1 >=24)zancun1 =20;break;case 12: //修改闹钟分钟的十位数zancun2 +=10;if (zancun2 >=60)zancun2-=60; break;case 13: //修改闹钟分钟的个位数zan cu n2 =za ncun2/10* 10+(za ncun2 %10+1) %10;break;case 14:zancun3 A=1;break;case 15: //修改倒计时小时的十位数zancun1 +=10;if (zancun1 >=100)zancun 1 -=100; break;case 16: //修改倒计时小时的个位数zancun1 =za ncu n1/10* 10+(za ncun1 %10+1) %10;break;case 17: //修改倒计时分钟的十位数zancun2 +=10;if (zancun2 >=60)zancun2-=60; break;case 18: //修改倒计时分钟的个位数zan cu n2 =za ncun2/10* 10+(za ncun2 %10+1) %10;break;case 19: //修改倒计时秒的十位数zancun3 +=10;if (zancun3 >=60)zancun3-=60; break;case 20: //修改倒计时秒的个位数zan cu n3 =za ncun3/10* 10+(za ncun3 %10+1) %10;break;case 21:case 22: //coun tdow n_hour =zancun1;coun tdow n_minute =za ncun2;coun tdow n_sec ond =za ncun3;flagl =21;break;case 23:case 24: //秒表复位flag1 =24;msec ond_minute =0;msecond_second =0;msec on d_msec ond =0;break;case 25:zancun1 ++;if (zancun1 ==100){zancun1 =0;zancun2 ++;if (zancun2 ==100){zancun2 =0;zancun3 ++;}}break;default : break;}while (s3_bit ==0){ _judge_dis();}〃等待按键释放}}} //显示处理函数void judge_clock() {zancun4 =hour_count &0xf0;zancun4 >>=4;zancun6 =hour_count &0x0f;zancun4 *=10;zancun4 +=za ncun6;zancun5=minute_count &0xf0;if (san ==1){zancun5 >>=4;zancun6 =minute_count &0x0f;zancun5 *=10;zancun5 +=za ncun6;if (msecond_count<=5) {speak =0; speak_co unt ++;}else{speak =1;}}else{speak =1;}}〃****************************************////闪烁显示子程序void dis_sa n( uchar s6,uchar s5,uchar s4,uchar s3,uchars1,uchar san){if (clock_hour ==zancun4 &&clock_minute ==zancun5){ 一 一if (clock_en { _ speak_co unt clock_flag speak_co unt} _ } else{clock_flag =0;} _if{ (clock_flag ==1 ==1&&clock_flag ==0)=0; //开启蜂鸣器=1;=0;&&speak_count <400)s2,ucharif (msecond_count<5) { _ display1(s6);}}else{display1(s6);}if (san ==2){if (msecond_count<5) { _ display2(s5);}}else{display2(s5);}if (san ==3){if (msecond_count<5) { _ display3(s4);}}else{display3(s4);}if (san ==4){if (msecond_count<5) { _ display4(s3);}}else{display4(s3);}if (san ==5){if (msecond_count<5){ _ display5(s2);}}else{display5(s2);}if (san ==6){if (msecond_count<5){ _ display6(s1);}}else{ display6(s1);}}〃****************************************//时钟显示程序void dis(uchar s6,uchar s5,uchar s4,uchar s3,uchar s2,uchar s1) { display1(s6);display2(s5);display3(s4);display4(s3);display5(s2);display6(s1);}〃********************************************************************************************void init_tO(){ _TMOD0x01;〃设定定时器工作方式1,定时器定时50毫秒TH0=(65536-50000)/256;TL0=(65536- 50000)%256;EA=1; //开总中断ET0=1; //允许定时器0中断t0_crycle =0; //定时器中断次数计数单元}//LED处理函数void dis_led(){if (msecond_count<5){ _Ied1_bit =1;Ied2_bit =1;}else{led1_bit =0;led2_bit =0;}}〃***************************************************************//功能:把数据1显示在数码管1上void display6(uchar dis_data){ _smg_data =tabl1[dis_data]; // 送显示断码dis_bit6 =0; // 锁存数据delay_50us(40); dis_bit6 =1;}〃***************************************************************//功能:把数据1显示在数码管1上void display5(uchar dis_data){ _smg_data =tabl1[dis_data]; // 送显示断码dis_bit5 =0; // 锁存数据delay_50us(40);dis_bit5 =1;} _〃***************************************************************//功能:把数据1显示在数码管1上void display4(uchar dis_data){ _smg_data =tabl1[dis_data]; // 送显示断码dis_bit4 =0; // 锁存数据delay_50us(40);dis_bit4 =1;} 〃***************************************************************//功能:把数据1显示在数码管1上void display3(uchar dis_data){ _smg_data =tabl1[dis_data]; // 送显示断码dis_bit3 =0; // 锁存数据delay_50us(40);dis_bit3 =1;}〃***************************************************************//功能:把数据1显示在数码管1上void display1(uchar dis_data){ _smg_data =tabl1[dis_data]; // 送显示断码dis_bit1 =0; // 锁存数据delay_50us(40);dis_bit1 =1;}〃***************************************************************//功能:把数据1显示在数码管1上void display2(uchar dis_data){ _smg_data =tabl1[dis_data]; // 送显示断码dis_bit2 =0; // 锁存数据delay_50us(40);dis_bit2 =1;}〃******************************************************************* *******************************// 函数名称:void delay_50US(unsigned int t)//功能:延时50*t(us)void delay_50us(uint t){ _unsigned char j;for (;t >0;t --){for (j =19;j >0;j --);}}〃******************************************************************* ************〃8微秒延时基准程序void delay_8us(uint t){while (-- t);}************〃3微秒延时程序void delay_3us() {}〃******************************************************************* ************//子程序功能:向DS18B2写一字节的数据void w_1byte_ds18b20(uchar value){uchar i =0;for (i =0;i <8;i ++){dq_ds18b20 =1;delay_3us();dq_ds18b20 =0; delay_8us(2);if ( value & 0x01) dq_ds18b20 =1; 〃DQ = 1 delay_50us(1); // 延时50us 以上delay_8us(2);value >>=1;}dq_ds18b20 =1; //DQ = 1}//读一个字节uchar r_1byte_ds18b20( void){ 一一uchar i =0;uchar value = 0;for (i =0;i <8;i ++){value >>=1;dq_ds18b20 =0;// DQ_L;delay_3us();dq_ds18b20 =1; 〃DQ_H;delay_8us(2);if (dq_ds18b20==1) value |= 0x80;delay_8us(6); // 延时40us}dq_ds18b20 =1;return value ;}11 ・**************************************************〃ds18b20复位子程序void rest_ds18b20( void){rest:delay_3us(); // 稍做延时delay_3us();dq_ds18b20 =1;delay_3us();dq_ds18b20 =0;// DQ_L; delay_50us(11); 〃480us<T<960usdq_ds18b20 =1; // 拉高总线delay_8us(5);if (dq_ds18b20==1){return ;}delay_50us(2); // 延时90usif (dq_ds18b20==1){return ;}else{goto rest;}}〃****************************************************//读取温度void readtemp_ds18b20( void){ _uchar temp32;rest_ds18b20();w_1byte_ds18b20(0xcc); //跳过读序列号的操作w_1byte_ds18b20(0x44); // 启动温度转换delay_8us(2);rest_ds18b20();w_1byte_ds18b20(0xcc); //跳过读序列号的操作w_1byte_ds18b20(0xbe); //读取温度寄存器等(共可读9个寄存器)前两个就是温度templ =r_1byte_ds18b20();temph =r_1byte_ds18b20();if ((temph &0xf0)) //判断温度的正负性{temp_flag =0; //温度为负数标志temph =-temph;tempi =-templ;t_x =tabl3[templ & OxOf]; // 计算温度的小数temp32 =temph & OxOf;temp32 <<=4;tempi >>=4;temp32 =temp32 | tempi;t_b =temp32/100%10; //计算温度的百位数据t_s =temp32/10%0;〃计算温度的十位数据t_g =temp32%0;〃计算温度的个位数据5else //为正数{t_x =tabl3[templ & 0x0f]; // 计算温度的小数temp32 =temph & 0x0f;temp32 <<=4;templ >>=4;temp32 =temp32 | templ;t_b =temp32/100%10; //计算温度的百位数据t_s =temp32/10%0;〃计算温度的十位数据t_g =temp32%0;〃计算温度的个位数据temp_flag =1;} _}void dis_temp() //温度显示函数{ _if (temp_flag =1){ _if (t_b ==0){dis(12,12,t_s,t_g,13,12);}else{dis(12,t_b,t_s,t_g,13,12);}}else{dis(14,t_b,t_s,t_g,13,12);}}/ / """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" / / , ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ############ //;子程序名:w_1byte_ds1302//;功能:向DS130写一个字节的数据void w_1byte_ds1302(uchar t){uchar i;for (i =0;i <8;i ++){if (t & 0x01){io_ds1302=1;}else{io_ds1302 =0;}clk_ds1302 =1;delay_3us();delay_3us();clk_ds1302 =0;delay_3us();delay_3us();t >>=1;}}/ / , ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ######//;子程序名:r_1byte_ds1302()//;功能:从DS130读一个字节的数据uchar r_1byte_ds1302(){ 一一uchar i,temp11 =0;io_ds1302 =1;//置10为1,准备读入数据for (i =0;i <8;i ++){temp11 >>=1;if (io_ds1302) temp11 |= 0x80;clk_ds1302 =1;delay_3us();delay_3us();clk_ds1302 =0;delay_3us();}return (temp11);}/ / """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""/ / , JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ """""""""""""""ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff//;子程序名:setbds1302//;功能:设置DS130初始时间,并启动计时void set_ds1302(){uchar i,j;rest_ds1302 =0;delay_3us();clk_ds1302 =0;delay_3us();rest_ds1302 =1;delay_3us();w_1byte_ds1302(0x8e); // 写控制命令字delay_3us();w_1byte_ds1302(0x00); // 写保护关闭clk_ds1302 =1;delay_3us();for (i =0,j =0x80;i <7;i ++,j +=2){rest_ds1302 =0;delay_3us();clk_ds1302 =0;delay_3us();rest_ds1302 =1;delay_3us();w_1byte_ds1302(j);delay_3us();w_1byte_ds1302(tab23[i]);delay_3us();delay_3us();clk_ds1302 =1;delay_3us();rest_ds1302 =0;delay_3us();delay_3us();} _rest_ds1302 =0;delay_3us();clk_ds1302 =0;delay_3us();rest_ds1302 =1;delay_3us();w_1byte_ds1302(0x8e); delay_3us();w_1byte_ds1302(0x80); clk_ds1302 =1;delay_3us();rest_ds1302 =0;delay_3us();}/ / """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" / / , ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff //;子程序名:get1302void get_ds1302(){ _uchar temp11[7],i,j;for (i =0;i <7;i ++){temp11[i] =0;}for (i =0,j =0x81;i <7;i ++,j +=2){rest_ds1302 =0;delay_3us();clk_ds1302 =0;delay_3us();delay_3us();w_1byte_ds1302(j);temp11[i] =r_1byte_ds1302();delay_3us();clk_ds1302 =1;delay_3us();rest_ds1302 =0;delay_3us();} _if (temp11[0] != 0xff){second_count =temp11[0]; }if (temp11[1] != 0xff) // 数据验证{minute_count =temp11[1]; }if (temp11[2] != 0xff) // 数据验证{hour_count =temp11[2]; }// date=temp[3];//mon th=temp[4];// week=temp[5];//year=temp[6];}/*===================================================================调试要求:1. MCU:AT89S52 芯片或AT89C522. 晶振:12MHz功能:多功能时钟+温度计/#inelude <reg52. h>#inelude vintrins . h>sbit dis_bit1 =P2A 7; //定义数码管控制口sbit dis_bit2 =卩2八6;//定义数码管控制口sbit dis_bit3 =卩2八4;//定义数码管控制口sbit dis_bit4 =卩2八3;//定义数码管控制口sbit dis_bit5 =卩2八1; //定义数码管控制口sbit dis_bit6 =P2A0; //定义数码管控制口sbit led1_bit =卩2八2; // 定时 LED 勺控制口sbit led2_bit =卩2八5; // 定时 LED 勺控制口sbit s1_bit =P1A0; // 定义S1 控制口sbit s2_bit =P01; // 定义 S2空制口sbit s3_bit =P02; // 定义 S3控制口sbit dq_ds18b20 =P3A3;// 定义控制 DS18B20 sbit speak =P3A7; //定义蜂鸣器控制口sbit clk_ds1302 =P3A6; // 定义控制 DS1302勺时钟线 sbit io_ds1302 =P3A5;//定义控制DS1302勺串行数据sbit rest_ds1302 =P3A4;#define smg_data P0 //定义数码管数据口 void delay_3us(); //3US 的延时程序 void delay_8us(ui nt t); //8US 延时基准程序void delay_50us(ui nt t); // void display1(uehardis_data); voiddisplay2(uehar dis_data); void display3(uehar dis_data); void display4(uehar dis_data); void display5(uehar dis_data); void display6(uehar dis_data);void init_t0(); //定时器0初始化函数void dis_led(); //LED 处理函数void judge_s1();//S1 按键处理函数 void judge_s2(); //S2 按键处理函数void judge_s3(); //S3 按键处理函数 void dis(uehar s6,uehar s5,uehar s4,uehar s3,uehar s2,uehar s1); 示子程序 void dis_sa n( uchar s6,uehar s5,uehar s4,uehar s3,uehars1,uchar san); 〃闪烁显示子程序void judge_dis(); //显示处理函数void judge_clock(); // 显示处理函数void set_ds1302(); // 设置时间void get_ds1302(); // 读取当前时间#define uehar#define uintunsigned char unsigned int延时50*T 微妙函数的声明//数码管1显示子程序 //数码管2显示子程序 //数码管3显示子程序//数码管4显示子程序//数码管5显示子程序//数码管6显示子程序 //显s2,ueharvoid w_1byte_ds1302(uchar t); // 向DS130写一个字节的数据uchar r_1byte_ds1302(); // 从DS130读一个字节的数据〃*******************************************************************//DS18B20测温函数定义void w_1byte_ds18b20(uchar value); // 向DS18B2写一个字节ucharr_1byte_ds18b20( void ); // 从DS18B2读取一个字节的数据voidrest_ds18b20( void ); //DS18B20复位程序void readtemp_ds18b20( void ); // 读取温度void dis_temp(); //温度显示函数//共阳数码管断码表const uchar tabl1[16] ={ 0xc0,0xf9,0xa4,0xb0,0x99,0x92,// 0 1 2 3 4 50x82,0xf8,0x80,0x90,0x86,0x87,0xFF,//6 7 8 9 E T B0xc6,0xbf,0xff };// C -const uchar tabl3[] ={ 0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09 };uchar t0_crycle;uchar hour_co un t, minu te_c oun t,sec on d_co un t,msec ond_count;uchar clock_hour,clock_m inu te;uchar coun tdow n_sec ond;uchar coun tdow n_hour,co un tdow n_min ute;uchar clock_en; //闹钟关闭和开启的标志,1开启,0关闭uchar flag1,sec on d_flag,za ncun 1,za ncun 2,za ncun3;uchar zancun4 ,za ncun 5,za ncun 6,za ncun7;uchar clock_flag,co un tdow n_flag;uchar msec on d_mi nute,msec on d_sec on d,mseco nd_mseco nd,mseco nd_flag; // 秒表相关参数uint speak_c ount;uchar templ,temph,temp_flag;uchar t_b,t_s,t_g,t_x,temp_flag2; //从左到右分别存储温度百位,十位,个位,小数位上电时默认的uchar tab23[3]; 〃二{0x40,0x59,0x23,0x28,0x11,0x06,0x09};//时间//主程序void main(){P3 =0x00;flag1 =0;zancun3 =0;msecond_minute =0; //置秒表相关参数为0msecond_second =0;msec on d_msec ond =0;speak =1;//关闭蜂鸣器speak_co unt =0;clock_hour =0;clock_m inute =0;clock_flag =0;countdown_flag =0; //倒计时标志位为0clock_en =0;//开机时默认关闭闹钟ini t_t0();TR0 =1;//// set_ds1302();〃设置DS130的初始时间//接下来开始编写让数码管显示的程序while (1){get_ds1302();judge_dis(); // 显示处理judge_s1();judge_s2();judge_s3();judge_clock(); //闹钟处理程序} _}void timer0() interrupt 1{TH0=(65536-50000)/256;TL0=(65536- 50000)%256;t0_crycle ++;if (t0_crycle ==2) // 0.1 秒{t0_crycle =0;msec on d_flag =1;msec ond_count ++;if (msecond_count==10)//1 秒。
51单片机ds1302时钟

sbit runing1=runing^1;//菜单
sbit runing2=runing^2;
sbit runing3=runing^3;
sbit runing4=runing^4;
sbit runing5=runing^5;//help
sbit runing6=runing^6;//闹铃
18b20初始化
------------------------------------------------*/
bit Init_DS18B20(void)
{
bit dat=0;
DQ = 1; //DQ复位
DelayUs2x(5); //稍做延时
DQ = 0; //单片机将DQ拉低
DelayUs2x(200); //精确延时大于480us小于960us
b=ReadOneChar(); //高位
b<<=8;
t=a+b;
return(t);
}
/*------------------------------------------------
写入命令函数
------------------------------------------------*/
void WriteOneChar(uchar dat)
{
uchar i=0;
for (i=8; i>0; i--)
{
DQ = 0;
DQ = dat&0x01;
DelayUs2x(25);
DQ = 1;
dat>>=1;
}
DelayUs2x(25);
可用按键修改时间的DS1302时钟显示程序

write_data(table1[num]);
}
/**************************显示欢迎界面函数*************************************/
void displaystar(void)
delay(500);大约延时500ms
**************************************************************/
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void delay20ms(void) //3*i*j+2*i=3*100*60+2*100=20000μs=20ms;
{
uchar i;
write_com(0x80);
for(i=0;i<16;i++)
write_data(table2[i]);
write_com(0x80+0x40);
for(i=0;i<16;i++)
write_data(table3[i]);
}
/***************************显示时间、日期子函数*********************************/
if(s1num!=0&&s4num==0)//按键1按下*次且s4再次之前未曾按过(按键按下时,时间修改函数)
采用51单片机控制的DS1302时钟程序

采用51单片机控制的DS1302时钟程序/*********************************************************************/ /* 实时时钟模块时钟芯片型号:DS1302 *//*//*********************************************************************/ sbit T_CLK = P2^7; /*实时时钟时钟线引脚 */sbit T_IO = P1^4; /*实时时钟数据线引脚 */sbit T_RST = P1^5; /*实时时钟复位线引脚 *//******************************************************************** ** 名称: v_RTInputByte* 说明:* 功能: 往DS1302写入1Byte数据* 调用:* 输入: ucDa 写入的数据* 返回值: 无***********************************************************************/ void v_RTInputByte(uchar ucDa){uchar i;ACC = ucDa;for(i=8; i>0; i--){T_IO = ACC0; /*相当于汇编中的 RRC */T_CLK = 1;T_CLK = 0;ACC = ACC >> 1;}}/******************************************************************** ** 名称: uchar uc_RTOutputByte* 说明:* 功能: 从DS1302读取1Byte数据* 调用:* 输入:* 返回值: ACC***********************************************************************/ uchar uc_RTOutputByte(void){uchar i;for(i=8; i>0; i--){ACC = ACC >>1; /*相当于汇编中的 RRC */ACC7 = T_IO;T_CLK = 1;T_CLK = 0;}return(ACC);}/******************************************************************** ** 名称: v_W1302* 说明: 先写地址,后写命令/数据* 功能: 往DS1302写入数据* 调用: v_RTInputByte()* 输入: ucAddr: DS1302地址, ucDa: 要写的数据* 返回值: 无***********************************************************************/ void v_W1302(uchar ucAddr, uchar ucDa){T_RST = 0;T_CLK = 0;T_RST = 1;v_RTInputByte(ucAddr); /* 地址,命令 */v_RTInputByte(ucDa); /* 写1Byte数据*/T_CLK = 1;T_RST =0;}/******************************************************************** ** 名称: uc_R1302* 说明: 先写地址,后读命令/数据* 功能: 读取DS1302某地址的数据* 调用: v_RTInputByte() , uc_RTOutputByte()* 输入: ucAddr: DS1302地址* 返回值: ucDa :读取的数据***********************************************************************/ uchar uc_R1302(uchar ucAddr){uchar ucDa;T_RST = 0;T_CLK = 0;T_RST = 1;v_RTInputByte(ucAddr); /* 地址,命令 */ucDa = uc_RTOutputByte(); /* 读1Byte数据 */T_CLK = 1;T_RST =0;return(ucDa);}/******************************************************************** ** 名称: v_BurstW1302T* 说明: 先写地址,后写数据(时钟多字节方式)* 功能: 往DS1302写入时钟数据(多字节方式)* 调用: v_RTInputByte()* 输入: 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>0;i--) /*8Byte = 7Byte 时钟数据 + 1Byte 控制*/{v_RTInputByte(*pSecDa);/* 写1Byte数据*/pSecDa++;}T_CLK = 1;T_RST =0;}/******************************************************************** ** 名称: v_BurstR1302T* 说明: 先写地址,后读命令/数据(时钟多字节方式)* 功能: 读取DS1302时钟数据* 调用: v_RTInputByte() , uc_RTOutputByte()* 输入: 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>0; i--){*pSecDa = uc_RTOutputByte(); /* 读1Byte数据 */pSecDa++;}T_CLK = 1;T_RST =0;}/******************************************************************** ** 名称: v_BurstW1302R* 说明: 先写地址,后写数据(寄存器多字节方式)* 功能: 往DS1302寄存器数写入数据(多字节方式)* 调用: v_RTInputByte()* 输入: 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>0;i--) /*31Byte 寄存器数据 */{v_RTInputByte(*pReDa); /* 写1Byte数据*/pReDa++;}T_CLK = 1;T_RST =0;}/******************************************************************** ** 名称: uc_BurstR1302R* 说明: 先写地址,后读命令/数据(寄存器多字节方式)* 功能: 读取DS1302寄存器数据* 调用: v_RTInputByte() , uc_RTOutputByte()* 输入: 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>0; i--) /*31Byte 寄存器数据 */{*pReDa = uc_RTOutputByte(); /* 读1Byte数据 */pReDa++;}T_CLK = 1;T_RST =0;}/******************************************************************** ** 名称: v_Set1302* 说明:* 功能: 设置初始时间* 调用: v_W1302()* 输入: pSecDa: 初始时间地址。
基于ds1302和LCD1602的日历时钟51单片机程序

#include <reg52.h>#include <intrins.h>#include <string.h>#define uint unsigned int#define uchar unsigned charsbit led = P2^3;//led代替闹铃sbit IO = P1^3; //定义1302管脚//6sbit SCLK = P1^4;//7sbit RST = P1^5; //5sbit RS = P2^2;//定义1602管脚sbit RW = P2^1;sbit EN = P2^0;sbit key1=P3^4;//选择//调时键盘sbit key2=P3^5;//加sbit key3=P3^6;//减sbit key4=P3^7;//确定sbit key11=P1^6;//选择//闹钟键盘sbit key22=P1^7;//加sbit key33=P3^0;//减sbit key44=P3^1;//确定uchar x1=0,x;int hour=8,minute=0;//闹钟的初始时间8:00uchar DateTime[9]; //秒,分,时,日,周,月,年 address,uchar lcd1[]={"DATE 00-00-00 "};uchar lcd2[]={"TIME 00:00:00 "};/***************延时*************/void delayms(uchar x)//延时毫秒程序{ uchar i,j;for(i=x;i>0;i--)for(j=110;j>0;j--);}void delayus(uchar x)//延时微秒程序{ uchar i;for(i=0;i<x;i++);}/********1302的驱动程序***********///写入数据,dat:要写入的数据void DS1302WriteByte(uchar dat){uchar i;SCLK=0;//初始时钟线置为0delayus(2);for(i=0;i<8;i++)//开始传输8个字节的数据{IO=dat&0x01;//取最低位,注意DS1302的数据和地址都是从最低位开始传输的delayus(2);SCLK=1;//时钟线拉高,制造上升沿,SDA的数据被传输delayus(2);SCLK=0;//时钟线拉低,为下一个上升沿做准备dat>>=1;//数据右移一位,准备传输下一位数据}}/********1302的驱动程序**********///功能: 读取数据,dat:读取的数据uchar DS1302ReadByte(){ uchar i;uchar dat;delayus(2);for(i=0;i<8;i++){dat>>=1;//要返回的数据左移一位if(IO==1)//当数据线为高时,证明该位数据为1dat|=0x80;//要传输数据的当前值置为1,若不是,则为0SCLK=1;//拉高时钟线delayus(2);SCLK=0;//制造下降沿delayus(2);}return dat;//返回读取出的数据/16*10+dat%16}/*********1302的驱动程序*********///从cmd相应地址中读取一个字节的数据uchar DS1302Read(uchar cmd)//cmd:要写入的控制字节,dat:读取的数据{uchar dat;RST=0;//初始CE线置为0SCLK=0;//初始时钟线置为0RST=1;//初始CE置为1,传输开始DS1302WriteByte(cmd);//传输命令字,要读取的时间/日历地址dat=DS1302ReadByte();//读取要得到的时间/日期SCLK=1;//时钟线拉高RST=0;//读取结束,CE置为0,结束数据的传输return dat;//返回得到的时间/日期}/**********1302的驱动程序*********///向cmd相应地址中写一个字节的数据void DS1302Write(uchar cmd, uint dat)//cmd:要写入的控制字,dat:要写入的数据{RST=0; //初始CE线置为0SCLK=0; //初始时钟线置为0RST=1; //初始CE置为1,传输开始DS1302WriteByte(cmd); //传输命令字,要写入的时间/日历地址DS1302WriteByte(dat); //写入要修改的时间/日期SCLK=1; //时钟线拉高RST=0; //读取结束,CE置为0,结束数据的传输}/*************初始化ds1302********///给1302写入日期和时钟的值void chushihuaDS1302(void){DS1302Write(0x8e,0x00);//写保护关DS1302Write(0x80,0x10); //初始秒DS1302Write(0x82,0x02);//初始分钟DS1302Write(0x84,0x15); //初始为24小时模式,初始时DS1302Write(0x86,0x01); //1日DS1302Write(0x88,0x08);//8月DS1302Write(0x8c,0x13);//2013年DS1302Write(0x8a,0x04);//星期4// DS1302Write(0x90,0x01); //充电//DS1302Write(0xc0,0xf0); //初始化一次标示//DS1302Write(0x8e,0x80);//写保护开}/************以下是1602的程序******************//******************************///向1602内写命令void write_order(uchar order){RS=0;P0=order;delayms(5);EN=1;delayms(5);EN=0;}/******************************///向1602内写数据void write_date(uchar date){RS=1;P0=date;delayms(5);EN=1;delayms(5);EN=0;}/******************************///lcd1602的初始化void chushihuaLCD1602(){ EN=0;write_order(0x38);write_order(0x0c);write_order(0x06);write_order(0x01);}/*************其他操作*****************/void gettime(){ uchar i,n;for(i=0,n=1;i<7,n<15;i++,n=n+2){ DateTime[i]=DS1302Read(0x80+n);delayus(1);}}void zhuanhuan(){ gettime();lcd1[5]=((DateTime[6]>>4)+0x30);lcd1[6]=((DateTime[6]&0x0f)+0x30);delayus(2);//年lcd1[14]=((DateTime[5]>>4)+0x30);lcd1[15]=((DateTime[5]&0x0f)+0x30);delayus(2);//周lcd1[11]=((DateTime[3]>>4)+0x30);lcd1[12]=((DateTime[3]&0x0f)+0x30);delayus(2);//日lcd1[8]=((DateTime[4]>>4)+0x30);lcd1[9]=((DateTime[4]&0x0f)+0x30);delayus(2);//月lcd2[5]=((DateTime[2]>>4)+0x30);lcd2[6]=((DateTime[2]&0x0f)+0x30);delayus(2);//时lcd2[8]=((DateTime[1]>>4)+0x30);lcd2[9]=((DateTime[1]&0x0f)+0x30);delayus(2);//分lcd2[11]=((DateTime[0]>>4)+0x30);lcd2[12]=((DateTime[0]&0x0f)+0x30);delayus(2);//秒if(DateTime[7]==DateTime[2] & DateTime[8]==DateTime[1]){led = 1;delayms(150);led = 0;}/**/}/***********************/void jianpan() //键盘调时{ uchar x2,address,max,min;int item;if(key1==0){ delayms(10);if(key1==0){ x1++;if(x1>=7) x1=1;switch(x1){ case 1: lcd2[15]='Y';x2=1;address=0x8c; max=99;min=0;break;//年case 2: lcd2[15]='M';x2=2;address=0x88; max=12;min=1;break;//月case 3: lcd2[15]='D';x2=3;address=0x86; max=31;min=1;break;//天case 4: lcd2[15]='H';x2=4;address=0x84; max=23;min=0;break;//时case 5: lcd2[15]='F';x2=5;address=0x82; max=59;min=0;break;//分case 6: lcd2[15]='W';x2=6;address=0x8A; max=7;min=1;break;//周}}while(!key1);}item=(DS1302Read(address+1)/16)*10 + (DS1302Read(address+1))%16;if(key2==0){ delayms(10);if(key2==0){ if(x2==1) {item++;}else if(x2==2) {item++;}else if(x2==3) {item++;}else if(x2==4) {item++;}else if(x2==5) {item++;}else if(x2==6) {item++;}}while(!key2);}if(key3==0){ delayms(10);if(key3==0){ if(x2==1) {item--;}else if(x2==2) {item--;}else if(x2==3) {item--;}else if(x2==4) {item--;}else if(x2==5) {item--;}else if(x2==6) {item--;}}while(!key3);}if(key4==0){ delayms(10);if(key4==0){ lcd2[15]=' ';x1=0;x2=0;}while(!key4);}//led=0;delayms(5000);led=1;if(item>max) item=min;if(item<min) item=max;DS1302Write(0x8e,0x00);//允许写操作delayms(10);DS1302Write(address,(item/10)*16+item%10); //写入DS1302 //转成BCD码delayms(20);DS1302Write(0x8e,0x80);//写保护,禁止写操作}void naozhong()//设定闹钟{ uchar da,xiao,i;if(key11==0){ delayms(10);if(key11==0){ x++;if(x>=4) x=1;switch(x){case 2: lcd2[13]='H';i=1;da=23;xiao=0;lcd2[14]=((hour>>4)+0x30);lcd2[15]=((hour&0x0f)+0x30);delayus(2);break;//时case 1: lcd2[13]='M';i=2;da=59;xiao=0;lcd2[14]=((minute>>4)+0x30);lcd2[15]=((minute&0x0f)+0x30);delayus(2);break;//分case 3: lcd2[13]=' ';lcd2[14]=' ';lcd2[15]=' ';x=0;i=0;break;}}while(!key11);}if(key22==0){ delayms(10);if(key22==0){ if(i==1){ hour=((hour/16)*10)+(hour%16);hour++;if(hour>da) hour=xiao;hour=(hour/10)*16+hour%10;lcd2[14]=((hour>>4)+0x30);lcd2[15]=((hour&0x0f)+0x30);delayus(2);}else if(i==2){ minute=((minute/16)*10)+(minute%16);minute++;if(minute>da) minute=xiao;minute=(minute/10)*16+minute%10;lcd2[14]=((minute>>4)+0x30);lcd2[15]=((minute&0x0f)+0x30);delayus(2);}}while(!key22);}if(key33==0){ delayms(10);if(key33==0){ if(i==1){ hour=((hour/16)*10)+(hour%16);hour--;if(hour<xiao) hour=da;hour=(hour/10)*16+hour%10;lcd2[14]=((hour>>4)+0x30);lcd2[15]=((hour&0x0f)+0x30);delayus(2);}else if(i==2){ minute=((minute/16)*10)+(minute%16);minute--;if(minute<xiao) minute=da;minute=(minute/10)*16+minute%10;lcd2[14]=((minute>>4)+0x30);lcd2[15]=((minute&0x0f)+0x30);delayus(2);}}while(!key33);}DateTime[7]=hour;DateTime[8]=minute;}/**/void wzd0() interrupt 0//外部中断0{jianpan();//}void wzd1() interrupt 2//外部中断1{naozhong();}void main(){uchar k;EA=1;EX0=1;IT0=1;PX0=1;EX1=1;IT1=1;PX1=0;RW=0;led=0;chushihuaLCD1602();if( (DS1302Read(0x81) & 0x80) ) chushihuaDS1302();//chushihuaDS1302();while(1){zhuanhuan();write_order(0x80);//lcd的第一行for(k=0;k<16;k++){ write_date(lcd1[k]);delayus(2);}write_order(0x80+0x40);//lcd的第二行for(k=0;k<16;k++){ write_date(lcd2[k]);delayus(2);}}}。
DS1302数码管电子闹钟程序

/*****************************************************///DS1302+数码管+3个独立按键//// 精确定时/////*****************************************************/ /****************************************************************/// 利用ds1302精确定时,同时按键可调时间。
//// 每操作一次时钟,都会有蜂鸣器响大约200ms,以提示操作。
///***************************************************************/#include<reg52.h>#include"ds1302.h"uchar code tab[]={ 0x3F,/*0*/0x06,/*1*/0x5B,/*2*/0x4F,/*3*/0x66,/*4*/0x6D,/*5*/0x7D,/*6*/0x07,/*7*/0x7F,/*8*/0x6F,/*9*/} ;//共阴码char clock1[3]={0};int i,j=0,flag1=0;void delay(uint xms){uint x,y;for(x=xms;x>0;x--)for(y=110;y>0;y--);}void init()//初始化{//RST=0;//SCLK=0;//write_1302(0x80,0x00);//写控制字,允许写//write_1302(0x90,0x00);//禁止涡流充电TMOD=0x01;TH0=(65536-50000)/256;TL0=(65536-50000)%256;EA=1;ET0=1;TR0=1;}void display(uchar miaog,uchar miaos,uchar feng,uchar fens,uchar shig,uchar shis)//数码管动态显示{P2=0x7f;P0=tab[miaog];delay(5);P2=0xbf;P0=tab[miaos];delay(5);P2=0xdf;P0=0xc0;delay(5);P2=0xef;P0=tab[feng];delay(5);P2=0xf7;P0=tab[fens];delay(5);P2=0xfb;P0=0xc0;delay(5);P2=0xfd;P0=tab[shig];delay(5);P2=0xfe;P0=tab[shis];delay(5);}write_sfm(uchar miao,uchar fen,uchar shi) //写入到数码管{uchar miaog,miaos,feng,fens,shig,shis;miaog=miao%10;miaos=miao/10;feng=fen%10;fens=fen/10;shig=shi%10;shis=shi/10;display(miaog,miaos,feng,fens,shig,shis);}void didi() //发声程序{buzzer=0;delay(50);buzzer=1;}void keyscan()//按键扫描程序{uchar temp;if(key1==0) //功能键{if(key1==0){while(!key1);key1n=key1n++;if(key1n==5)key1n=1;switch(key1n){case 1://didi();temp=(miao)/10*16+(miao)%10;//将秒转化成bcd码,没这句秒就变化,不知为什么write_1302 (0x8e,0x00); //禁止写保护write_1302 (0x80,0x80|temp); //时钟暂停write_1302 (0x8e,0x80); //允许写保护break;case 2 ://didi();break;case 3 ://didi();break;case 4 ://didi();temp=miao/10*16+miao%10;write_1302 (0x8e,0x00); //禁止写保护write_1302 (0x80,0x00|temp);//时钟开始write_1302 (0x8e,0x80); //允许写保护break;}}}if(key4==0) //闹钟键{if(key4==0){while(!key4);keyn++;if(keyn==4)keyn=0;while(keyn){EA=0; //闹钟键if(key4==0)if(key4==0){while(!key4);keyn++;if(keyn==4)keyn=0;}write_sfm(clock1[2],clock1[1],clock1[0]);if(keyn==1) //时修改{if(key3==0) //减键{//delay(3);if(key3==0){while(!key3);clock1[0]--;if(clock1[0]<0)clock1[0]=24;}}if(key2==0) //加键{//delay(3);if(key2==0){while(!key2);clock1[0]++;if(clock1[0]>24)clock1[0]=0;}}}if(keyn==2) //分修改{if(key3==0) //减键{//delay(3);if(key3==0){while(!key3);clock1[1]--;if(clock1[1]<0)clock1[1]=59;}}if(key2==0) //加键{//delay(3);if(key2==0){while(!key2);clock1[1]++;if(clock1[1]>59)clock1[1]=0;}}}if(keyn==3) //秒修改{if(key3==0) //减键{//delay(3);if(key3==0){while(!key3);clock1[2]--;if(clock1[2]<0)clock1[2]=59;}}if(key2==0) //加键{//delay(3);if(key2==0){while(!key2);clock1[2]++;if(clock1[2]>59)clock1[2]=0;}}}}} EA=1;}if(key1n!=0) //当按下功能键key1,按以下才有用{if(key2==0) //加键{delay(3);if(key2==0){while(!key2);switch(key1n){case 1 : //didi(); //秒temp=(miao+1)/10*16+(miao+1)%10;if(miao==59)temp=0;write_1302 (0x8e,0x00); //禁止写保护write_1302 (0x80,0x80|temp);write_1302 (0x8e,0x80); //允许写保护break;case 2 : // didi(); //分temp=(fen+1)/10*16+(fen+1)%10;if(fen==59)temp=0;write_1302 (0x8e,0x00); //禁止写保护write_1302 (0x82,temp);write_1302 (0x8e,0x80); //允许写保护break;case 3 :// didi();temp=(shi+1)/10*16+(shi+1)%10; //时if(shi==23)temp=0;write_1302 (0x8e,0x00); //禁止写保护write_1302 (0x84,temp);write_1302 (0x8e,0x80); //允许写保护break;}}}if(key3==0) //减键{delay(3);if(key3==0){while(!key3);switch(key1n){case 1 ://didi();temp=(miao-1)/10*16+(miao-1)%10; //秒if(miao==0)temp=89;write_1302 (0x8e,0x00); //禁止写保护write_1302 (0x80,0x80|temp);write_1302 (0x8e,0x80); //允许写保护break;case 2 ://didi();temp=(fen-1)/10*16+(fen-1)%10; //分if(fen==0)temp=89;write_1302 (0x8e,0x00); //禁止写保护write_1302 (0x82,temp);write_1302 (0x8e,0x80); //允许写保护break;case 3 ://didi();temp=(shi-1)/10*16+(shi-1)%10; //时if(shi==0)temp=35;write_1302 (0x8e,0x00); //禁止写保护write_1302 (0x84,temp);write_1302 (0x8e,0x80); //允许写保护break;}}}}//write_1302(0x80,miao|0x80);//miao++;/* if(key2==0){if(key2==0){while(!key2);write_1302(0x80,miao|0x00);//打开1302振荡器}}*/}void main(){init();//buzzer=0;//miao=20;//fen=10;//shi=23;while(1){miao = BCD_Decimal(read_1302(0x81));fen = BCD_Decimal(read_1302(0x83));shi = BCD_Decimal(read_1302(0x85));keyscan();if((miao==clock1[2])&&(fen==clock1[1])&&(shi==clock1[0])) {flag1=1;for(i=0;i<10;i++)didi();}if(j==100) for(i=0;i<10;i++) didi();if(j==200) {for(i=0;i<10;i++)didi();flag1=0;j=0;}}}void tiemr0() interrupt 1{if(flag1) j++;TH0=(65536-50000)/256;TL0=(65536-50000)%256;write_sfm(miao,fen,shi); }。
51单片机ds1302实时时钟程序

51单⽚机ds1302实时时钟程序#ifndef __DS1302_H_#define __DS1302_H_//---包含头⽂件---//#include#include//---重定义关键词---//#ifndefuchar#define uchar unsigned char#endif#ifndefuint#define uint unsigned int#endif//---定义ds1302使⽤的IO⼝---//sbit DSIO=P3^4;sbit RST=P3^5;sbit SCLK=P3^6;//---定义全局函数---//void Ds1302Write(ucharaddr, uchardat); uchar Ds1302Read(ucharaddr);void Ds1302Init();void Ds1302ReadTime();//---加⼊全局变量--//extern uchar TIME[7]; //加⼊全局变量#endif #include"ds1302.h"//---DS1302写⼊和读取时分秒的地址命令---////---秒分时⽇⽉周年最低位读写位;-------//uchar code READ_RTC_ADDR[7] = {0x81, 0x83, 0x85, 0x87, 0x89, 0x8b, 0x8d};uchar code WRITE_RTC_ADDR[7] = {0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c};//---DS1302时钟初始化2013年1⽉1⽇星期⼆12点00分00秒。
---////---存储顺序是秒分时⽇⽉周年,存储格式是⽤BCD码---//uchar TIME[7] = {0, 0, 0x12, 0x01, 0x01, 0x02, 0x13};/************************************************************************ * 函数名: Ds1302Write* 函数功能: 向DS1302命令(地址+数据)* 输⼊: addr,dat* 输出: ⽆************************************************************************* void Ds1302Write(ucharaddr, uchardat){uchar n;RST = 0;_nop_();SCLK = 0;//先将SCLK置低电平。
基于80C51单片机,DS1302时钟芯片的实时时钟,

temp>>=1; delay(5); CLK=1; } return temp;
Hale Waihona Puke //右移一位} //******************************// /*写指令*/ //******************************// void write_com(uchar com) { rs=0; rw=0; P0=com; delay(10); en=0; delay(10); en=1; } //******************************// /*写数据*/ //******************************// void write_date(uchar date) { rs=1; rw=0; P0=date; delay(10); en=0; delay(10); en=1; } //******************************// /*显示*/ //******************************// void display(uchar x,uchar y) { uchar shi,ge;
shi=y/10; ge=y%10; write_com(0x80+0x40+x); write_date(0x30+shi); write_date(0x30+ge); } void init() { char r; write_com(0x01); write_com(0x06); write_com(0x0f); write_com(0x38); write_com(0x80); for(r=0;r<13;r++) { write_date(table[r]); delay(10); } write_com(0x80+0x40); for(r=0;r<12;r++) { write_date(table1[r]); delay(10); } } void main() { init(); while(1) { display(10,read_1302(0x81)); display(7,read_1302(0x83)); display(4,read_1302(0x85)); } }
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
#include <reg51.h>#include <intrins.h>#define uchar unsigned char#define uint unsigned intuchar count_10ms; //定义10ms计数器sbit K1 = P3^7; //定义K1键sbit K2 = P3^4; //定义K2键sbit K3 = P3^5; //定义K3键sbit K4 = P3^6; //P1^3定义K4键sbit K5 = P3^3;sbit BEEP=P2^2; //定义蜂鸣器sbit reset = P1^6; //P2^5;sbit sclk = P1^7; //P2^6;sbit io = P2^6; //P2^7;sbit LCD_RS=P1^0;sbit LCD_RW=P1^1 ;sbit LCD_EN=P1^2;bit K1_FLAG=0; //定义按键标志位,当按下K1键时,该位置1,K1键未按下时,该位为0。
uchar disp_buf[16] ={0x00}; //定义显示缓冲区uchar time_buf[7] ={0,0,0x12,0,0,0,0}; //DS1302时间缓冲区,存放秒、分、时、日、月、星期、年uchar temp [2]={0}; //用来存放设置时的小时、分钟的中间值uint m=0,n=0,r=0;/********以下是函数声明********/void Delay_ms(uint xms) ;bit lcd_busy();void lcd_wcmd(uchar cmd);void lcd_wdat(uchar dat) ;void lcd_clr() ;void lcd_init() ;void write_byte(uchar inbyte); //写一字节数据函数声明uchar read_byte(); //读一字节数据函数声明void write_ds1302(uchar cmd,uchar indata); //写DS1302函数声明uchar read_ds1302(uchar addr); //读DS1302函数声明void set_ds1302(uchar addr,uchar *p,uchar n); //设置DS1302初始时间函数声明void get_ds1302(uchar addr,uchar *p,uchar n); //读当前时间函数声明void init_ds1302(); //DS1302初始化函数声明/********以下是延时函数********/void Delay_ms(uint xms){uint i,j;for(i=xms;i>0;i--) //i=xms即延时约xms毫秒for(j=70;j>0;j--);}/********以下是LCD忙碌检查函数********/bit lcd_busy(){bit result;LCD_RS = 0;LCD_RW = 1;LCD_EN = 1;_nop_();_nop_();_nop_();_nop_();result = (bit)(P0&0x80);LCD_EN = 0;return result;}/********以下是写指令寄存器IR函数********/void lcd_wcmd(uchar cmd){while(lcd_busy());LCD_RS = 0;LCD_RW = 0;LCD_EN = 0;_nop_();_nop_();P0 = cmd;_nop_();_nop_();_nop_();_nop_();LCD_EN = 1;_nop_();_nop_();_nop_();_nop_();LCD_EN = 0;}/********以下是写寄存器DR函数********/void lcd_wdat(uchar dat){while(lcd_busy());LCD_RS = 1;LCD_RW = 0;LCD_EN = 0;P0 = dat;_nop_();_nop_();_nop_();_nop_();LCD_EN = 1;_nop_();_nop_();_nop_();_nop_();LCD_EN = 0;}/********以下是LCD清屏函数********/void lcd_clr(){lcd_wcmd(0x01); //清除LCD的显示内容Delay_ms(5);}/********以下是LCD初始化函数********/void lcd_init(){Delay_ms(15); //等待LCD电源稳定lcd_wcmd(0x38); //16*2显示,5*7点阵,8位数据Delay_ms(5);lcd_wcmd(0x38);Delay_ms(5);lcd_wcmd(0x38);Delay_ms(5);lcd_wcmd(0x0c); //显示开,关光标Delay_ms(5);lcd_wcmd(0x06); //移动光标Delay_ms(5);lcd_wcmd(0x01); //清除LCD的显示内容Delay_ms(5);}/********以下是写一字节数据函数********/void write_byte(uchar inbyte){uchar i;for(i=0;i<8;i++){sclk=0; //写时低电平改变数据if(inbyte&0x01)io=1;elseio=0;sclk=1; //高电平把数据写入DS1302_nop_();inbyte=inbyte>>1;}}/********以下是读一字节数据函数********/uchar read_byte(){uchar i,temp=0;io=1;for(i=0;i<7;i++){sclk=0;if(io==1)temp=temp|0x80;elsetemp=temp&0x7f;sclk=1; //产生下跳沿temp=temp>>1;}return (temp);}/********写DS1302函数, 往DS1302的某个地址写入数据********/ void write_ds1302(uchar cmd,uchar indata){sclk=0;reset=1;write_byte(cmd);write_byte(indata);sclk=0;reset=0;}/********读DS1302函数,读DS1302某地址的的数据********/ uchar read_ds1302(uchar addr){uchar backdata;sclk=0;reset=1;write_byte(addr); //先写地址backdata=read_byte(); //然后读数据sclk=0;reset=0;return (backdata);}/********初始化DS1302函数********/void init_ds1302(){reset=0;sclk=0;write_ds1302(0x80,0x00); //写秒寄存器write_ds1302(0x90,0xab); //写充电器write_ds1302(0x8c,0x13); //以下写入初始化时间日期write_ds1302(0x88,0x09); //write_ds1302(0x86,0x16); //write_ds1302(0x8a,0x05); //写入星期write_ds1302(0x84,0x10); //write_ds1302(0x82,0x13); //write_ds1302(0x80,0x00); //write_ds1302(0x8e,0x80); //写保护控制字,禁止写}/*********以下是蜂鸣器响一声函数********/void beep(){BEEP=0; //蜂鸣器响Delay_ms(100);BEEP=1; //关闭蜂鸣器Delay_ms(100);}/********以下是转换函数,负责将走时数据转换为适合LCD显示的数据********/void LCD_conv (uchar in7,in5,in4,in1,in2,in3 )//形参in1、in2、in3接收实参time_buf[2]、time_buf[1]、time_buf[0]传来的小时、分钟、秒数据{disp_buf[0]=in1/10+0x30; //小时十位数据disp_buf[1]=in1%10+0x30; //小时个位数据disp_buf[2]=in2/10+0x30; //分钟十位数据disp_buf[3]=in2%10+0x30; //分钟个位数据disp_buf[4]=in3/10+0x30; //秒十位数据disp_buf[5]=in3%10+0x30; //秒个位数据disp_buf[6]=2+0x30; //年千位数据disp_buf[7]=0+0x30; //年百位数据disp_buf[8]=in7/10+0x30; //年十位数据disp_buf[9]=in7%10+0x30; //年时个位数据disp_buf[10]=in5/10+0x30; //月十位数据disp_buf[11]=in5%10+0x30; //月个位数据disp_buf[12]=in4/10+0x30; //日十位数据disp_buf[13]=in4%10+0x30; //日个位数据}/********以下是LCD显示函数,负责将函数LCD_conv转换后的数据显示在LCD上********/void LCD_disp (){lcd_wcmd(0x80+3); //显示第一行lcd_wdat(disp_buf[6]); //显示年千位lcd_wdat(disp_buf[7]); //显示年百位lcd_wdat(disp_buf[8]); //显示年十位lcd_wdat(disp_buf[9]); //显示年个位lcd_wdat(0x3a);lcd_wdat(disp_buf[10]); //显示月十位lcd_wdat(disp_buf[11]); //显示月个位lcd_wdat(0x3a);lcd_wdat(disp_buf[12]); //显示日十位lcd_wdat(disp_buf[13]); //显示日个位lcd_wcmd(0x44 + 0x80); //从第2行第4列开始显示lcd_wdat(disp_buf[0]); //显示小时十位lcd_wdat(disp_buf[1]); //显示小时个位lcd_wdat(0x3a); //显示':'lcd_wdat(disp_buf[2]); //显示分钟十位lcd_wdat(disp_buf[3]); //显示分钟个位lcd_wdat(0x3a); //显示':'lcd_wdat(disp_buf[4]); //显示秒十位lcd_wdat(disp_buf[5]); //显示秒个位}/********以下是按键处理函数********/void KeyProcess(){uchar min16,hour16,ri16,yue16,nian16; //定义16进制的分钟和小时变量write_ds1302(0x8e,0x00); //DS1302写保护控制字,允许写write_ds1302(0x80,0x80); //时钟停止运行lcd_wcmd(0x0f);lcd_wcmd(0x80+0x40+12);if(K2==0){Delay_ms(10); //延时去抖if(K2==0){while(!K2);m++;if(m==6){m=1;}}}if(K3==0){Delay_ms(10); //延时去抖if(K3==0){while(!K3);m--;if(m==0){m=5;}}}if(m!=0){if(m==1&&K4==0){Delay_ms(10); //延时去抖if(m==1&&K4==0){lcd_wcmd(0x0f);lcd_wcmd(0x80+0x40+8);while(!K4);beep();time_buf[1]=time_buf[1]+1; //分钟加1if(time_buf[1]==60) time_buf[1]=0; //当分钟加到60时初始化为0min16=time_buf[1]/10*16+time_buf[1]%10; //将所得的分钟数据转变成16进制数据write_ds1302(0x82,min16);}}if(m==2&&K4==0){Delay_ms(10); //延时去抖if(m==2&&K4==0){lcd_wcmd(0x0f);lcd_wcmd(0x80+0x40+5);while(!K4);beep();time_buf[2]=time_buf[2]+1; //小时减1if(time_buf[2]==24) time_buf[2]=0; //当变成0时初始化为24hour16=time_buf[2]/10*16+time_buf[2]%10; //将所得的小时数据转变成16进制数据write_ds1302(0x84,hour16);}}if(m==3&&K4==0){Delay_ms(10); //延时去抖if(m==3&&K4==0){lcd_wcmd(0x0f);lcd_wcmd(0x80+12);while(!K4);beep();time_buf[3]=time_buf[3]+1; //分钟减1if(time_buf[3]==32) time_buf[3]=0; //当分钟加到60时初始化为0ri16=time_buf[3]/10*16+time_buf[3]%10; //将所得的分钟数据转变成16进制数据write_ds1302(0x86,ri16);}}if(m==4&&K4==0){Delay_ms(10); //延时去抖if(m==4&&K4==0){lcd_wcmd(0x0f);lcd_wcmd(0x80+8);while(!K4);beep();time_buf[4]=time_buf[4]+1; //分钟减1if(time_buf[4]==13) time_buf[4]=0; //当分钟加到60时初始化为0yue16=time_buf[4]/10*16+time_buf[4]%10; //将所得的分钟数据转变成16进制数据write_ds1302(0x88,yue16);}}if(m==5&&K4==0){Delay_ms(10); //延时去抖if(m==5&&K4==0){lcd_wcmd(0x0f);lcd_wcmd(0x80+6);while(!K4);beep();time_buf[6]=time_buf[6]+1; //分钟减1if(time_buf[6]==100) time_buf[6]=0; //当分钟加到60时初始化为0nian16=time_buf[6]/10*16+time_buf[6]%10; //将所得的分钟数据转变成16进制数据write_ds1302(0x8C,nian16);}}if(m==1&&K5==0){Delay_ms(10); //延时去抖if(m==1&&K5==0){lcd_wcmd(0x0f);lcd_wcmd(0x80+0x40+8);while(!K5);beep();time_buf[1]=time_buf[1]-1; //分钟加1if(time_buf[1]==-1) time_buf[1]=59; //当分钟加到60时初始化为0min16=time_buf[1]/10*16+time_buf[1]%10; //将所得的分钟数据转变成16进制数据write_ds1302(0x82,min16);}}if(m==2&&K5==0){Delay_ms(10); //延时去抖if(m==2&&K5==0){lcd_wcmd(0x0f);lcd_wcmd(0x80+0x40+5);while(!K5);beep();time_buf[2]=time_buf[2]-1; //小时减1if(time_buf[2]==-1) time_buf[2]=23; //当变成0时初始化为24hour16=time_buf[2]/10*16+time_buf[2]%10; //将所得的小时数据转变成16进制数据write_ds1302(0x84,hour16);}}if(m==3&&K5==0){Delay_ms(10); //延时去抖if(m==3&&K5==0){lcd_wcmd(0x0f);lcd_wcmd(0x80+12);while(!K5);beep();time_buf[3]=time_buf[3]-1; //分钟减1if(time_buf[3]==0) time_buf[3]=31; //当分钟加到60时初始化为0ri16=time_buf[3]/10*16+time_buf[3]%10; //将所得的分钟数据转变成16进制数据write_ds1302(0x86,ri16);}}if(m==4&&K5==0){Delay_ms(10); //延时去抖if(m==4&&K5==0){lcd_wcmd(0x0f);lcd_wcmd(0x80+8);while(!K5);beep();time_buf[4]=time_buf[4]-1; //分钟减1if(time_buf[4]==0) time_buf[4]=12; //当分钟加到60时初始化为0yue16=time_buf[4]/10*16+time_buf[4]%10; //将所得的分钟数据转变成16进制数据write_ds1302(0x88,yue16);}}if(m==5&&K5==0){Delay_ms(10); //延时去抖if(m==5&&K5==0){lcd_wcmd(0x0f);lcd_wcmd(0x80+6);while(!K5);beep();time_buf[6]=time_buf[6]-1; //分钟减1if(time_buf[6]==0) time_buf[6]=99; //当分钟加到60时初始化为0nian16=time_buf[6]/10*16+time_buf[6]%10; //将所得的分钟数据转变成16进制数据write_ds1302(0x8C,nian16);}}}}/********以下是读取时间函数,负责读取当前的时间,并将读取到的时间转换为10进制数********/void get_time(){uchar sec,min,hour,ri,yue,nian; //定义秒、分和小时变量write_ds1302(0x8e,0x00); //控制命令,WP=0,允许写操作write_ds1302(0x90,0xab); //涓流充电控制sec=read_ds1302(0x81); //读取秒min=read_ds1302(0x83); //读取分hour=read_ds1302(0x85); //读取时ri=read_ds1302(0x87); //读取日yue=read_ds1302(0x89); //读取月nian=read_ds1302(0x8D); //读取年time_buf[0]=sec/16*10+sec%16; //将读取到的16进制数转化为10进制time_buf[1]=min/16*10+min%16; //将读取到的16进制数转化为10进制time_buf[2]=hour/16*10+hour%16; //将读取到的16进制数转化为10进制time_buf[3]=ri/16*10+ri%16; //将读取到的16进制数转化为10进制time_buf[4]=yue/16*10+yue%16; //将读取到的16进制数转化为10进制time_buf[6]=nian/16*10+nian%16; //将读取到的16进制数转化为10进制if(m!=0){if(m==1)lcd_wcmd(0x80+0x40+8);if(m==2)lcd_wcmd(0x80+0x40+5);if(m==3)lcd_wcmd(0x80+12);if(m==4)lcd_wcmd(0x80+9);if(m==5)lcd_wcmd(0x80+6);}}/********以下是主函数********/void main(void){uint a;P0 = 0xff;P2 = 0xff;lcd_init(); //LCD初始化函数(在LCD驱动程序软件包中)lcd_clr(); //清屏函数(在LCD驱动程序软件包中)init_ds1302(); //DS1302初始化while(1){get_time(); //读取当前时间if(K1==0) //若K1键按下{Delay_ms(10); //延时10ms去抖if(K1==0){while(!K1);a++;}}if(a!=0){if(a==1){beep(); //蜂鸣器响一声K1_FLAG=1; //K1键标志位置1,以便进行时钟调整//时钟停止运行}if(a==2){beep();lcd_wcmd(0x0c);write_ds1302(0x80,time_buf[0]); //调整完毕后,启动时钟运行write_ds1302(0x8e,0x80); //写保护控制字,禁止写K1_FLAG=0; //将K1键按下标志位清0a=0;m=0;}}if(K1_FLAG==1)KeyProcess(); //若K1_FLAG为1,则进行走时调整LCD_conv(time_buf[6],time_buf[4],time_buf[3],time_buf[2],time_buf[1],time_buf[0]);//将DS1302的年/月/日/小时/分/秒传送到转换函数LCD_disp(); //调LCD显示函数,显示年、月、日小时、分和秒}}。