51单片机的数字钟程序
51单片机作的电子钟程序及电路图

51单片机作的电子钟程序在很多地方已经有了介绍,对于单片机学习者而言这个程序基本上是一道门槛,掌握了电子钟程序,基本上可以说51单片机就掌握了80%。
常见的电子钟程序由显示部分,计算部分,时钟调整部分构成。
时钟的基本显示原理:时钟开始显示为0时0分0秒,也就是数码管显示000000,然后每秒秒位加1 ,到9后,10秒位加1,秒位回0。
10秒位到5后,即59秒,分钟加1,10秒位回0。
依次类推,时钟最大的显示值为23小时59分59秒。
这里只要确定了1秒的定时时间,其他位均以此为基准往上累加。
开始程序定义了秒,十秒,分,十分,小时,十小时,共6位的寄存器,分别存在30h,31h,32h,33h,34h,35h单元,便于程序以后调用和理解。
6个数码管分别显示时、分、秒,一个功能键,可以切换调整时分秒、增加数值、熄灭节电等功能全部集一键。
以下是部分汇编源程序,购买我们产品后我们用光盘将完整的单片机汇编源程序和烧写文件送给客户。
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 中断入口程序 ;; (仅供参考) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ORG 0000H ;程序执行开始地址LJMP START ;跳到标号START执行ORG 0003H ;外中断0中断程序入口RETI ;外中断0中断返回ORG 000BH ;定时器T0中断程序入口LJMP INTT0 ;跳至INTTO执行ORG 0013H ;外中断1中断程序入口RETI ;外中断1中断返回ORG 001BH ;定时器T1中断程序入口LJMP INTT1 ;跳至INTT1执行ORG 0023H ;串行中断程序入口地址RETI ;串行中断程序返回;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; 主程序 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;START: MOV R0,#70H ;清70H-7AH共11个内存单元MOV R7,#0BH;clr P3.7 ;CLEARDISP: MOV @R0,#00H ;INC R0 ;DJNZ R7,CLEARDISP ;MOV 20H,#00H ;清20H(标志用)MOV 7AH,#0AH ;放入"熄灭符"数据MOV TMOD,#11H ;设T0、T1为16位定时器MOV TL0,#0B0H ;50MS定时初值(T0计时用)MOV TH0,#3CH ;50MS定时初值MOV TL1,#0B0H ;50MS定时初值(T1闪烁定时用)MOV TH1,#3CH ;50MS定时初值SETB EA ;总中断开放SETB ET0 ;允许T0中断SETB TR0 ;开启T0定时器MOV R4,#14H ;1秒定时用初值(50M S×20)START1: LCALL DISPLAY ;调用显示子程序JNB P3.7,SETMM1 ;P3.7口为0时转时间调整程序SJMP START1 ;P3.7口为1时跳回START1 SETMM1: LJMP SETMM ;转到时间调整程序SETMM; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; 1秒计时程序 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;T0中断服务程序INTT0: PUSH ACC ;累加器入栈保护PUSH PSW ;状态字入栈保护CLR TR0 ;关闭定时器T0MOV A,#0B7H ;中断响应时间同步修正ADD A,TL0 ;低8位初值修正MOV TL0,A ;重装初值(低8位修正值)MOV A,#3CH ;高8位初值修正ADDC A,TH0 ;MOV TH0,A ;重装初值(高8位修正值)SETB TR0 ;开启定时器T0DJNZ R4, OUTT0 ;20次中断未到中断退出ADDSS: MOV R4,#14H ;20次中断到(1秒)重赋初值MOV R0,#71H ;指向秒计时单元(71H-72H)ACALL ADD1 ;调用加1程序(加1秒操作)MOV A,R3 ;秒数据放入A(R3为2位十进制数组合)CLR C ;清进位标志CJNE A,#60H,ADDMM ;ADDMM: JC OUTT0 ;小于60秒时中断退出ACALL CLR0 ;大于或等于60秒时对秒计时单元清0MOV R0,#77H ;指向分计时单元(76H-77H)ACALL ADD1 ;分计时单元加1分钟MOV A,R3 ;分数据放入ACLR C ;清进位标志CJNE A,#60H,ADDHH ;ADDHH: JC OUTT0 ;小于60分时中断退出ACALL CLR0 ;大于或等于60分时分计时单元清0MOV R0,#79H ;指向小时计时单(78H-79H)ACALL ADD1 ;小时计时单元加1小时MOV A,R3 ;时数据放入ACLR C ;清进位标志CJNE A,#24H,HOUR ;HOUR: JC OUTT0 ;小于24小时中断退出ACALL CLR0 ;大于或等于24小时小时计时单元清0OUTT0: MOV 72H,76H ;中断退出时将分、时计时单元数据移MOV 73H,77H ;入对应显示单元MOV 74H,78H ;MOV 75H,79H ;POP PSW ;恢复状态字(出栈)POP ACC ;恢复累加器RETI ;中断返回; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 闪动调时程序 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;T1中断服务程序,用作时间调整时调整单元闪烁指示INTT1: PUSH ACC ;中断现场保护PUSH PSW ;MOV TL1, #0B0H ;装定时器T1定时初值MOV TH1, #3CH ;DJNZ R2,INTT1OUT ;0.3秒未到退出中断(50MS中断6次)MOV R2,#06H ;重装0.3秒定时用初值CPL 02H ;0.3秒定时到对闪烁标志取反JB 02H,FLASH1 ;02H位为1时显示单元"熄灭"MOV 72H,76H ;02H位为0时正常显示MOV 73H,77H ;MOV 74H,78H ;MOV 75H,79H ;INTT1OUT: POP PSW ;恢复现场POP ACC ;RETI ;中断退出FLASH1: JB 01H,FLASH2 ;01H位为1时,转小时熄灭控制MOV 72H,7AH ;01H位为0时,"熄灭符"数据放入分MOV 73H,7AH ;显示单元(72H-73H),将不显示分数据MOV 74H,78H ;MOV 75H,79H ;AJMP INTT1OUT ;转中断退出FLASH2: MOV 72H,76H ;01H位为1时,"熄灭符"数据放入小时MOV 73H,77H ;显示单元(74H-75H),小时数据将不显示MOV 74H,7AH ;MOV 75H,7AH ;AJMP INTT1OUT ;转中断退出; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 加1子程序 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ADD1: MOV A,@R0 ;取当前计时单元数据到ADEC R0 ;指向前一地址SWAP A ;A中数据高四位与低四位交换ORL A,@R0 ;前一地址中数据放入A中低四位ADD A,#01H ;A加1操作DA A ;十进制调整MOV R3,A ;移入R3寄存器ANL A,#0FH ;高四位变0MOV @R0,A ;放回前一地址单元MOV A,R3 ;取回R3中暂存数据INC R0 ;指向当前地址单元SWAP A ;A中数据高四位与低四位交换ANL A,#0FH ;高四位变0MOV @R0,A ;数据放入当削地址单元中RET ;子程序返回; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 清零程序 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;............. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 时钟调整程序 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;当调时按键按下时进入此程序SETMM: cLR ET0 ;关定时器T0中断CLR TR0 ;关闭定时器T0LCALL DL1S ;调用1秒延时程序JB P3.7,CLOSEDIS ;键按下时间小于1秒,关闭显示(省电)MOV R2,#06H ;进入调时状态,赋闪烁定时初值SETB ET1 ;允许T1中断SETB TR1 ;开启定时器T1SET2: JNB P3.7,SET1 ;P3.7口为0(键未释放),等待SETB 00H ;键释放,分调整闪烁标志置1SET4: JB P3.7,SET3 ;等待键按下LCALL DL05S ;有键按下,延时0.5秒JNB P3.7,SETHH ;按下时间大于0.5秒转调小时状态MOV R0,#77H ;按下时间小于0.5秒加1分钟操作LCALL ADD1 ;调用加1子程序MOV A,R3 ;取调整单元数据CLR C ;清进位标志CJNE A,#60H,HHH ;调整单元数据与60比较HHH: JC SET4 ;调整单元数据小于60转SET4循环LCALL CLR0 ;调整单元数据大于或等于60时清0CLR C ;清进位标志AJMP SET4 ;跳转到SET4循环CLOSEDIS: SETB ET0 ;省电(LED不显示)状态。
基于51单片机的数码管时钟(带闹钟调时秒表)

