51单片机+ds1302+DS18b20温度时钟
12864+ds1302+ds18b20数字时钟_温度_日期同步显示

毕业(论文)说明书题目:系别:专业:指导老师:学生姓名:学号:理论研究工程设计工程技术研究软件开发2014年7 月18日一毕业设计(论文)内容与要求一、主要研究内容1、8051单片机硬件结构。
2、C语言程序设计基础内容。
3、单片机C语言程序设计的方法。
4、DS18B20温度传感器的使用方法。
5、DS1302时钟芯片的用法。
6、12864LCD液晶屏的编程使用方法。
二、要求1、能够以指针的形式在LCD12864上显示当前时间的小时和分钟和秒。
2、能够以数字加汉字的形式在LCD12864上显示当前时间的小时和分钟和秒。
3、能够以数字加汉字的形式在LCD12864上显示当前年月日。
4、能够以数字加汉字的形式在LCD12864上显示当前星期。
5、时间采用时钟芯片DS1302控制。
6、温度采用DS18B20温度传感器检测当前温度。
7、所有功能在LCD12864当中同步显示。
8、采用AT89S52或者STC89C52RC单片机控制。
三、引言随着人们生活水平的不断提高,单片机控制无疑是人们追求的目标之一,它所给人带来的方便也是不可否定的,要为现代人工作、科研、生活、提供更好的更方便的设施就需要从数单片机技术入手,一切向着数字化控制,智能化控制方向发展。
本设计是数据采集及处理,显示系统与单片机有效结合,本设计是通过在“单片机原理及应用”课堂上学习的知识的综合应用,以及查阅资料,培养一种自学的能力。
并且引导一种创新的思维,把学到的知识应用到日常生活当中。
在设计的过程中,不断的学习,思考和同学间的相互讨论,运用科学的分析问题的方法解决遇到的困难,掌握单片机系统一般的开发流程,学会对常见问题的处理方法,积累设计系统的经验,充分发挥教学与实践的结合。
全能提高个人系统开发的综合能力,开拓了思维,为今后能在相应工作岗位上的工作打下了坚实的基础。
四、方案设计及方案论证1.时钟温度的总体设计思路按照系统的设计功能要求,本时钟温度系统的设计必须采用单片机软件系统实现,用单片机的自动控制能力配合ds1302和ds18b20来控制时钟和温度的调整显示。
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 秒。
温度(温度传感器ds18b20)控制系统(水温) 带ds1302时间显示 lcd1602显示

