51单片机可调时钟
基于51单片机的多功能电子钟设计
基于51单片机的多功能电子钟设计1. 本文概述随着现代科技的发展,电子时钟已成为日常生活中不可或缺的一部分。
本文旨在介绍一种基于51单片机的多功能电子钟的设计与实现。
51单片机因其结构简单、成本低廉、易于编程等特点,在工业控制和教学实验中得到了广泛应用。
本文将重点阐述如何利用51单片机的这些特性来设计和实现一个具有基本时间显示、闹钟设定、温度显示等功能的电子钟。
本文的结构安排如下:将详细介绍51单片机的基本原理和特点,为后续的设计提供理论基础。
接着,将分析电子钟的功能需求,包括时间显示、闹钟设定、温度显示等,并基于这些需求进行系统设计。
将详细讨论电子钟的硬件设计,包括51单片机的选型、时钟电路、显示电路、温度传感器电路等。
软件设计部分将介绍如何通过编程实现电子钟的各项功能,包括时间管理、闹钟控制、温度读取等。
本文将通过实验验证所设计的电子钟的功能和性能,并对实验结果进行分析讨论。
通过本文的研究,旨在为电子钟的设计提供一种实用、经济、可靠的方法,同时也为51单片机的应用提供一个新的实践案例。
2. 51单片机概述51单片机,作为一种经典的微控制器,因其高性能、低功耗和易编程的特性而被广泛应用于工业控制、智能仪器和家用电器等领域。
它基于Intel 8051微处理器的架构,具备基本的算术逻辑单元(ALU)、程序计数器(PC)、累加器(ACC)和寄存器组等核心部件。
51单片机的核心是其8位CPU,能够处理8位数据和执行相应的指令集。
51单片机的内部结构主要包括中央处理单元(CPU)、存储器、定时器计数器、并行IO口、串行通信口等。
其存储器分为程序存储器(ROM)和数据存储器(RAM)。
程序存储器通常用于存放程序代码,而数据存储器则用于存放运行中的数据和临时变量。
51单片机还包含特殊功能寄存器(SFR),用于控制IO端口、定时器计数器和串行通信等。
51单片机的工作原理基于冯诺伊曼体系结构,即程序指令和数据存储在同一块存储器中,通过总线系统进行传输。
DIY基于51单片机的旋转LED数字电子钟
标签:DIY基于51单片机的旋转LED数字电子钟(红外线遥控调时)在网上看到不少老外做的各种旋转LED显示屏,非常COOL,我也动手用洞洞板试做了一个类似的显示屏,结果感觉还不错。
于是再接再励继续努力,将作品进一步改进,完善后制成如今这个样子。
由于刚学51单片机,加上制作电路板软件也是从零开始,的确花了我不少的时间和精力。
不过也就是在这艰难的独立制作中,真正学到了不少实在的东西。
本项目的关键是如何解决高速旋转的电路板如何供电,如何调时的问题。
我采用电机电刷的原理,将旋转轴钻空,通过一只插头将电源的从反面引到前面的电路板上,而这个旋转的插头又与固定在背板上的两个铜片接触的。
调时的问题有些困难,一是让电路板在旋转前与PC机相接,由电脑传送调时数据,这虽然可行但不方便。
还有就是用遥控方法,但此方案在调试方面有很大的困难。
显示方式上,我采用平衡式的两排LED,这除了在旋转时能较好的保持平衡外,主要能利用两边交替显示方式,比单排要快一倍。
本装置不仅是一个时钟,它还可以动态显示汉字及图案,这就看如何发挥了。
其具体制作过程如下:一。
旋转电机的制作从制作成本与方便考虑,选用旧电脑用的大软驱上的直流无刷电机,只是对局部进行改造。
就是这种古董软驱软驱上的直流无刷电机拆开后的电机仔细拆开直流电机,将带圆盘的铝轴从中开孔,让它刚好能插入一个插头。
将旋转轴加工成这样装配好以后按拆开时的顺序,反序将轴安装直流电机上。
电机装配完成后用两片铜片做的电刷电刷装好后的侧面图将电路板上较突出的元件改焊在反面,电机的电源接法。
从电路板标注的符号看,“+”为电源正,“G”为电源负,“C”与“M”端分别与电源正相连匀可使电机运转将一张旧唱片按电机座的位置开孔,而定位用的挡光板应根据电路板上感光组件的位置确定。
二。
电路板的制作本制作品用51单片机控制,具体电原理图如下:用Protel 99设计制作了电路板。
最后得到完成的作品。
遥控器用的是松下车载机的,只用了其中的六个键。
基于-51单片机可调数字钟的设计
师学院单片机技术课程实践——基于89C51单片机可调数字钟的仿真设计班级::学号:辅导老师:设计时间:1. 设计目的1.1设计目的(1)掌握51系列部定时/计数器的原理和基本应用;(2)掌握使用单片机处理复杂逻辑的方法;(3)掌握多位数码管动态显示的方法;(4)掌握独立式(和矩阵)键盘的编程方法;(5)掌握利用汇编语言编写单片机系统的应用软件的方法;(6) 巩固,加深和扩大单片机应用的知识面,提高综合及灵活运用所学知识解决工业控制的能力;(7) 培养针对课题需要,选择和查阅有关手册,图表及文献资料的自学能力,提高组成系统,编程,调试的动手能力;(8) 熟悉单片机用系统开发,研制的过程,软硬件设计方法,容及步骤.(9) 了解数字钟的组成及工作原理.1.2设计性能(1)用51单片机的定时/计数器TMR0产生一秒的定时时间,作为秒计数时间;(2)当一秒产生时,秒计数加1;(3)开机时,显示00.00.00,并开始连续计时;(4)计时满23.29.59时,返回00.00.00重新开始计时;(5)在以上设计基础上,在单片机的I/O口上分别接入四个按键:K0—控制“秒”的调整,每按一次加1秒;K1—控制“分”的调整,每按一次加1分;K2—控制“时”的调整,每按一次加1小时;K3—时间复位按键。
2.系统电路的方案2.1实现时钟计时的基本方法用AT89C51单片机的定时/计数器T0产生一秒的定时时间,作为秒计数时间,当一秒产生时,秒计数加1开机时。
显示00-00-00的时间,开始计时;计时满23-59-59时,返回00-00-00重新计时AT89C51单片机的部16位定时/计数器是一个可编程定时/计数器,它既可以工作在13位定时方式,也可以工作在16位定时方式和8位定时方式。
只要通过设置特殊功能寄存器TMOD,即可完成。
定时/计数器何时工作也是通过TCON特殊功能寄存器来设置的。
在此设计中,选择16位定时工作方式。
用51单片机和1602编写的时钟,可调时
#include<reg52.h>#define uint unsigned int#define uchar unsigned charsbit rs=P1^0;sbit rw=P1^1;sbit lcden=P2^5;sbit dula=P2^6;sbit wela=P2^7;sbit k1=P3^0;sbit k2=P3^1;sbit k3=P3^2;sbit rd=P3^7;sbit beep=P2^3;uchar num1,num2,num3,num4,num0,num,numa,yue,ri; char shi,fen,miao,we;uint nian;uchar code table1[]=" 2013-05-06-MON ";uchar code table2[]=" 00-00-00 ";void delay(uint x){uint i,j;for(i=x;i>0;i--)for(j=110;j>0;j--);}void di(){beep=0;delay(100);beep=1;}void write_com(uchar com){rs=0;P0=com;delay(5);lcden=1;delay(5);lcden=0;delay(5);}void write_date(uchar date){rs=1;P0=date;delay(5);lcden=1;delay(5);lcden=0;delay(5);}void write_sfm(uchar add,uchar date) {uchar shi,ge;shi=date/10;ge=date%10;write_com(0x80+0x40+add);write_date(0x30+shi);write_date(0x30+ge);}void write_nyr(uchar add,uchar date) {uchar shi,ge;// qian=date/1000;// bai=date%1000/100;shi=date%100/10;ge=date%10;write_com(0x80+add);// write_date(0x30+qian);// write_date(0x30+bai);write_date(0x30+shi);write_date(0x30+ge);}/*void write_nian(uchar add,uchar date) {uchar qian,bai,shi,ge;qian=date%10000/1000;bai=date%1000/100;shi=date%100/10;ge=date%10;write_com(0x80+add);write_date(0x30+qian);write_date(0x30+bai);write_date(0x30+shi);write_date(0x30+ge);} */void write_week(uchar add,char we){//写液晶星期显示函数write_com(0x80+12);switch(we){case 1: write_date('M');delay(5);write_date('O');delay(5);write_date('N');break;case 2: write_date('T');delay(5);write_date('U');delay(5);write_date('E');break;case 3: write_date('W');delay(5);write_date('E');delay(5);write_date('D');break;case 4: write_date('T');delay(5);write_date('H');delay(5);write_date('U');break;case 5: write_date('F');delay(5);write_date('R');delay(5);write_date('I');break;case 6: write_date('S');delay(5);write_date('A');delay(5);write_date('T');break;case 7: write_date('S');delay(5);write_date('U');delay(5);write_date('N');break;}}void init() // 初始化函数{rw=0;dula=0;wela=0;lcden=0;fen=58;shi=10;miao=34;nian=11;write_com(0x38);write_com(0x0f);write_com(0x06);write_com(0x01);write_com(0x80);for(num=0;num<18;num++){write_date(table1[num]);delay(5);}write_com(0x80+0x40);for(num=0;num<12;num++){write_date(table2[num]);delay(5);}TMOD=0x01;TH0=(65536-45872)/256;TL0=(65536-45872)%256;num0++;EA=1;ET0=1;TR0=1;}void time0() interrupt 1{TH0=(65536-45872)/256;TL0=(65536-45872)%256;num0++;if(num0==20){ num0=0;miao++;if(miao==60){fen++;miao=0;if(fen==60){fen=0;shi++;if(shi==24)shi=0;we++;ri++;if(ri==32){ri=1;yue++;if(yue==13){yue=1;nian++;if(nian==30){nian=11;}write_nyr(3,nian);}write_nyr(6,yue);}write_nyr(9,ri);if(we==8){we=1;}write_week(12,we);}write_sfm(4,shi);}write_sfm(7,fen);}write_sfm(10,miao);}}void keyscan(){rd=0;if(k1==0)delay(5);if(k1==0){ num1++;while(!k1); //等于1就退出if(num1==1){write_com(0x80+0x40+11);write_com(0x0f);}if(num1==2){write_com(0x80+0x40+8);}if(num1==3){write_com(0x80+0x40+5);}if(num1==4){// num1=0;write_com(0x80+14);TR0=1;}if(num1==5){write_com(0x80+10);}if(num1==6){write_com(0x80+7);}if(num1==7){write_com(0x80+4);}if(num1==8){num1=0;write_com(0x0c);TR0=1;}}if(num1!=0){TR0=0;if(num1==1){if(k2==0){delay(5);if(k2==0){miao++;if(miao==59)miao=-1;while(!k2) ;write_sfm(10,miao);}}}if(num1==2){if(k2==0)delay(5);if(k2==0){fen++;if(fen==59)fen=-1;while(!k2);write_sfm(7,fen);}}if(num1==3){if(k2==0)delay(5);if(k2==0){shi++;if(shi==24)shi=0;while(!k2);write_sfm(4,shi);}}if(num1==4){if(k2==0){delay(5);if(k2==0){we++;if(we==8)we=1;while(!k2);write_com(0x80+12);write_week(12,we);}}}if(num1==5){if(k2==0)delay(5);if(k2==0){ri++;if(ri==32)ri=0;while(!k2);write_nyr(9,ri);}}if(num1==6){if(k2==0)delay(5);if(k2==0){yue++;if(yue==13)yue=1;while(!k2);write_nyr(6,yue);}}if(num1==7){if(k2==0)delay(5);if(k2==0){nian++;if(nian==30)nian=11;while(!k2);write_nyr(3,nian);}}}if(k3==0){delay(5);if(k3==0){while(!k3);switch(num1){case 1:miao--;if(miao==-1)miao=59; while(!k3);write_sfm(10,miao);break;case 2:fen--;if(fen==-1)fen=59; while(!k3);write_sfm(7,fen);break;case 3:shi--;if(shi==-1)shi=23; while(!k3);write_sfm(4,shi);break;case 4:we--;if(we==0)we=7; while(!k3); //write_com(0x80+12);write_week(12,we);break;case 5:ri--;if(ri==0)ri=31;while(!k3);write_nyr(9,ri);break;case 6:yue--;if(yue==0)yue=12;while(!k3);write_nyr(6,yue);break;case 7:nian--;if(nian==10)nian=30;while(!k3);write_nyr(3,nian);break;}}}}void main(){ init();while(1){// di();keyscan();}}。
51单片机可调时电子时钟程序
//*******************基于51单片机的可调时电子时钟实验**********************////***电子时钟前两位为分钟,后两位为秒钟,逢38秒进1分***********************////***按下调时键第一次,秒钟闪烁,进入编辑状态******************************////***按下调时键第二次,分钟闪烁,进入编辑状态******************************////***按下调时键第三次,则确定**********************************************////***在编辑状态下,按下增/减按钮,闪烁位则进行加/减操作********************////***若在编辑状态下,按下增/减按钮时间超过1S,则闪烁位以0.5秒的速度自加1***//#include<reg51.h>#define uint unsigned int#define uchar unsigned charsbit wela1=P2^4;sbit wela2=P2^5;sbit wela3=P2^6;sbit wela4=P2^7;sbit key1=P1^5;sbit key2=P1^6;sbit key3=P1^7;//位定义uchar code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};uchar miao,fen,mode,modeflag;//模式标志位bit flag,flash,miao_long,fen_long;//*********延时子函数*************// void delay(uint z){uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}//********定时器T0和变量的初始化****// void T0_init(){miao=00;fen=00;mode=0;modeflag=0;flash=0;flag=0;P2=0x0f;//锁存允许接口全部置低电平TMOD=0x01;//选择定时器工作方式TH0=(65536-2000)/256;TL0=(65536-2000)%256;//赋初值EA=1;//开总中断ET0=1;//开定时器中断TR0=1;//启动定时器}//*******数码管显示子函数***********// void display(){if(flag==0)//闪烁标志位为0时不闪烁{wela1=1;P0=table[fen/10];wela1=0;wela2=1;P0=table[fen%10];wela2=0; //送数给分位显示wela3=1;P0=table[miao/10];wela3=0;wela4=1;P0=table[miao%10];wela4=0; //送数给秒位显示}else //闪烁标志位为1时闪烁{if(mode==1)//模式为1,即调秒{if(miao_long==0)//没有长按加、减按钮{if(flash==0)//当闪烁等于0时{wela3=1;P0=table[miao/10];wela3=0;wela4=1;P0=table[miao%10];wela4=0;}else//当闪烁等于1时{P0=0xff;wela3=0;wela4=1;P0=0xff;wela4=0;}}else//长按了加、减按钮{wela3=1;P0=table[miao/10];wela3=0;wela4=1;P0=table[miao%10];wela4=0;}}else//模式为2,即调分{wela3=1;P0=table[miao/10];wela3=0;wela4=1;P0=table[miao%10];wela4=0; //在秒位熄灭的那一刻,按下调时键时,要把秒位点亮if(fen_long==0)//没有长按加、减按钮{if(flash==0){P0=table[fen/10];wela1=0;wela2=1;P0=table[fen%10];wela2=0;}else{wela1=1;P0=0xff;wela1=0;wela2=1;P0=0xff;wela2=0;}}else//长按了加、减按钮{wela1=1;P0=table[fen/10];wela1=0;wela2=1;P0=table[fen%10];wela2=0;}}}}//*********key1按钮子程序**************//void key1_scan(){if(key1==0){delay(10);//消抖if(key1==0){modeflag++;//模式标志位自加1flag=1;//闪烁标志位打开mode++;//模式自加1if(mode==3)//只在模式1:调秒,模式2:调分中间选择mode=0;while(!key1);//松手检测}}else if(modeflag==3)//按键次数到了第三次{modeflag=0;flag=0;while(!key1);}}//************key2,key3子程序**************//void key23_scan(){if(key2==0)//加数的操作{delay(10);if(key2==0){if(mode==1)//如果是模式1的话,key2键对秒加1{miao++;if(miao==38)//38秒进1分miao=0;delay(1000);//若按下的时间超过了1S钟,则视为长按while(!key2){miao_long=1;miao++;if(miao==38)miao=0;delay(200);}miao_long=0;//跳出长按,恢复短按的状态}else if(mode==2)//如果是模式2的话,key2键对分加一{fen++;if(fen==60)//60分钟进1fen=0;delay(1000);//若按下的时间超过了1S钟,则视为长按while(!key2){fen_long=1;fen++;if(fen==60)fen=0;delay(200);}fen_long=0;//跳出长按,恢复短按的状态}}else if(key3==0)//减数的操作{delay(10);if(key3==0){if(mode==1)//如果是模式1的话,key3键对秒减一{miao--;if(miao==0)miao=37;delay(1000);//若按下的时间超过了1S钟,则视为长按while(!key3){miao_long=1;miao--;if(miao==0)miao=37;delay(200);}miao_long=0;//跳出长按,恢复短按的状态}else if(mode==2)//如果是模式2的话,key3键对分减一{fen--;if(fen==0)fen=59;delay(1000);//若按下的时间超过了1S钟,则视为长按while(!key3)fen_long=1;fen--;if(fen==0)fen=59;delay(200);}fen_long=0;//跳出长按,恢复短按的状态}}}}void main(){T0_init();while(1){key1_scan();key23_scan();}}void T0_time() interrupt 1{static uchar t=0;static uint i=0;TH0=(65536-50000)/256;TL0=(65536-50000)%256;if(flag==0)//时间显示调整{i++;if(i==20){i=0;miao++;if(miao==38){miao=0;fen++;if(fen==60){fen=0;}}}}t++;if(t==10){t=0;flash=~flash;//闪烁标志位取反}display();}。
基于汇编语言的51单片机可调数字钟的设计
目录摘要 (3)Abstract (4)引言 (5)第一章绪论 (6)1.1 课题的背景 (6)1.2课题的来源 (7)1.3课题的意义 (7)第二章设计目的及要求 (8)2.1设计目的 (8)2.2设计要求 (8)2.1.1 基本要求 (8)2.1.2 高级要求 (8)2.1.3毕业设计作品要求 (9)第三章系统方案选择与论证 (10)3.1方案选择 (10)3.1.1方案比较 (10)3.1.2 芯片的选择 (10)3.2方案论证 (11)3.2.1显示模块方案选择与论证 (11)3.2.2时钟信号方案选择与论证 (11)3.3电路设计最终方案 (12)第四章系统电路的总体方案 (13)4.1数字钟的工作原理 (13)4.1.1实现时钟计时的基本方法 (14)4.1.2数字钟的时间显示 (15)4.1.3数字钟的启、停及时间调整 (15)4.2总体设计 (16)第五章系统的硬件设计 (17)5.1 AT89C52单片机最小系统 (17)5.2单片机的概念 (17)5.2.1单片机的结构 (17)5.2.2单片机的功能介绍 (20)5.3复位电路 (23)5.4电源电路 (24)5.5时钟振荡电路 (24)5.6键盘控制电路 (24)5.7 LED数码管显示电路 (26)第六章系统的软件设计 (28)6.1系统软件设计流程图 (28)6.2 系统中断流程图 (29)6.3 子程序说明 (31)6.3.1 按键扫描 (31)6.3.2 数码管动态扫描 (32)第七章数字钟元件清单和软件介绍 (33)7.1数字钟元件清单 (33)7.2 软件介绍 (33)7.2.1软件调试 (34)7.2.2硬件调试 (34)第八章总结 (35)参考文献 (36)致谢 (37)附录 (38)附录一系统程序源代码 (38)附录二电路原理图 (44)基于汇编语言的51单片机可调数字钟的设计摘要在当今社会,随着计算机在社会领域的渗透和大规模集成电路的发展,单片机的应用正在不断地走向深入,由于它具有功能强,体积小,功耗低,价格便宜,工作可靠,使用方便等特点,因此它特别适合于与控制有关的系统,越来越广泛地应用于自动控制,智能化仪器,仪表,数据采集,军工产品以及家用电器等各个领域,单片机往往是作为一个核心部件来使用,在根据具体硬件结构,以及针对具体应用对象特点的软件相结合,以作完善。
基于51单片机的简易电子钟设计
基于51单片机的简易电子钟设计一、设计目的现代社会对于时间的要求越来越精确,电子钟成为家庭和办公场所不可缺少的设备之一、本设计基于51单片机,旨在实现一个简易的电子钟,可以显示当前的时间,并且能够通过按键进行时间的调整和设置闹钟。
二、设计原理本设计主要涉及到51单片机的IO口、定时器、中断、LCD显示技术等方面知识。
1.时钟模块时钟模块采用定时器0的中断进行时间的累加和更新。
以1秒为一个时间单位,每当定时器0中断发生,就将时间加1,并判断是否需要更新小时、分钟和秒的显示。
同时,根据用户按键的操作,可以调整时间的设定。
2.显示模块显示模块采用16x2字符LCD显示屏,通过51单片机的IO口与LCD连接。
可以显示当前时间和设置的闹钟时间。
初次上电或者重置后,LCD显示时间为00:00:00,通过定时器中断和键盘操作,实现时间的更新和设定闹钟功能。
3.键盘模块键盘模块采用矩阵键盘连接到51单片机的IO口上,用于用户进行时间的调整和设置闹钟。
通过查询键盘的按键状态,根据按键的不同操作,实现时间的调整和闹钟设定功能。
4.中断模块中断模块采用定时器0的中断,用于1秒的定时更新时间。
同时可以添加外部中断用于响应用户按键操作。
三、主要功能和实现步骤1.系统初始化。
2.设置定时器,每1秒产生一次中断。
3.初始化LCD显示屏,显示初始时间00:00:00。
4.查询键盘状态,判断是否有按键按下。
5.如果按键被按下,根据不同按键的功能进行相应的操作:-功能键:设置、调整、确认。
-数字键:根据键入的数字进行时间的调整和闹钟设定。
6.根据定时器的中断,更新时间的显示。
7.判断当前时间是否与闹钟设定时间相同,如果相同,则触发闹钟,进行提示。
8.循环执行步骤4-7,实现连续的时间显示和按键操作。
四、系统总结和改进使用51单片机设计的简易电子钟可以显示当前时间,并且实现时间的调整和闹钟设定功能。
但是由于硬件资源有限,只能实现基本的功能,不能进行其他高级功能的扩展,例如闹铃的音乐播放、温度、湿度的显示等。
51单片机可调电子时钟
目录摘要 (2)Abstract (3)1.设计目的 (4)2.设计任务 (4)2.1.任务1:开机界面的设置 (4)2.2.任务2:LCD-1602显示日期时间 (4)2.3.任务3:时间与日期的调整 (4)3.硬件设计 (4)3.1.STC89C51(51单片机) (4)3.2.LCD-1602液晶显示屏 (5)4.软件设计 (7)4.1.应用软件 (7)4.2.程序框图 (7)4.3.使用说明 (7)4.4.注意事项 (8)4.5.调试结果 (8)5.收获 (9)附录: (10)附录A.硬件图 (10)附录B.主要程序 (11)摘要电子时钟是单片机系统的一个应用,由硬件和软件相配合使用。
本文通过对单片机的控制实现日历功能电子时钟的设计,以达到学习、了解单片机相关指令在各方面的应用。
硬件由主控器、显示电路、键盘接口等三个模块组成。
该时钟设计以STC-89C51作为主控器,控制显示时钟信息;显示模块用LCD-1602液晶屏;键盘接口电路由普通按键完成。
软件利用C语言编程实现单片机的控制功能。
关键词:电子时钟、单片机、LCD-1602液晶显示AbstractElectronic clock is a single chip microcomputer system application, by the use of hardware and software. In this paper, through the control of single-chip microcomputer to achieve the design of the electronic clock, in order to achieve learning, to understand the microcontroller related instructions in various aspects of the application. The hardware is composed of three modules, such as the main controller, the display circuit, the keyboard interface and so on. The clock is designed with STC-89C51 as the main controller, controlling the display clock information; the display module uses the LCD-1602 LCD screen; the keyboard interface circuit is completed by the ordinary button. Software uses C language programming microcontroller control functions.Key words: electronic clock, single chip microcomputer,LCD-1602 liquid crystal display1.设计目的该电子时钟由C语言编写而成,利用单片机定时器控制时钟运行,实现按键调整时间和日期的功能。
51单片机C语言可调时钟(2)(1)
/*这是一个真正有意义的时钟key1功能键选择可调位,短按,每按一下有一位闪烁长按闪烁不断向下一位推移key2 加键短按相应闪烁的位加1,长按连续加1;key3 减键短按相应闪烁的位减1,长按连续减一;key4 确定键按下退出调时,正常显示;*/#include<reg52.h>#define uint unsigned int#define uchar unsigned char#define LED P0#define KEY_1 0x0e#define KEY_2 0x0d#define KEY_3 0x0b#define KEY_4 0x07#define KEY_NULL 0x0f#define KEY_PRESS 0x80#define KEY_LONG 0x40#define KEY_STATE_INIT 0#define KEY_STATE_PRESS 1#define KEY_STATE_LONG 2#define KEY_STATE_UP 3#define KEY_LONG_PERIOD 20#define KEY_CONTINUE_PERIOD 10bit set;bit dao1S=0;bit dao2MS=0;bit dao10MS;sbit dula=P2^6;sbit wela=P2^7;sbit key1=P3^4;sbit key2=P3^5;sbit key3=P3^6;sbit key4=P3^7;int main_flag,exit_flag,up_flag,down_flag;int tab[]={0,0,0,0,0,0};uchar weitable[]={0x01,0x02,0x04,0x08,0x10,0x20};uchar tab1[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; void nint(){ TMOD=0X01;TH0=0XF8;TL0=0XCC;TR0=1;ET0=1;}uchar KeyScan(){if(key1==0) return KEY_1;if(key2==0) return KEY_2;if(key3==0) return KEY_3;if(key4==0) return KEY_4;return KEY_NULL;}uchar GetKey(){uchar keyRetu=0,keyTemp=KEY_NULL;static uchar s_keyState=KEY_STATE_INIT,keyTime=0,keyLast=KEY_NULL;keyTemp=KeyScan();switch (s_keyState){case KEY_STA TE_INIT:if(keyTemp!=KEY_NULL){s_keyState=KEY_STA TE_PRESS;}break;case KEY_STA TE_PRESS:if(keyTemp!=KEY_NULL){s_keyState=KEY_STA TE_LONG;keyTime=0;keyLast=keyTemp;}else{s_keyState=KEY_STA TE_INIT;}break;case KEY_STA TE_LONG:if(keyTemp==KEY_NULL){s_keyState=KEY_STA TE_INIT;keyRetu=(keyLast|KEY_PRESS);}else{if(++keyTime>=KEY_LONG_PERIOD) //按下时间>1s{s_keyState=KEY_STATE_UP;keyTime=0;}}break;case KEY_STA TE_UP:if(keyTemp==KEY_NULL){s_keyState=KEY_STA TE_INIT;}else{if(++keyTime>=KEY_CONTINUE_PERIOD) //按下时间>0.5s {keyTime=0;keyRetu=(keyLast|KEY_LONG);}}break;}return keyRetu;}void updatetime(){if(dao1S){dao1S=0;if(++tab[5]==10){ tab[5]=0;if(++tab[4]==6){tab[4]=0;if(++tab[3]==10){ tab[3]=0;if(++tab[2]==6){ tab[2]=0;if(tab[0]<2){if(++tab[1]==10){ tab[1]=0;tab[0]++;}}else{ if(tab[1]==4){ tab[1]=0;tab[0]=0;}} }}}}}}void display(){ static uchar k=0;dula=1;LED=tab1[tab[k]];if(set&&((k==main_flag-1))){LED=0XFF;}dula=0;LED=0Xff;wela=1;LED=weitable[k];wela=0;if(++k>5) k=0;}void sittime(uchar hour,uchar minute,uchar second ) { uchar a1,a2,b1,b2,c1,c2;a1=hour/10;a2=hour%10;b1=minute/10;b2=minute%10;c1=second/10;c2=second%10;tab[0]=a1;tab[1]=a2;tab[2]=b1;tab[3]=b2;tab[4]=c1;tab[5]=c2;}void main(){ nint();EA=1;sittime(15,20,15);while(1){updatetime();if(dao2MS){dao2MS=0;display();}if(dao10MS){dao10MS=0;switch (GetKey()){case (KEY_1|KEY_PRESS):if(++main_flag>=7)main_flag=0;break;case (KEY_1|KEY_LONG):if(++main_flag>=7)main_flag=0;break;case (KEY_2|KEY_PRESS):switch(main_flag){case 1:{if(++tab[0]>=3)tab[0]=0;}break;case 2:{if(++tab[1]>4)tab[1]=0;}break;case 3:{if(++tab[2]>5)tab[2]=0;}break;case 4:{if(++tab[3]>9)tab[3]=0;}break;case 5:{if(++tab[4]>5)tab[4]=0;}break;case 6:if(++tab[5]>9)tab[5]=0;}break;case (KEY_2|KEY_LONG): switch(main_flag) {case 1:{if(++tab[0]>=3)tab[0]=0;}break;case 2:{if(++tab[1]>4)tab[1]=0;}break;case 3:{if(++tab[2]>5)tab[2]=0;}break;case 4:{if(++tab[3]>9)tab[3]=0;}break;case 5:{if(++tab[4]>5)tab[4]=0;}break;case 6:if(++tab[5]>9)tab[5]=0;}break;case (KEY_3|KEY_PRESS):switch(main_flag){case 1:{if(--tab[0]<0)tab[0]=2;}break;case 2:{if(--tab[1]<0)tab[1]=4;}break;case 3:{if(--tab[2]<0)tab[2]=5;}break;case 4:{if(--tab[3]<0)tab[3]=9;}break;case 5:{if(--tab[4]<0)tab[4]=5;}break;case 6:if(--tab[5]<0)tab[5]=9;}break;case (KEY_3|KEY_LONG): switch(main_flag){case 1:{if(--tab[0]<0)tab[0]=2;}break;case 2:{if(--tab[1]<0)tab[1]=4;}break;case 3:{if(--tab[2]<0)tab[2]=5;}break;case 4:{if(--tab[3]<0)tab[3]=9;}break;case 5:{if(--tab[4]<0)tab[4]=5;}break;case 6:if(--tab[5]<0)tab[5]=9;}break;case (KEY_4|KEY_PRESS):main_flag=0;display();}}}}void timer() interrupt 1{ static count=0;static count1=0;TH0=0XF8;TL0=0XCC;dao2MS=1;count++;if(++count1==10){ c ount1=0;dao10MS=1;}if(!(count%25)) set = !set;if(count==500) {count=0;dao1S=1; }}。
51单片机控制基于1602液晶显示 电子时钟【带闹铃和整点报时】
write_date(week6[num]);
delay1();
}
};
break;
}
}
void display() //显示时间子程序
{
write_week(week);
write_ymd(3,year);
write_ymd(6,months);
write_ymd(9,day);
write_sfm(0,shi);
write_sfm(3,fen);
write_sfm(6,miao);
}
void display_1() //显示闹钟子程序
{
write_week(week_1);
write_ymd(3,year1);
write_ymd(6,months1);
write_ymd(9,day1);
write_sfm(0,shi1);
write_com(0x80+add);
write_date(0x30+sh);
write_date(0x30+ge);
}
void write_week(uchar add) //周几显示
{
switch(add)
{
case 0:{
write_com(0x80+12);//设置数据起始地址
for(num=0;num<3;num++)
{
write_date(week3[num]);
delay1();
}
};
break;
case 4:{
write_com(0x80+12);//设置数据起始地址
for(num=0;num<3;num++)
基于51单片机的数字时钟,带秒表和时间设置
要求:
使用1个6位共阴数码管,3个按键,1个74LS254和51单片机最小系统制作一个带秒表功能的电子时钟,并要求当使用秒表功能时可以对秒表进行暂停和清零,且秒表精度为100ms以上;显示时钟时要求时、分、秒用数码上的点隔开;设置时钟时可以切换设置“时”和“分”,并在数码管上有相应闪烁以区分
以下是我做的原理图:
刚写的程序,有很详细的注释,希望大家一起学习交流:
以下是仿真文件和C程序,网盘分享给大家:
/share/link?shareid=3375444058&uk=453592216 /share/link?shareid=3375444058&uk=453592216 /share/link?shareid=3375444058&uk=453592216
(上面3个是一样的,怕有些吧友没看到)
希望吧友们一起分享自己的作品。
51单片机设置的电子闹钟(可调时间和闹钟)
#include<reg52.h>#define uint unsigned int#define uchar unsigned char#define LED P0 // 数码管的段选#define LIGHT P1 // 时分秒位的指示灯#define WS P2 // 数码管的位选sbit key1=P3^0; // 时间暂停/开始sbit key2=P3^1; // 时间/闹钟设置sbit key3=P3^2; // 增加sbit key4=P3^3; // 减少sbit alarm=P3^6; // 闹铃uchar tab[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; // 0-9 uchar tab_dp[10]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef}; // 0.-9.(带小数点)uchar data1[]={0,0,0,0,0,0};uchar data2[]={0,0,0,0,0,0};uint t,k,kk,k1,flag;uint bbh,bbm,bbs,bbh1,bbm1,bbs1;uint sec,min,hour,sec1,min1,hour1; // 定义秒,分,时void init();void display();void display_bb();void delay( uint );void keyscan();void main(){init();while(1){keyscan();if(k1==0||k1==1||k1==2||k1==3) // 显示调节时间{display();}if(k1==4||k1==5||k1==6) // 显示调节闹钟{display_bb();}if((bbh==hour)&&(bbm==min)&&data1[4]==0&&data1[5]==5) // 5s报时{alarm=~alarm;delay(1);}if((bbs==sec)&&(bbm==min)&&(bbh==hour)) // 可调报时{alarm=~alarm;delay(1);}}}void init(){WS=LIGHT=flag=0;sec=min=hour=0; // 将0赋给时分秒TMOD=0x01; // 方式1 P129(见课本)TH0=0x3c; // 65536-50000=15536=0x3cb0(50ms) P128(见课本)TL0=0xb0;EA=1; // 开总中断 P161(见课本)TR0=1; // 定时/计数器0开启ET0=1; // 定时器/计数器0溢出中断启动 P161(见课本)}void delay( unsigned int t) // 延时函数{unsigned int i;while(t--)for(i=0;i<125;i++);}void display() // 显示时间函数{if(TF0==1) // 定时器/计数器溢出 P130(见课本){TF0=0; // 清中断标志位t++;if(t==20) // (50ms*20=1s){t=0;sec++; // 秒加1if(sec==60) // 秒为60,则清零,分加1 {sec=0;min++;}if(min==60) // 分为60,则清零,时加1{min=0;hour++;}if(hour==24)// 时为24,则清零{hour=0;}}}data1[5]=sec%10;data1[4]=sec/10;data1[3]=min%10;data1[2]=min/10;data1[1]=hour%10;data1[0]=hour/10;WS=0xdf; // 1101 1111 ,低电平显示LED=tab[data1[5]];delay(1);WS=0xef; // 1110 1111LED=tab[data1[4]];delay(1);WS=0xf7; // 1111 0111LED=tab_dp[data1[3]];delay(1);WS=0xfb; // 1111 1011LED=tab[data1[2]];delay(1);WS=0xfd; // 1111 1101LED=tab_dp[data1[1]];delay(1);WS=0xfe; // 1111 1110LED=tab[data1[0]];delay(1);}void display_bb() // 显示闹钟函数{data2[5]=bbs%10;data2[4]=bbs/10;data2[3]=bbm%10;data2[2]=bbm/10;data2[1]=bbh%10;data2[0]=bbh/10;WS=0xdf; // 1101 1111 ,低电平显示LED=tab[data2[5]];delay(1);WS=0xef; // 1110 1111LED=tab[data2[4]];delay(1);WS=0xf7; // 1111 0111LED=tab_dp[data2[3]];delay(1);WS=0xfb; // 1111 1011LED=tab[data2[2]];delay(1);WS=0xfd; // 1111 1101LED=tab_dp[data2[1]];delay(1);WS=0xfe; // 1111 1110LED=tab[data2[0]];delay(1);}void keyscan() // 键盘扫描{if(key1==0) // 暂停/开始{++kk;while(!key1){display();if(kk==1){TR0=0;if(k1==0||k1==1||k1==2||k1==3) // 显示调节时间{display();}if(k1==4||k1==5||k1==6) // 显示调节闹钟{display_bb();}if(key2==0) // 模式选择(调节时间/闹钟){k1++;while(!key2){if(k1==1) // 第1次按下{sec1=sec; // 保存秒的数值sec=88; // 显示88,表示可以调节秒的数值了display(); // 显示88sec=sec1; // 恢复前一刻秒的数值}if(k1==2){min1=min;min=88;display();delay(1);min=min1;}if(k1==3){hour1=hour;hour=88;display();delay(1);hour=hour1;}if(k1==4){sec1=bbs; // 保存秒的数值bbs=66; // 显示66,表示可以调节秒的数值了display_bb(); // 显示66bbs=sec1; // 恢复前一刻秒的数值}if(k1==5){min1=bbm;bbm=66;display_bb();delay(10);bbm=min1;}if(k1==6){hour1=bbh;bbh=66;display_bb();delay(10);bbh=hour1;}if(k1==7){k1=0;display();}}}if(key3==0) // 时间/闹钟增加设置{while(!key3){if(k1==1){sec++; // 秒加1delay(60);if(sec==60)sec=0;display();}if(k1==2){min++;delay(60);if(min==60)min=0;display();}if(k1==3){hour++;delay(60);if(hour==24)hour=0;display();}if(k1==4){bbs++; // 秒加1delay(60);if(bbs==60)bbs=0;display_bb();}if(k1==5){bbm++;delay(60);if(bbm==60)bbm=0;display_bb();}if(k1==6){bbh++;delay(60);if(bbh==24)display_bb();}if(k1==7){k1=0;display();}}}if(key4==0) // 时间/闹钟减少设置 {while(!key4){if(k1==1){sec--; // 秒加1delay(60);if(sec==0)sec=60;display();}if(k1==2){min--;delay(60);if(min==0)min=60;display();}if(k1==3){hour--;delay(60);if(hour==0)hour=24;display();}if(k1==4){bbs--; // 秒减1delay(60);if(bbs==0)display_bb();}if(k1==5){bbm--;delay(60);if(bbm==0)bbm=60;display_bb();}if(k1==6){bbh--;delay(60);if(bbh==0)bbh=24;display_bb();}if(k1==7){k1=0;display();}}}}}if(kk==2){kk=0;k1=0;TR0=1;}}}。
51单片机24小时闹钟时钟可调简单程序
51单片机24小时闹钟时钟可调简单程序#includeunsigned char seg[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; unsigned char con[6]={0x1,0x2,0x4,0x8,0x10,0x20};unsigned char mm=0;unsigned char ss=0;unsigned char hh=0;unsigned char count=100;unsigned char TH=01,TM=00,m;sbit S1=P3^3;sbit S2=P3^4;sbit S3=P3^5;sbit S4=P3^6;sbit S5=P3^7;sbit S6=P3^2;sbit bell=P3^0;main(){TMOD=1;TH0=-10000>>8;TL0=-10000; //10毫秒间隔EA=1;ET0=1;TR0=1;while(1);}void isr_time0() interrupt 1 //24小时{unsigned int i=0,j;unsigned char time[6];TH0=-10000>>8;TL0=-10000;count--;if(count==0){count=100;ss++;if(ss==60){ss=0;mm++;if(mm==60){mm=0;hh++;if(hh==24)hh=0;}}if(S5==0){TH++;} //闹钟调时if(S6==0){TM++;} //闹钟调分if(hh==TH){ unsigned int a,b,y;if(mm>=01){m=0;}if(mm==TM&&ss<10){if(m<10){do{m++;ss++; //ss确保闹钟时间继续for(a=0;a<1250;a++){bell=!bell;for(b=0;b<15;b++);} //取反for(y=0;y<1250;y++){bell=!bell;for(b=0;b<33;b++);}for(a=0;a<1250;a++){bell=!bell;for(b=0;b<15;b++);}for(a=0;a<1250;a++){bell=!bell;for(b=0;b<33;b++);}}while(m<10);}}}if(S1==0){hh++; //时钟加if(hh==24){hh=0;}}if(S2==0){mm++; //分钟加if(mm==60){ mm=0;hh++;}}if(S3==0&&hh>0){hh--; //时钟减if(hh==0){hh=23;}}if(S4==0&&mm>0){mm--; //分钟减if(mm==0){ mm=59;}}}time[3]=hh/10;time[2]=hh%10; //显示位time[1]=mm/10;time[0]=mm%10;for(i=0;i<6;i++){P2=con[i];if(i==1||i==2) //小数点P1=seg[time[i]]&0x7f;else P1=seg[time[i]];for(j=100;j>0;j--);}}。
51单片机数字钟设计程序
51单片机数字钟设计程序51单片机是一种常用的单片机芯片,它具有体积小、功耗低、性能稳定等特点,被广泛应用于各种电子设备中。
本文将以51单片机数字钟设计程序为主题,介绍如何使用51单片机设计并实现一个简单的数字钟。
我们需要了解一下数字钟的基本原理。
数字钟主要由时钟芯片、数码管、按键等组成。
时钟芯片负责计时和控制,数码管用于显示时间,按键则用于设置和调整时间。
在设计数字钟的程序时,我们需要考虑以下几个方面:1. 时钟设置:首先,我们需要设置时钟芯片的工作模式。
一般来说,时钟芯片有两种工作模式,分别是24小时制和12小时制。
我们可以通过按键来选择工作模式,并将选择结果保存到相应的寄存器中。
2. 时间显示:接下来,我们需要将时钟芯片中的时间数据通过数码管显示出来。
数码管通常由7段LED组成,每段LED对应一个数字或字符。
我们可以通过控制数码管的引脚状态来实现不同数字的显示。
同时,为了使时间显示更加清晰,我们可以在数码管之间加入冒号等分隔符。
3. 时间调整:为了保证时间的准确性,我们需要提供时间调整的功能。
可以通过按键来实现时间的增加和减少,从而调整时钟芯片中的时间数据。
当按键按下时,我们可以检测到相应的信号,并将其转换为时间调整的命令。
4. 闹钟功能:除了显示时间,数字钟还可以具备闹钟功能。
我们可以设置一个闹钟时间,并在达到闹钟时间时触发相应的报警信号。
一般来说,闹钟功能可以通过按键设置,并将设置结果保存在相应的寄存器中。
当时钟芯片中的时间与闹钟时间一致时,我们可以通过控制蜂鸣器等外设来发出报警信号。
通过以上的设计,我们可以实现一个简单的数字钟。
当然,如果我们希望数字钟具备更多的功能,比如温湿度显示、定时器等,我们还可以在程序中添加相应的代码来实现。
总结一下,本文以51单片机数字钟设计程序为主题,介绍了数字钟的基本原理以及设计过程。
通过对时钟芯片、数码管、按键等的控制,我们可以实现时间的显示、调整和闹钟功能。
51单片机的时钟工作原理
51单片机的时钟工作原理一、什么是时钟时钟是指系统用于同步各种操作的重要信号。
在51单片机中,时钟用于控制指令的执行、数据的传送、中断的处理以及外部设备的操作等。
时钟信号的频率决定了单片机的运行速度和性能,因此时钟电路的设计和工作对于单片机的正常运行非常重要。
二、时钟的基本要求1.稳定性:时钟信号必须具有较高的稳定性,即频率不能随着温度、电压等变化而波动。
在51单片机中,通常使用晶振作为时钟源,晶振具有较好的频率稳定性。
2.精确性:时钟信号的频率必须是精确的,以保证单片机正常工作。
在51单片机中,时钟频率通常是晶振频率的整数分频倍数。
3.可调性:有时需要调节时钟频率,以满足不同应用的需求。
在51单片机中,通过改变分频系数或选用不同的晶振频率可以实现时钟频率的调节。
三、51单片机的时钟电路1.晶振电路:晶振是时钟电路的核心部件,它提供稳定且精确的时钟信号。
晶振电路通常由晶体振荡器和负载电容组成。
晶体振荡器包括一个晶体谐振回路,通过晶体的共振来产生稳定的时钟信号。
负载电容用于调整晶振振荡器的频率。
2.频率切换与分频电路:由于晶振的频率通常较高,超过了单片机内部工作的最高频率,因此需要通过频率切换和分频来降低时钟频率。
分频电路通常由多个单元组成,其中包括可调的分频系数以实现时钟频率的调节。
3.时钟信号发生电路:时钟信号发生电路将时钟频率切换和分频后的信号发送给单片机的各个模块,如控制器、ALU、存储器等。
四、分频原理分频是指将输入信号的频率降低到指定的频率。
在51单片机中,分频主要通过两个机制来实现:定时/计数器和时钟选择。
1.定时/计数器:51单片机中的定时/计数器可以设置为12位或16位。
通过设定定时/计数器的初值和工作方式,可以实现对输入时钟的分频。
2.时钟选择:51单片机内部有多个时钟源可供选择,包括晶振、外部时钟和内部振荡电路等。
通过设置时钟选择位或时钟控制寄存器,可以选择所需的时钟源。
五、时钟频率调节有时需要调节单片机的时钟频率,以满足不同应用的需求。
基于C51单片机的数字可调时钟
河南机电高等专科学校《C51程序设计》大作业设计题目:数字可调时钟班级:通技091学号:090413128姓名:成绩:2011年11月1 设计任务制作数字可调时钟,要求可以分开调节分、时、年、月、日,能够显示温度。
2电路原理图以下为protel99se画的的原理图3 系统流程图数字可调时钟分以下四个部分构成:显示部分:此次显示采用了动态扫描显示,采用74ls573进行数据锁存。
温度采集:温度采集采用了18b20采集的,18b20转化温度较快,精度高。
时钟:采用普通的ds1302芯片。
数据运算:单片机用普通的8051单片机(12M晶振)。
4 源程序/*******************************数字可调时钟*********************************/ /*******************************by:lhc****************************************/ #include<reg51.h> #define DataPort P0void delayms(unsigned char i); sbit DQ=P1^3; sbit sclk=P1^4;sbit date=P1^5; sbit rst=P1^6;sbit LATCH1=P2^2;//定义锁存使能端口 段锁存 sbit LATCH2=P2^3;// 位锁存unsigned char time[8]={20,11,11,27,11,30,00,7}; //年 月日 时 分 秒 周 unsigned char time1[8],readtemflag;unsigned char code DuanMa[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};// 显示段码值0~9unsigned char code WeiMa[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//分别对应相应的数码管点亮,即位码unsigned char code pingnian[13]={ 0,31,28,31,30,31,30,31,31,30,31,30,31};//平年的月份天数 unsigned char code yunnian[13]= { 0,31,29,31,30,31,30,31,31,30,31,30,31};//闰年的月份天数 unsigned char TempData[8]; //存储显示值的全局变量 void delay(unsigned char i) {while(--i); //us 延时函数}void delayms(unsigned char i) //ms 延时函数 {while(i--) { delay(245); delay(245); } }bit rest(void)//18b20重启函数{ bit k=0; DQ=1; delay(5); DQ=0; delay(150); delay(200); DQ=1; delay(40); k =DQ; delay(25); r eturn(k); }unsigned char read()//18b20读数据函数{ unsigned char i=0; unsigned char dat=0;for(i=0;i<8;i++) {DQ=0; dat>>=1; DQ=1;if(DQ) dat|=0x80; delay(25); }return (dat);}void write(unsigned char dat)//18b20写数据函数{unsigned char i=0; for(i=0;i<8;i++){ DQ = 0; DQ = dat&0x01; delay(25); DQ = 1; dat>>=1;} delay(25);}unsigned int ReadTemperature(void) //读取温度函数{ unsigned char a=0; unsigned int kk=0,b=0;LOOP:if(rest()==0){ write(0xCC); //跳过ROM w rite(0x44); //初始化温度转换delayms(20); rest();TH1=0XFa; TL1=0Xff; write(0xCC); write(0xBE); //读取温度a=read(); b=read(); b<<=8; kk=a+b; return(kk);} else goto LOOP;}void restds1302(void){sclk=0; rst=0; //ds1302重启 }void writebyte(unsigned char addr,unsigned char byte) //写入ds1302一个字节数据{ unsigned char i;rst=1;addr=addr&0xfe;for(i=0;i<8;i++){ date=addr&0x01; sclk=1; sclk=0; addr>>=1;}for(i=0;i<8;i++){ date=byte&0x01; sclk=1; sclk=0; byte>>=1;}rst=0;}unsigned char readbyte(unsigned char addr) //读取一个字节的数据{ unsigned char i,temp;rst=1; addr=addr|0x01;for(i=0;i<8;i++) //读函数{ date=addr&0x01;sclk=1; sclk=0;addr=addr>>1;}for(i=0;i<8;i++){temp=temp>>1;if(date) temp|=0x80;else temp&=0x7f; sclk=1; sclk=0;}rst=0;return temp;}void writetime(void) //调时函数{unsigned char i,tmp;for(i=0;i<8;i++){ //BCD处理tmp=time[i]/10;time1[i]=time[i]%10;time1[i]=time1[i]+tmp*16;}writebyte(0x8e,0x00);//关闭写保护writebyte(0x80,0x80);// 暂停writebyte(0x8c,time1[1]);// 年写入writebyte(0x88,time1[2]);//月写入writebyte(0x86,time1[3]);// 日写入//些时间writebyte(0x84,time1[4]);// 时写入writebyte(0x82,time1[5]);// 分写入writebyte(0x80,time1[6]);// 秒写入writebyte(0x8a,time1[7]);// 周写入//writebyte(0x80,0x00);// 秒写入writebyte(0x8e,0x80);//打开写保护}void readtime(void) //读取时间函数{ unsigned char i,tmp;time1[1]=readbyte(0x8d);// 年读time1[2]=readbyte(0x89);// 月读time1[3]=readbyte(0x87);// 日读// 读时间time1[4]=readbyte(0x85);// 时time1[5]=readbyte(0x83);// 分time1[6]=readbyte(0x81);// 秒time1[7]=readbyte(0x8b);// 周for(i=0;i<8;i++) //BCD处理{ tmp=time1[i]/16;time[i]=time1[i]%16;time[i]=time[i]+tmp*10;}}void Display(unsigned char FirstBit,unsigned char Num) //动态显示函数{ static unsigned char i=0;DataPort=0; //清空数据,防止有交替重影LATCH1=1; //段锁存LATCH1=0;DataPort=WeiMa[i+FirstBit]; //取位码LATCH2=1; //位锁存LATCH2=0;DataPort=TempData[i]; //取显示数据,段码LATCH1=1; //段锁存LATCH1=0; i++;if(i==Num) i=0;}unsigned char key(void) //键盘读取函数{ unsigned char i;if(P3!=0xff){ delay(10); if(P3!=0xff){ i=P3; while(P3!=0xff) ;switch(i){case 0xfe:return 1;break;case 0xfd:return 2;break;case 0xfb:return 3;break;default:return 0;break;}}}return 0;}void T1_rest() //定时器1的初始化函数{TMOD|=0X10;TH1=0XF8;TL1=0X30;EA=1 ;ET1= 1;TR1=1;}void isr0(void) interrupt 3{static unsigned char qq;TR1=0; TH1=0XF8; TL1=0X30;Display(0,8); //送去显示qq++;if(qq==200){ qq=0,readtemflag=1; } TR1=1; }void main(){unsigned char bian=0,k=0;unsigned char num=6;unsigned int h,l,tempp,year;bit nianflag; restds1302(); writetime(); T1_rest();while(1){readtime(); year=time[1]*200;if(year%4==0&&year%100!=0||year%400==0) nianflag=1;else nianflag=0; k=key();if(k!=0){ if(k==1){ bian++;num=6; k=0; }//调节显示的内容if(bian==3) bian=0;if(k==2){ num--;if(num<4) bian=1;if(num>3) bian=0; //选着调节对象分,时,年月日if(num==0) num=6; k=0;}if(k==4&&num!=6) //调节对象(分时年月日)加一{ time[num]++;if(num==5&&time[num]==60) time[num]=0;if(num==4&&time[num]==24) time[num]=0;if(num==3&&nianflag){if(time[3]>yunnian[time[2]]) time[3]=1;}else if(num==3){ if(time[3]>pingnian[time[2]])time[3]=1;}if(num==2&&time[num]==13) time[num]=1;if(num==1&&time[num]==99) time[num]=0; k=0;}if(k==3&&num!=6) //调节对象(分时年月日)减一{ time[num]--;if(time[num]==-1&&num==5) time[num]=59;if(time[num]==-1&&num==4) time[num]=23;if(num==3&&nianflag){ if(time[3]==0) time[3]=yunnian[time[2]]; }else if(num==3){ if(time[3]==0) time[3]=pingnian[time[2]]; }if(time[num]==0&&num==2) time[num]=12;if(time[num]==-1&&num==1) time[num]=99; k=0;}if(nianflag){ if(time[3]>yunnian[time[2]]) time[3]=1;}else { if(time[3]>pingnian[time[2]]) time[3]=1; }writetime();}if(bian==0) //对时,分,秒,显示数据分离处理{TempData[0]=DuanMa[time[4]/10];TempData[1]=DuanMa[time[4]%10];TempData[2]=0x40; //加入"-"TempData[3]=DuanMa[time[5]/10];//分TempData[4]=DuanMa[time[5]%10];TempData[5]=0x40;TempData[6]=DuanMa[time[6]/10];//秒TempData[7]=DuanMa[time[6]%10];if(num!=6){ delayms(30);if(num==4){ TempData[0]=0; TempData[1]=0; delayms(30); }if(num==5){ TempData[3]=0; TempData[4]=0; delayms(30); }}}else if(bian==1) //对年月日的显示数据分离处理{ TempData[0]=DuanMa[time[1]/10]; TempData[1]=DuanMa[time[1]%10];TempData[2]=0x40;//加入"-"TempData[3]=DuanMa[time[2]/10];//月TempData[4]=DuanMa[time[2]%10];TempData[5]=0x40;TempData[6]=DuanMa[time[3]/10];//日TempData[7]=DuanMa[time[3]%10];if(num!=6){ delayms(30);if(num==1){ TempData[0]=0;TempData[1]=0;delayms(30); }if(num==2){ TempData[3]=0;TempData[4]=0;delayms(30); }if(num==3){ TempData[6]=0;TempData[7]=0;delayms(30); }}}else if(bian==2) //对温度和星期的显示数据分离处理{if( readtemflag==1){ tempp=ReadTemperature();readtemflag=0;}if(tempp&0x8000){ TempData[0]=0x40;//负号标志tempp=~tempp; tempp +=1;}elseTempData[0]=0;h=tempp>>4; l=tempp&0x0F; l=l*6/10;//小数近TempData[1]=DuanMa[(h%100)/10]; //十位温度TempData[2]=DuanMa[(h%100)%10]|0x80; //个位温度,带小数点TempData[3]=DuanMa[l];TempData[4]=0x39; TempData[5]=0;TempData[6]=DuanMa[time[7]/10];TempData[7]=DuanMa[time[7]%10];}}}参考文献【1】Brian W.Kernighan,Dennis M.Ritchie.C.程序设计语言.机械工业出版社,机械工业出版社,2004.1.【2】祁伟,杨婷.单片机C51程序设计教程与实验,北京航空航天大学出版社,2006.1. 【3】梅丽凤,郝万新.单片机原理及应用,清华大学出版社,2009.7.【4】18B20数据手册.【5】DS1302数据手册.。
51单片机设置的电子闹钟(可调时间和闹钟)
#include<reg52.h>#define uint unsigned int#define uchar unsigned char#define LED P0 // 数码管的段选#define LIGHT P1 // 时分秒位的指示灯#define WS P2 // 数码管的位选sbit key1=P3^0; // 时间暂停/开始sbit key2=P3^1; // 时间/闹钟设置sbit key3=P3^2; // 增加sbit key4=P3^3; // 减少sbit alarm=P3^6; // 闹铃uchar tab[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; // 0-9uchar tab_dp[10]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef}; // 0.-9.(带小数点)uchar data1[]={0,0,0,0,0,0};uchar data2[]={0,0,0,0,0,0};uint t,k,kk,k1,flag;uint bbh,bbm,bbs,bbh1,bbm1,bbs1;uint sec,min,hour,sec1,min1,hour1; // 定义秒,分,时void init();void display();void display_bb();void delay( uint );void keyscan();void main(){init();while(1){keyscan();if(k1==0||k1==1||k1==2||k1==3) // 显示调节时间{display();}if(k1==4||k1==5||k1==6) // 显示调节闹钟{display_bb();}if((bbh==hour)&&(bbm==min)&&data1[4]==0&&data1[5]==5) // 5s报时{alarm=~alarm;delay(1);}if((bbs==sec)&&(bbm==min)&&(bbh==hour)) // 可调报时{alarm=~alarm;delay(1);}}}void init(){WS=LIGHT=flag=0;sec=min=hour=0; // 将0赋给时分秒TMOD=0x01; // 方式1 P129(见课本)TH0=0x3c; // 65536-50000=15536=0x3cb0(50ms) P128(见课本)TL0=0xb0;EA=1; // 开总中断P161(见课本)TR0=1; // 定时/计数器0开启ET0=1; // 定时器/计数器0溢出中断启动P161(见课本)}void delay( unsigned int t) // 延时函数{unsigned int i;while(t--)for(i=0;i<125;i++);}void display() // 显示时间函数{if(TF0==1) // 定时器/计数器溢出P130(见课本){TF0=0; // 清中断标志位t++;if(t==20) // (50ms*20=1s){t=0;sec++; // 秒加1if(sec==60) // 秒为60,则清零,分加1{sec=0;min++;}if(min==60) // 分为60,则清零,时加1{min=0;hour++;}if(hour==24)// 时为24,则清零{hour=0;}}}data1[5]=sec%10;data1[4]=sec/10;data1[3]=min%10;data1[2]=min/10;data1[1]=hour%10;data1[0]=hour/10;WS=0xdf; // 1101 1111 ,低电平显示LED=tab[data1[5]];delay(1);WS=0xef; // 1110 1111LED=tab[data1[4]];delay(1);WS=0xf7; // 1111 0111LED=tab_dp[data1[3]];delay(1);WS=0xfb; // 1111 1011LED=tab[data1[2]];delay(1);WS=0xfd; // 1111 1101LED=tab_dp[data1[1]];delay(1);WS=0xfe; // 1111 1110LED=tab[data1[0]];delay(1);}void display_bb() // 显示闹钟函数{data2[5]=bbs%10;data2[4]=bbs/10;data2[3]=bbm%10;data2[2]=bbm/10;data2[1]=bbh%10;data2[0]=bbh/10;WS=0xdf; // 1101 1111 ,低电平显示LED=tab[data2[5]];delay(1);WS=0xef; // 1110 1111LED=tab[data2[4]];delay(1);WS=0xf7; // 1111 0111LED=tab_dp[data2[3]];delay(1);WS=0xfb; // 1111 1011LED=tab[data2[2]];delay(1);WS=0xfd; // 1111 1101LED=tab_dp[data2[1]];delay(1);WS=0xfe; // 1111 1110LED=tab[data2[0]];delay(1);}void keyscan() // 键盘扫描{if(key1==0) // 暂停/开始{++kk;while(!key1){display();if(kk==1){TR0=0;if(k1==0||k1==1||k1==2||k1==3) // 显示调节时间{display();}if(k1==4||k1==5||k1==6) // 显示调节闹钟{display_bb();}if(key2==0) // 模式选择(调节时间/闹钟){k1++;while(!key2){if(k1==1) // 第1次按下{sec1=sec; // 保存秒的数值sec=88; // 显示88,表示可以调节秒的数值了display(); // 显示88sec=sec1; // 恢复前一刻秒的数值}if(k1==2){min1=min;min=88;display();delay(1);min=min1;}if(k1==3){hour1=hour;hour=88;delay(1);hour=hour1;}if(k1==4){sec1=bbs; // 保存秒的数值bbs=66; // 显示66,表示可以调节秒的数值了display_bb(); // 显示66bbs=sec1; // 恢复前一刻秒的数值}if(k1==5){min1=bbm;bbm=66;display_bb();delay(10);bbm=min1;}if(k1==6){hour1=bbh;bbh=66;display_bb();delay(10);bbh=hour1;}if(k1==7){k1=0;display();}}}if(key3==0) // 时间/闹钟增加设置{while(!key3){if(k1==1){sec++;// 秒加1if(sec==60)sec=0;display();}if(k1==2){min++;delay(60);if(min==60)min=0;display();}if(k1==3){hour++;delay(60);if(hour==24)hour=0;display();}if(k1==4){bbs++; // 秒加1delay(60);if(bbs==60)bbs=0;display_bb();}if(k1==5){bbm++;delay(60);if(bbm==60)bbm=0;display_bb();}if(k1==6){bbh++;delay(60);if(bbh==24)bbh=0;display_bb();if(k1==7){k1=0;display();}}}if(key4==0) // 时间/闹钟减少设置{while(!key4){if(k1==1){sec--; // 秒加1delay(60);if(sec==0)sec=60;display();}if(k1==2){min--;delay(60);if(min==0)min=60;display();}if(k1==3){hour--;delay(60);if(hour==0)hour=24;display();}if(k1==4){bbs--; // 秒减1delay(60);if(bbs==0)bbs=60;display_bb();if(k1==5){bbm--;delay(60);if(bbm==0)bbm=60;display_bb();}if(k1==6){bbh--;delay(60);if(bbh==0)bbh=24;display_bb();}if(k1==7){k1=0;display();}}}}}if(kk==2){kk=0;k1=0;TR0=1;}}}。
51单片机的多功能电子钟
基于51单片机的多功能电子钟设计课程名称单片机原理及应用课程设计学生姓名所在班级学号联系电话起止时间指导老师目录一、摘要²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²2二、总体方案设计与论证²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²21、液晶显示模块²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²22、实时时间计算模块²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²23、实时环境温度采集模块²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²24、报警模块²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²25、设置模块²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²3三、总体方案组成框图²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²3四、系统硬件设计²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²41、LCD显示模块²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²42、实时时间计算模块²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²83、实时环境温度检测模块²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²114、报警模块²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²165、设置模块²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²16五、系统软件设计²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²17六、系统硬件PROTEUS仿真原理图²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²18七、系统硬件仿真运行情况图²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²181、显示开机界面²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²182、显示实时时间²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²193、显示当前温度²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²194、时间设置²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²205、最高报警温度设置²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²206、闹钟时间设置²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²217、超温²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²218、闹钟时间到²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²22 附录一:部分源程序代码²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²22 附录二:参考文献²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²23摘要单片机就是微控制器,是面向应用对象设计、突出控制功能的芯片。
51单片机做可调时钟(带秒表)另附proteus仿真图
/*********************信息学院09级电一***********************/
/**************************柳剑*******************************/
void display(uchar hour,uchar min,uchar sec)
{
unsigned char i;
TempData[0]=duanma[hour/10];
TempData[1]=duanma[hour%10];
TempData[2]=0x40;
TempData[3]=duanma[min/10];//用于显示分
#include<reg51.h>
#define uchar unsigned char
#define uint unsigned int
sbit menu=P3^2;
sbit reset=P1^0;//清零,秒表状态下也是清零
sbit add_min=P1^1;//调分时加一
sbit add_hour=P1^2;//调时时加一,秒表时按下不动跑表,松开暂停,再次按下继续跑表
hour0++;
if(hour0==24)
hour0=0;
}
}
}
}
/*************按键扫描1****************/
void keyscan1()
{
//display(hour0,min0,sec0);
if(reset==0)
{
51单片机制作诺基亚5110时间可调的时钟
该表时间可以调整,当按下调整按键的时候,时钟的时位开始闪烁,可以移动调整闪烁位,然后可以加时间,当再按下调整键的时候就不再闪烁了#include "reg52.h"#include "shu.h" 数据的编码不过没写在上面#include "zi.h" 汉字的字模表#include "xzimu.h" 小写字母的字模表sbit sce=P2^0; 芯片使能sbit res=P2^1; 复位端sbit dc=P2^2; 数据命令端口sbit sdin=P2^3; 串行数据输入端口sbit sclk=P2^4; 串行时钟输入端sbit k4=P1^3; 调整时间,时间加,选择位左移右移。
具体是哪个键后面会提到sbit k3=P1^2;sbit k2=P1^1;sbit k1=P1^0;unsigned char shi=12,fen=0,miao=0,count=0,dingwei=0; 时分秒定位等全局变量bit wei; 位定义全局变量这个主要是控制哪位开始闪烁void delay_1ms(void) 延时子程序{unsigned int i; 定义无符号数for(i=0;i<50;i++);}void LCD_write_byte(unsigned char dt,unsigned char command) 液晶写数据命令函数{unsigned char i;sce=0; 使芯片使能,低电平有效dc=command; dc即为数据命令选择控制端口for(i=0;i<8;i++){if(dt&0x80) 判断最高位,如果为1,则数据输出为1sdin=1;elsesdin=0;dt=dt<<1; 左移一位,即次高位,通过循环八次即把一个字节的数据传输出去sclk=0; 时钟的一个上升沿才能把数据传输出去,芯片接收数据的时候只认上升沿,一个上升沿传输一个数据sclk=1;}dc=1;sce=1; 使芯片接下来不受控制sdin=1; 相当于数据输入端的初始化}void LCD_init(void) LCD初始化{res=0; 使芯片复位delay_1ms(); 延时一小段时间res=1; 复位不再有效LCD_write_byte(0x21,0); 功能设置,选择扩展指令集LCD_write_byte(0xd0,0); 设置V OPLCD_write_byte(0x20,0); 功能设置,选择标准指令集LCD_write_byte(0x0C,0); 显示控制}void LCD_set_xy(unsigned char y,unsigned char x) 设定地址行列此显示分为6页(即行),84列{LCD_write_byte(0x40|y,0); 设定y地址LCD_write_byte(0x80|x,0); 设定x地址}void LCD_write_shu(unsigned char x,unsigned char y,unsigned char z) 写数字如果数据比较会占用两页的话就得设置两次地址,分为上下两页写{unsigned char i;LCD_set_xy(x,y*8); 设定显示的位置第N页for(i=1;i<=8;i++){LCD_write_byte(shu[z*16+i],1); 写shu这个数组中的数据}LCD_set_xy(x+1,y*8); 设定显示的位置第N+1页for(i=9;i<=16;i++){LCD_write_byte(shu[z*16+i],1); 写shu这个数组中的紧接下来的数据}}void LCD_write_zi(unsigned char x,unsigned char y,unsigned char z) 写字和上个函数一样{unsigned char i;LCD_set_xy(x,y*8);for(i=1;i<=16;i++){LCD_write_byte(zi[z*32+i],1);}LCD_set_xy(x+1,y*8);for(i=17;i<=32;i++){LCD_write_byte(zi[z*32+i],1);}}void LCD_write_xzimu(unsigned char x,unsigned char y,unsigned char z) 写小字母函数一样{unsigned char i;LCD_set_xy(x,y*8);for(i=1;i<=8;i++){LCD_write_byte(xzimu[z*16+i],1);}LCD_set_xy(x+1,y*8);for(i=9;i<=16;i++){LCD_write_byte(xzimu[z*16+i],1);}}void LCD_clear(void) LCD清屏{unsigned char t;unsigned char k;LCD_set_xy(0,0); 设定清屏的起始地址for(t=0;t<=6;t++) 循环清屏六页{for(k=0;k<84;k++){LCD_write_byte(0x00,1); 全屏写数据零即为清屏}}}timer0()interrupt 1 using 1{ 定时器0TH0=0x4b;TL0=0xff; count++; 定时值可以自己查}void LCD_san(unsigned char x,unsigned char y,unsigned char z) LCD闪烁函数{if(count==8) 定时器定时周期到了八次之后就写空白{LCD_write_xzimu(x,y,4);}if(count==18) 等定时器定时周期到了十八次的时候就写此刻的时间,这样就能实现闪烁的功能了{LCD_write_shu(x,y,z);}}void LCD_tiaoshi(void) 时间调试函数{if(k4==0) 如果k4按键按下{delay_1ms(); 延时去抖动if(k4!=0) 如果按键松开了,则再处理程序,这样可以防止一次按键,程序被执行多次{wei=~wei; wei即为闪烁控制标志位,如果wei==0;则不闪dingwei=1;if(wei==0){LCD_write_shu(2,1,shi/10);LCD_write_shu(2,2,shi%10);LCD_write_shu(2,4,fen/10);LCD_write_shu(2,5,fen%10);}}}if(wei==1){switch(dingwei) dingwei即选择哪一位闪烁,相当于一个闪烁标志位{case 1: LCD_san(2,1,shi/10);break;case 2: LCD_san(2,2,shi%10);break;case 3: LCD_san(2,4,fen/10);break;case 4: LCD_san(2,5,fen%10);break;default: break;}if(k3==0&dingwei!=1) 闪烁位左移{delay_1ms();if(k3!=0){dingwei--;switch(dingwei){case 1: LCD_write_shu(2,2,shi%10);break;case 2: LCD_write_shu(2,4,fen/10);break;case 3: LCD_write_shu(2,5,fen%10);break;default: break;}}}if(k1==0) 时间加{delay_1ms();if(k1!=0){switch(dingwei){case 1: {if(shi/10<=1){shi=shi+10;}else shi=shi-20;};break;case 2: {if(shi%10<9){shi++;}else shi=shi-9;};break;case 3: {if(fen/10<5){fen+=10;}else fen-=50;};break;case 4: {if(fen%10<9){fen++;}else fen-=9;};break;default: break;}}}if(k2==0&dingwei!=4) 闪烁位右移{delay_1ms();if(k2!=0){dingwei++ ;switch(dingwei){case 2: LCD_write_shu(2,1,shi/10);break;case 3: LCD_write_shu(2,2,shi%10);break;case 4: LCD_write_shu(2,4,fen/10);break;default: break;}}}}if(shi>=24){shi-=4;}}void main(){unsigned char k;res=0; 液晶复位for(k=0;k<250;k++);res=1;LCD_init(); 液晶初始化LCD_clear(); 液晶清屏LCD_write_zi(0,1,0); //chong “重”这个汉字这些就是一开机液晶屏显示的初始时间LCD_write_zi(0,3,1); //qing “庆”LCD_write_zi(0,5,2); //shi “时”LCD_write_zi(0,7,3); //jian “间”LCD_write_shu(2,3,10); //mao hao 冒号LCD_write_shu(2,6,10); // mao haoLCD_write_shu(2,1,1); //shi gao 写时的高位LCD_write_shu(2,2,2); //shi di 时的地位LCD_write_shu(2,4,0); //fen gao 分的高位LCD_write_shu(2,5,0); //shi diLCD_write_shu(2,7,0); //miao gaoLCD_write_shu(2,8,0); //miao diLCD_write_xzimu(4,0,0); //cLCD_write_xzimu(4,1,1); //oLCD_write_xzimu(4,2,2); //mLCD_write_xzimu(4,3,3); //eLCD_write_xzimu(4,4,7); //LCD_write_xzimu(4,5,8); //bLCD_write_xzimu(4,6,9); //aLCD_write_xzimu(4,7,10); //bLCD_write_xzimu(4,8,11); //yEA=1;TMOD=0x01; //工作方式定时0TH0=0x4b;TL0=0xff; //定时50msET0=1; //定时器0中断允许TR0=1;while(1){if(count==10) 半秒到了就开始闪烁时间之间的冒号{LCD_write_xzimu(2,3,4);LCD_write_xzimu(2,6,4);}if(count==20) 到了一秒则开始处理时间{LCD_write_shu(2,3,10);LCD_write_shu(2,6,10);count=0;if(miao!=60) 若秒没到60则秒加一{miao++;LCD_write_shu(2,7,miao/10);LCD_write_shu(2,8,miao%10);}if(miao==60){fen++;miao=0;LCD_write_shu(2,7,0);LCD_write_shu(2,8,0);LCD_write_shu(2,4,fen/10);LCD_write_shu(2,5,fen%10);if(fen==60){shi++;LCD_write_shu(2,1,shi/10);LCD_write_shu(2,2,shi%10);fen=0;LCD_write_shu(2,4,0);LCD_write_shu(2,5,0);if(shi==24){shi=0;LCD_write_shu(2,1,0);LCD_write_shu(2,2,0);}}}} LCD_tiaoshi();}}。