基于51单片机的数码管时钟(带闹钟调时秒表)/**************************************************************** ************ ** *********************************************************** ** * * ** * * ** * 基于51单片机的数码管时钟程序* ** ** * * ** * * *********************************************************** ** ** ************************************************************ ****************/#include<stdio.h>#define uint unsigned int#define uchar unsigned charsbit dula=P2^6; //申明u1锁存器的锁存端sbit wela=P2^7; //申明u2锁存器的锁存端sbit key1=P3^0; //功能键sbit key2=P3^1;//增大键sbit key3=P3^2;//减小键sbit key4=P3^3;//秒表查看键sbit beep=P2^3;//蜂鸣端uchar num,num1,num2,numm;uchar numf,num,nums,num;uchar s,s1,f,f1,m,m1;uchar ns,ns1,nf,nf1;uchar numns,numnf;uchar dingshi;void display(uchar m,uchar m1,ucharf,uchar f1,uchar s,uchar s1);void display1(uchar nf,uchar nf1,uchar ns,uchar ns1);void key();void key1();void alram();void di();void delayms(xms);void T0_time() interrupt 1;void miaobiao();uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x77,0x7c,0x39,0x5e,0x79,0x71};/*********************************************************主函数void main()*********************************************************/int main(){TMOD=0X01;TH0=(65536-46080)/256;TL0=(65536-46080)%256;EA=1;ET0=1;TR0=1;nums=12;numf=0;num2=0;num=0;while(1){if(dingshi==0){keyscan();display(m,m1,f,f1,s,s1);alarm();}else{miaobiao();keyscan1();display1(nf,nf1,ns,ns1);}}return 0;}/********************************************************* 蜂鸣器函数di()*********************************************************/ void di(){beep=0;delayms(100);beep=1;}/********************************************************** 按键调时函数key()**********************************************************/ void keyscan(){if(key1==0){delayms(10);display(m,m1,f,f1,s,s1);}}}/********************************************** 按键设定闹钟函数keyscan1();***********************************************/ void keyscan1(){if(key1==0){delayms(10);if(key1==0){ numns++;if(numns==24);numns=0;while(!key1);di();display1(nf,nf1,ns,ns1);}}if(key2==0){delayms(10);if(key2==0){ numnf++;if(numnf==24);numnf=0;while(!key2);di();display1(nf,nf1,ns,ns1);}}if(key3==0){delayms(10);if(key3==0){dingshi=0;while(!key1);di();display1(nf,nf1,ns,ns1);}}}/********************************************************* 闹钟函数alram()*********************************************************/ void alram(){if((nums==numns)&&(numnf==numf))beep=0;}/*********************************************************秒表函数miaobiao()*********************************************************/ void miaobiao(){if(key4==0){delayms(100);if(key4==0){while(!key4);di();displaym(uchar m,uchar m1);}}}/********************************************************* 正常显示函数display()*********************************************************/ void display(uchar m,uchar m1,ucharf,uchar f1,uchar s,uchar s1){dula=1;P0=table[m1]//秒位第1位dula=0;PO=0xff;// 送入位选信号前关闭所有显示,防止打开位选锁存时wela=1;P0=0xef;wela=0;delayms(10);dula=1;P0=table[m]; //秒第2位dula=0;P0=0xff;wela=1;P0=0xdf;wela=0;delayms(100)dula=1;P0=table[f1]; //分第1位dula=0;P0=0xff;wela=1;P0=0xfb;wela=0;delayms(100)dula=1;P0=table[f]; //分第2位dula=0;P0=0xff;wela=1;P0=0xf7;wela=0;delayms(10)dula=1;P0=table[s1]; //时第1位dula=0;P0=0xff;wela=1;P0=0xfe;wela=0;delayms(100)dula=1;P0=table[s]; //时第2位dula=0;P0=0xff;wela=1;P0=0xfd;wela=0;delayms(10)}/********************************************************** ***调时闹钟显示函数display1()*********************************************************** **/void display1(uchar nf,uchar nf1,uchar ns,uchar ns1){nf1=numnf/10;nf=numnf%10;ns1=nums/10;ns=nums%10;dula=1;P0=table[nf1];//分第1位dula=0;P0=0xff;wela=1;P0=0xfb;//待改参数wela=0;delayms(10);dula=1;P0=table[nf];//分第2位dula=0;P0=0xff;wela=1;P0=0xf7;//待改参数wela=0;delayms(10);P0=table[ns1];//时第1位dula=0;P0=0xff;wela=1;P0=0xfe;//待改参数wela=0;delayms(10);dula=1;P0=table[ns];//时第2位dula=0;P0=0xfd;wela=1;P0=0xff;//待改参数wela=0;delayms(10);}/********************************************************** ***秒表显示函数displaym()*********************************************************** **/void displaym(uchar m,uchar m1){dula=1;P0=table[m1];//秒位第一位P0=0xff;wela=1;P0=0Xbf;wela=0;delayms(10);dula=1;P0=table[m];dula=0;P0=0xff;wela=1;P0=0X7f;wela=0;delayms(10);}/**************************************************** 中断服务函数void T0_time() interrupt 1****************************************************/ void T0_time() interrupt 1{TH0=(65536-45872)/256; //46080TL0=(65536-45872)%256;num2++;if(num2==20){num++;num2=0;m=num%10;m1=num/10;f=numf%10;f1=numf/10;s=nums%10;s1=nums/10;if(num==59){num=0;numf++;if(numf==59){numf=0;nums++;}if(nums==24)nums=0;}}}/*************************************************** 延时函数delayms()***************************************************/ void delayms(xms){uint i,j;for(i=xms;i>0;i--)for(j=110;j>0;j--); }。
51-数字时钟-89C52-单片机C语言程序