if(k4==0)
{
(times[4])--;
if((times[4])==0x00)
{(times[4])=0x12;}
}
write_1302(0x88,times[4]);
}
break;
case 4:
{
if(k3==0);
delay(12);
if(k3==0)
{
(times[6])++;
}
/************************************************************/
void rdtemp(void)
{
txreset();
rxwait();
delay_b(1);//延时
wrbyte(0xcc);
wrbyte(0xbe);
tpl=rdbyte();
}
write_1302(0x82,times[1]);
}
break;
case 1:
{
if(k3==0);
delay(12);
if(k3==0)
{
(times[2])++;
if((times[2])==0x24)
{(times[2])=0x00;}
write_1302(0x84,times[2]);
}
void delay(uint z)
{
uint i,j;
for(i=0;i<=z;i++)
for(j=0;j<=500;j++);
}
void keycan()
{
if(k2==0);
51单片机实现基于DS1302_1602_18B20的多功能电子时钟_带测温功能

#include<reg51.h>#define uchar unsigned char#define uint unsigned int/*------------------寄存器地址定义------------*/#define WRITE_SECOND 0x80#define WRITE_MINUTE 0x82#define WRITE_HOUR 0x84#define WRITE_DAY 0x86#define WRITE_MONTH 0x88#define WRITE_YEAR 0x8C#define WRITE_PROTECT 0x8E#define WRITE_WEEK 0x8A#define WRITE_CURRENT 0x90#define READ_SECOND 0x81#define READ_MINUTE 0x83#define READ_HOUR 0x85#define READ_DAY 0x87#define READ_MONTH 0x89#define READ_WEEK 0x8B#define READ_YEAR 0x8Dsbit RST=P3^5; //DS1302片选sbit DIO=P3^4; //DS1302数据信号sbit SCLK=P3^6; //DS1302时钟信号sbit ACC7=ACC^7;sbit ACC0=ACC^0;unsigned char count;sbit beep=P1^4;void INITIAL_1302();unsigned char READ_1302(unsigned char addr);void WRITE_1302(unsigned char addr,unsigned char date); sbit LCD_E=P2^7; //液晶使能端sbit LCD_RS=P2^6; //液晶数据命令选择端sbit LCD_RW=P2^5; //液晶读写选择端sbit key0=P3^2; //功能键sbit key1=P3^3; //增大键sbit key2=P3^4; //减小键sbit DQ=P3^7; //18b20温度输入输出端char hour,minute,second,week,day,month,year,tem; unsigned char num,flag;unsigned char str1[]=" 20 - - ";unsigned char str2[]=" : : C";void delay(unsigned char z);void LCD_WRITE_COM(unsigned char com);void LCD_WRITE_DA TA(unsigned char date);void LCD_WRITE_SFM(unsigned char addr,unsigned char date);void LCD_WRITE_NYR(unsigned char addr,unsigned char date);void LCD_WRITE_WEEK(unsigned char week);void LCD_INITIAL();void LCD_WRITE_TEMP(uchar addr,uchar temp);void keyscan();void INITIAL_TEMER0();uchar TMPH ,TMPL;void w1602c(uchar com);void w1602d(uchar data01);void delay2(uint ms);void delay3(uint us);uchar resert(void);uchar read_byte();void write_byte(uchar val);uint get_temp();void display();void delay3(uint us); //18b20uchar resert(void); //18b20uchar read_byte(); //18b20void write_byte(uchar val); //18b20uint get_temp(); //18b20void main(){LCD_INITIAL(); //液晶初始化INITIAL_1302(); //DS1302初始化INITIAL_TEMER0(); //定时器初始化while(1){keyscan(); //按键扫描if(flag==0) //当标志位为0,允许读取DS1302数据,将数据送入液晶显示{second=READ_1302(0x81);LCD_WRITE_SFM(10,second);minute=READ_1302(0x83);LCD_WRITE_SFM(7,minute);hour=READ_1302(0x85);LCD_WRITE_SFM(4,hour);week=READ_1302(0x8b);LCD_WRITE_WEEK(week);day=READ_1302(0x87);LCD_WRITE_NYR(9,day);month=READ_1302(0x89);LCD_WRITE_NYR(6,month);year=READ_1302(0x8d);LCD_WRITE_NYR(3,year);tem=get_temp();LCD_WRITE_TEMP(13,tem);}}}/**********************1602BU份******************************************************/void delay(unsigned char z) //1602de延时函数{unsigned char x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}void LCD_WRITE_COM(unsigned char com){LCD_RS=0;LCD_RW=0;LCD_E=1;P0=com;delay(5);LCD_E=0;}void LCD_WRITE_DA TA(unsigned char date){LCD_RS=1;LCD_RW=0;LCD_E=1;P0=date;delay(5);LCD_E=0;}void LCD_WRITE_SFM(unsigned char addr,unsigned char date) {unsigned char shi,ge;shi=date/10;ge=date%10;LCD_WRITE_COM(0x80+0x40+addr);LCD_WRITE_DATA(0x30+shi);LCD_WRITE_DATA(0x30+ge);}void LCD_WRITE_NYR(unsigned char addr,unsigned char date) {char shi,ge;shi=date/10;ge=date%10;LCD_WRITE_COM(0x80+addr);LCD_WRITE_DATA(0x30+shi);LCD_WRITE_DATA(0x30+ge);}void LCD_WRITE_WEEK(unsigned char week){LCD_WRITE_COM(0x80+12);switch(week){case 1: LCD_WRITE_DA TA('M');delay(5);LCD_WRITE_DATA('O');delay(5);;LCD_WRITE_DATA('N');break;case 2: LCD_WRITE_DA TA('T');delay(5);LCD_WRITE_DATA('U');delay(5);LCD_WRITE_DATA('E');break;case 3: LCD_WRITE_DA TA('W');delay(5);LCD_WRITE_DATA('E');delay(5);LCD_WRITE_DATA('D');break;case 4: LCD_WRITE_DA TA('T');delay(5);LCD_WRITE_DATA('H');delay(5);LCD_WRITE_DATA('U');break;case 5: LCD_WRITE_DA TA('F');delay(5);LCD_WRITE_DATA('R');delay(5);LCD_WRITE_DATA('I');break;case 6: LCD_WRITE_DA TA('S');delay(5);LCD_WRITE_DATA('A');delay(5);LCD_WRITE_DATA('T');break;case 7: LCD_WRITE_DA TA('S');delay(5);LCD_WRITE_DATA('U');delay(5);LCD_WRITE_DATA('N');break;}}void LCD_WRITE_TEMP(uchar addr,uchar temp){char shi,ge;shi=temp/10;ge=temp%10;LCD_WRITE_COM(0x80+0x40+addr);LCD_WRITE_DATA(0x30+shi);LCD_WRITE_DATA(0x30+ge);}void LCD_INITIAL(){unsigned char i;LCD_WRITE_COM(0x38);LCD_WRITE_COM(0x0c);LCD_WRITE_COM(0x06); //经本人试验证明1602初始化不清屏也可实现LCD_WRITE_COM(0x80);for(i=0;i<16;i++){LCD_WRITE_DATA(str1[i]);delay(5);}LCD_WRITE_COM(0x80+0x40);//液晶第二行显示for(i=0;i<16;i++){LCD_WRITE_DATA(str2[i]);delay(5);}}/***************************1302部分***************************************************/void WRITE_1302(unsigned char addr,unsigned char date) {unsigned char i;RST=0;SCLK=0;RST=1;for(i=8;i>0;i--){SCLK=0;ACC=addr;DIO=ACC0;addr>>=1;SCLK=1;}for(i=8;i>0;i--){SCLK=0;ACC=date;DIO=ACC0;date>>=1;SCLK=1;}RST=0;}unsigned char READ_1302(unsigned char addr){unsigned char i,date1,date2;RST=0;SCLK=0;RST=1;for(i=8;i>0;i--){SCLK=0;ACC=addr;DIO=ACC0;addr>>=1;SCLK=1;}for(i=8;i>0;i--){ACC7=DIO;SCLK=1;ACC>>=1;SCLK=0;}RST=0;date1=ACC;date2=date1/16;date1=date1%16;date1=date1+date2*10;return(date1) ;}void INITIAL_1302(){WRITE_1302(WRITE_SECOND,READ_1302(READ_SECOND)&0x7f); //启动DS1302}/**************************键盘扫描部分***************************************************/void keyscan(){if(key0==0)//确认功能键按下{delay(20);if(key0==0)//去抖{while(!key0);//释放num++;switch(num){case 1: flag=1; //修改时间,禁止从DS1302读数据TR0=0; //定时器关LCD_WRITE_COM(0x0f); //光标开始闪烁LCD_WRITE_COM(0x80+3);//第一次按下,光标定位到年位置break;case 2: LCD_WRITE_COM(0x80+6);//第二次按下,光标定位到月位置break;case 3: LCD_WRITE_COM(0x80+9);//第三次按下,光标定位到日位置break;case 4: LCD_WRITE_COM(0x80+12);//第四次按下,光标定位到星期位置break;case 5: LCD_WRITE_COM(0x80+0x40+4);//第五次按下,光标定位到时位置break;case 6: LCD_WRITE_COM(0x80+0x40+7);//第六次按下,光标定位到分位置break;case 7: LCD_WRITE_COM(0x80+0x40+10);//第七次按下,光标定位到秒位置break;case 8: num=0;//第八次按下,记录清零LCD_WRITE_COM(0x0c);//不显示光标WRITE_1302(WRITE_PROTECT,0x00); //允许写操作WRITE_1302(0x80,(second/10*16)+second%10);//将调节后的秒写入DS1302WRITE_1302(0x82,(minute/10*16)+minute%10);//将调节后的分写入DS1302WRITE_1302(0x84,(hour/10*16)+hour%10);//将调节后的时写入DS1302WRITE_1302(0x8a,(week/10*16)+week%10);//将调节后的星期写入DS1302WRITE_1302(0x86,(day/10*16)+day%10);//将调节后的日写入DS1302WRITE_1302(0x88,(month/10*16)+month%10);//将调节后的月写入DS1302WRITE_1302(0x8c,(year/10*16)+year%10);//将调节后的年写入DS1302WRITE_1302(WRITE_PROTECT,0x80); //开写保护flag=0; //时间修改完毕,允许液晶从DS1302读数据TR0=1;break;}}}if(num!=0){if(key1==0)//确认增大键按下{delay(20);if(key1==0)//增大键确实按下{while(!key1);switch(num){case 1: year++;//调节年if(year==100)year=0;LCD_WRITE_NYR(3,year);//将调节后的年送入液晶显示LCD_WRITE_COM(0x80+3);//光标回到指定处break;case 2: month++;//调节月if(month==13)month=0;LCD_WRITE_NYR(6,month);//将调节后的月送入液晶显示LCD_WRITE_COM(0x80+6);//光标回到指定处break;case 3: day++;//调节日if(day==32)day=0;LCD_WRITE_NYR(9,day);//将调节后的日送入液晶显示LCD_WRITE_COM(0x80+9);//光标回到指定处break;case 4: week++;if(week==8)week=0;LCD_WRITE_WEEK(week);//将调节后的星期送入液晶显示LCD_WRITE_COM(0x80+12);//光标回到指定处break;case 5: hour++;if(hour==24)hour=0;LCD_WRITE_SFM(4,hour);//将调节后的小时送入液晶显示LCD_WRITE_COM(0x80+0x40+4);//光标回到指定处break;case 6: minute++;if(minute==60)minute=0;LCD_WRITE_SFM(7,minute);//将调节后的分送入液晶显示LCD_WRITE_COM(0x80+0x40+7);//光标回到指定处break;case 7: second++;if(second==60)second=0;LCD_WRITE_SFM(10,second);//将调节后的秒送入液晶显示LCD_WRITE_COM(0x80+0x40+10);//光标回到指定处break;default:break;}}}if(key2==0)//确认减小键按下{delay(20);if(key2==0)//减小键确实按下{while(!key2);switch(num){case 1: year--;//调节年if(year==-1)year=99;LCD_WRITE_NYR(3,year);LCD_WRITE_COM(0x80+3);break;case 2: month--;//调节月if(month==-1)month=12;LCD_WRITE_NYR(6,month);LCD_WRITE_COM(0x80+6);break;case 3: day--;//调节日if(day==-1)day=31;LCD_WRITE_NYR(9,day);LCD_WRITE_COM(0x80+9);break;case 4: week--;//调节星期if(week==0)week=7;LCD_WRITE_WEEK(week);LCD_WRITE_COM(0x80+12);break;case 5: hour--;//调节时if(hour==-1)hour=23;LCD_WRITE_SFM(4,hour);LCD_WRITE_COM(0x80+0x40+4);break;case 6: minute--;//调节分if(minute==-1)minute=59;LCD_WRITE_SFM(7,minute);LCD_WRITE_COM(0x80+0x40+7);break;case 7: second--;//调节秒if(second==-1)second=59;LCD_WRITE_SFM(10,second);LCD_WRITE_COM(0x80+0x40+10);break;default:break;}}}}}/*******************************蜂鸣器部分******************************************//*-----------定时器0初始化-------------------------*/void INITIAL_TEMER0(){TMOD=0x01;TH0=(65536-20000)/256;TL0=(65536-20000)%256; //晶振频率12MHZ 定时20ms作右TR0=1;EA=1;ET0=1;}/*-------------------------------------------*/void timer0()interrupt 1{TH0=(65536-20000)/256;TL0=(65536-20000)%256; //重装count++;if(count==50) //1秒到{count=0;beep=0; //蜂鸣器响delay(5);beep=1; //蜂鸣器灭}if(tem>=30){beep=0;}}/*****************************18b20部分*********************************************888*/void delay3(uint us){uint s;for(s=0;s<us;s++);}uchar resert(void){uchar ready;DQ=0;delay3(32) ;DQ=1;delay3(3);ready=DQ;delay3(25);return ready;}uchar read_byte(){uchar i,j;uchar value=0;for(i=0;i<8;i++){DQ=0;DQ=1;for(j=0;j<3;j++);if(DQ){value|=0x01<<i;}delay3(6) ;}return value;}void write_byte(uchar val) {uchar i,temp;for(i=0;i<8;i++){temp=val>>i;temp=temp&0x01;DQ=0;if(temp==1)DQ=1;delay3(5);DQ=1;}DQ=1;}uint get_temp(){float f_temp;uint temp;P2=0x00;resert();delay3(50);write_byte(0xcc);write_byte(0x44);resert();write_byte(0xcc);write_byte(0xbe);TMPL = read_byte();TMPH = read_byte();temp = TMPH;temp <<= 8;TMPL=TMPL&0xf0;temp = temp | TMPL;f_temp=temp*0.0625;temp=f_temp;return temp;}。
51单片机 12864 st7920液晶 DS1302 DS18B20 万年历 显示出了温度值 温度符号时间

st7920显示驱动、ds1302驱动、ds18b20驱动 显示时间,温度
******************************************************************************/
sbit a3 = ACC ^ 3;
sbit a4 = ACC ^ 4;
sbit a5 = ACC ^ 5;
sbit a6 = ACC ^ 6;
sbit a7 = ACC ^ 7;
bit flag, Bell_Swh,Hourb,Minb,Kgb;//闹钟调时闪烁标志位
0x3C,0x0F,0x00,0x64,0x01,0xFF,0xF0,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
0x3F,0x1F,0x00,0x60,0x0F,0xFF,0xFC,0x00,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x7E,0x01,0x81,0xF8,0x00,0x0F,0x01,0xE0,0x00,0x00,0x00,0x00,0x01,0xE6,0x00,
0x00,0x0E,0x03,0x43,0xEF,0xFC,0x0F,0x80,0xC0,0x00,0x00,0x00,0x00,0x03,0x7F,0x00,
bit sec=0,min=0,hour=0,year=0,mon=0,day=0,weekk=0; //闪烁标志位
unsigned char id;
DS1302可调时钟+DS18B20温度数码管切换显示

DS1302可调时钟+DS18B20温度数码管切换显示(2013-01-04 15:30:28)转载▼标签:校园#include#include#define uchar unsigned char#define uint unsigned int#define Write_Protect 0x8e //写保护#define OutPut P2 //显示输出sbit DQ=P1^7; //ds18b20单总线定义为P1.7sbit Beep=P3^2; //蜂鸣器输出端定义为P3.2sbit RST=P1^2; //复位端口定义在P1.2引脚sbit IO=P1^1; //数据输出端定义在P1.1引脚sbit SCLK=P1^0; //时钟输出端口定义在P1.0引脚sbit key=P1^3; //时间调节控制键sbit key1=P1^5; //每按一次位加一sbit key2=P1^4; //每按一次位减一sbit key3=P1^6; //显示切换uchar data disdata[5];uint tvalue;//温度值uchar tflag;//温度正负标志uchar code Wei[]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01}; //位选数据uchar code Duan[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //0--9共阴代码code uchar Waddr[]={0x80,0x82,0x84,0x86,0x88,0x8c,0x8a};code uchar Raddr[]={0x81,0x83,0x85,0x87,0x89,0x8d,0x8b};uchar timeset[]={0x01,0x02,0x03,0x04,0x05,0x00,0x01};uchar time_buf[7];uchar time_disp[7];uchar dispdat[8];uchar Btdis=0,k=0,z;bit btx,btx1,btx2,btx3,bt1,bt2,bt3;bit Btread;void ex_model(); //显示模式切换void delaynms(uchar n){uchar i,j;for(i=n;i>0;i--)for(j=125;j>0;j--);}void Ds1302_Write_Byte(unsigned char addr, unsigned char d){unsigned char i;RST=1;//写入目标地址:addraddr = addr & 0xFE; //最低位置零for (i = 0; i < 8; i++){if (addr & 0x01){IO=1;}else{IO=0;}SCLK=1;SCLK=0;addr = addr >> 1; }//写入数据:dfor (i = 0; i < 8; i++){if (d & 0x01){IO=1;}else{IO=0;}SCLK=1;SCLK=0;d = d >> 1;}RST=0; //停止DS1302总线}uchar Ds1302_Read_Byte(unsigned char addr){unsigned char i;unsigned char temp;RST=1;//写入目标地址:addraddr = addr | 0x01; //最低位置高for (i = 0; i < 8; i ++){if (addr & 0x01)IO=1;}else{IO=0;}SCLK=1;SCLK=0;addr = addr >> 1;}//输出数据:tempfor (i = 0; i < 8; i++){temp = temp >> 1;if (IO){temp |= 0x80;}else{temp &= 0x7F;SCLK=1;SCLK=0;}RST=0; //停止DS1302总线return temp;}void Write1302(uchar dat){uchar i;SCLK=0;for(i=0;i<8;i++){IO=dat&0x01;SCLK=1;SCLK=0;dat=dat>>1;}}uchar Readset1302(uchar Cmd){uchar dat;SCLK=0;RST=1;Write1302(Cmd);SCLK=1;RST=0;return dat;}void Ds1302_Write_Time(void){unsigned char i,tmp;uchar flag;flag=Readset1302(0x81);if(flag&0x80) //判断时钟芯片是否停止,为1时时钟停止{//掉电保存for(i=0;i<7;i++) //BCD 处理{tmp=timeset[i]/10;//timeset[]={0x01,0x02,0x03,0x04,0x05,0x06,0x01}time_buf[i]=timeset[i]; //time_buf[7]time_buf[i]=time_buf[i]+tmp*16;}Ds1302_Write_Byte(0x8e,0x00); //关闭写保护Ds1302_Write_Byte(Waddr[6],time_buf[6]); //周Ds1302_Write_Byte(Waddr[5],time_buf[0]); //年Ds1302_Write_Byte(Waddr[4],time_buf[1]); //月Ds1302_Write_Byte(Waddr[3],time_buf[2]); //日Ds1302_Write_Byte(Waddr[2],time_buf[3]); //时Ds1302_Write_Byte(Waddr[1],time_buf[4]); //分Ds1302_Write_Byte(Waddr[0],time_buf[5]); //秒Ds1302_Write_Byte(0x8e,0x80); //打开写保护}}void Ds1302_Read_Time(void){unsigned char i,tmp;// Ds1302_Write_Byte(0x8e,0x00); //关闭写保护time_buf[0]=Ds1302_Read_Byte(Raddr[5]); //年time_buf[1]=Ds1302_Read_Byte(Raddr[4]); //月time_buf[2]=Ds1302_Read_Byte(Raddr[3]); //日time_buf[3]=Ds1302_Read_Byte(Raddr[2]); //时time_buf[4]=Ds1302_Read_Byte(Raddr[1]); //分time_buf[5]=(Ds1302_Read_Byte(Raddr[0]))&0x7F; //秒time_buf[6]=Ds1302_Read_Byte(Raddr[6]); //周// Ds1302_Write_Byte(0x8e,0x80); //打开写保护for(i=0;i<8;i++) //BCD 处理{tmp=time_buf[i]/16;//time_buf[]={年,月,日,时,分,秒,周}time_buf[i]=time_buf[i];time_disp[i]=time_buf[i]+tmp*10;}}void Ds1302_Init(void){RST=0;//RST脚置低SCLK=0;//SCK脚置低Ds1302_Write_Byte(0x80,0x00);}void display(){uchar i;if(Btdis==0){if(bt2==0){dispdat[0]=Duan[time_disp[3]/10]; //时dispdat[1]=Duan[time_disp[3]];}else{dispdat[0]=0xff;dispdat[1]=0xff;}dispdat[2]=0xbf; //"-"if(bt3==0){dispdat[3]=Duan[time_disp[4]/10]; //分dispdat[4]=Duan[time_disp[4]];}else{dispdat[3]=0xff;dispdat[4]=0xff;}dispdat[5]=0xbf;dispdat[6]=Duan[time_disp[5]/10]; //秒dispdat[7]=Duan[time_disp[5]];}if(Btdis==1){if(bt1==0){dispdat[0]=Duan[time_disp[0]/10]; //年dispdat[1]=Duan[time_disp[0]];}else{dispdat[0]=0xff;dispdat[1]=0xff;}dispdat[2]=0xbf; //"-"if(bt2==0){dispdat[3]=Duan[time_disp[1]/10]; //月dispdat[4]=Duan[time_disp[1]];}else{dispdat[3]=0xff;dispdat[4]=0xff;}dispdat[5]=0xbf;if(bt3==0){dispdat[6]=Duan[time_disp[2]/10]; //日dispdat[7]=Duan[time_disp[2]];}else{dispdat[6]=0xff;dispdat[7]=0xff;}}if(Btdis==2){dispdat[0]=0xff;if(bt1==0){dispdat[1]=Duan[time_disp[6]]; //周}else{dispdat[1]=0xff;}dispdat[2]=0xbf; //"-" dispdat[3]=0xbf;dispdat[4]=0xbf;dispdat[5]=0xbf;dispdat[6]=Duan[time_disp[5]/10];dispdat[7]=Duan[time_disp[5]];}if(Btdis==3){ds1820disp();}for(i=0;i<8;i++){P0=dispdat[i];OutPut=Wei[i]; //Wei[]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01}delaynms(1);P0=0xff;}}void baoshi(){ uchar i;if(((time_disp[4])==59)&&((time_disp[5])>=55)&&((time_disp[5])<=60))//分和秒的报时条件{for(i=0;i<8;i++) //小灯轮流点亮,蜂鸣器发出滴答声{P3=Duan[i];delaynms(300);}}elseP3=0xdb;}void keyscan(){display();if(!key){if(btx==0){if(!key){btx=1;k++;}while(k==1){Btdis=1;display();if(!key){if(btx==0){if(!key){btx=1;k++;}}}else{btx=0;}if(!key1){if(btx1==0){if(!key1){btx1=1;if(time_disp[0]<99){time_disp[0]++;}else{time_disp[0]=0;}}}}else{btx1=0;}if(!key2){if(btx2==0){if(!key2){btx2=1;if(time_disp[0]>0){time_disp[0]--;}else{time_disp[0]=99;}}}}else{btx2=0;}}while(k==2){Btdis=1;display();if(!key){if(btx==0){if(!key){btx=1;k++;}}}else{btx=0;}if(!key1){if(btx1==0){if(!key1){btx1=1;if(time_disp[1]<12){time_disp[1]++;if(time_disp[1]==2){if(time_disp[0]%4==0){if(time_disp[2]>29){time_disp[2]=29;}}else if(time_disp[2]>28){time_disp[2]=28;}}}else{time_disp[1]=1;}}}}else{btx1=0;}if(!key2){if(btx2==0){if(!key2){btx2=1;if(time_disp[1]>1){time_disp[1]--;if(time_disp[1]==2){if(time_disp[0]%4==0){if(time_disp[2]>29){time_disp[2]=29;}}else if(time_disp[2]>28){time_disp[2]=28;}}}else{time_disp[1]=12;}}}}else{btx2=0;}}while(k==3){Btdis=1;display();if(!key){if(btx==0){if(!key){btx=1;k++;}}}else{btx=0;}if(!key1){if(btx1==0){if(!key1){btx1=1;if(time_disp[1]==2){if(time_disp[0]%4==0){if(time_disp[2]<29){time_disp[2]++;}else{time_disp[2]=1;}}else if(time_disp[2]<28){time_disp[2]++;}else{time_disp[2]=1;}}else if(time_disp[1]<8){if(time_disp[1]%2==0) //小于8月的月份除以2的余数为0则为小月{if(time_disp[2]<30){time_disp[2]++;}else{time_disp[2]=1;}}else if(time_disp[1]%2==1) //小于8月的月份除以2的余数为1则为大月{if(time_disp[2]<31){time_disp[2]++;}else{time_disp[2]=1;}}}else if(time_disp[1]>7){if(time_disp[1]%2==0){if(time_disp[2]<31){time_disp[2]++;}else{time_disp[2]=1;}}else if(time_disp[1]%2==1){if(time_disp[2]<30){time_disp[2]++;}else{time_disp[2]=1;}}}}}}else{btx1=0;}if(!key2){if(btx2==0){if(!key2){btx2=1;if(time_disp[1]==2){if(time_disp[0]%4==0){if(time_disp[2]>1){time_disp[2]--;}{time_disp[2]=29;}}else if(time_disp[2]>1){time_disp[2]--;}else{time_disp[2]=28;}}else if(time_disp[1]<8){if(time_disp[1]%2==0){if(time_disp[2]>1){time_disp[2]--;}{time_disp[2]=30;}}else if(time_disp[1]%2==1){if(time_disp[2]>1){time_disp[2]--;}else{time_disp[2]=31;}}}else if(time_disp[1]>7){if(time_disp[1]%2==0){if(time_disp[2]>1)time_disp[2]--;}else{time_disp[2]=31;}}else if(time_disp[1]%2==1){if(time_disp[2]>1){time_disp[2]--;}else{time_disp[2]=30;}}}}}else{btx2=0;}}while(k==4){Btdis=2;display();if(!key){if(btx==0){if(!key){btx=1;k++;}}}{btx=0;}if(!key1){if(btx1==0){if(!key1){btx1=1;if(time_disp[6]<7){time_disp[6]++;}else{time_disp[6]=1;}}}else{btx1=0;}if(!key2){if(btx2==0){if(!key2){btx2=1;if(time_disp[6]>1){time_disp[6]--;}else{time_disp[6]=7;}}}}else{btx2=0;}}while(k==5){Btdis=0;display();if(!key){if(btx==0){if(!key){btx=1;k++;}}}{btx=0;}if(!key1){if(btx1==0){if(!key1){btx1=1;if(time_disp[3]<23){time_disp[3]++;}else{time_disp[3]=0;}}}else{btx1=0;}if(!key2){if(btx2==0){if(!key2){btx2=1;if(time_disp[3]>0){time_disp[3]--;}else{time_disp[3]=23;}}}}else{btx2=0;}}while(k==6){Btdis=0;display();if(!key){if(btx==0){if(!key){btx=1;k++;}}}{btx=0;}if(!key1){if(btx1==0){if(!key1){btx1=1;if(time_disp[4]<59){time_disp[4]++;}else{time_disp[4]=0;}}}else{btx1=0;}if(!key2){if(btx2==0){if(!key2){btx2=1;if(time_disp[4]>0){time_disp[4]--;}else{time_disp[4]=59;}}}}else{btx2=0;}}while(k==7){uchar tmp;uchar i;for(i=0;i<7;i++){timeset[i]=time_disp[i];}//将调整后的时候写入DS1302for(i=0;i<7;i++) //BCD 处理{tmp=timeset[i]/10;//timeset[]={0x01,0x02,0x03,0x04,0x05,0x06,0x01}time_buf[i]=timeset[i]; //time_buf[7]time_buf[i]=time_buf[i]+tmp*16;}Ds1302_Write_Byte(0x8e,0x00); //关闭写保护Ds1302_Write_Byte(Waddr[6],time_buf[6]); //周Ds1302_Write_Byte(Waddr[5],time_buf[0]); //年Ds1302_Write_Byte(Waddr[4],time_buf[1]); //月Ds1302_Write_Byte(Waddr[3],time_buf[2]); //日Ds1302_Write_Byte(Waddr[2],time_buf[3]); //时Ds1302_Write_Byte(Waddr[1],time_buf[4]); //分Ds1302_Write_Byte(Waddr[0],time_buf[5]); //秒Ds1302_Write_Byte(0x8e,0x80); //打开写保护k=0;}}else{btx=0;}if(!key3){if(btx3==0){if(!key3){btx3=1;if(Btdis<3){Btdis++;}else{Btdis=0;}}}}else{btx3=0;}}void ex_model(){if(((time_disp[5])>=0)&&((time_disp[5])<=8)) //前八秒显示温度Btdis=3;if(((time_disp[5])>=9)&&((time_disp[5])<=12)) //显示周Btdis=2;if(((time_disp[5])>=13)&&((time_disp[5])<=18)) //显示年Btdis=1;if(((time_disp[5])>=19)&&((time_disp[5])<=59)) //显示当前时间Btdis=0;}void tiaoshidisplay(){if(z==15){z=0;switch(k){case 1:bt1=~bt1;P3=~P3;break; //年case 2:bt2=~bt2;bt1=0;P3=~P3;break; //月case 3:bt3=~bt3;bt2=0;P3=~P3;break; //日case 4:bt1=~bt1;bt3=0;P3=~P3;break; //周case 5:bt2=~bt2;bt1=0;P3=~P3;break; //时case 6:bt3=~bt3;bt2=0;P3=~P3;break; //分default:bt3=0;break;}}}void delay_18B20(unsigned int i)//延时1微秒{while(i--);}void ds1820rst(){ unsigned char x=0;DQ = 1; //DQ复位delay_18B20(4); //延时DQ = 0; //DQ拉低delay_18B20(100); //精确延时大于480usDQ = 1; //拉高delay_18B20(40);}uchar ds1820rd(){ unsigned char i=0;unsigned char dat = 0;for (i=8;i>0;i--){ DQ = 0; //给脉冲信号dat>>=1;DQ = 1; //给脉冲信号if(DQ)dat|=0x80;delay_18B20(10);}return(dat);}void ds1820wr(uchar wdata){unsigned char i=0;for (i=8; i>0; i--) { DQ = 0;DQ = wdata&0x01;delay_18B20(10);DQ = 1;wdata>>=1;}}read_temp(){uchar a,b;ds1820rst();ds1820wr(0xcc);/ds1820wr(0x44);/ds1820rst();ds1820wr(0xcc);/ds1820wr(0xbe);/a=ds1820rd();。
51单片机课程设计(DS1302时钟、18B20温度计)

摘要: 该设计实现了24小时制的时间显示及设定、年月日星期的显示及设定、闹钟的设定、温度的检测及显示等功能。
设计共分为四大部分,分别是控制部分、时钟部分、温度检测部分和人机交互部分。
以单片机(A T89C51)组成的最小系统为整个设计的控制核心,单片机通过对时钟芯片(DS1302)的控制完成时钟的功能,通过对温度传感器(18B20)的控制完成温度检测的功能,最后通过对数码管、蜂鸣器及按键的控制完成时间和温度的显示以及调整时间、设定闹钟等功能。
时间和温度的显示以及调整时间、设定闹钟等功能。
关键词:电子钟;温度计;单片机关键词:电子钟;温度计;单片机目录目录摘要: ......................................................................................................................1 第一章 设计任务设计任务设计任务 ...................................................................................................3 第二章 电路设计电路设计电路设计 ...................................................................................................3 2.1电路方案的比较 . (3)2.2根据设计绘制框图及原理图根据设计绘制框图及原理图.........................................................................5 第三章 工作原理工作原理工作原理 ...................................................................................................7 3.1 单片机的工作原理. (7)3.2 DS18B20的工作原理 (8)3.3DS1302的工作原理 (10)3.4数码管的工作原理 (12)第四章 调试与验证调试与验证 (12)4.1程序调试 (12)4.2仿真验证 (15)参考文献 (15)附录附录.....................................................................................................................16 附录一附录一 使用说明使用说明..............................................................................................16 附录二附录二 元件清单元件清单..............................................................................................16 附录三 pcb 版图版图...............................................................................................17 附录四附录四 程序清单程序清单 (18)第一章设计设计任务1、基本要求、基本要求)能够实现时间的正确显示,并且可以对表进行调整。
玩转DS1302和DS18B20

对于市面上的大多数51单片机开发板来说。
ds1302和ds18b20应该是比较常见的两种外围芯片。
ds130 2是具有SPI总线接口的时钟芯片。
ds18b20则是具有单总线接口的数字温度传感器。
下面让我们分别来认识并学会应用这两种芯片。
首先依旧是看DS1302的datasheet中的相关介绍。
上面是它的一些基本的应用介绍。
下面是它的引脚的描述。
下面是DS1302的时钟寄存器。
我们要读取的时间数据就是从下面这些数据寄存器中读取出来的。
当我们要想调整时间时,可以把时间数据写入到相应的寄存器中就可以了。
这是DS1302内部的31个RAM寄存器。
在某些应用场合我们可以应用到。
如我们想要做一个带定时功能的闹钟。
则可以把闹钟的时间写入到31个RAM寄存器中的任意几个。
当单片机掉电时,只要我们的DS 1302的备用电池还能工作,那么保存在其中的闹钟数据就不会丢失~~由于对于这些器件的操作基本上按照数据手册上面提供的时序图和相关命令字来进行操作就可以了。
因此在我们应用这些器件的时候一定要对照着手册上面的要求来进行操作。
如果觉得还不够放心的话。
可以到网上下载一些参考程序。
对着手册看别人的程序,看别人的思路是怎么样的。
DS1302和单片机的连接很简单。
只需一根复位线,一根时钟线,一根数据线即可。
同时它本身还需要接一个32.768KHz的晶振来提供时钟源。
对于晶振的两端可以分别接一个6PF左右的电容以提高晶振的精确度。
同时可以在第8脚接上一个3.6V的可充电的电池。
当系统正常工作时可以对电池进行涓流充电。
当系统掉电时,DS1302由这个电池提供的能量继续工作。
下面让我们来驱动它。
sbit io_DS1302_RST = P2^0 ;sbit io_DS1302_IO = P2^1 ;sbit io_DS1302_SCLK = P2^2 ;//-------------------------------------常数宏---------------------------------//#define DS1302_SECOND_WRITE 0x80 //写时钟芯片的寄存器位置#define DS1302_MINUTE_WRITE 0x82#define DS1302_HOUR_WRITE 0x84#define DS1302_WEEK_WRITE 0x8A#define DS1302_DAY_WRITE 0x86#define DS1302_MONTH_WRITE 0x88#define DS1302_YEAR_WRITE 0x8C#define DS1302_SECOND_READ 0x81 //读时钟芯片的寄存器位置#define DS1302_MINUTE_READ 0x83#define DS1302_HOUR_READ 0x85#define DS1302_WEEK_READ 0x8B#define DS1302_DAY_READ 0x87#define DS1302_MONTH_READ 0x89#define DS1302_YEAR_READ 0x8D//-----------------------------------操作宏----------------------------------//#define DS1302_SCLK_HIGH io_DS1302_SCLK = 1 ;#define DS1302_SCLK_LOW io_DS1302_SCLK = 0 ;#define DS1302_IO_HIGH io_DS1302_IO = 1 ;#define DS1302_IO_LOW io_DS1302_IO = 0 ;#define DS1302_IO_READ io_DS1302_IO#define DS1302_RST_HIGH io_DS1302_RST = 1 ;#define DS1302_RST_LOW io_DS1302_RST = 0 ;/******************************************************* 保存时间数据的结构体*******************************************************/struct{uint8 Second ;uint8 Minute ;uint8 Hour ;uint8 Day ;uint8 Week ;uint8 Month ;uint8 Year ;}CurrentTime ;/****************************************************************************** * Function: static void v_DS1302Write_f( uint8 Content ) * * Description:向DS1302写一个字节的内容** Parameter:uint8 Content : 要写的字节** *******************************************************************************/static void v_DS1302Write_f( uint8 Content ){uint8 i ;for( i = 8 ; i > 0 ; i-- ){if( Content & 0x01 ){DS1302_IO_HIGH}else{DS1302_IO_LOW}Content >>= 1 ;DS1302_SCLK_HIGHDS1302_SCLK_LOW}}/****************************************************************************** * Function: static uint8 v_DS1302Read_f( void ) ** Description: 从DS1302当前设定的地址读取一个字节的内容* * Parameter: ** Return: 返回读出来的值(uint8) *******************************************************************************/ static uint8 v_DS1302Read_f( void ){uint8 i, ReadValue ;DS1302_IO_HIGHfor( i = 8 ; i > 0 ; i-- ){ReadValue >>= 1 ;if( DS1302_IO_READ ){ReadValue |= 0x80 ;}else{ReadValue &= 0x7f ;}DS1302_SCLK_HIGHDS1302_SCLK_LOW}return ReadValue ;}/******************************************************************************* Function: void v_DS1302WriteByte_f( uint8 Address, uint8 Content ) ** Description: 从DS1302指定的地址写入一个字节的内容** Parameter: Address: 要写入数据的地址** Content: 写入数据的具体值** Return: * ******************************************************************************/void v_DS1302WriteByte_f( uint8 Address, uint8 Content ){DS1302_RST_LOWDS1302_SCLK_LOWDS1302_RST_HIGHv_DS1302Write_f( Address ) ;v_DS1302Write_f( Content ) ;DS1302_RST_LOWDS1302_SCLK_HIGH}/******************************************************************************* Function: uint8 v_DS1302ReadByte_f( uint8 Address ) ** Description:从DS1302指定的地址读出一个字节的内容** Parameter:Address: 要读出数据的地址** ** Return: 指定地址读出的值(uint8) *******************************************************************************/uint8 v_DS1302ReadByte_f( uint8 Address ){uint8 ReadValue ;DS1302_RST_LOWDS1302_SCLK_LOWDS1302_RST_HIGHv_DS1302Write_f( Address ) ;ReadValue = v_DS1302Read_f() ;DS1302_RST_LOWDS1302_SCLK_HIGHreturn ReadValue ;}/******************************************************************************* Function: void v_ClockInit_f( void ) ** Description:初始化写入DS1302时钟寄存器的值(主程序中只需调用一次即可) * * Parameter:** ** Return: *******************************************************************************/void v_ClockInit_f( void ){if( v_DS1302ReadByte_f( 0xc1) != 0xf0 ){v_DS1302WriteByte_f( 0x8e, 0x00 ) ; //允许写操作v_DS1302WriteByte_f( DS1302_YEAR_WRITE, 0x08 ) ; //年v_DS1302WriteByte_f( DS1302_WEEK_WRITE, 0x04 ) ; //星期v_DS1302WriteByte_f( DS1302_MONTH_WRITE, 0x12 ) ; //月v_DS1302WriteByte_f( DS1302_DAY_WRITE, 0x11 ) ; //日v_DS1302WriteByte_f( DS1302_HOUR_WRITE, 0x13 ) ; //小时v_DS1302WriteByte_f( DS1302_MINUTE_WRITE, 0x06 ) ; //分钟v_DS1302WriteByte_f( DS1302_SECOND_WRITE, 0x40 ) ; //秒v_DS1302WriteByte_f( 0x90, 0xa5 ) ; //充电v_DS1302WriteByte_f( 0xc0, 0xf0 ) ; //判断是否初始化一次标识写入v_DS1302WriteByte_f( 0x8e, 0x80 ) ; //禁止写操作}}/******************************************************************************* Function: void v_ClockUpdata_f( void ) ** Description:读取时间数据,并保存在结构体CurrentTime中** Parameter:** ** Return:*******************************************************************************/void v_ClockUpdata_f( void ){CurrentTime.Second = v_DS1302ReadByte_f( DS1302_SECOND_READ ) ;CurrentTime.Minute = v_DS1302ReadByte_f( DS1302_MINUTE_READ ) ;CurrentTime.Hour = v_DS1302ReadByte_f( DS1302_HOUR_READ ) ;CurrentTime.Day = v_DS1302ReadByte_f( DS1302_DAY_READ ) ;CurrentTime.Month = v_DS1302ReadByte_f( DS1302_MONTH_READ ) ;CurrentTime.Week = v_DS1302ReadByte_f( DS1302_WEEK_READ ) ;CurrentTime.Year = v_DS1302ReadByte_f( DS1302_YEAR_READ ) ;}有了上面的这些函数我们就可以对DS1302进行操作了。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
时钟电路图:PCB板:单片机程序:/*========================================================= ===========调试要求::AT89S52芯片或AT89C522.晶振:12MHz功能:多功能时钟+温度计====================================================================*/#include<>#include<>#define uchar unsigned char#define uint unsigned intsbit dis_bit1=P2^7;振:12MHz功能:多功能时钟+温度计=========================================================== =========*/#include<>#include<>#define uchar unsigned char#define uint unsigned intsbit dis_bit1=P2^7;//定义数码管控制口sbit dis_bit2=P2^6;//定义数码管控制口sbit dis_bit3=P2^4;//定义数码管控制口sbit dis_bit4=P2^3;//定义数码管控制口sbit dis_bit5=P2^1;//定义数码管控制口sbit dis_bit6=P2^0;//定义数码管控制口sbit led1_bit=P2^2;//定时LED的控制口sbit led2_bit=P2^5;//定时LED的控制口sbit s1_bit=P1^0; //定义S1控制口sbit s2_bit=P1^1; //定义S2控制口sbit s3_bit=P1^2; //定义S3控制口sbit dq_ds18b20=P3^3;//定义控制DS18B20sbit speak=P3^7; //定义蜂鸣器控制口sbit clk_ds1302=P3^6;//定义控制DS1302的时钟线sbit io_ds1302=P3^5;//定义控制DS1302的串行数据sbit rest_ds1302=P3^4;#define smg_data P0//定义数码管数据口void delay_3us();//3US的延时程序void delay_8us(uint t);//8US延时基准程序void delay_50us(uint t);//延时50*T微妙函数的声明void display1(uchar dis_data);//数码管1显示子程序void display2(uchar dis_data);//数码管2显示子程序void display3(uchar dis_data);//数码管3显示子程序void display4(uchar dis_data);//数码管4显示子程序void display5(uchar dis_data);//数码管5显示子程序void display6(uchar dis_data);//数码管6显示子程序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_san(uchar s6,uchar s5,uchar s4,uchar s3,uchar s2,uchar s1,uchar san);//闪烁显示子程序void judge_dis();//显示处理函数void judge_clock();//显示处理函数void set_ds1302();//设置时间void get_ds1302();//读取当前时间void w_1byte_ds1302(uchar t);//向DS1302写一个字节的数据uchar r_1byte_ds1302();//从DS1302读一个字节的数据//********************************************************* **************//DS18B20测温函数定义void w_1byte_ds18b20(uchar value);//向DS18B20写一个字节uchar r_1byte_ds18b20(void);//从DS18B20读取一个字节的数据void rest_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_count,minute_count,second_count,msecond_count; uchar clock_hour,clock_minute;uchar countdown_second;uchar countdown_hour,countdown_minute;uchar clock_en;//闹钟关闭和开启的标志,1开启,0关闭uchar flag1,second_flag,zancun1,zancun2,zancun3;uchar zancun4,zancun5,zancun6,zancun7;uchar clock_flag,countdown_flag;ucharmsecond_minute,msecond_second,msecond_msecond,msecond_flag; //秒表相关参数uint speak_count;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;//置秒表相关参数为0 msecond_second=0;msecond_msecond=0;speak=1;//关闭蜂鸣器speak_count=0;clock_hour=0;clock_minute=0;clock_flag=0;countdown_flag=0;//倒计时标志位为0clock_en=0;//开机时默认关闭闹钟init_t0();TR0=1;//// set_ds1302();//设置DS1302的初始时间//接下来开始编写让数码管显示的程序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)// 秒{t0_crycle=0;msecond_flag=1;msecond_count++;if(msecond_count==10)//1秒{msecond_count=0;second_flag=1;}}}//************************************************** //显示处理函数void judge_dis(){if(flag1==0){if(second_flag==1){zancun7++;second_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=second_count&0xf0;zancun6>>=4;dis(zancun4,hour_count&0x0f,zancun5,minute_count&0x0f,zancu n6,second_count&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,zancun1%10,zancun2/10,zancun2%10,12,12,1);break;case 7:dis_san(zancun1/10,zancun1%10,zancun2/10,zancun2%10,12,12,2 );break;case 8:dis_san(zancun1/10,zancun1%10,zancun2/10,zancun2%10,12,12,3 );break;case 9://进入修改时间,时间分位个位闪烁dis_san(zancun1/10,zancun1%10,zancun2/10,zancun2%10,12,12,4 );break;case 10://进入修改闹钟,闹钟小时十位闪烁dis_san(zancun1/10,zancun1%10,zancun2/10,zancun2%10,12,zanc un3,1);break;case 11://进入修改闹钟,闹钟小时个位闪烁dis_san(zancun1/10,zancun1%10,zancun2/10,zancun2%10,12,zanc un3,2);break;case 12://进入修改闹钟,闹钟小时十位闪烁dis_san(zancun1/10,zancun1%10,zancun2/10,zancun2%10,12,zanc un3,3);break;case 13://进入修改闹钟,闹钟小时个位闪烁dis_san(zancun1/10,zancun1%10,zancun2/10,zancun2%10,12,zancun3,4);break;case 14://进入修改闹钟的开关dis_san(zancun1/10,zancun1%10,zancun2/10,zancun2%10,12,zanc un3,6);break;case 15:dis_san(zancun1/10,zancun1%10,zancun2/10,zancun2%10,zancun3 /10,zancun3%10,1);break;case 16:dis_san(zancun1/10,zancun1%10,zancun2/10,zancun2%10,zancun3 /10,zancun3%10,2);break;case 17:dis_san(zancun1/10,zancun1%10,zancun2/10,zancun2%10,zancun3 /10,zancun3%10,3);break;case 18:dis_san(zancun1/10,zancun1%10,zancun2/10,zancun2%10,zancun3 /10,zancun3%10,4);break;case 19:dis_san(zancun1/10,zancun1%10,zancun2/10,zancun2%10,zancun3 /10,zancun3%10,5);break;case 20:dis_san(zancun1/10,zancun1%10,zancun2/10,zancun2%10,zancun3/10,zancun3%10,6);break;case 21:if(second_flag==1){second_flag=0;countdown_second--;if(countdown_second==255){countdown_second=59;countdown_minute--;if(countdown_minute==255){countdown_minute=59; countdown_hour--;if(countdown_hour==255){flag1=22;countdown_minute=0;countdown_hour=0;countdown_second=0;countdown_flag=1;}}}}dis(countdown_hour/10,countdown_hour%10,countdown_minute/10 ,countdown_minute%10,countdown_second/10,countdown_second%1 0);//break;case 22:if(countdown_flag>0 && countdown_flag<7){speak=0;if(second_flag==1){second_flag=0;countdown_flag++;}}else{speak=1;}dis(countdown_hour/10,countdown_hour%10,countdown_minute/10,countdown_minute%10,countdown_second/10,countdown_second%1 0);//break;case 23:dis(msecond_minute/10,msecond_minute%10,msecond_second/10,m second_second%10,msecond_msecond%10,12);break;case 24:if(msecond_flag==1){msecond_flag=0;msecond_msecond++;if(msecond_msecond==10){msecond_msecond=0;msecond_second++;if(msecond_second==60){msecond_second=0;msecond_minute++;if(msecond_minute==100){msecond_minute=99;flag1=23;}}}}dis(msecond_minute/10,msecond_minute%10,msecond_second/10,m second_second%10,msecond_msecond%10,12);break;case 25:dis(zancun3/10,zancun3%10,zancun2/10,zancun2%10,zancun1/10, zancun1%10);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)//判断是否有按键按下{delay_50us(1);// 延时,去除机械抖动if(s2_bit==0){switch (flag1){case1: //在显示SET1状态下按S2件,进入修改时间 flag1=6;zancun4=hour_count&0xf0;zancun4>>=4;zancun6=hour_count&0x0f;zancun1=zancun4*10+zancun6;//zancun1=hour_count;zancun5=minute_count&0xf0;zancun5>>=4;zancun6=minute_count&0x0f;zancun2=zancun5*10+zancun6;// zancun2=minute_count;break;case 2://在显示SET2状态下按S2,进入设置闹钟 zancun1=clock_hour;zancun2=clock_minute;flag1=10;break;case 6://修改时钟小时十位状态下按S2件case 7://修改时钟小时个位状态下按S2件case 8://修改时钟分钟十位状态下按S2件case 9://修改时钟分钟个位状态下按S2件//zancun4=zancun1/10;tab23[2]=zancun1/10*16+zancun1%10;//zancun5=zancun2&0xf0;//zancun5>>=4;tab23[1]=zancun2/10*16+zancun2%10; hour_count=tab23[2];minute_count=tab23[1];second_count=0;tab23[0]=0;set_ds1302();//设置DS1302的初始时间 flag1=0;break;case 10://修改闹钟小时十位状态下按S2case 11://修改闹钟小时个位状态下按S2case 12://修改闹钟分钟十位状态下按S2case 13://修改闹钟分钟个位状态下按S2case 14://修改闹钟使能状态下按S2clock_hour=zancun1;clock_minute=zancun2;clock_en=zancun3;flag1=0;break;case 3:flag1=15;zancun1=countdown_hour; zancun2=countdown_minute; zancun3=countdown_second;break;case 15:case 16:case 17:case 18:case 19:case 20:countdown_hour=zancun1; countdown_minute=zancun2; countdown_second=zancun3; flag1=21;countdown_flag=0;break;case 22:flag1=21;break;case 21:flag1=22;break;case 4:flag1=23;//秒表暂停msecond_minute=0;msecond_second=0;msecond_msecond=0;break;case 23:flag1=24;break;case 24:flag1=23;break;case 5:flag1=25;//进入计数器模式 zancun1=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=zancun1%10;break;case 7://修改时间小时的个位数zancun1=zancun1/10*10+(zancun1%10+1)%10;break;case 8://修改时间分钟的十位数zancun2+=10;if(zancun2>=60)zancun2-=60;break;case 9://修改时间分钟的个位数zancun2=zancun2/10*10+(zancun2%10+1)%10;break;case 10://修改闹钟小时的十位数zancun1+=10;if(zancun1>=24)zancun1=zancun1%10;break;case 11://修改闹钟小时的个位数zancun1=zancun1/10*10+(zancun1%10+1)%10;break;case 12://修改闹钟分钟的十位数zancun2+=10;if(zancun2>=60)zancun2-=60;break;case 13://修改闹钟分钟的个位数zancun2=zancun2/10*10+(zancun2%10+1)%10;break;case 14:zancun3^=1;break;case 15://修改倒计时小时的十位数zancun1+=10;if(zancun1>=100)zancun1-=100;break;case 16: //修改倒计时小时的个位数zancun1=zancun1/10*10+(zancun1%10+1)%10;break;case 17://修改倒计时分钟的十位数zancun2+=10;if(zancun2>=60)zancun2-=60;break;case 18: //修改倒计时分钟的个位数zancun2=zancun2/10*10+(zancun2%10+1)%10;break;case 19://修改倒计时秒的十位数zancun3+=10;if(zancun3>=60)zancun3-=60;break;case 20: //修改倒计时秒的个位数zancun3=zancun3/10*10+(zancun3%10+1)%10;break;case 21:case 22://countdown_hour=zancun1;countdown_minute=zancun2;countdown_second=zancun3;flag1=21;break;case 23:case 24://秒表复位flag1=24;msecond_minute=0;msecond_second=0;msecond_msecond=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+=zancun6;zancun5=minute_count&0xf0;zancun5>>=4;zancun6=minute_count&0x0f;zancun5*=10;zancun5+=zancun6;if(clock_hour==zancun4 && clock_minute==zancun5) {if(clock_en==1 && clock_flag==0){speak_count=0;//开启蜂鸣器clock_flag=1;speak_count=0;}}else{clock_flag=0;}if(clock_flag==1 && speak_count<400){if(msecond_count<=5){speak=0;speak_count++;}else{speak=1;}}else{speak=1;}}//****************************************////闪烁显示子程序void dis_san(uchar s6,uchar s5,uchar s4,uchar s3,uchar s2,uchar s1,uchar san){if(san==1){if(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);}}elsedisplay3(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);。