51-数字时钟-89C52-单片机C语言程序数字时钟89C52 单片机C语言程序STC89C52|/************** 【数字时钟】****************//****【功能】1、时间显示2、秒表3、闹钟4、日期显示都可以设置****/#include /*包含器件配置文件*/#define uchar unsigned char /*宏定义字符型数据整型数据*/ #define uint unsigned intuchar code H[] = {0x0f, 0x07, 0x0b, 0x0d, 0x0e}; /*按键【P3】端口断码用于按键*/ char Code[10] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d,0x7d, 0x07, 0x7f, 0x6f}; /*显示【0 1 2 3 4 5 6 7 8 9】数字的数码管的段码*/ uchar code C[] = {0x0, 0xFE, 0xFD, 0xFB, 0xF7, 0xEF, 0xDF, 0xBF, 0x7F};/*列扫描控制LED1位2位3位4位5位6位7位8位*/uchar MON[]={0,31,28,31,30,31,30,31,31,30,31,30,31};uchar A;uchar BIN=0; /* 【BIN】作为倒计时开始的标志*/uchar hour = 0; /* 定义[时][分][秒] */uchar min = 0;uchar sec = 0;uint shi=12;uint fen=30;uchar Mmin=0;uchar Msec=30;uchar M0=0;uchar m=0;uchar year=9;uchar month=7;uchar month2;uchar day=19;uchar set1 = 1; /* set1=1 是调节时分秒set1=2时时调节年月日set=3时事调节闹钟*/uchar set2 = 1; /* set2=1时是调节【时】位set2=2时事调节【分】位*/uint x = 0; /* x 每【0.01s】自加一*/void Delay(uint k);void Timer0() /*定时器T0 5mS初始化*/{TMOD = 0x01; /*设置*定时器0**计数方式一* (每12个时钟脉冲计数一次)或IT0=1 第二种计数方式*/TH0 = (65536 - 10000) / 256; /*给定计时器高位赋予初值=15536/256*/TL0 = (65536 - 10000) % 256; /*给定计时器低位赋予初值=15536%256 */ET0 = 1; /*打开定时器外部终断0允许ET1是中断器1的开关*/ EA = 1; /*打开总中断允许*/TR0 = 1;}void T0_srv(void) interrupt 1 /*5mS定时中断服务函数秒分时的值*/{TH0 = (65536 - 10000) / 256; /*给定计时器高位赋予初值=15536/256*/TL0 = (65536 - 10000) % 256; /*给定计时器低位赋予初值=15536%256 */x++;if(x==100){sec++;x=0; /*没每一秒【sec】加一*/if(sec==60){min++;sec=0;if(min==60) /*每一分钟【min】加一*/ {min = 0;hour++;if(hour==24){hour = 0; /*每一小时【hour】加一*/ day++;if(year%4==0) /*是否闰年的判断*/ MON[2]=29;else MON[2]=28;if(day==MON[month]){day=0;month++;}}}}}if(BIN==1)if(Mmin!=0||Msec!=0){M0 = 100-x;if(M0==100){ if(Mmin>0){Msec--;if(Msec==0){Msec=60;Mmin-- ;}if(Msec==0) {Mmin=0;Msec=0;M0=0;} }if(Mmin==0){if(Msec!=0)Msec--;if(Msec==0){Msec=0;M0=0;}}}}if(Mmin==0&&Msec==0){M0=0;}} /*秒表分秒M0的赋值*/}void Scan_key() /*按键扫描函数【Scan_key()】*/ {P3=H[0];if(P3!=H[0])Delay(1);if(P3==H[4]){set1++;if(set1>4) set1 = 1;er1: if(P3==H[4]) goto er1; /*按下键后未释放,在此等候*/ }Delay(1);if(P3==H[3]){set2++;if(set2>3) set2 = 1;er2: if(P3==H[3]) goto er2; /*按下键后未释放,在此等候*/ }Delay(1);if(P3==H[1]){BIN++;if(BIN>1) BIN=0;er3: if(P3==H[1]) goto er3; /*按下键后未释放,在此等候*/ }}}void Time_show() /*时间的显示变量为【时】【分】【秒】*/ { P0 = Code[hour/10]; /*第一位数字显示【时】的【十】位*/ P2 = C[1];Delay(1);P0 = Code[hour%10]; /*第二位数字显示【时】的【个】位*/P2 = C[2];Delay(1);if(x/50==0)P0 = 0x40; /*第三位符号【-】的显示*/elseP0 = 0x00;P2 = C[3];Delay(1);P0 = Code[min/10]; /*第四位的数字的显示【分】的【十】位*/ P2 = C[4];Delay(1);P0 = Code[min%10]; /*第五位的数字显示【分】的【个】位*/ P2 = C[5];Delay(1);Delay(1);if(x/50==0)P0 = 0x40; /*第六位符号【-】的显示*/elseP0 = 0x00;P2 = C[6];Delay(1);P0 = Code[sec/10]; /*第七位数字的显示【秒】的【十】位显示*/P2 = C[7];Delay(1);P0 = Code[sec%10]; /*第八位数字的显示【秒】的【个】位显示*/ P2 = C[8];Delay(1);}void Year_show(){P0 = Code[year/10]; /*第一位数字显示【年】的【十】位*/P2 = C[1];Delay(1);P0 = Code[year%10]; /*第二位数字显示【年】的【个】位*/P2 = C[2];Delay(1);P0 = 0x40; /*第三位符号【-】的显示*/P2 = C[3];Delay(1);P0 = Code[month/10]; /*第四位的数字的显示【月】的【十】位*/P2 = C[4];Delay(1);P0 = Code[month%10]; /*第五位的数字显示【月】的【个】位*/P2 = C[5];Delay(1);Delay(1);P0 = 0x40; /*第六位符号【-】的显示*/P2 = C[6];Delay(1);P0 = Code[day/10]; /*第七位数字的显示【天】的【十】位显示*/P2 = C[7];Delay(1);P0 = Code[day%10]; /*第八位数字的显示【天】的【个】位显示*/ P2 = C[8];Delay(1);}void Clock_show(){P0 = Code[shi/10]; /*第一位数字显示【时】的【十】位*/P2 = C[4];P0 = Code[shi%10]; /*第二位数字显示【时】的【个】位*/P2 = C[5];Delay(1);P0 = 0x40; /*第三位符号【-】的显示*/P2 = C[6];Delay(1);P0 = Code[fen/10]; /*第四位的数字的显示【分】的【十】位*/ P2 = C[7];Delay(1);P0 = Code[fen%10]; /*第五位的数字显示【分】的【个】位*/P2 = C[8];Delay(1);}void Miao_show() /*时间的显示变量为【时】【分】【秒】*/ { P0 = Code[Mmin/10]; /*第一位数字显示【时】的【十】位*/P2 = C[1];Delay(1);P0 = Code[Mmin%10]; /*第二位数字显示【时】的【个】位*/ P2 = C[2];Delay(1);P0 = 0x40; /*第三位符号【-】的显示*/P2 = C[3];Delay(1);P0 = Code[Msec/10]; /*第四位的数字的显示【分】的【十】位*/ P2 = C[4];Delay(1);P0 = Code[Msec%10]; /*第五位的数字显示【分】的【个】位*/ P2 = C[5];Delay(1);P0 = 0x40; /*第六位符号【-】的显示*/P2 = C[6];Delay(1);P0 = Code[M0/10]; /*第七位数字的显示【秒】的【十】位显示*/P2 = C[7];Delay(1);P0 = Code[M0%10]; /*第八位数字的显示【秒】的【个】位显示*/ P2 = C[8];Delay(1);}void Time_set() /*调整时间的函数time_set() */{Scan_key();if(set1==1){if(set2==1) /*当set1=1 set2=1时位时的设置*/{if(P3==H[2]) hour++; /*按一下第三行的键hour 就加一*/Delay(1);if(hour>24) hour=0;while(P3==H[2]); /*按键未释放,在此等候*/}if(set2==2) /*当set1=1 set2=1时位时的设置*/{if(P3==H[2]) min++; /*按一下第三行的键hour 就加一*/Delay(1);if(min>60){ min=0; hour++;}while(P3==H[2]); /*按键未释放,在此等候*/}}}void Year_set() /*调整时间的函数time_set() */{Scan_key();if(set1==2){if(set2==1) /*当set1=1 set2=1时位时的设置*/{if(P3==H[2]) year++; /*按一下第三行的键hour 就加一*/ Delay(1);if(year>100) year=0;while(P3==H[2]);}if(set2==2) /*当set1=1 set2=1时位时的设置*/{if(P3==H[2]) month++; /*按一下第三行的键hour 就加一*/ Delay(1);if(month>12){ month=0; year++;}while(P3==H[2]);}if(set2==3){if(P3==H[2]) day++; /*按一下第三行的键hour 就加一*/ Delay(1);if(day>MON[month]){ day=0; month++;}while(P3==H[2]); /*按键未释放,在此等候*/}}}Clock_set(){Scan_key();if(set1==3){if(set2==1) /*当set1=1 set2=1时位时的设置*/{if(P3==H[2]) shi++; /*按一下第三行的键hour 就加一*/ Delay(1);if(shi>24) shi=0;while(P3==H[2]); /*按键未释放,在此等候*/}if(set2==2) /*当set1=1 set2=1时位时的设置*/{if(P3==H[2]) fen++; /*按一下第三行的键hour 就加一*/ Delay(1);if(fen>60){ fen=0; shi++;}while(P3==H[2]); /*按键未释放,在此等候*/}}}void Miao_set() /*调整时间的函数time_set() */{Scan_key();if(set1==4){if(set2==1) /*当set1=1 set2=1时位时的设置*/{if(P3==H[2]) Mmin++; /*按一下第三行的键hour 就加一*/Delay(1);if(Mmin>24) Mmin=0;while(P3==H[2]); /*按键未释放,在此等候*/}if(set2==2) /*当set1=1 set2=1时位时的设置*/{if(P3==H[2]) Msec++; /*按一下第三行的键hour 就加一*/ Delay(1);。
51单片机数字钟汇编程序

SEC EQU 32H ;秒即时时间\伪指令MIN EQU 31H ;分HOUR EQU 30H ;时DAY EQU 35H ;日MON EQU 34H ;月YEAR EQU 33H ;年MIN_1 EQU 41H ;分定时器1路、开存储单元HOUR_1 E QU 42H ;时DAY_1 EQU 43H ;MON_1 EQU 44H ;YEAR_1 EQU 45H ;MIN_11 EQU 40H ;分定时器1路、关存储单元HOUR_11 EQU 46H ;时DAY_11 EQU 47H ;日MON_11 EQU 48H ;月YEAR_11 EQU 49H ;年ORG 0000HLJMP MAINORG 0003H ;中断转换显示年月日、INT0(SB4键)LJMP WB0ORG 000BH ;计数中断T0、方式1LJMP TT0ORG 0013HLJMP WB1; 调整时间、定时、INT1(SB0键);------主程序ORG 0030HMAIN: MOV YEAR,#02;初始化付值MOV MON,#05MOV DAY,#01MOV HOUR,#00MOV MIN,#00MOV SEC,#00CLR 40H ;定时单元1路清零CLR 41HCLR 42HCLR 43HCLR 44HCLR 45HCLR 46HCLR 47HCLR 48HCLR 49H;-------开中断MOV TMOD,#01H ;计数、模式1、T0MOV TL0,#0B0H ;100SM 计数定时MOV TH0,#3CH ;CLR P3.0MOV 20H,#0AH ;10次*100SMSETB PT0 ;T0为最高级SETB TR0 ;允许计数SETB ET0 ;允许T0中断SETB EX0 ;允许INT0中断SETB EX1 ;允许INT1中断SETB EA ;开总中断;------显示、定时器启动判断LOOP: MOV R1,#30H; 存储单元MOV R4,#01H; 位选通MOV R3,#03H; 三组显示NEXT: MOV A,@R1 ;MOV B,#10 ;将存储单元转换成两高低两组的BCD码DIV ABSWAP AORL A,BMOV P0,A;输出MOV P2,R4INC R1 ;下一单元MOV A,R4 ;RL A ;位移MOV R4,ALCALL DE5SM ;延时0.5SMDJNZ R3,NEXT ;全扫描显示一偏;------判断定时输出(只编写了一路)CJNE R7,#88H,LOOP ;是8则开,否则、定时已关、转;---------开MOV A,YEARCJNE A,YEAR_1,LOOP_1;年比较,不等转关MOV A,MONCJNE A,MON_1,LOOP_1MOV A,DAYCJNE A,DAY_1,LOOP_1MOV A,HOURCJNE A,HOUR_1,LOOP_1MOV A,MINCJNE A,MIN_1,LOOP_1CPL P3.0;---------关LOOP_1:MOV A,YEARCJNE A,YEAR_11, LOOP;年比较MOV A,MONCJNE A,MON_11,LOOPMOV A,DAYCJNE A,DAY_11,LOOPMOV A,HOURCJNE A,HOUR_11,LOOPMOV A,MINCJNE A,MIN_11,LOOPCPL P3.0LJMP LOOP;-----年月日显示中断子程序WB0: PUSH PSWPUSH ACCPUSH BPUSH 01HPUSH 02HPUSH 03HPUSH 04HMOV R2,#0FFH ;中断扫描次数TURN: MOV R1,#33HMOV R4,#01HMOV R3,#03HNEXT_1:MOV A,@R1MOV B,#10DIV ABSWAP AORL A,BMOV P0,AMOV P2,R4INC R1RL AMOV R4,ALCALL DE5SMDJNZ R3,NEXT_1DJNZ R2,TURN ;反复显示一定时间后返回POP 04HPOP 03HPOP 02HPOP 01HPOP BPOP ACCPOP PSWRETI;-----计数中断服务子程序TT0: PUSH PSWPUSH ACCPUSH BPUSH 06HMOV TH0,#3CH;重装计数MOV TL0,#0BH;DJNZ 20H,OUT ;转到中断跳出pop程序MOV 20H,#0AH ; 重装:100*10=1000;-----进位程序INC S ECMOV R6,SEC ;CJNE R6,#60,OUT;比较MOV SEC,#00 ;INC MINMOV R6,MINCJNE R6,#60,OUTMOV MIN,#00INC HOURMOV R6,HOURCJNE R6,#25,OUTMOV HOUR,#00INC DAYMOV R5,MONCJNE R5,#1,MON_22;是否1月、不是转2 月MOV R5,DAYCJNE R5,#32,OUT ; 本月是否益出INC MONMOV DAY,#1LJMP OUTOUT: P OP 06HPOP BPOP ACCPOP PSWRETIMON_22:MOV R5,MONCJNE R5,#2,MON_33;是否2月、不是转3月MOV A,YEAR ;判断是否瑞年MOV B,#4DIV ABMOV A,BJNZ OUT_1;不是则转(A不为零则转)MOV R5,DAYCJNE R5,#30,OUT;如是瑞年、判断是否到29天INC M ONMOV DAY,#1LJMP OUTOUT_1:MOV R5,DAYCJNE R5,#29,OUT ;平年二月判断INC MONMOV DAY,#1LJMP OUTMON_33:MOV R5,MONCJNE R5,#3,MON_44MOV R5,DAYCJNE R5,#32,OUTINC MONMOV DAY,#1LJMP OUTMON_44:MOV R5,MONCJNE R5,#4,MON_55MOV R5,DAYCJNE R5,#31,OUTINC M ONMOV DAY,#1LJMP OUTMON_55:MOV R5,MONCJNE R5,#5,MON_66MOV R5,DAYCJNE R5,#32,OUTINC M ONMOV DAY,#1LJMP OUTMON_66:MOV R5,MONCJNE R5,#6,MON_77MOV R5,DAYCJNE R5,#31,OUTINC M ONMOV DAY,#1LJMP OUTMON_77:CJNE R5,#7,MON_88MOV R5,DAYCJNE R5,#32,L1INC M ONMOV DAY,#1L1: LJMP OUTMON_88:MOV R5,MONCJNE R5,#8,MON_99MOV R5,DAYCJNE R5,#32,L2INC M ONMOV DAY,#1L2: LJMP OUTMON_99:MOV R5,MONCJNE R5,#9,MON_00MOV R5,DAYCJNE R5,#31,L3INC M ONMOV DAY,#1L3: LJMP OUTMON_00:MOV R5,MONCJNE R5,#10,MON_AAMOV R5,DAYCJNE R5,#32,L4INC M ONMOV DAY,#1L4: LJMP OUTMON_AA:MOV R5,MONCJNE R5,#11,MON_BBMOV R5,DAYCJNE R5,#31,L5INC M ONMOV DAY,#1L5: LJMP OUTMON_BB:MOV R5,DAYCJNE R5,#32,L6INC Y EARMOV MON,#1L6: LJMP OUT;-----校对时间、定时调整中断WB1 : PUSH PSWPUSH ACCPUSH BPUSH 00HMOV P2,#00HSHOW_1:MOV A,#01H;显示1MOV P0,AMOV P2,#0FFH;三组数码管都显示1路LCALL READ ;调用读p1口键程序CJNE A,01H,SHOW_1;去抖后比较LCALL DE250SM ; 延时250秒CJNE A,#0FBH,ttT1LJMP SB3_1ttT1: CJNE A,#0FEH,SHOW_1AJMP SHOW_2;-------二组显示SHOW_2:MOV A,#02H; 显示2MOV P0,AMOV P2,#0FFH;LCALL READCJNE A,01H,SHOW_2 ;去抖后比较LCALL DE250SM; 延时250秒CJNE A,#0FBH,T2;不等转去判断此时SB3按了没LJMP SB3_2T2: CJNE A,#0FEH,SHOW_2AJMP SHOW_3;_------三组显示SHOW_3:MOV A,#03H; 显示3MOV P0,AMOV P2,#0FFH;位码LCALL READCJNE A,01H,SHOW_3;去抖后比较LCALL DE250SM;延时250秒CJNE A,#0FBH,T3;不等转去判断此时SB3按了没LJMP SB3_3T3: CJNE A,#0FEH,SHOW_3AJMP SHOW_4;------即时年单元调时、显示SHOW_4:MOV A,YEAR ;调出年单元MOV B,#10 ;BCD转换DIV A BSWAP AORL A,BMOV P0,A ;MOV P2,#01H;LCALL READLCALL DE250SMCJNE A,01H,SHOW_4 ;去抖CJNE A,#0FEH,KEY2_1 ;按SB2 转年调整AJMP MON_CH ;按SB1往下调月单元KEY2_1:CJNE A,#0FDH,SHOW_4LCALL YEAR_AD ; 调用年调整AJMP SHOW_4 ;MON_CH:MOV A,MON ; 月单元调整MOV B,#10DIV A BSWAP AORL A,BMOV P0,A ;MOV P2,#02H;LCALL READLCALL DE250SMCJNE A,01H,MON_CH ;去抖CJNE A,#0FEH,KEY2_2 ;按SB2 转月调整LJMP DAY_CH ;按SB1往下调日单元KEY2_2:CJNE A,#0FDH,MON_CHLCALL MON_AD ; 调用月调整LJMP MON_CH ;DAY_CH:MOV A,DAY ; 日单元调整MOV B,#10DIV A BSWAP AORL A,BMOV P0,A ;MOV P2,#04H;LCALL READLCALL DE250SMCJNE A,01H,DAY_CH ;去抖CJNE A,#0FEH,KEY2_3 ;按SB2 转日调整LJMP HOUR_CH ;按SB1往下调时单元KEY2_3:CJNE A,#0FDH,DAY_CHLCALL DAY_AD ; 调用日调整LJMP DAY_CHHOUR_CH:MOV A,HOUR ; 时单元调整MOV B,#10DIV A BSWAP AORL A,BMOV P0,A ;MOV P2,#01H;LCALL READLCALL DE250SMCJNE A,01H,HOUR_CH ;去抖CJNE A,#0FEH,KEY2_4 ;按SB2 转时调整AJMP MIN_CH ;按SB1往下调分单元KEY2_4:CJNE A,#0FDH,HOUR_CHLCALL HOUR_AD ; 调用时调整AJMP HOUR_CH ;MIN_CH:MOV A,MIN ; 分单元调整MOV B,#10DIV A BSWAP AORL A,BMOV P0,A ;MOV P2,#02H;LCALL READLCALL DE250SMCJNE A,01H,MIN_CH ;去抖CJNE A,#0FEH,KEY2_5 ;按SB2 转分调整AJMP SEC_CH ;按SB1往下调秒单元KEY2_5:CJNE A,#0FDH,MIN_CHLCALL MIN_AD ; 调用分调整LJMP MIN_CH ;SEC_CH:MOV A,SEC ; 秒单元调整MOV B,#10DIV A BSWAP AORL A,BMOV P0,A ;MOV P2,#04H;LCALL READLCALL DE250SMCJNE A,01H,SEC_CH ;去抖CJNE A,#0FEH,KEY2_6 ;按SB2 秒调整LJMP OUT_A ;按SB1跳出KEY2_6:CJNE A,#0FDH,SEC_CHCLR SEC ; 归零LJMP SEC_CH ;;-------按SB2\定时器年单元加1子程序SB3_2:LJMP SHOW_2 ;二路没编返回SB3_3:LJMP SHOW_3 ;三路没编返回SB3_1:MOV A,YEAR_1 ; 调时年单元MOV B,#10DIV A BSWAP AORL A,BMOV P0,AMOV P2,#01HLCALL READLCALL DE250SMCJNE A,01H,SB3_1CJNE A,#0FBH,KEY2_7 ;按SB2 转年调整LJMP MON_111 ;按SB1往下调月单元KEY2_7:CJNE A,#0FDH, SB3_1INC Y EAR_1 ; 1路年单元加1MOV R5,YEAR_1CJNE R5,#09,SB3_1 ;益出MOV YEAR_1,#00HAJMP SB3_1 ;;-------月单元加1子程序MON_111:MOV A,MON_1 ; 调时月单元显示MOV B,#10DIV A BSWAP AORL A,BMOV P0,AMOV P2,#02HLCALL READLCALL DE250SMCJNE A,01H,MON_111CJNE A,#0FBH,KEY2_8 ;按SB2 转月调整LJMP DAY_111KEY2_8:CJNE A,#0FDH,MON_111INC M ON_1 ;1路月单元加1MOV R5,MON_1CJNE R5,#13,MON_111;益出MOV MON_1,#01HAJMP MON_111 ; 转到月显;_------日单元加1子程序DAY_111:MOV A,DAY_1 ; 调时日单元显示提示MOV B,#10DIV A BSWAP AORL A,BMOV P0,AMOV P2,#04HLCALL READLCALL DE250SMCJNE A,01H,DAY_111CJNE A,#0FBH,KEY2_9 ;按SB2 转日调整LJMP HOUR_111KEY2_9:CJNE A,#0FDH,DAY_111INC D AY_1 ;1组日单元加1MOV R5,DAY_1CJNE R5,#32,DAY_111;益出MOV DAY_1,#01HAJMP DAY_111 ; 转到日显;-------按SB2时单元加1子程序HOUR_111:MOV A,HOUR_1 ; 调时时单元显示提示MOV B,#10DIV A BSWAP AORL A,BMOV P0,AMOV P2,#01HLCALL READLCALL DE250SMCJNE A,01H,HOUR_111CJNE A,#0FBH,KEY2_10 ; 按SB2 转时调整LJMP MIN_111KEY2_10:CJNE A,#0FDH,HOUR_111INC H OUR_1MOV R5,HOUR_1CJNE R5,#24,HOUR_111;益出MOV HOUR_1,#00HAJMP HOUR_111 ; 转到时显;-------分单元加1子程序MIN_111:MOV A,MIN_1 ; 调时分单元、并显示提示MOV B,#10DIV A BSWAP AORL A,BMOV P0,AMOV P2,#02HLCALL READLCALL DE250SMCJNE A,01H,MIN_111CJNE A,#0FBH,KEY2_11 ;按SB2 转分调整AJMP OFF_CH ;按SB3往下调定时:关单元KEY2_11:CJNE A,#0FDH, MIN_111INC M IN_1 ;1路分单元加1MOV R5,MIN_1CJNE R5,#60,MIN_111;益处MOV MIN_1,#00HAJMP MIN_111 ; 转到分显;年单元调整OFF_CH:MOV A,YEAR_11 ; 调时年单元MOV B,#10DIV A BSWAP AORL A,BMOV P0,AMOV P2,#01HLCALL READLCALL DE250SMCJNE A,01H,OFF_CHCJNE A,#0FBH,KEY2_F7 ;按SB2 转年调整LJMP MON_OFF ;按SB1往下调月单元KEY2_F7:CJNE A,#0FDH,OFF_CHINC Y EAR_11 ; 1路年单元加1MOV R5,YEAR_11CJNE R5,#09,OFF_CH ;益出MOV YEAR_11,#00HAJMP OFF_CH ;;-------月单元加1子程序MON_OFF:MOV A,MON_11 ; 调时月单元显示MOV B,#10DIV A BSWAP AORL A,BMOV P0,AMOV P2,#02HLCALL READLCALL DE250SMCJNE A,01H,MON_OFFCJNE A,#0FBH,KEY2_F8 ;按SB2 转月调整LJMP DAY_OFFKEY2_F8:CJNE A,#0FDH,MON_OFFINC M ON_11 ;1路月单元加1MOV R5,MON_11CJNE R5,#13,MON_OFF;益出MOV MON_11, #01HAJMP MON_OFF ; 转到月显;_------日单元加1子程序DAY_OFF:MOV A,DAY_11 ; 调时日单元显示提示MOV B,#10DIV A BSWAP AORL A,BMOV P0,AMOV P2,#04HLCALL READLCALL DE250SMCJNE A,01H,DAY_OFFCJNE A,#0FBH,KEY2_F9 ;按SB2 转日调整LJMP HOUR_OFFKEY2_F9:CJNE A,#0FDH,DAY_OFFINC D AY_11 ;1组日单元加1MOV R5,DAY_11CJNE R5,#32,DAY_OFF;益出MOV DAY_11,#01HAJMP DAY_OFF ; 转到日显;-------按SB2时单元加1子程序HOUR_OFF:MOV A,HOUR_11 ; 调时时单元显示提示MOV B,#10DIV A BSWAP AORL A,BMOV P0,AMOV P2,#01HLCALL READLCALL DE250SMCJNE A,01H,HOUR_OFFCJNE A,#0FBH,KEY2_F10 ; 按SB2 转时调整LJMP MIN_OFFKEY2_F10:CJNE A,#0FDH,HOUR_OFFINC H OUR_11MOV R5,HOUR_11CJNE R5,#24,HOUR_OFF;益出MOV HOUR_11,#00HAJMP HOUR_OFF ; 转到时显;-------分单元加1子程序MIN_OFF:MOV A,MIN_11 ; 调时分单元、并显示提示MOV B,#10DIV A BSWAP AORL A,BMOV P0,AMOV P2,#02HLCALL READLCALL DE250SMCJNE A,01H,MIN_OFFCJNE A,#0FBH,KEY2_F11 ;按SB2 转分调整LJMP ON_1 ;按SB3往下调定时:开与关KEY2_F11:CJNE A,#0FDH, MIN_OFFINC M IN_11 ;1路分单元加1MOV R5,MIN_11CJNE R5,#60,MIN_OFF;益处MOV MIN_11,#00HLJMP MIN_OFF ; 转到分显;-------开、关定时ON_1: CJNE A,#0FBH,MIN_OFFK1: MOV A,#88HMOV R7,AMOV P0,AMOV P2,#0FFH;三组都显示开LCALL READLCALL DE250SMCJNE A,01H,ON_1;去抖后比较CJNE A,#0FBH,KEY2_12 ;按SB2 转关LJMP OUT_A ;按SB3调出、处于开状态KEY2_12:CJNE A,#0FDH, K1k2: MOV A,#00H; 显示0关MOV R7,AMOV P0,AMOV P2,#0FFH;LCALL READLCALL DE250SMCJNE A,01H,K2;去抖后比较CJNE A,#0FBH,KEY2_13 ;按SB2 转开LJMP OUT_A ;SB3调出、处关状态KEY2_13:CJNE A,#0FDH,K2 ; 比较按了没LJMP K1 ; 按了SB2、转开OUT_A:POP 00HPOP BPOP ACCPOP PSWRETI;_------读取按键程序READ: MOV A,P1;读取按键MOV R1,ALCALL DE10MSMOV A,P1RET;_----延时程序DE5SM:PUSH 01HMOV R1,#0FFHDJNZ R1,$POP 01HRETDE10MS:PUSH 04HPUSH 05HMOV R4,#0AHDl1: MOV R5,#0FFHDl2: DJNZ R5,$DJNZ R4,Dl1POP 05HPOP 04HRETDE250SM:PUSH 02HPUSH 00HMOV R0,#0FFH DEL: MOV R2,#0FFHDJNZ R2,$DJNZ R0,DELPOP 00HPOP 02HRET;_---调整时间进位程序MIN_AD:INC MINMOV R6,MINCJNE R6,#60,OU1MOV MIN,#00OU1: RETHOUR_AD:INC HOURMOV R6,HOURCJNE R6,#25,OU2MOV HOUR,#00OU2: RETDAY_AD:INC DAYMOV R6,DAYCJNE R6,#32,OU3 ; 是否益出MOV DAY,#01HOU3: RETMON_AD:INC MONMOV R6,MONCJNE R6,#13,OU4 ; 是否益出MOV MON,#01HOU4: RETYEAR_AD:INC YEARMOV R6,YEARCJNE R6,#09,OU5;是否益出MOV YEAR,#00HOU5: RETEND。
51单片机数码管时钟程序

本人初学51,编写简单时钟程序。
仅供参考学习#include<reg52.h>#define uint unsigned int#define uchar unsigned charUchar code table_d[16] = {0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef,0xf7,0xfc,0xb9,0xde,0xf9,0xf1 };uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0xef};void delay(uint);unsigned long i,num,t=1;void main(){TMOD=0X01;TH0=(65536-10000)/256;TL0=(65536-10000)%256;EA=1;ET0=1;TR0=1;while(1){num=i/20;//i为秒位if(i==1728000)//一天大概是这个秒吧,,,应该是,呵呵。
就是世间到24时就归零。
i=0;//也可用下面这个部分来代替上面的。
/*if(i==20){ i=0;num++;if(num==5184000)num=0;}*///num=9;P2=7;//P2口为数码管控制端,我的是38译码器控制,就直接对其赋值来控制时,分,秒的显示;P0=table[i%100%10];delay(t);P2=6;P0=table[i%100/10];delay(t);P0=table_d[(num%60)%10];P2=5;delay(t);P0=table[(num%60)/10];P2=4;delay(t);P0=table_d[((num/60)%60)%10];P2=3;delay(t);P0=table[((num/60)%60)/10];P2=2;delay(t);P0=table_d[(num/3600)%10] ;P2=1;delay(t);P0=table[(num/3600)/10];P2=0;delay(t);}}void inttimer() interrupt 1{TH0=(65536-10000)/256;TL0=(65536-10000)%256;i++;}void delay(uint xms){uint i,j;for(i=xms;i>0;i--)for(j=110;j>0;j--);}程序可能有点小问题,对初学者是个很好的启发。
51单片机电子闹钟程序(亲自编写,可用)

学校电子钟,有闹钟功能,按键可调时间,可调打铃时间,打铃时间长短显示,每个模块有功能注释。
其中正常时间显示和闹钟时间显示可用一个开关来调整。
芯片选择STC89C52程序:#include<reg51.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned int//定义显示段码uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00};uchar codebbtime[]={0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; uchar clock[]={0,0,0,0};uchar clock1[]={12,30,0};uchar weikong[6];uchar bbduration=4;uchar lingtime=9;//学校打铃时间组uchar shangwu1[]={8,30};uchar shangwu2[]={10,0};uchar shangwu3[]={10,20};uchar shangwu4[]={11,50};uchar xiawu1[]={13,30};uchar xiawu2[]={15,00};uchar xiawu3[]={15,15};uchar xiawu4[]={16,45};//按键定义sbit mode=P1^7;sbit sec_clr=P1^0;sbit min_set_add=P1^3;sbit min_set_sub=P1^4;sbit hour_set_add=P1^1;sbit hour_set_sub=P1^2;sbit bb_set_add=P1^5;sbit bb_set_sub=P1^6;sbit speaker=P2^6;//延时函数void delay(unsigned int t){while(t--);//时钟进位函数void clockjinwei(){clock[0]++;if(clock[0]==20){clock[1]++;clock[0]=0;if(clock[1]==60){clock[2]++;clock[1]=0;if(clock[2]==60){clock[3]++;clock[2]=0;if(clock[3]==24)clock[3]=0;}}}}//定时器0中断服务函数void timer0(void) interrupt 1 using 1 {TMOD=0x01;TH0=0x3c;TL0=0xb0;clockjinwei();}//时钟分位显示函数void fenwei(){weikong[0]=clock[3]/10;weikong[1]=clock[3]%10;weikong[2]=clock[2]/10;weikong[3]=clock[2]%10;weikong[4]=clock[1]/10;weikong[5]=clock[1]%10;}//闹钟分位显示函数void naofen(){weikong[0]=clock1[0]/10;weikong[1]=clock1[0]%10;weikong[2]=clock1[1]/10;weikong[3]=clock1[1]%10;weikong[4]=clock1[2]/10;weikong[5]=clock1[2]%10; }//闹钟定时显示函数void naozhongdisplay(){uchar z,s;uchar x=0x01;naofen();for(z=0;z<6;z++){P2=0;P0=table[weikong[z]];P2=x;x=_crol_(x,1);for(s=0;s<255;s++);}}//时钟显示函数void display(){uchar i,j;uchar x=0x01;fenwei();for(i=0;i<6;i++){P2=0;P0=table[weikong[i]];P2=x;x=_crol_(x,1);for(j=0;j<255;j++);}}//总显示函数void zhongxian(){if(mode==1)delay(100);if(mode==1)display();if(mode==0)delay(100);if(mode==0)naozhongdisplay();}//按键处理程序void key_set(){zhongxian();P1=0xff;if(min_set_add==0){delay(100);if(min_set_add==0){if(mode==1){clock[2]++;if(clock[2]==60){clock[2]=0;}while(min_set_add==0)zhongxian();}}if(mode==0){clock1[1]++;if(clock1[1]==60){clock1[1]=0;}while(min_set_add==0)zhongxian();}}//if(min_set_sub==0){delay(100);if(min_set_sub==0){if(mode==1){clock[2]--;if(clock[2]==0)clock[2]=59;}while(min_set_sub==0)zhongxian();if(mode==0){clock1[1]--;if(clock1[1]==0)clock1[1]=59;}while(min_set_sub==0)zhongxian();}}//if(hour_set_add==0){delay(100);if(hour_set_add==0){if(mode==1){clock[3]++;if(clock[3]==24){clock[3]=0;}while(hour_set_add==0)zhongxian();}if(mode==0){clock1[0]++;if(clock1[0]==24){clock1[0]=0;}while(hour_set_add==0)zhongxian();}}}//if(hour_set_sub==0){delay(100);if(hour_set_sub==0){if(mode==1){clock[3]--;if(clock[3]==0)clock[3]=23;}while(hour_set_sub==0)zhongxian();if(mode==0){clock1[0]--;if(clock1[0]==0)clock1[0]=23;}while(hour_set_sub==0)zhongxian();}}//if(sec_clr==0){delay(100);if(sec_clr==0){clock[1]=0;}while(sec_clr==0)zhongxian();}}//闹钟响铃函数void bb(){if(clock[1]<=bbduration){speaker=1;delay(100);speaker=0;}else speaker=0;}//打铃函数void daling(){if(clock[1]<=lingtime){speaker=1;delay(100);speaker=0;}else speaker=0;}//时间比较函数void bijiao(){if(clock[3]==shangwu1[0]){if(clock[2]==shangwu1[1])daling();}if(clock[3]==shangwu2[0]){if(clock[2]==shangwu2[1])daling();}if(clock[3]==shangwu3[0]){if(clock[2]==shangwu3[1])daling();}if(clock[3]==shangwu4[0]){if(clock[2]==shangwu4[1])daling();}if(clock[3]==xiawu1[0]){if(clock[2]==xiawu1[1])daling();}if(clock[3]==xiawu2[0]){if(clock[2]==xiawu2[1])daling();}if(clock[3]==xiawu3[0]){if(clock[2]==xiawu3[1])daling();}if(clock[3]==xiawu4[0]){if(clock[2]==xiawu4[1])daling();}}//闹钟比较void naobijiao(){if(clock[3]==clock1[0]){if(clock[2]==clock1[1]||clock[2]==clock1[1]+1||clock[2]==clock1[1]+2) bb();}}//响铃时长显示函数void bbtimeshow(){P3=bbtime[bbduration];if(bbduration>15)bbduration=0;}//响铃按键处理函数void bbtime_set(){bbtimeshow();if(bb_set_add==0){delay(100);if(bb_set_add==0)bbduration++;while(bb_set_add==0)bbtimeshow();}if(bb_set_sub==0){delay(100);if(bb_set_sub==0)bbduration--;while(bb_set_sub==0)bbtimeshow();}}//主程序void main(){EA=1;ET0=1;TR0=1;while(1){key_set();bijiao();bbtime_set();naobijiao();}}电路图:分四部分显示:如果在学习这个程序过程中有什么问题,可以发邮件到******************询问。
51单片机数字钟实验(原理图及程序)
51单片机数字钟实验(原理图及程序)1.实验任务(1.开机时,显示12:00:00的时间开始计时;(2.P0.0/AD0控制“秒”的调整,每按一次加1秒;(3.P0.1/AD1控制“分”的调整,每按一次加1分;(4.P0.2/AD2控制“时”的调整,每按一次加1个小时;2.电路原理图图4.20.13.系统板上硬件连线(1.把“单片机系统”区域中的P1.0-P1.7端口用8芯排线连接到“动态数码显示”区域中的A-H端口上;(2.把“单片机系统:区域中的P3.0-P3.7端口用8芯排线连接到“动态数码显示”区域中的S1-S8端口上;(3.把“单片机系统”区域中的P0.0/AD0、P0.1/AD1、P0.2/AD2端口分别用导线连接到“独立式键盘”区域中的SP3、SP2、SP1端口上;4.相关基本知识(1.动态数码显示的方法(2.独立式按键识别过程(3.“时”,“分”,“秒”数据送出显示处理方法5.程序框图6.汇编源程序SECOND EQU 30HMINITE EQU 31HHOUR EQU 32HHOURK BIT P0.0MINITEK BIT P0.1SECONDK BIT P0.2DISPBUF EQU 40HDISPBIT EQU 48HT2SCNTA EQU 49HT2SCNTB EQU 4AHTEMP EQU 4BHORG 00HLJMP STARTORG 0BHSTART: MOV SECOND,#00HMOV MINITE,#00HMOV HOUR,#12MOV DISPBIT,#00HMOV T2SCNTA,#00HMOV T2SCNTB,#00HMOV TEMP,#0FEHLCALL DISPMOV TMOD,#01HMOV TH0,#(65536-2000) / 256 MOV TL0,#(65536-2000) MOD 256 SETB TR0SETB ET0SETB EAWT: JB SECONDK,NK1LCALL DELY10MSJB SECONDK,NK1INC SECONDMOV A,SECONDCJNE A,#60,NS60MOV SECOND,#00HNS60: LCALL DISPJNB SECONDK,$NK1: JB MINITEK,NK2LCALL DELY10MSJB MINITEK,NK2INC MINITECJNE A,#60,NM60 MOV MINITE,#00H NM60: LCALL DISPJNB MINITEK,$ NK2: JB HOURK,NK3LCALL DELY10MS JB HOURK,NK3INC HOURMOV A,HOURCJNE A,#24,NH24 MOV HOUR,#00H NH24: LCALL DISPJNB HOURK,$NK3: LJMP WTDELY10MS:MOV R6,#10D1: MOV R7,#248DJNZ R7,$DJNZ R6,D1RETDISP:MOV A,#DISPBUF ADD A,#8DEC AMOV R1,AMOV A,HOURMOV B,#10MOV @R1,ADEC R1MOV A,BMOV @R1,ADEC R1MOV A,#10MOV@R1,ADEC R1MOV A,MINITE MOV B,#10DIV ABMOV @R1,ADEC R1MOV A,BMOV @R1,ADEC R1MOV A,#10MOV@R1,ADEC R1MOV A,SECOND MOV B,#10DIV ABMOV @R1,ADEC R1MOV A,BMOV @R1,ADEC R1INT_T0:MOV TH0,#(65536-2000) / 256 MOV TL0,#(65536-2000) MOD 256 MOV A,#DISPBUFADD A,DISPBITMOV R0,AMOV A,@R0MOV DPTR,#TABLEMOVC A,@A+DPTRMOV P1,AMOV A,DISPBITMOV DPTR,#TABMOVC A,@A+DPTRMOV P3,AINC DISPBITMOV A,DISPBITCJNE A,#08H,KNAMOV DISPBIT,#00HKNA: INC T2SCNTAMOV A,T2SCNTACJNE A,#100,DONEMOV T2SCNTA,#00HINC T2SCNTBMOV A,T2SCNTBCJNE A,#05H,DONEMOV T2SCNTB,#00HINC SECONDMOV A,SECONDCJNE A,#60,NEXTMOV SECOND,#00HINC MINITEMOV A,MINITECJNE A,#60,NEXTMOV MINITE,#00HINC HOURMOV A,HOURCJNE A,#24,NEXTMOV HOUR,#00HNEXT: LCALL DISPDONE: RETITABLE: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH,40H TAB: DB 0FEH,0FDH,0FBH,0F7H,0EFH,0DFH,0BFH,07FHEND7.C语言源程序#include <AT89X51.H>unsigned char code dispcode[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00}; unsigned char dispbitcode[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; unsigned char dispbuf[8]={0,0,16,0,0,16,0,0};unsigned char dispbitcnt;unsigned char second;unsigned char minite;unsigned char hour;unsigned int tcnt;unsigned char mstcnt;unsigned char i,j;void main(void){TMOD=0x02;TH0=0x06;TL0=0x06;TR0=1;ET0=1;EA=1;while(1){if(P0_0==0){for(i=5;i>0;i--)for(j=248;j>0;j--);if(P0_0==0){second++;if(second==60){second=0;}dispbuf[0]=second%10; dispbuf[1]=second/10; while(P0_0==0);}}if(P0_1==0){for(i=5;i>0;i--)for(j=248;j>0;j--);if(P0_1==0){minite++;if(minite==60){minite=0;}dispbuf[3]=minite%10; dispbuf[4]=minite/10; while(P0_1==0);}}if(P0_2==0){for(i=5;i>0;i--)for(j=248;j>0;j--);if(P0_2==0){hour++;if(hour==24){hour=0;}dispbuf[6]=hour%10;dispbuf[7]=hour/10;while(P0_2==0);}}}}void t0(void) interrupt 1 using 0{mstcnt++;if(mstcnt==8){mstcnt=0;P1=dispcode[dispbuf[dispbitcnt]]; P3=dispbitcode[dispbitcnt];dispbitcnt++;if(dispbitcnt==8){dispbitcnt=0;}}tcnt++;if(tcnt==4000){tcnt=0;second++;if(second==60){second=0;minite++;if(minite==60){minite=0;hour++;if(hour==24) {hour=0; }}}dispbuf[0]=second%10; dispbuf[1]=second/10; dispbuf[3]=minite%10; dispbuf[4]=minite/10; dispbuf[6]=hour%10; dispbuf[7]=hour/10; }}。
数字钟51单片机程序c语言
goto F0; //*按键未释放,在此等候*//
}
//*延时子函数*/
unsigned char i,j;
for(i=5;i>0;i--)
for(j=248;j>0;j--);
}
//*5mS定时中断服务 子函数*//
void zd(void) interrupt 1
{
TH0=-(4800//256);
TL0=-(4800%256);
deda++;
}
//*调整走时时间*//
{
t_dirve();
}
if(P3_7==0)
delay(1);
if(P3_7==0)
t_min++;
if(t_min==60)
{
if(deda<=100)
d_05s=0;
else d_05s=1;
if(deda>=200)
{sec++;deda=0;}
if(sec==60)
{min++;sec=0;}
if(min==60)
{hour++;min=0;}
if(hour==24)
{hour=0;}
p_out(); //*判别闹时到 子函数*// 否
}
//*定时器 T0 5mS初始化*//
void init_timer()
{
TMOD=0x01;
TH0=-(4800//256);
TL0=-(4800%256);
IE=0x82;
用51单片机和1602液晶做的数字钟
用51单片机和1602液晶做的数字钟数字钟是人们日常生活中常见的时间显示设备,它能够精确显示当前的时间,并且兼具简约和实用性。
本文将介绍使用51单片机和1602液晶屏幕制作自己的数字钟的方法。
所需材料在开始制作之前,我们需要准备以下材料: - 51单片机开发板 - 1602液晶屏幕 - 数字时钟芯片RTC(Real-Time Clock) - 面包板和导线 - 电阻和电容 - 编程器和烧录器硬件连接首先,我们需要将51单片机、1602液晶屏幕和RTC芯片连接起来。
根据硬件接口的定义和引脚功能的规定,我们可以进行以下连接: - 将51单片机的VCC 引脚连接到1602液晶屏幕的VCC引脚,用于提供电源。
- 将51单片机的GND引脚连接到1602液晶屏幕的GND引脚,用于地线连接。
- 将51单片机的P0口连接到1602液晶屏幕的数据线D0-D7,用于数据传输。
- 将51单片机的P2口连接到1602液晶屏幕的RS引脚,用于选择数据和命令传输。
- 将51单片机的P3口连接到1602液晶屏幕的EN引脚,用于启用LCD。
此外,还需要将RTC芯片连接到51单片机上,以实现时间的准确显示。
具体的连接方式可以参考RTC芯片的规格说明书。
软件编程完成硬件连接后,我们需要进行软件编程,以便控制51单片机、1602液晶屏幕和RTC芯片的功能。
初始化首先,我们需要对51单片机和1602液晶屏幕进行初始化设置。
这包括设置引脚的功能模式、初始化1602液晶屏幕的显示模式和清空显示区域。
读取时间接下来,我们需要通过RTC芯片来读取当前的时间。
这通常包括读取RTC芯片存储的年、月、日、时、分和秒的数据。
显示时间读取时间后,我们可以将其显示在1602液晶屏幕上。
这可以通过更新特定的LCD显示区域来实现。
我们可以在指定的位置、特定的行和列上显示时间。
更新时间为了实现实时的时间显示,我们需要定期更新显示的时间。
可以使用定时器中断来定期更新时间,并根据需要刷新液晶屏幕上的显示。
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--);}}。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
#include<reg52.h>typedef unsigned int uint;typedef unsigned char uchar;sbit LED_Bit1 = P2^4;sbit LED_Bit2 = P2^5;sbit LED_Bit3 = P2^6;sbit LED_Bit4 = P2^7;sbit KEY0 = P3^7;sbit KEY1 = P3^6;sbit KEY2=P3^5;sbit KEY3=P3^4;sbit buzzer=P3^0;sbit led_0=P1^0;sbit led_1=P1^1;sbit led_2=P1^2;sbit led_3=P1^3;sbit led_4=P1^4;sbit led_5=P1^5;sbit led_6=P1^6;sbit led_7=P1^7;uchar Count = 0;Count1=0;uchar Second1=0;uchar hour=10,minute=23,Second = 0;uchar month=8,day=1;uchar clockhour=0,clockminute=0;uint mode=0,clockflag=0,year=2011;uchar code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e}; void Delay(uint m){uint x,y;for(x = m;x > 0;x--)for(y = 110;y > 0;y--);}void Timer_Init(void){TMOD = 0x11;TH0 = (65536 - 10000)/256;TL0 = (65536 - 10000)%256;TH1 = (65536 - 10000)/256;TL1 = (65536 - 10000)%256;TR0 = 1;ET0 = 1;ET1=1;TR1=1;EA = 1;}void LED_DynamicDisplay(uchar Bit1,uchar Bit2,uchar Bit3,uchar Bit4) {LED_Bit1 = 0;LED_Bit2 = 1;LED_Bit3 = 1;LED_Bit4 = 1;P0=table[Bit1];if(mode==2||mode==9||mode==7){if(Count<50)P0=table[Bit1]&0x7f;}// else// P0=table[Bit1];Delay(1);P0 = 0xFF; //消?影®¡ãLED_Bit1 = 1;LED_Bit2 = 0;LED_Bit3 = 1;LED_Bit4 = 1;P0=table[Bit2];if(mode==0){if(Count<50)P0=table[Bit2]&0x7f;}if(mode==3)P0=table[Bit2]&0x7f;//if(mode==2||mode==1||mode==4||mode==5)// P0=table[Bit2];Delay(1);P0 = 0xFF; //消?影®¡ãLED_Bit1 = 1;LED_Bit2 = 1;LED_Bit3 = 0;LED_Bit4 = 1;P0=table[Bit3];if(mode==1||mode==6||mode==8){if(Count<50)P0=table[Bit3]&0x7f;}Delay(1);P0 = 0xFF; //消?影®¡ãLED_Bit1 = 1;LED_Bit2 = 1;LED_Bit3 = 1;LED_Bit4 = 0;P0 = table[Bit4];Delay(1);P0 = 0xFF;}void SecondCounterSetVaule(){if(Count >= 100){Second++;Count = 0;}if(Second>=60){Second=0;minute++;}if(minute >= 60){minute = 0;hour++;}if(hour==24){day++;hour=0;}if(month==1||month==3||month==5||month==7||month==8||month==10||month==12) {if(day==32){month++;day=1;}}else{if(day==31){month++;day=1;}}if(month==13){month=1;year++;}}void KeyScan(){if(KEY2==0){Delay(5);if(KEY2==0){mode++;if(mode==3){TR1=0 ;TH1 = (65536 - 10000)/256;TL1 = (65536 - 10000)%256;TR1=1 ;Second1=0;}if(mode==10){mode=0;}while(!KEY2);}}if(KEY3==0){Delay(5);if(KEY3==0){if(buzzer==1){clockflag=0;}mode=0;TR0=1;while(!KEY3);}}if(KEY0 == 0){Delay(5);if(KEY0 == 0){if(mode==3)TR1=0;if(mode==1){TR0=0;minute++;}if(mode==2){hour++;}if(mode==4){year++;}if(mode==6){day++;}if(mode==7){month++;}if(mode==8){clockminute++;clockflag++;}if(mode==9){clockflag++;clockhour++;}while(!KEY0);}}if(KEY1 == 0){Delay(5);if(KEY1 == 0){if(mode==3){TH1 = (65536 - 10000)/256;TL1 = (65536 - 10000)%256;Count1 = 0;Second1 = 0;TR1=1;}if(mode==4){year--;}if(mode==6){day--;}if(mode==7){month--;}while(!KEY1);}}SecondCounterSetVaule();}int main(){Timer_Init();while(1){if(clockflag){if(hour==clockhour&&minute==clockminute)buzzer=1;}KeyScan();LED_DynamicDisplay(hour/10,hour%10,minute/10,minute%10);while(mode==3){KeyScan();LED_DynamicDisplay(Second1/10,Second1%10,Count1/10,Count1%10);}while(mode==4){KeyScan();LED_DynamicDisplay(year/1000,year/100%10,year%100/10,year%10);}while(mode==5||mode==6||mode==7){KeyScan();LED_DynamicDisplay(month/10,month%10,day/10,day%10);}while(mode==8||mode==9){KeyScan();LED_DynamicDisplay(clockhour/10,clockhour%10,clockminute/10,clockminute%10);}}return 0;}void timer0(void) interrupt 1 using 1 {Count++;TH0 = (65536 - 10000)/256;TL0 = (65536 - 10000)%256;}void timer1(void) interrupt 3 using 2 {Count1++;if(Count1==100){Count1=0;Second1++;}if(Second1==60){Second1=0;}TH1 = (65536 - 10000)/256;TL1 = (65536 - 10000)%256;}。