电子时钟程序
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不显示)状态。
电子时钟程序代码
#include<reg52.h>#define uchar unsigned char#define uint unsigned intuchar code weixuan[8]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01}; //位选,控制哪个数码管亮。
(从右到左)ucharcodeduanxuan[12]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf, 0xff}; //0-9,'-','灭'uchar data timedata[3]={0x00,0x00,0x00}; //时间缓冲区,分别为:秒、时、分。
uchar data datetime[8]={0xc0,0xc0,0xbf,0xc0,0xc0,0xbf,0xc0,0xc0}; //时间缓冲区,初始化显示00-00-00。
uchar tt1,tt2,tt,tt0,num=0;uchar flag,flag1,flag2,flash;sbit key1=P1^3;sbit key2=P1^5;sbit key3=P1^7;//**************延时函数*********************************void delay(uint del){uchar i, j;for(i=0; i<del; i++)for(j=0; j<=148; j++);}//********************调用显示************************void display(){datetime[0]=timedata[0]%10; datetime[1]=timedata[0]/10; //秒datetime[3]=timedata[1]%10; datetime[4]=timedata[1]/10; //分 datetime[6]=timedata[2]%10; datetime[7]=timedata[2]/10; //时 if(!flag){P2=0X80; //秒显示P0=duanxuan[datetime[0]];delay(2);P2=0X40;P0=duanxuan[datetime[1]];delay(2);}else{P2=0X80; //秒显示P0=duanxuan[datetime[0]]|flash;delay(2);P2=0X40;P0=duanxuan[datetime[1]]|flash;delay(2);}P2=0X20; //显示'-'P0=duanxuan[10];delay(2);if(!flag1){P2=0X10; //分显示P0=duanxuan[datetime[3]];delay(2);P2=0X08;P0=duanxuan[datetime[4]];delay(2);}else{P2=0X10; //分显示P0=duanxuan[datetime[3]]|flash;delay(2);P2=0X08;P0=duanxuan[datetime[4]]|flash;delay(2);}P2=0X04; //显示'-' P0=duanxuan[10];delay(2);if(!flag2){P2=0X02; //小时P0=duanxuan[datetime[6]];delay(2);P2=0X01;P0=duanxuan[datetime[7]];delay(2);}else{P2=0X02; //小时P0=duanxuan[datetime[6]]|flash;delay(2);P2=0X01;P0=duanxuan[datetime[7]]|flash;delay(2);}}/******************按键调节时间*****************************/ void keyscan(){if(key1==0){delay(10);if(key1==0){num++;while(!key1);while(1){if(num==1){flag=1;flag1=0;flag2=0;if(key2==0){delay(10);if(key2==0){timedata[0]--;if(timedata[0]==-1)timedata[0]=60;while(!key2);}}if(key3==0){delay(10);if(key3==0){timedata[0]++;if(timedata[0]==60)timedata[0]=0;while(!key3);}}}if(key1==0){delay(10);if(key1==0)num++;while(!key1);}if(num==2){flag=0;flag1=1;flag2=0;if(key2==0){delay(10);if(key2==0){timedata[1]--;if(timedata[1]==-1)timedata[1]=60;while(!key2);}}if(key3==0){delay(10);if(key3==0){timedata[1]++;if(timedata[1]==60)timedata[1]=0;while(!key3);}}if(num==3){flag=0;flag1=0;flag2=1;if(key2==0){delay(10);if(key2==0){timedata[2]--;if(timedata[2]==-1)timedata[2]=24;while(!key2);}}if(key3==0){delay(10);if(key3==0){timedata[2]++;if(timedata[2]==25)timedata[2]=0;while(!key3);}}if(num==4){num=0;flag=0;flag1=0;flag2=0;break;}}}}}//主函数void main(){TMOD=0x01;ET0=1;TR0=1;TH0=0x40;TL0=0x00;EA=1;while(1){keyscan();}}//***************定时器函数*************************** void timer1() interrupt 1{TH0=0x40; //50ms自加一次。
LED数字显示电子时钟源程序代码
LED数字显示电子时钟源程序代码程序:(注已完全经过调试,达到预期目的)#include<reg51.h>#define uchar unsigned char#define uint unsigned intuchar count=0;sbit LED=P1^0;uchar tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //显示数码管0,1,3,4,5,6,7,8,9 uchar miao=0,fen=0,hour=0;void delay(uint i) //延迟函数{uint j;for(;i>0;i--)for(j=124;j>0;j--);}void init(){ET0=1;TMOD=0x51; //选定定时器0,1和中断0,1TH0=(65536-25000)/256;TL0=(65536-25000)%256; //设定时器0时间为250ms一次ET1=1;TH1=0xff;TL1=0xff; //定时器1为中断EX0=1;IT0=1; //中断0开EX1=1;IT1=1; //中断1开TR0=1; //定时器0开TR1=1; //定时器1开EA=1; //总中断开}void display() //时钟显示函数{P0=tab[hour/10%10];P2=0xfe;delay(1);P0=tab[hour%10];P2=0xfd;delay(1);P0=tab[fen/10%10];P2=0xfb;delay(1);P0=tab[fen%10];P2=0xf7;delay(1);P0=tab[miao/10%10];P2=0xef;delay(1);P0=tab[miao%10];P2=0xdf;delay(1);}void main() //主函数{init();LED=0;while(1){display();}}void T0_int() interrupt 1 //定时器0函数{TH0=(65536-25000)/256;TL0=(65536-25000)%256;count++;if(count==20){count=0;miao= miao +1;LED=~LED;if(sec==60){miao=0;fen= fen +1;if(fen ==60){fen =0;hour=hour+1;if(hour==24)hour=0;}}}}void T1_int() interrupt 3 //定时器1函数控制秒针加1 {TH1=0xff;TL1=0xff;miao=miao+1;if(miao ==60)miao =0;}void I1_int() interrupt 2 //中断1函数控制按键分针加1 {EX0=0;fen= fen +1;if(fen ==60)fen =0;EX0=1;}void I0_int() interrupt 0 //中断函数0控制按键时针加1 {EX1=0;hour=hour+1;if(hour==24)hour=0;EX1=1;}。
单片机C语言_电子时钟程序
#include<AT89X52.H>#define uint unsigned int#define uchar unsigned charunsigned char key2;bit ding=1;unsigned char Getkey(void);uchar a,n=0,shi,fen,miao;void delay01s(void);uchar LED[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};uchar LED1[]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};//有小数点的void init(); //函数声明void Delay(unsigned char z);//函数声明void display(); //函数声明//函数声明void main() //函数声明{P1=0xfe;//对P1口赋初值init(); //函数调用while(1){//函数调用key2=Getkey();switch(key2){case 1:shi++;if(shi==24){shi=0;}break;case 2:fen++;if(fen==60){fen=0;}break;case 3:if(fen!=0)fen--;if(fen==24){fen=0;}break;case 4:ding=~ding;default:break;}display(); //函数调用}}void init(){TMOD=0x01; //定时器工作方式选择和赋初值TH0=(65536-50000)/256;TL0=(65536-50000)%256;EA=1; //开总中断ET0=1; //开定时器中断TR0=1; //启动定时器}void timer0() interrupt 1 //中断服务程序{if(ding==1){TH0=(65536-50000)/256;//中断时间50msTL0=(65536-50000)%256; //定时器重新赋初值a++;if(a==10){n=~n;}if(a==20){n=~n;a=0;P1=P1<<1|P1>>7;miao++;if(miao==60){miao=0;fen++;if(fen==60){fen=0;shi++;if(shi==24){shi=0;}}}}}}void display()//显示程序{P0=LED[shi/10];P2=((P2&0x0f)|0x70); Delay(4);if(n==0){P0=LED[shi%10];}else{P0=LED1[shi%10];}P2=((P2&0x0f)|0xb0);Delay(4);P0=LED[fen/10];P2=((P2&0x0f)|0xd0);Delay(4);P0=LED[fen%10];P2=((P2&0x0f)|0xe0);Delay(4);}/**********获得键值子程序**********************/ unsigned char bool;//bool 是否松键的标志unsigned char Getkey(void){unsigned char temp,key=0;P2=(P2&0xff)|0x0f;if((P2&0xff)!=((P2&0xff)|0x0f)) // 有键按下{//delay01s();if(((P2&0xff)!=((P2&0xff)|0x0f)) &&(bool==0)) // 有键按下{temp=~(P2|0xf0);if(temp==1) key=1;else if(temp==2) key=2;else if(temp==4) key=3;else if(temp==8) key=4;bool=1;}}if(((P2&0xff)==((P2&0xff)|0x0f)) &&(bool==1)){bool=0;}return key; //返回1~16键值}/********延时程序******/void delay01s(void){unsigned char j,k;for(j=5;j>0;j--) //198{for(k=15;k>0;k--)//248{;}}}void Delay(unsigned char z){unsigned char i,j,k; //定义变量for(i=z;i>0;i--)for(j=25;j>0;j--)for(k=20;k>0;k--);}#include<reg52.h>//头文件#define uchar unsigned char//宏定义#define uint unsigned intsbit P31=P3^1;//位声明sbit P32=P3^2;sbit P33=P3^3;uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//共阴段码表uint hou1,hou2,min1,min2,sec1,sec2,numhou,nummin,numsec,yue1,yue2,ri1,ri2,numyue,numri; uint num,m,n;void delayms(uint xms)//延时函数{uint i,j;for(i=xms;i>0;i--)for(j=110;j>0;j--);}void p31xd()//按键P31消抖{ delayms(2);while(P31!=1);delayms(2);}void p32xd()//按键P32消抖{ delayms(1);while(P32!=1);delayms(1);}void p33xd()//按键P33消抖{ delayms(1);while(P33!=1);delayms(1);}void displaysj()//显示时间{P2=0x00;P0=table[hou1];//显示时的第一位P2=0X20;delayms(1);P2=0xff;P0=table[hou2]&0x7f;//显示时的第二位与小数点P2=0X10;delayms(1);P2=0xff;P0=table[min1];//显示分的第一位P2=0X08;delayms(1);P2=0xff;P0=table[min2]&0x7f;//显示时的第二位与小数点P2=0X04;delayms(1);P2=0xff;P0=table[sec1];//显示秒的第一位P2=0X02;delayms(1);P2=0xff;P0=table[sec2];//显示秒的第二位P2=0X01;delayms(1);}void displayrq()//显示日期{ P2=0x00;P0=table[yue1];//显示月的第一位P2=0X20;delayms(1);P2=0x00;P0=table[yue2]&0x7f;//显示月的第二位P2=0X10;delayms(1);P2=0x00;P0=table[ri1];//显示日的第一位P2=0X08;delayms(1);P2=0x00;P0=table[ri2];//显示日的第二位P2=0X04;delayms(1);}void houqh()//时针切换函数{hou1=numhou/10;hou2=numhou%10;}void minqh()//分针切换函数{min1=nummin/10;min2=nummin%10;}void secqh()//秒针切换函数{sec1=numsec/10;sec2=numsec%10;}void yueqh()//月切换函数{yue1=numyue/10;yue2=numyue%10;}void riqh()//日切换函数{ri1=numri/10;ri2=numri%10;}void start()//初始化函数{num=0;TMOD=0x01;TH0=(65532-45872)/256;TL0=(65532-45872)%256;EA=1;IT0=0;//电平触发(低电平有效)EX0=1;ET0=1;TR0=1;yueqh(),riqh();//初始化日月切换}void ritiao()//日期的调节函数{ if(P32==0)//日期加一调节键{p32xd();if((numyue==1)||(numyue==3)||(numyue==5)||(numyue==7)||(numyue==8)||(numyue==10)||( numyue==12)){numri+=1;if(numri>=31)//如果是大月,日期有31号,等于符号是防止日期大于31号而乱码{numri=1;}}if((numyue==4)||(numyue==6)||(numyue==9)||(numyue==11)){numri+=1;if(numri>=30)//如果是小月,日期有30号{numri=1;}}if(numyue==2){numri+=1;if(numri>=28)//如果是小月,日期有28号{numri=1;}}riqh();//日期调节后切换一下}if(P33==0)//日期减一调节键{p33xd();if((numyue==1)||(numyue==3)||(numyue==5)||(numyue==7)||(numyue==8)||(numyue==10)||( numyue==12)){numri-=1;if(numri==0){numri=31;}}if((numyue==4)||(numyue==6)||(numyue==9)||(numyue==11)){numri-=1;if(numri==0){numri=30;}}if(numyue==2){numri-=1;if(numri==0){numri=28;}}riqh();}}void yuetiao()//月份的调节函数{if(P32==0){p32xd();numyue+=1;if(numyue==13)//月份为12时再加一马上为一月{numyue=1;}yueqh();}if(P33==0){p33xd();numyue-=1;if(numyue==0){numyue=12;}yueqh();}}void int0() interrupt 0{p31xd();while(P31!=0)//第一次按下p31时,进行秒调时{for(m=0;m<40;m++)//此for循环不显示秒,为的是使秒闪烁{P2=0x00;P0=table[hou1];P2=0X20;delayms(1);P2=0x00;P0=table[hou2]&0x7f;P2=0X10;delayms(1);P2=0x00;P0=table[min1];P2=0X08;delayms(1);P2=0x00;P0=table[min2]&0x7f;P2=0X04;delayms(1);if(P32==0)//如果按一下P32,则秒加一{p32xd();numsec+=1;if(numsec==60){numsec=0;}secqh();}if(P33==0)//如果按一下P33,则秒减一{p33xd();numsec-=1;if(numsec==-1){numsec=59;}secqh();}};for(n=0;n<40;n++)//此循环时分秒全显示,也为的是使秒闪烁{ displaysj();if(P32==0){p32xd();numsec+=1;if(numsec==60){numsec=0;}secqh();}if(P33==0){p33xd();numsec-=1;if(numsec==-1){numsec=59;}secqh();}}};p31xd();while(P31!=0)//第二次按下p31时,进行分调时{for(m=0;m<40;m++){P2=0x00;P0=table[hou1];P2=0X20;delayms(1);P2=0x00;P0=table[hou2]&0x7f;P2=0X10;delayms(1);P2=0x00;P0=table[sec1];P2=0X02;delayms(1);P2=0x00;P0=table[sec2];P2=0X01;delayms(1);if(P32==0){p32xd();nummin+=1;if(nummin==60){nummin=0;}minqh();}if(P33==0){p33xd();nummin-=1;if(nummin==-1){nummin=59;}minqh();}}for(n=0;n<40;n++){ displaysj();if(P32==0){p32xd();nummin+=1;if(nummin==60){nummin=0;}minqh();}if(P33==0){nummin-=1;if(nummin==-1){nummin=59;}minqh();}}};p31xd();while(P31!=0)//第三次按下p31时,进行时调时{for(m=0;m<40;m++){P2=0x00;P0=table[min1];P2=0X08;delayms(1);P2=0x00;P0=table[min2]&0x7f;P2=0X04;delayms(1);P2=0x00;P0=table[sec1];P2=0X02;delayms(1);P2=0x00;P0=table[sec2];P2=0X01;delayms(1);if(P32==0){p32xd();numhou+=1;if(numhou==24){numhou=0;}}if(P33==0){p33xd();numhou-=1;if(numhou==-1){numhou=23;}houqh();}}for(n=0;n<40;n++){ displaysj();if(P32==0){p32xd();numhou+=1;if(numhou==24){numhou=0;}houqh();}if(P33==0){p33xd();numhou-=1;if(numhou==-1){numhou=23;}houqh();}}}p31xd();while(P31!=0)//第四次按下p31时,进行日期调节{for(m=0;m<50;m++){ P2=0x00;P0=table[yue1];P2=0x20;delayms(1);P2=0x00;P0=table[yue2]&0x7f;P2=0x10;delayms(1);ritiao();}for(n=0;n<50;n++){ displayrq();ritiao();}}p31xd();while(P31!=0)//第五次按下p31时,进行月调节{for(m=0;m<50;m++){P2=0xff;P0=table[ri1];P2=0xf7;delayms(1);P2=0xff;P0=table[ri2];P2=0xfb;delayms(1);yuetiao();}for(n=0;n<50;n++){ displayrq();yuetiao();}}p31xd();}void yuejia(){ numri=1;numyue+=1;if(numyue==13){numyue=1;}}void timer0() interrupt 1{TH0=(65532-46100)/256;TL0=(65532-46100)%256;num++;if(num==20){num=0;TH0=(65532-46100)/256;TL0=(65532-46100)%256;numsec=numsec+1;if(numsec==60){numsec=0;nummin=nummin+1;if(nummin==60){nummin=0;numhou=numhou+1;if(numhou==24){numhou=0;numri+=1;if((numyue==1)||(numyue==3)||(numyue==5)||(numyue==7)||(numyue==8)||(numyue==10)||( numyue==12)){numri+=1;if(numri>=31){numri=1;numyue+=1;if(numyue==13){numyue=1;}}}if((numyue==4)||(numyue==6)||(numyue==9)||(numyue==11)){numri+=1;if(numri>=31){numri=1;numyue+=1;if(numyue==13){numyue=1;}}}if(numyue==2){numri+=1;if(numri>=29){numri=1;numyue+=1;if(numyue==13){numyue=1;}}}}}}}}void main(){numhou=12;//初始化时间设为12点,日期设为1月1日nummin=0;numsec=0;numyue=1;numri=1;start();while(1){if(P32==1)//默认(没有按下p32时)显示时间{houqh(),minqh(),secqh();displaysj();}if(P32==0)//当按下p32键时显示日期{yueqh(),riqh();displayrq();}}}。
电子设计自动化(EDA)_数字时钟程序模块(LED数码管显示)_实验报告
电子设计自动化(EDA)—数字时钟LED数码管显示二、实验内容和实验目的1. 6个数码管动态扫描显示驱动2. 按键模式选择(时\分\秒)与闹钟(时\分)调整控制,3. 用硬件描述语言(或混合原理图)设计时、分、秒计数器模块、闹钟模块、按键控制状态机模块、动态扫描显示驱动模块、顶层模块。
要求使用实验箱左下角的6个动态数码管(DS6 A~DS1A)显示时、分、秒;要求模式按键和调整按键信号都取自经过防抖处理后的按键跳线插孔。
实验目的: 1)学会看硬件原理图, 2)掌握FPGA硬件开发的基本技能3)培养EDA综合分析、综合设计的能力三、实验步骤、实现方法(或设计思想)及实验结果主要设备: 1)PC机, 2)硬件实验箱, 3)Quartus II软件开发平台。
1.打开Quartus II , 连接实验箱上的相关硬件资源, 如下图1所示。
2.建立新文件, 选择文本类型或原理图类型。
3. 编写程序。
4.编译5. 仿真, 加载程序到芯片, 观察硬件输出结果(数码管显示)6.结果正确则完成。
若结果不正确, 则修改程序, 再编译, 直到正确。
模24计数器模块LIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;USE IEEE.STD_LOGIC_UNSIGNED.ALL;USE IEEE.STD_LOGIC_ARITH.ALL;ENTITY count24 ISPORT(clk,en:IN STD_LOGIC;cout:OUT STD_LOGIC;hh,hl:OUT STD_LOGIC_VECTOR(3 DOWNTO 0));END count24;ARCHITECTURE arc OF count24 ISSIGNAL a,b:STD_LOGIC_VECTOR(3 DOWNTO 0);BEGINPROCESS(clk,en)BEGINhh<=a;hl<=b;IF(clk'EVENT AND clk='1') THENIF(en='1') THENIF(a="0010" AND b="0011") THENa<="0000";b<="0000";ELSE IF(b="1001") THENa<=a+'1';b<="0000";ELSE b<=b+'1';END IF;END IF;IF(a="0010" AND b="0010") THENcout<='1';ELSE cout<='0';END IF;END IF;END IF;END PROCESS;END arc;模60计数器模块LIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;USE IEEE.STD_LOGIC_UNSIGNED.ALL;USE IEEE.STD_LOGIC_ARITH.ALL;ENTITY count60 ISPORT(clk,en:IN STD_LOGIC;cout:OUT STD_LOGIC;hh,hl:OUT STD_LOGIC_VECTOR(3 DOWNTO 0));END count60;ARCHITECTURE arc OF count60 ISSIGNAL a,b:STD_LOGIC_VECTOR(3 DOWNTO 0);SIGNAL sout:STD_LOGIC;BEGINPROCESS(clk)BEGINhh<=a; hl<=b;IF(clk'EVENT AND clk='1') THENIF(en='1') THENIF(a="0101" AND b="1001") THENa<="0000";b<="0000";ELSE IF(b="1001") THENa<=a+'1';b<="0000";ELSE b<=b+'1';END IF;END IF;END IF;END IF;END PROCESS;sout<='1' WHEN a="0101" AND b="1001" ELSE '0';cout<=sout AND en;END arc;4-7显示译码模块LIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;ENTITY segment4to7 ISPORT(s:IN STD_LOGIC_VECTOR(3 DOWNTO 0);a,b,c,d,e,f,g:OUT STD_LOGIC);END segment4to7;ARCHITECTURE arc OF segment4to7 IS SIGNAL y:STD_LOGIC_VECTOR(6 DOWNTO 0); BEGINa<= y(6);b<= y(5);c<= y(4);d<= y(3);e<= y(2); f<= y(1);g<= y(0);PROCESS(s)BEGINCASE s ISWHEN "0000"=>y<="1111110"; WHEN "0001"=>y<="0110000"; WHEN "0010"=>y<="1101101"; WHEN "0011"=>y<="1111001"; WHEN "0100"=>y<="0110011"; WHEN "0101"=>y<="1011011"; WHEN "0110"=>y<="1011111"; WHEN "0111"=>y<="1110000"; WHEN "1000"=>y<="1111111"; WHEN "1001"=>y<="1111011"; WHEN OTHERS=>y<="0000000"; END CASE;END PROCESS;END arc;带闹钟控制模块LIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;ENTITY mode_adjust_with_alarm ISPORT (adjust,mode,clk1hz: IN STD_LOGIC;clkh,enh,clkm,enm,clks,enha: OUT STD_LOGIC;clkh_a,clkm_a:OUT STD_LOGIC;mode_ss: OUT STD_LOGIC_VECTOR(2 DOWNTO 0));END mode_adjust_with_alarm;ARCHITECTURE arc OF mode_adjust_with_alarm ISTYPE mystate IS (s0,s1,s2,s3,s4,s5);SIGNAL c_state,next_state: mystate;BEGINPROCESS (c_state)BEGINCASE c_state ISWHEN s0=> next_state <= s1; clkh<=clk1hz; clkm<=clk1hz; clks<=clk1hz;enh<='0'; enm<='0'; enha<='0'; clkh_a<= '0'; clkm_a<= '0'; mode_ss <="000";WHEN s1=> next_state <= s2; clkh<=adjust; clkm<= '0'; clks<='0';enh<='1'; enm<='0';enha<='0'; clkh_a<= '0';clkm_a<= '0'; mode_ss <="001";WHEN s2=> next_state <= s3; clkh<= '0'; clkm<=adjust; clks <= '0';enh<='0';enm<='1';enha<='0'; clkh_a<= '0'; clkm_a<= '0'; mode_ss <="010";WHEN s3=> next_state <= s4; clkh<= '0'; clkm<= '0'; clks<=adjust;enh<='0'; enm<='0';enha<='0'; clkh_a<= '0'; clkm_a<= '0'; mode_ss <="011";WHEN s4=> next_state <= s5; clkh<= clk1hz; clkm<= clk1hz; clks<=clk1hz;enh<='0';enm<='0';enha<='1'; clkh_a<=adjust; clkm_a<= '0'; mode_ss <="100";WHEN s5=> next_state <= s0; clkh<= clk1hz; clkm<= clk1hz; clks<=clk1hz;enh<='0'; enm<='0'; enha<='0'; clkh_a<= '0'; clkm_a<=adjust; mode_ss <="101";END CASE;END PROCESS;PROCESS (mode)BEGINIF (mode'EVENT AND mode='1') THENc_state<=next_state ;END IF;END PROCESS;END arc;扫描模块LIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;USE IEEE.STD_LOGIC_UNSIGNED.ALL;ENTITY scan ISPORT(clk256hz:IN STD_LOGIC;ss:OUT STD_LOGIC_VECTOR(2 DOWNTO 0));END scan;ARCHITECTURE arc OF scan ISTYPE mystate IS (s0, s1,s2,s3,s4,s5);SIGNAL c_state,next_state: mystate;BEGINPROCESS ( c_state )BEGINCASE c_state ISWHEN s0=> next_state <=s1; ss<="010";WHEN s1=> next_state <=s2; ss<="011";WHEN s2=> next_state <=s3; ss<="100";WHEN s3=> next_state <=s4; ss<="101";WHEN s4=> next_state <=s5; ss<="110";WHEN s5=> next_state <=s0; ss<="111";END CASE;END PROCESS;PROCESS (clk256hz)BEGINIF (clk256hz'EVENT AND clk256hz='1') THENc_state<=next_state ;END IF;END PROCESS;END arc;复用模块LIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;ENTITY mux ISPORT(hh,hl,mh,ml,sh,sl,hha,hla,mha,mla:IN STD_LOGIC_VECTOR(3 DOWNTO 0);ss,mode_ss:IN STD_LOGIC_VECTOR(2 DOWNTO 0);y:OUT STD_LOGIC_VECTOR(3 DOWNTO 0);alarm:OUT STD_LOGIC);END mux;ARCHITECTURE arc OF mux ISSIGNAL a,hhtmp,hltmp,mhtmp,mltmp,shtmp,sltmp:STD_LOGIC_VECTOR(3 DOWNTO 0);BEGINPROCESS(mode_ss)BEGINCASE mode_ss ISWHEN "000"=>hhtmp<=hh; hltmp<=hl; mhtmp<=mh; mltmp<=ml; shtmp<=sh; sltmp<=sl;WHEN "001"=>hhtmp<=hh; hltmp<=hl; mhtmp<=mh; mltmp<=ml; shtmp<=sh; sltmp<=sl;WHEN "010"=>hhtmp<=hh; hltmp<=hl; mhtmp<=mh; mltmp<=ml; shtmp<=sh; sltmp<=sl;WHEN "011"=>hhtmp<=hh; hltmp<=hl; mhtmp<=mh; mltmp<=ml; shtmp<=sh; sltmp<=sl;WHEN "100"=> hhtmp<=hha; hltmp<=hla; mhtmp<=mha; mltmp<=mla; shtmp<=sh; sltmp<=sl;WHEN "101"=> hhtmp<=hha; hltmp<=hla; mhtmp<=mha; mltmp<=mla; shtmp<=sh; sltmp<=sl;WHEN OTHERS=>hhtmp<="0000";hltmp<="0000";mhtmp<="0000";mltmp<="0000";shtmp<="0000";sltmp<="0000"; END CASE;END PROCESS;PROCESS(ss)BEGINCASE ss ISWHEN "010"=> a <=hhtmp;WHEN "011"=> a <=hltmp;WHEN "100"=> a <=mhtmp;WHEN "101"=> a <=mltmp;WHEN "110"=> a <=shtmp;WHEN "111"=> a <=sltmp;WHEN OTHERS => a <="0000";END CASE;y<=a;END PROCESS;alarm<='1' WHEN ((hh=hha)AND(hl=hla)AND(mh=mha)AND(ml=mla)) ELSE '0';END arc;闪烁模块LIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;USE IEEE.STD_LOGIC_UNSIGNED.ALL;ENTITY blink_control ISPORT(ss,mode_ss:IN STD_LOGIC_VECTOR(2 DOWNTO 0);blink_en:OUT STD_LOGIC);END blink_control;ARCHITECTURE arc OF blink_control ISBEGINPROCESS (ss,mode_ss)BEGINIF(ss="010" AND mode_ss="001") THEN blink_en<='1';ELSIF(ss="011" AND mode_ss="001") THEN blink_en<='1';ELSIF(ss="100" AND mode_ss="010") THEN blink_en<='1';ELSIF(ss="101" AND mode_ss="010") THEN blink_en<='1';ELSIF(ss="110" AND mode_ss="011") THEN blink_en<='1';ELSIF(ss="111" AND mode_ss="011") THEN blink_en<='1';ELSIF(ss="010" AND mode_ss="100") THEN blink_en<='1';ELSIF(ss="011" AND mode_ss="100") THEN blink_en<='1';ELSIF(ss="100" AND mode_ss="101") THEN blink_en<='1';ELSIF(ss="101" AND mode_ss="101") THEN blink_en<='1';ELSE blink_en<='0';END IF;END PROCESS;END arc;Top文件LIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;USE IEEE.STD_LOGIC_UNSIGNED.ALL;ENTITY design3 ISPORT (mode,adjust,clk1hz,clk2hz,clk256hz,clk1khz:IN STD_LOGIC;alarm,a,b,c,d,e,f,g:OUT STD_LOGIC;ss:OUT STD_LOGIC_VECTOR(2 DOWNTO 0));END design3;ARCHITECTURE arc OF design3 ISCOMPONENT mode_adjust_with_alarm PORT (adjust,mode,clk1hz: IN STD_LOGIC;clkh,enh,clkm,enm,clks,enha: OUT STD_LOGIC;clkh_a,clkm_a:OUT STD_LOGIC;mode_ss: OUT STD_LOGIC_VECTOR(2 DOWNTO 0));END COMPONENT;COMPONENT scan PORT (clk256hz:IN STD_LOGIC;ss:OUT STD_LOGIC_VECTOR(2 DOWNTO 0));END COMPONENT;COMPONENT segment4to7 PORT (s: IN STD_LOGIC_VECTOR(3 DOWNTO 0);a,b,c,d,e,f,g: OUT STD_LOGIC);END COMPONENT;COMPONENT mux PORT(hh,hl,mh,ml,sh,sl,hha,hla,mha,mla:IN STD_LOGIC_VECTOR(3 DOWNTO 0);ss,mode_ss:IN STD_LOGIC_VECTOR(2 DOWNTO 0);y:OUT STD_LOGIC_VECTOR(3 DOWNTO 0);alarm:OUT STD_LOGIC);END COMPONENT;COMPONENT blink_control PORT(ss,mode_ss:IN STD_LOGIC_VECTOR(2 DOWNTO 0);blink_en:OUT STD_LOGIC);END COMPONENT;COMPONENT count24 PORT (clk,en:IN STD_LOGIC;cout:OUT STD_LOGIC;hh,hl:OUT STD_LOGIC_VECTOR(3 DOWNTO 0));END COMPONENT;COMPONENT count60 PORT (clk ,en:IN STD_LOGIC;cout:OUT STD_LOGIC;hh,hl:OUT STD_LOGIC_VECTOR(3 DOWNTO 0));END COMPONENT;SIGNALclkh,enh,clkm,enm,clks,clkh_a,clkm_a,coutm,couts,coutm_en,couts_en,cout,vcc,coutma_en,coutma,alarm1,bli nk_en,blink_tmp,enha: STD_LOGIC;SIGNAL mode_ss,ss1:STD_LOGIC_VECTOR(2 DOWNTO 0);SIGNAL hh,hl,mh,ml,sh,sl,hha,hla,mha,mla,y,i:STD_LOGIC_VECTOR(3 DOWNTO 0);BEGINvcc<='1';coutm_en <= enh OR coutm;couts_en <= enm OR couts;coutma_en<= enha OR coutma;blink_tmp<=blink_en and clk2hz;i(3)<=y(3) OR blink_tmp;i(2)<=y(2) OR blink_tmp;i(1)<=y(1) OR blink_tmp;i(0)<=y(0) OR blink_tmp;ss<=ss1;alarm<=alarm1 AND clk1khz;u1:mode_adjust_with_alarmPORT MAP( adjust,mode,clk1hz,clkh,enh,clkm,enm,clks,enha,clkh_a,clkm_a,mode_ss);u2:count24 PORT MAP(clkh,coutm_en,cout,hh,hl);u3:count60 PORT MAP(clkm,couts_en,coutm,mh,ml);u4:count60 PORT MAP(clks,vcc,couts,sh,sl);u5:count24 PORT MAP(clkh_a,coutma_en,cout,hha,hla);u6:count60 PORT MAP(clkm_a,vcc,coutma,mha,mla);u7:mux PORT MAP(hh,hl,mh,ml,sh,sl,hha,hla,mha,mla,ss1,mode_ss,y,alarm1);u8:scan PORT MAP(clk256hz,ss1);u9:blink_control PORT MAP(ss1,mode_ss,blink_en);u10:segment4to7 PORT MAP(i,a,b,c,d,e,f,g);END arc;实验结果:数字钟包括正常的时分秒计时, 实验箱左下角的6个动态数码管(DS6 A~DS1A)显示时、分、秒。
单片机电子时钟设计程序
单片机电子时钟设计程序
1.引用头文件和定义全局变量
首先需要引用相应的头文件,例如`reg52.h`,并定义全局变量用于
存储时间、闹钟时间以及其他相关参数。
2.初始化时钟
在主函数中,首先进行时钟的初始化。
这包括设置定时器和中断相关
的寄存器,以及初始化显示屏和按钮等外设。
3.时间更新
编写一个中断服务函数,用于根据定时器的中断来更新时间。
在该中
断服务函数中,需要将全局变量中的时间进行递增,并考虑到分钟、小时、日期和星期等的进位和换算。
4.按钮输入
设置一个子函数用于读取按钮输入,并根据按钮的状态来进行相应的
操作,比如切换时钟显示模式、设置闹钟等。
5.显示时间
编写一个子函数用于将时间信息显示在数码管上。
这需要先将时间信
息转换为数码管的显示格式,然后通过IO口输出控制数码管的显示。
6.闹钟设置
使用按钮输入的功能,可以设置闹钟时间和开关闹钟功能。
当闹钟时
间到达时,可以通过控制蜂鸣器发声或点亮LED等方式来进行提醒。
7.主函数
在主函数中,循环执行按钮输入的检测和相应操作,以及时间的更新和显示等功能。
可以通过一个状态机来控制整个程序的流程。
以上是一个简要的单片机电子时钟设计程序的概述。
实际的程序设计过程中,还需要考虑到各个模块之间的交互、错误处理、电源管理以及代码的优化等细节问题。
具体的程序实现可以根据具体需求和硬件平台的差异进行适当的修改和扩展。
基于STC89C52多功能电子时钟系统程序+原理图
一、设计任务设计制作一台以控制器为核心的多功能电子时钟系统二、设计要求:①.系统具有3种工作模式状态(正常时钟显示模式、系统校准模式、秒表计时模式);系统所有功能,均能够通过上位PC机对其操作修改与实时动态显示。
(PC主机端可利用高级语言进行人机界面设计)②.在正常时钟显示模式时,时钟具有显示年、月、日、时、分、秒的功能。
③.在正常时钟显示模式时,系统具有整点报时的功能,在离整点前10秒时,自动发出鸣叫声,步长1秒,每间隔1秒鸣叫一次,前4响是低音,后1响为高音,共鸣叫5次,最后1响结束时为整点。
高音频率为1KHz;④.在系统校准模式时,系统具有快速校准时间的功能。
⑤.在秒表计时模式时,可兼做比赛时间记录表。
秒表记时的精度为0.1秒,由3个键分别控制秒表的启动、清零、记录功能,可连续记录3组时间,并能够显示记录时间。
⑥.系统显示器采用LCD液晶显示器1602或其它显示器件,并采用键盘对相关数据进行设置与操作。
原理图设计制作一台以控制器为核心的多功能电子时钟系统二、设计要求:①.系统具有3种工作模式状态(正常时钟显示模式、系统校准模式、秒表计时模式);系统所有功能,均能够通过上位PC机对其操作修改与实时动态显示。
(PC主机端可利用高级语言进行人机界面设计)(注:此三种模式可以通过SET键盘来回切换,在正常时钟模式,第二排显示S:time,校准模式显示S:adjst,秒表模式,是TN~T3:四个秒表模式);②.在正常时钟显示模式时,时钟具有显示年、月、日、时、分、秒的功能。
(注:这个已经全部显示了,含星期)③.在正常时钟显示模式时,系统具有整点报时的功能,在离整点前10秒时,自动发出鸣叫声,步长1秒,每间隔1秒鸣叫一次,前4响是低音,后1响为高音,共鸣叫5次,最后1响结束时为整点。
高音频率为1KHz;(注:这个都实现了,要验证的话就是将时钟调整到59分后验证即可)④.在系统校准模式时,系统具有快速校准时间的功能。
SW电子时钟程序
第 7 页
GO5: IN0:
SW电子时钟.ASM MOV R3,#00H INC 41H RETI RETI
LCALL DELY ;延时消抖 JNB P3.2,SLECT RETI SLECT: DEC 47H MOV A,47H CJNE A,#00H,GGG0 MOV 47H,#04H RETI GGG0: RETI TABLE: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH END
SW电子时钟.ASM ADD A,#80H MOV P0,A MOV P2,#0BFH LCALL DEALY1 MOV P2,#0FFH ;时,十位 LCALL DEALY1 MOV A,45H ANL A,#0FH CJNE A,#04H,WENT6 MOV A,46H ANL A,#0FH CJNE A,#02H,WENT6 MOV 45H,#00H ;时归零 MOV 46H,#00H WENT6: MOV A,46H MOVC A,@A+DPTR MOV P0,A MOV P2,#07FH LCALL DEALY1 LJMP SW0 TIME1: MOV TH0, #03CH ;定时器T0重新赋初值 MOV TL0, #0B0H CLR TF0 INC R3 ;R3不为20,返回 CJNE R3,#14H,GO5 第 6 页
SW1:
CJNE SETB LJMP CJNE SETB LJMP
SW电子时钟.ASM A,#04H,SW1 TR0 SWN A,#00H,SW2 TR0 SWN
SW2: SW3: SW4:
CLR TR0 ;判断调那位 CJNE A,#03H,SW3 LJMP SLECT3 CJNE A,#02H,SW4 LJMP SLECT2 LJMP SLECT1
具有记忆功能的电子时钟(附程序)
一、题义分析及解决方案1、题意需求分析根据本设计给定的内容和要求可知:本实验要使用可编程的输入、输出接口8279A芯片来驱动一个八位的LED数码管显示器,本实验中LED驱动采用动态扫描方式显示,共用到八个数码管显示器,在显示的过程中是逐个点亮的,分别用来显示时钟的:时位-分位-秒位。
显示的初值设置为:23:59:59,每隔一秒,显示值改变一次。
其中一秒的控制可以通过循环执行扫描子程序来实现的。
在显示的过程中,通过键盘的设置可以进行时间的调整和暂停计数。
本实验中由于要实现断电存储功能故还需用到存储芯片AT24C02,它与CPU之间的通信时通过接口8255A芯片实现的,通过对SCL和SDA引脚与8255A的PC0和PC1引脚相连实现对电压的拉高、拉低,从而实现计时时钟的定时存储。
当断电重新启动后,电子时钟要求能够按照断电前的时间继续计数。
根据要求提出以下问题:(1)如何实现LED的动态扫描显示(2)8279A如何工作(3)1S如何控制(4)存储芯片如何存储数据2、解决问题的思路及方法1)硬件部分本实验采用8279A芯片、LED发光二极管、十六进制小键盘、8255A芯片、AT24C02存储芯片,由于8279A芯片的输出电流与LED不匹配,需采用74L240驱动电流。
8279芯片是一通用可编程键盘显示接口器件,可以实现对键盘/显示器的自动扫描,以减轻CPU负担。
与LED数码管、驱动器、按键可组成一个最基本键盘显示系统。
具有显示稳定,程序简单,不会出现误动作等特点。
AT24C02是记忆芯片,不能与CPU直接相连,要通过接口8255A芯片与CPU 实现通信。
2)软件部分初始值设置:在程序的数据段中定义秒、分、时的初值,并在LED上显示。
计时:上电后,数码管显示起始时间为23:59:59,通过键盘按键实现输入,当显示了1s时,秒位加1,并判断秒位是否为60,若不是,则直接显示时间;若是,则将秒位置0,分位加1,接着判断分位是否为60,若不是,则直接显示;若是,则将分位置0,时位加1,然后判断时位是否为24,若不是,则直接显示;若是,则将所有时间清零,重新计时。
单片机电子时钟设计程序(一)
单片机电子时钟设计程序(一)引言概述:电子时钟是一种广泛应用于家庭、办公室和公共场所的设备。
它在我们日常生活中起到了举足轻重的作用。
本文将介绍如何设计一个基于单片机的电子时钟程序,该程序能够准确地显示时间,并具备一些常用功能。
正文:1. 时钟芯片选择- 研究市场上常用的时钟芯片类型,如RTC芯片、单片机内部时钟等。
- 根据需求选择适合的时钟芯片,考虑其精度、功耗和价格等因素。
- 确定所选时钟芯片与单片机的连接方式和通信协议。
2. 硬件电路设计- 根据所选的时钟芯片类型和要求,设计电路连接图。
- 包括时钟芯片与单片机的连接,蜂鸣器和LED数码管等外部器件的接口设计。
- 确保电路可靠性和稳定性,避免干扰和电源问题。
3. 软件程序编写- 熟悉所选单片机的编程语言和开发环境。
- 设计时钟的显示逻辑,包括时、分、秒的显示方式和刷新频率。
- 实现时间的自动更新功能,通过与时钟芯片的通信获取准确的时间信息。
- 添加常用功能,如闹钟设置、定时器等,并编写相应的逻辑控制代码。
4. 调试与测试- 焊接和连接电路,并将单片机程序烧录进芯片。
- 进行硬件和软件的联合调试,确保电子时钟的功能正常。
- 测试不同情况下的准确性和稳定性,如供电中断、温度变化等。
5. 优化与改进- 对电子时钟的外观和显示效果进行优化,增加界面美感。
- 优化编程代码,提高时钟的运行效率和响应速度。
- 改进硬件电路,减少功耗和杜绝干扰,提高系统稳定性。
总结:通过本文提供的指导,我们可以设计一个功能齐全、准确可靠的单片机电子时钟程序。
从选择时钟芯片到硬件电路设计,再到软件程序编写和调试与测试,每个步骤都需要认真思考和细致操作。
通过不断优化与改进,我们可以提高电子时钟的性能和用户体验,为人们提供更好的时间显示和功能体验。
简单的51单片机时钟程序
简单的51单片机时钟程序,可以通过按键来设置时间,按键可以自己更改。
#include<reg52.h>#define uint unsigned int#define uchar unsigned char#define tt 46080 //设置时间间隔,对应11.0592MHZ的晶振uchar code table[]="Happy every day!";uchar code table1[]="00:00:00";uchar num,hh,mm,ss,t,s1num=0;sbit en=P3^4;sbit rs=P3^5;sbit rw=P3^6;sbit s1=P3^0;sbit s2=P3^1;sbit s3=P3^2;//按键所用的端口sbit s4=P3^3;void delay(uint z){uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--); //大约是1ms,因为单片机的时钟周期为11.0592mhz。
}void write_com(uchar com){rs=0; //指令P0=com; //写指令函数delay(1);en=1;delay(1);en=0;}void write_data(uchar dat){rs=1; //数据P0=dat; //写指令函数delay(1);en=1;delay(1);en=0;}void init(){en=0; //初始时使能为0rw=0;write_com(0x38); //显示屏模式设置为1602方案write_com(0x0c);write_com(0x06); //显示开关/光标设置write_com(0x01); //清屏write_com(0x80); //指针置零for(num=0;num<16;num++)write_data(table[num]);write_com(0xc3);for(num=0;num<8;num++)write_data(table1[num]);}void dingshi(){TMOD=0x01; //确定定时器工作模式(定时模式)TH0=(65536-tt)/256; //赋初值为tt微秒TL0=(65536-tt)%256; //不赋值时默认其值是0EA=1; //开总中断ET0=1; //开定时器0中断// IE=0x82; //总线写法TR0=1; //启动定时器0 总线TCON=0x10;}void shuanxin(uchar add,uchar date){uchar shi,ge;write_com(0xc3+add); //指针指向shi=date/10;ge=date%10;write_data(0x30+shi);write_data(0x30+ge); //指针自动后移,故不必再写指针位置}/***************借助蜂鸣器接地起作用***************/ void keyscan(){if(s1==0){delay(5);if(s1==0){s1num++;while(!s1);if(s1num==1){TR0=0; //时钟停止运行write_com(0xca); //指针指向sswrite_com(0x0f); //光标闪烁}if(s1num==2){write_com(0xc7); //指针指向mmwrite_com(0x0f);}if(s1num==3){write_com(0xc4); //指针指向hhwrite_com(0x0f);}if(s1num==4){s1num=0;TR0=1; //时钟运行write_com(0x0c); //取消闪烁}}}/***************调节时间****************/if(s1num!=0) //目的是使s1按下的前提才起作用{if(s2==0){delay(5);if(s2==0){while(!s2); //松手检测,松手后方可向下执行if(s1num==1){ss++;if(ss==60)ss=0;shuanxin(6,ss);write_com(0xca);}if(s1num==2){mm++;if(mm==60)mm=0;shuanxin(3,mm);write_com(0xc7);}{hh++;if(hh==24)hh=0;shuanxin(0,hh);write_com(0xc4);}}}}if(s1num!=0) //s1按下的前提才起作用{if(s3==0){delay(5);if(s3==0){while(!s3);if(s1num==1){ss--;ss=59;shuanxin(6,ss);write_com(0xca);}if(s1num==2){mm--;if(mm==-1)mm=59;shuanxin(3,mm);write_com(0xc7);}if(s1num==3){hh--;if(hh==-1)hh=23;shuanxin(0,hh);write_com(0xc4);}}}}if(s1num!=0) //s1按下的前提才起作用{if(s4==0){delay(5);if(s4==0){while(!s4);if(s1num==1){ss=0;shuanxin(6,ss);write_com(0xca);}if(s1num==2){mm=0;shuanxin(3,mm);write_com(0xc7);}if(s1num==3){hh=0;shuanxin(0,hh);write_com(0xc4);}}}}}void main(){init();dingshi();while(1){keyscan();if(t==20){P1=P1-1;t=0;ss++;if(ss==60){ss=0;mm++;if(mm==60){mm=0;hh++;if(hh==24){hh=0;}shuanxin(0,hh);}shuanxin(3,mm);}shuanxin(6,ss);}}}void time0() interrupt 1{TH0=(65536-tt)/256; //不赋值时默认其值是0 TL0=(65536-tt)%256;t++;}。
单片机汇编程序51电子时钟.doc
单片机汇编程序 51电子时钟电子钟设计实验报告一)实验目的:1、进一步掌握定时器的使用和编程方法。
2、进一步掌握中断处理程序的编程方法。
3、进一步掌握数码显示电路的驱动方法。
4、进一步掌握键盘电路的驱动方法。
5、进一步掌握软件数据处理的方法。
二)内容要求:1、利用CPU的定时器和数码显示电路,设计一个电子时钟。
格式如下:XX XX XX 由左向右分别为:时、分、秒。
2、电子时钟有秒表功能。
3、并能用键盘调整时钟时间。
4、电子时钟能整点报时、整点对时功能。
5、能设定电子时钟的闹铃。
三)主要元件:电阻4.7K 10个 2K 1个四位共阳数码管1个二位共阳数码管1个按钮开关4个万用板(中板)1个 9012PNP 7个排线排阵若干电线一捆蜂鸣器1个最小系统一个四)系统说明:按P1.0键,如果按下的时间小于1秒进入省电模式(数码管不显示,开T0计时器),如果按下的时间大于1秒则进入时间调整.。
在时间调整状态:再按P1.0,如果按下时间大于0.5秒转调小时状态,按下时间小于0.5秒加1分钟操作。
在小时调整状态再按P1.0键,如果按下时间大于0.5秒退出时间调整,如果按下时间小于0.5秒加1小时操作。
按P1.1键,进入闹铃调分状态,按P1.2分加1,按P1.0分减1。
若再按P1.3,则进入调整状态,按P1.2时加1,按P1.0分时。
按P1.1键,闹铃有效,显示式样变为00:00:—0;再按P1.1键,闹铃无效,显示式样变为00:00:—。
按P1.3键,调整闹钟时间结束。
按P1.2键,进入秒表计时功能,按P1.2键暂停或清零,按P1.1键退出秒表回到时钟状态。
而且本系统还有整点报时功能,以及按键伴有声音提示。
五)程序流程图:开始 TO中断初始化保护现场进入功能调用显示定时初值校正程序子程序N Y键按下, 1S到,Y N加1S处理整点到NY恢复现场,中断返回按时间鸣叫次数主程序流程图 T0中断计时程序流程图T1中断保护现场T1中断服务程序流程图秒表/闪烁,时钟调时闪烁加10MS处理闪烁处理恢复现场,中断返回六)电路图七)程序清单:中断入口程序 ;; DISPFIRST EQU 30H BELL EQU P1.4CONBS EQU 2FHOUTPX EQU P2 ;P2位选OUTPY EQU P0 ;P0段选INP0 BIT P1.0INP1 BIT P1.1INP2 BIT P1.2ORG 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 ;串行中断程序返回;QQQQ:MOV A,#10HMOV B,79HMUL ABADD A,78HMOV CONBS,ABSLOOP:LCALL DS20MSLCALL DL1SLCALL DL1SLCALL DL1SDJNZ CONBS,BSLOOPCLR 08HAJMP START;; 主程序 ;;START:MOV R0,#00H ;清70H-7AH共11个内存单元MOV R7,#80H ;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秒定时用初值(50MS×20)MOV DISPFIRST ,#70HSTART1: LCALL DISPLAY ;调用显示子程序JNB INP0,SETMM1 ;P1.0口为0时转时间调整程序JNB INP1,FUNSS ; 秒表功能,P1.1按键调时时作减1加能JNB INP2,FUNPT ;STOP,PUSE,CLRJNB P1.3,TSFUNSJMP START1 ;P1.0口为1时跳回START1SETMM1: LJMP SETMM ;转到时间调整程序SETMM FUNSS: LCALL DS20MSJB INP1,START1WAIT11: JNB INP1,WAIT11CPL 03HMOV DISPFIRST,#00H :显示秒表数据单元MOV 70H,#00HMOV 71H,#00HMOV 76H,#00HMOV 77H,#00HMOV 78H,#00HMOV 79H,#00HAJMP START1FUNPT: LCALL DS20MSJB INP2,START1WAIT22: JNB INP2,WAIT21CLR ET0CLR TR0WAIT33: JB INP2,WAIT31 LCALL DS20MSJB INP2,WAIT33WAIT66: JNB INP2,WAIT61 MOV R0,#70H ;清70H-79H共10 个内存单元MOV R7,#0AH ;CLEARP: MOV @R0,#00H ;INC R0 ;DJNZ R7,CLEARP ;WAIT44: JB INP2,WAIT41 LCALL DS20MSJB INP2,WAIT44WAIT55: JNB INP2,WAIT51 SETB ET0SETB TR0AJMP START1WAIT21: LCALL DISPLAY AJMP WAIT22WAIT31: LCALL DISPLAY AJMP WAIT33WAIT41: LCALL DISPLAYAJMP WAIT44WAIT51: LCALL DISPLAYAJMP WAIT55WAIT61: LCALL DISPLAYAJMP WAIT66 TSFUN:LCALL DS20MSWAIT113:JNB P1.3,WAIT113JB 05H,CLOSESPMOV DISPFIRST,#50HMOV 50H,#0CHMOV 51H,#0AHDSWAIT:SETB EALCALL DISPLAYJNB P1.2,DSFINCJNB P1.0,DSDECJNB P1.3,DSSFU AJMP DSWAITCLOSESP:CLR 05HCLR BELLAJMP START1 DSSFU:LCALL DS20MS JB P1.3,DSWAIT LJMP DSSFUNN DSFINC:LCALL DS20MS JB P1.2,DSWAIT DSWAIT12:LCALL DISPLAY JNB P1.2,DSWAIT12 CLR EAMOV R0,#53H LCALL ADD1MOV A,R3CLR CCJNE A,#60H,ADDHH22ADDHH22:JC DSWAITACALL CLR0AJMP DSWAITDSDEC:LCALL DS20MSLCALL DISPLAYDSWAITEE:LCALL DISPLAYJNB P1.0,DSWAITEECLR EAMOV R0,#53HLCALL SUB1LJMP DSWAIT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1秒计时程序 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;T0中断服务程序INTT0: PUSH ACC ;累加器入栈保护PUSH PSW ;状态字入栈保护CLR ET0 ;关T0中断允许CLR TR0 ;关闭定时器T0JB 03H,FSSMOV 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秒时对秒计时单元清0 MOV 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 ;清进位标志JB 03H,OUTT0 ;秒表时最大数为99CJNE A,#24H,HOUR ;HOUR: JC OUTT0 ;小于24小时中断退出ACALL CLR0 ;大于或等于24小时小时计时单元清0OUTT0: MOV 72H,76H ;中断退出时将分、时计时单元数据移MOV 73H,77H ;入对应显示单元MOV 74H,78H ;MOV 75H,79H ;LCALL BAOJPOP PSW ;恢复状态字(出栈)POP ACC ;恢复累加器SETB ET0 ;开放T0中断RETI ;中断返回 ;秒表计时程序(10MS加1),低2位为0.1、0.01秒,中间2位为秒,最高位为分。
基于单片机C语言电子时钟完整版(闹钟,整点报时)
《单片机技术》课程设计说明书数字电子钟系、部:电气与信息工程学院学生姓名:指导教师:职称专业:班级:完成时间:2013-06-07摘要电子钟在生活中应用非常广泛,而一种简单方便的数字电子钟则更能受到人们的欢迎。
所以设计一个简易数字电子钟很有必要。
本电子钟采用ATMEL公司的AT89S52单片机为核心,使用12MHz 晶振与单片机AT89S52 相连接,通过软件编程的方法实现以24小时为一个周期,同时8位7段LED数码管(两个四位一体数码管)显示小时、分钟和秒的要求,并在计时过程中具有定时功能,当时间到达提前定好的时间进行蜂鸣报时。
该电子钟设有四个按键KEY1、KEY2、KEY3、KEY4和KEU5键,进行相应的操作就可实现校时、定时、复位功能。
具有时间显示、整点报时、校正等功能。
走时准确、显示直观、运行稳定等优点。
具有极高的推广应用价值。
关键词电子钟;AT89S52;硬件设计;软件设计ABSTRACTClock is widely used in life, and a simple digital clock is more welcomed by people. So to design a simple digital electronic clock is necessary.The system use a single chip AT89S52 of ATMEL’s as its core to control The crystal oscillator clock,using of E-12MHZ is connected with the microcontroller AT89S52, through the software programming method to achieve a 24-hour cycle, and eight 7-segment LED digital tube (two four in one digital tube) displays hours, minutes and seconds requirements, and in the time course of a timing function, when the time arrived ahead of scheduled time to buzz a good timekeeping. The clock has four buttons KEY1, KEY2, KEY3,KEY4 and KEY5 key, and make the appropriate action can be achieved when the school, timing, reset. With a time display, alarm clock settings, timer function, corrective action. Accurate travel time, display and intuitive, precision, stability, and so on. With a high application value.Key words Electronic clock;;AT89S52;Hardware Design;Software Design目录1设计课题任务、功能要求说明及方案介绍 (1)1.1设计课题任务 (1)1.2功能要求说明 (1)1.3设计总体方案介绍及原理说明 (1)2设计课题硬件系统的设计 (2)2.1设计课题硬件系统各模块功能简要介绍 (2)2.2设计课题电路原理图、PCB图、元器件布局图 (2)2.3设计课题元器件清单 (5)3设计课题软件系统的设计 (6)3.1设计课题使用单片机资源的情况 (6)3.2设计课题软件系统各模块功能简要介绍 (6)3.3设计课题软件系统程序流程框图 (6)3.4设计课题软件系统程序清单 (10)4设计结论、仿真结果、误差分析、教学建议 (21)4.1设计课题的设计结论及使用说明 (21)4.2设计课题的仿真结果 (21)4.3设计课题的误差分析 (22)4.4设计体会 (22)4.5教学建议 (22)结束语 (23)参考文献 (24)致谢 (25)附录 (26)1 设计课题任务、功能要求说明及方案介绍1.1 设计课题任务设计一个具有特定功能的电子钟。
DS12C887电子时钟(附程序)
下面附有实物图和引脚接法图及程序时钟实物图LCD1602引脚连接P1.0 P1.1 P1.2P0.0~P0.7DS12C887引脚连接(打叉的表示不接)蜂鸣器引脚连接按键引脚连接P1.3P3.4P3.5P3.6P3.7源程序#include<reg52.h>#include<intrins.h>#define uint unsigned int#define uchar unsigned charsbit lcdrs=P1^0;sbit rw=P1^1;sbit lcden=P1^2;sbit s1=P3^4; //功能键sbit s2=P3^5; //增大键sbit s3=P3^6; //减小键sbit s4=P3^7; //闹铃查看键sbit beep=P1^3;//蜂鸣器sbit dscs=P1^7;sbit dsas=P1^6;sbit dsrw=P1^5;sbit dsds=P1^4;sbit dsirq=P3^3; //中断bit flag1,flag_ri;//定义标志位flag1设置闹铃uchar count,s1num,flag,t0_num;char miao,shi,fen,year,month,day,week,amiao,afen,ashi;char code table[]=" 20 - - "; // 20 - -uchar code table1[]=" : : "; // : :void write_ds(uchar,uchar); uchar read_ds(uchar);void set_time(); void read_alarm();void set_alarm(uchar,uchar,uchar);void delayms(uint z) //延时毫秒的程序{uint x,y;for(x=z;x>0;x--)for(y=112;y>0;y--);}void di(){beep=0;delayms(100);beep=1;}void write_cmd(uchar cmd){lcden=0;lcdrs=0;P0=cmd;_nop_();lcden=1;delayms(1);lcden=0;_nop_();}void write_dat(uchar dat){lcden=0;lcdrs=1;P0=dat;_nop_();lcden=1;delayms(1);lcden=0;_nop_();}void lcdint(){lcden=0;write_cmd(0x38); // 显示模式设置write_cmd(0x0c); //开显示,不显示光标,不闪烁write_cmd(0x06); //写一个字符后地址加1,屏幕不移write_cmd(0x01); //清屏delayms(1);}void init(){uchar num;rw=0;EA=1;//开总中断EX1=1;//开外部中断1IT1=1;//外部中断下降沿触发flag1=0; t0_num=0;s1num=0;week=1;/* write_ds(0x0A,0x20);//打开振荡器write_ds(0x0B,0x26);//设置24小时模式,数据二进制格式,开启闹铃中断set_time();//设置上电默认时间,调试的时候用*/lcdint();write_cmd(0x80);for(num=0;num<15;num++){write_dat(table[num]);}write_cmd(0xc0);for(num=0;num<11;num++){write_dat(table1[num]);}}void write_sfm(uchar add,char date) //写时间,2位一起写{char shi,ge;shi=date/10;ge=date%10;write_cmd(0xc0+add);write_dat(0x30+shi);write_dat(0x30+ge);}void write_nyr(uchar add,char date)//年月日{char shi,ge;shi=date/10;ge=date%10;write_cmd(0x80+add);write_dat(0x30+shi);write_dat(0x30+ge);}void write_week(char we)//星期{write_cmd(0x80+12);switch(we){case 1: write_dat('M');write_dat('O');write_dat('N');break;case 2: write_dat('T');write_dat('U');write_dat('E');break;case 3: write_dat('W');write_dat('E');write_dat('D');break;case 4: write_dat('T');write_dat('H');write_dat('U');break;case 5: write_dat('F');write_dat('R');write_dat('I');break;case 6: write_dat('S');write_dat('A');write_dat('T');break;case 7: write_dat('S');write_dat('U');write_dat('N');break;}}void keyscan(){if(flag_ri==1){if((s1==0)||(s2==0)||(s3==0)||(s4==0))//按任意键取消闹钟报警{delayms(5);if((s1==0)||(s2==0)||(s3==0)||(s4==0)){while(!(s1&&s2&&s3&&s4));di();flag_ri=0;}}}if(s1==0) //如果功能按键1按下{delayms(5); //去抖动if(s1==0){while(!s1); //等待松手s1num++; //记下次数di(); //蜂鸣器响if(flag1==1) //设置闹铃为1时才对s1num调整,只调秒,分,时{if(s1num>3){s1num=1;}}flag=1; //在调整时间时标志位flag为1,不进行正常操作switch(s1num){case 1:write_cmd(0xc0+10); write_cmd(0x0f); break; //按一下秒钟指针显示闪烁case 2:write_cmd(0xc0+7); break;case 3:write_cmd(0xc0+4); break;case 4:write_cmd(0x80+12); break;case 5:write_cmd(0x80+9); break;case 6:write_cmd(0x80+6); break;case 7:write_cmd(0x80+3); break;default: //用default可以解决s1num跑飞s1num=0;write_cmd(0x0c); //按了8次关闪烁,flag=0,退出调整,显示时间flag=0;write_ds(0,miao); //将调整后的时间写入ds12c887write_ds(2,fen);write_ds(4,shi);write_ds(6,week);write_ds(7,day);write_ds(8,month);write_ds(9,year);break;. . . .}}}if(s1num!=0) //S1有按下过,检测S2,S3{if(s2==0) //如果按键2按下执行加{delayms(5);if(s2==0){while(!s2);di();switch(s1num){case 1:miao++;if(miao>59){miao=0;}write_sfm(10,miao);write_cmd(0x80+0x40+10);break;. . . . case 2:fen++;if(fen>59){fen=0;}write_sfm(7,fen);write_cmd(0x80+0x40+7);break;case 3:shi++;if(shi>23){shi=0;}write_sfm(4,shi);write_cmd(0x80+0x40+4);break;case 4:week++;if(week>7){. . . .week=1;}write_week(week);write_cmd(0x80+12);break;case 5:day++;if(day>31){day=1;}write_nyr(9,day);write_cmd(0x80+9);break;case 6:month++;if(month>12){month=1;}write_nyr(6,month);write_cmd(0x80+6);. . . .break;case 7:year++;if(year>99){year=0;}write_nyr(3,year);write_cmd(0x80+3);break;}}}if(s3==0){delayms(5);if(s3==0){while(!s3);di();switch(s1num){case 1:. . . .miao--;if(miao<0){miao=59;}write_sfm(10,miao);write_cmd(0x80+0x40+10);break;case 2:fen--;if(fen<0){fen=59;}write_sfm(7,fen);write_cmd(0x80+0x40+7);break;case 3:shi--;if(shi<0){shi=23;write_sfm(4,shi);write_cmd(0x80+0x40+4);break;case 4:week--;if(week<1){week=7;}write_week(week);write_cmd(0x80+12);break;case 5:day--;if(day<1){day=31;}write_nyr(9,day);write_cmd(0x80+9);break;month--;if(month<1){month=12;}write_nyr(6,month);write_cmd(0x80+6);break;case 7:year--;if(year<0){year=99;}write_nyr(3,year);write_cmd(0x80+3);break;}}}}if(s4==0){delayms(5);if(s4==0){while(!s4);di(); flag1=~flag1; //闹铃调好后再按一次键返回if(flag1==0) //退出闹钟设置保存数值{flag=0; //启动时间显示write_cmd(0x80+0x40);write_dat(' ');write_dat(' ');write_cmd(0x0c); //清屏下,否则光标乱跳(闹铃调时间时)write_ds(1,miao);write_ds(3,fen);write_ds(5,shi);}else //设置闹钟{read_alarm(); //读原始数据miao=amiao;fen=afen;shi=ashi;write_cmd(0xc0);write_dat('R');write_dat('i');write_cmd(0x80+0x40);write_sfm(4,ashi);write_sfm(7,afen);write_sfm(10,amiao);}}}}void write_ds(uchar add,uchar date)//写12c887函数{dscs=0;dsas=1;dsds=1;dsrw=1;P0=add; //写地址dsas=0;dsrw=0;P0=date; //写数据dsrw=1;dsas=1;dscs=1;}uchar read_ds(uchar add) //读12c887 {uchar ds_date;dsas=1;dsds=1;dsrw=1;dscs=0;P0=add;dsas=0;dsds=0;P0=0xff;ds_date=P0;dsds=1;dsas=1;dscs=1;return ds_date;}/*void set_time() //初始化{write_ds(0,0); //秒write_ds(1,10); //秒闹铃write_ds(2,34); //分钟write_ds(3,34); //分钟闹铃write_ds(4,15); //小时write_ds(5,15); //小时闹铃write_ds(6,5); //星期write_ds(7,20); //日write_ds(8,5); //月write_ds(9,11); //年}*/void read_alarm(){amiao=read_ds(1);afen=read_ds(3);ashi=read_ds(5);}void main(){init();while(1){keyscan(); //键盘不断扫描if(flag_ri==1) //如果闹铃时间到{di();delayms(100);di();delayms(500);}if(flag==0&&flag1==0){keyscan();year=read_ds(9);month=read_ds(8);day=read_ds(7);week=read_ds(6);shi=read_ds(4);fen=read_ds(2);miao=read_ds(0);write_sfm(10,miao);write_sfm(7,fen);write_sfm(4,shi);write_week(week);write_nyr(3,year);write_nyr(6,month);write_nyr(9,day);}}}void exter()interrupt 2 //闹铃外部中断1{uchar c; //闹铃时间到flag_ri=1;c=read_ds(0x0c); //读C寄存器表示响应中断}。
电子时钟设计DS++可调闹钟+程序清单
电子时钟设计DS++可调闹钟+程序清单本文主要介绍一种新型的电子时钟设计,名为DS++可调闹钟。
这种电子时钟不仅能够显示当前日期和时间,而且其可调节的闹钟功能也十分实用。
同时,我们还提供程序清单,供各位读者借鉴学习。
1. 电子时钟设计的背景和目标电子时钟已经成为人们日常生活中不可或缺的物品之一。
在市场上,人们可以买到各种各样的电子时钟,从简单的数字显示到智能语音交互。
然而,我们常常发现,在时钟设计中,用户体验常常被忽视。
比如,有的时钟功能繁杂,使用起来困难;有的时钟质量低劣,经常出现故障。
为了解决这些问题,我们决定设计一种更为智能且易用的电子时钟,就是DS++可调闹钟。
本次电子时钟设计的目标是:1)提供准确的时间显示和日期显示;2)提供可调闹钟功能和提示功能;3)简单易用,方便用户使用。
2. DS++可调闹钟设计方案2.1 电路原理图DS++可调闹钟的电路包括微处理器、振荡器、液晶显示模块、蜂鸣器、按键等部分。
主控芯片采用AT89S52(51系列微控制器),与液晶显示模块通过IIC总线通信。
振荡器采用32.768kHz的石英晶体振荡器,保证时钟的准确性。
2.2 功能模块设计液晶显示模块的设计是优化DS++可调闹钟的关键。
我们选用了1602A型液晶显示屏,显示内容包括日期、时间和闹钟状态。
闹钟模块是DS++可调闹钟的核心模块之一,它通过可调节的闹钟时间和闹钟提示音,方便用户设置并响铃提醒。
2.3 电路调试及测试在电路设计和焊接完成后,我们需要进行电路调试和测试。
在调试过程中,我们主要测试了电子时钟的时间显示、日期显示、闹钟设置等功能。
同时,我们还测试了与之相协调的同时供电设备,比如移动电源和插座电源。
3. 程序清单DS++可调闹钟的程序基于Keil/µVision IDE的汇编语言编写。
半个时钟周期内的指令流水线技术使得程序库在嵌入式微控制器上的表现达到质的提升,且运行速度更快。
DS++可调闹钟的程序清单如下:- 初始化电路;- 显示日期、时间;- 等待用户按键;-用户按键相应操作;- 播放闹钟提示音;- 关闭闹钟。
51单片机数码管电子时钟C程序
//**单片机stc89c52, 8位共阴数码管12M晶振//*******P0 位选,P2 段选❖******//#include 〃reg52・ h〃#define uchar unsigned char#define uint unsigned intuchar code tab[] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x40, Oxff}; uchar n;uchar hh, mm, ss;uchar nhh, nmm, nss;uint year;uchar day, mon, week;uchar hhs, hhg, mms, mmg, sss, ssg;uchar days,dayg, mons, mong;uchar nhhs, nhhg, nmms, nmmg, nsss, nssg;uchar setl=l, set2=l;sbit dula=P3 3;sbit fm=P3 2;sbit kl二P3"4;sbit k2二P3"5;sbit k3二P3飞;sbit k4二P3"7;uchar tablel[] = {31, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 〃闰年uchar table2[] = {31, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; //非闰年void jishi ();void baoshi ();void alarm();void set_time();void set_alarm();void set_mdw();void key_change():void key_set ();void delay (int m) 〃延时程序,延时m*0. 5msuint i;uint j;for (i=0;i<m;i++){for(j=0;j<500;j++){}}}void timerO() interrupt 1 {TMOD二0x01;TH0=0x3c;TLO=Oxbl;n++;JishiO;}main()TMOD二0x01;TH0=0x3c;TLO二Oxbl;TRO二1;EA二1;ETO二1;hh=12;mm=00;ss=00;nhh二7;nmm=30;nss=0;year=2012;mon=01;day=01;week=7; while(1){hhs=hh/10%10; // 时分秒hhg=hh%10;mms=mm/10%10;mmg=mm%10;sss=ss/10%10;ssg=ss%10;nhhs=nhh/10%10; 〃闹钟nhhg=nhh%10; nmms=nmm/10%10;nmmg=nmm%10; nsss=nss/10%10;nssg=nss%10; days=day/10%10;//月Hday萨day%10; mons=mon/10%10;mong=mon%10;key_change () ; //kl 按键扫描key_set (); //k2 按键扫描set_time() ; //设置时间set.mdwO ; //设置月日星期set_alarm() ; //设置闹钟辻(setl-1) //正常走时显示dula=l: P2=tab [hhs] ; dula=O: P2=0xff; PO=Oxef; delay (1) ;P0二Oxff; //时十位dula二1;P2二tab[hhg]; dula=0;P2=0xff;PO=Oxdf;delay(1) ; PO二Oxff;//时个位dula=l;P2=tab[10]:dula=0;P2=0xff; PO=Oxbf;delay(1); PO二Oxffdula=l: P2=tab [mms] : dula=0: P2 二Oxff ;P0 二0x7f; delay (1) ;P0 二Oxff; //分十位dula=l; P2=tab [mmg] ; dula=0; P2=0xf f; P0=0xfe; delay (1) ; PO 二Oxff;//分个位dula=l;P2=tab[10]; dula=0:P2=0xff;PO=Oxfd:delay(1); PO二Oxffdula二1;P2二tab[sss]; dula=0;P2=0xff;PO=Oxfb:delay(1) ; PO二Oxff;//秒十位dula二1;P2二tablssg]; dula=0:P2=0xff;P0=0xf7; delay(1) ;P0二Oxff; //秒个位}辻(set 1=2) //设置时间dula=l; P2=tab [hhs] ; dula=0; P2=Oxff; PO=Oxef; delay (1) ;P0二Oxff; //时十位dula二1;P2二tablhhg]; dula=0:P2=0xff;PO=Oxdf;delay(1) ; PO二Oxff;//时个位dula=l:P2=tab[10]:dula=0;P2=0xff; PO=Oxbf;delay(1); PO二Oxffdula=l: P2=tab [mms] : dula=0: P2 二Oxff ;P0 二0x7f; delay (1) ;P0 二Oxff; //分十位dula=l; P2=tab [mmg] ; dula=0: P2=0xf f: P0=0xfe; delay (1) ; PO 二Oxff;//分个位dula=l;P2=tab[10]; dula=0:P2=0xff;PO=Oxfd:delay(1); PO二Oxffdula二1;P2二tab[sss]; dula=0;P2=0xff;PO=Oxfb:delay(1) ; PO二Oxff;//秒十位dula二1;P2二tablssg]; dula=0:P2=0xff;P0=0xf7; delay(1) ;P0二Oxff; //秒个位}辻(set 1-3) //正常显示月日-星期(肆匕诂S )M心T P 鏗\m x o u o 匕(DAPWZJXOUOddxouzdoudnp 二席*〕qpf Zd二 H d n p 创+忌、、d x o u o d - (I )A p w q J x o u o d d x o u z d o H £n p =s 〕q p f z d =%-n p 、、—、、、、QJXOUOd - (I)xp^p&Jxouod2Jxouzdo%w 〔OI 〕qeTzd=%-np 心T p g 'm x o u o d - u)APW*xouoddxouzd oUPTnp 二"App 〕qpfzd二%-np^+、、dxouocr(DAP^PQZXOUOmxouzdou d n p 二 SAPP 〕qpfzd 二%-np 、、—、、、、QJXOUOdJI) A32P cu q x o u o d 世o %I n p 二2〕q e F CN d 二%H T P 鏗\m x o u o 匕(DAPWZJXOUOddxouzdoudnp 二席*〕qpf Zd二 H d n p 创+忌、、d x o u o d - (I )A p w q J x o u o d d x o u z d o H £n p =s 〕q p f z d =%-n p 、、—、、、、心 J x o u o d - (I)xp^p&Jxouod2Jxouzdo%w 〔OI 〕qeTzd=%-np 心T p g 'm x o u o d - u)APW*xouoddxouzd oUPTnp 二"App 〕qpfzd 二%-np ^+0、、d x ouocr(DAP^PQZXOUOmxouzdoudnp二SAPP〕qpfzd二%-np 、、—、、、、QJXOUOd J I ) A32Pcu q x o u o d £0 世dula=l; P2=tab [nhhs]; dula=O; P2二Oxff; PO二Oxef; delay (1) ; PO二Oxff; 〃时十位dula=l;P2=tab[nhhg]; dula=0;P2=0xff;PO=Oxdf; delay (1) ; PO二Oxff;//时个位dula=l;P2=tab[10];dula=0;P2=0xff; PO=Oxbf;delay(1); PO二Oxff dula=l:P2=tab [nmms] : dula=0; P2=0xff ;P0=0x7f; delay (1) ;PO=Oxff; //分十位dula=l;P2=tab[nmmg] :dula=0;P2=0xff;PO=Oxfe; delay (1) ; PO=Oxff;//分个位dula=l;P2=tab[10]; dula=0:P2=0xff;PO=Oxfd:delay(1) ; PO二Oxffdula=l ;P2=tab[nsss] : dula=0;P2=0xff ;PO=Oxfb; delay (1) ; PO二Oxff;//秒十位dula=l;P2=tab[nssg] ; dula=0: P2=0xff; PO=Oxf7; delay (1) ;PO=Oxff; //秒个位} if(setl—6) //设置闹钟定时dula=l; P2=tab [nhhs] ; dula=0; P2二Oxff; PO二Oxef; delay (1) ; PO二Oxff; 〃时十位dula=l;P2=tab[nhhg]; dula=0;P2=0xff;PO=Oxdf; delay (1) ; PO二Oxff;//时个位dula=l;P2=tab[10];dula=0;P2=0xff; PO=Oxbf;delay(1); PO二Oxff dula=l:P2=tab [nmms] : dula=0; P2=0xff ;P0=0x7f; delay (1) ;PO=Oxff; //分十位dula=l;P2=tab[nmmg] :dula=0;P2=0xff;PO=Oxfe;delay(1) ; PO二Oxff;//分个位dula=l;P2=tab[10]; dula=0;P2=0xff;PO=Oxfd:delay(1); PO二Oxff dula=l;P2=tab[nsss]; dula二0;P2二Oxff;P0二Oxfb;delay(l) ; PO二Oxff;//秒十位dula=l;P2=tab[nssg] ; dula=0: P2=0xff; PO=Oxf7; delay (1) ;P0二Oxff; //秒个位}baoshi () : //整点报时alarm () ; //闹钟}}void JishiO 〃计时函数辻(n二二20){n=0;ss++;辻(ss=60){ss二0;mm++;if(mm二二60){mm^O;hh++;辻(hh=24){hh二0;day++;week++;if(week==8){week二0;}if (year%4==0&&year%100! =0 year%400==0) //闰年if(day=二tablel[mon]+l){day=0;mon++;if(mon==13){mon二0;year++;}}else //非闰年{辻(day—table2 [mon]+l){day=0;mon++;辻(mon—13){mon二0;year++;}}}}}}}}uchar incone (uchar n) //加 1 函数{辻(k3=0){delay(20);if(k3==0){n++;while(!k3);}}return(n);}uchar decone(uchar m) //减 1 函数{ if (k4==0){delay(20);if(k4==0)辻(m<0){m 二0;}}}}void key_change() //kl 按键扫描{ if(kl==0){delay(20);if(kl==0){setl++;while(!kl);if(setl==7){setl二1;}}void key_set() //k2 按键扫描{if(k2==0){delay(20);{set2++;while(!k2);辻(set2=4){set2=l;}}}}void baoshi () //整点报时函数{ fm=O;}if(ss==l){fm=l;}}void alarm() //闹钟函数{uchar x;if(nhh==0){goto end;}if(hh==nhh&&mm二二nmm&&ss==nss)fm=O; delay(30); fm=l; delay(20); fm=0; delay(30); fm=l; delay(20); fm=0; delay(30); fm=l; delay(20); fm=0; delay(30); fm=l; delay (180);end:;}void set_time() //设置时间函数{辻(setl==2){辻(set2==l){hh=incone(hh);if(hh==24){hh=0;}if(hh==-l){hh二23;}hh二decone(hh);}mm=incone(mm); if(mm==60) {mm 二0;}if(mm==-l) {mm=59;}mm=decone(mm); }辻(set2=3){ss=incone(ss);辻(ss=60){ss=O;}if (ss—-1){ss=59;}ss二decone (ss);}void set_mdw() //设置月日星期函数{ 辻(setl==4) {辻(set2==l){mon=incone(mon);if(mon二二13){mon=l;}mon=decone(mon);if(mon==0){mon二12;}}if(set2==2)day=incone(day);if(day==32){day=l;} day=decone(day);if (day—0){day=31;}}辻(set2=3){week=incone(week);if(week==8){week二1;}week二decone(week);if(week==0){week=7;}}}void set_alarm() //设置闹钟函数{ if(setl二二6){辻(set2=l){nhh二incone(nhh);辻(nhh二二24) {nhh二0;}辻(nhh—-1){nhh二23;}nhh二decone(nhh); }if(set2==2){nmm二incone(nmm); if (nmm—60) {nmm二0;}nmm二decone(nmm); if (nmm 二二 T){nmm=59;}}辻(set2二二3) {nss=incone (nss); if (nss=60){nss=0;}nss二decone(nss); if(nss==-l){nss二59;}}}。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
+-+机电工程系课程设计报告题目:专业:班级:学号:姓名:同组人:指导老师:答辩日期:一、绪论当今世界但片机以飞快的速度在发展,了解和掌握单片机技术是我们机电系学生应该学习的课程之一,基于本学期对单片机的学习,现在对单片机语言所写出的电子时钟展开说明,现在生活很多东西都是离不开电子了,许许多多的东西都被电子产品所代替,时钟就是一种在我们生活之中很普通的电子产品,它虽然在单片机机之中算是一种比较简单的东西,但它在我们生活在是普遍存在的,它能让我们对更多的电子产品有所了解,所以我们想要了解更多的电子产品,电子时钟也是我们应该了解的,所以我们对电子时钟展开课程设计,并对其工作原理及工作方式进行了解,这样能让我们初步学习到有关的电子产品。
设计过程中我们将对生活中电子时钟的工作方式进行了解,接着我们要在学过的单片机语言基础上,对电子时钟这样的工作方式进行单片机解释,有单片机语言解释,为什么电子时钟要这样工作,接着我们有汇编语言写出电子时钟程序,在报告中我们将对单机汇编语言的有关语句进行解释,并对单片机的电路板的工作原理进行解释,并对电子时钟工作方式进行说明。
二、对本课程设计的分析2.1 工作原理当电子时钟上电时候将在电子时钟上显示23-30-00,带表现在是时间,电子时钟将按正常的时间一样走动,有对应的四个按钮用来调整时钟所对应的时间,第一个按钮对应设置按钮,当它按下去时候,时钟将停止走动,这时候将进入调时间模式,第二个按键用来选择调的是时还有分还秒,第三个按键用来加运算的,第四个按键用来减运算的。
2.2 P3口对应的按键操作功能系统框图开始P3.0是否按下P3.1是否按下YES P3.2是否按下P3.3是否按下NOP3.3是否按下21H 是否为几YESP3.2是否按下P3.3是否按下P3.2是否按下NO时加一YES NO时减一是否为一YES NO分加一分减一是否为2NOYES YES NO秒加一秒减一说明:以上框图是系统版上对应的四个按键对电子时钟的操作功能,在什么情况下,对应的按键实现什么样的功能。
三、 主要电路模块的实现方案比较及选择3.1 电子时钟显示电路说明:P2口对应的为数码管的位选当P2为01H时候对应的最右边的数码管被点亮,将01H依次左移,数码管从右到左依次扫描,对应的数码管依次点亮,而我们就是根据数码管的动态显示让每位数码管显示1MS从右到左依次显示,而人的眼睛看上去就是同时看到8位数码管都亮了。
数码上另外8个端口接到P1口,,用来点亮每位数码管里对应的LED的亮灭,从而在数码管上显示我们想要她显示的数字。
3.2:51单片机最小系统版电路说明:左上角对应的是时钟复位电路,当S5按下时候,对应的时钟值会回到初始设定的值,左下角对应的是时钟晶体振荡电路,其产生的脉冲直接送给内部时钟电路,外接晶振时,C10和C11通常选择20-30pF,C10和C11对频率有微调作用,影响晶振的稳定性和起振的速度。
3.3 :电源指示灯电路说明:该电路用来观看电路是否有上电3.4:电子时钟按键调节电路说明:,该电路由4个按键组成,其中S1是设置按键,该按键功能是让电子时钟进入调时模式;S2是选择按键,该按键功能是用来选择是时调整,分调整,还是秒调整;S3按键对应的功能是加1操作;S4对应的功能是减一操作。
3.5:蜂鸣器电路说明:该电路我们设定时间到时将报警呼叫3.6 :下载程序电路说明:该电路是用来下载我们对应的时钟程序的,Max232产品是由德州仪器公司(TI)推出的一款兼容RS232标准的芯片。
该器件包含2驱动器、2接收器和一个电压发生器电路提供TIA/EIA-232-F电平。
四、系统电路图说明:电源模块上电后给单片机上电,整个电路只有上电后才能工作,串口模块一边连接到单片机,一边连接到电脑,通过STC将程序下载单片机,当单片机上电后,电子时钟就能工作了,系统电路图对应的8个9012的基极连接到单片机的P2口,用来开关9012从而达到数码管动态显示的位选效果,8个9012集电极连接到数码管的的位选。
数码管的a-g连接到单片机的P1口,单片机的的P1口将给数码管送码值以显示我们要的数字。
按键电路通过导线接到P3.0到P3.3,通过按键调整时间,蜂鸣器电路通过导线接到P1.7口,当设定时间到时候将报警呼叫。
五、系统的软件设计5.1 :程序初始化SHI EQU 51HFEN EQU 52HMIAO EQU 53HCNTR EQU 21H ;选择设置对象计数器ORG 00HJMP STARTORG 0BH ;中断入口地址JMP T0_INTORG 30HSTART: MOV 20H,#0MOV TMOD,#01HMOV TL0,#LOW(15536)MOV TH0,#HIGH(15536)MOV SHI,#23MOV FEN,#00MOV MIAO,#00MOV 56H,#10MOV 59H,#10MOV R7,#20SETB ET0SETB EASETB TR05.2 :主程序MAIN:CALL KSCAN ;调用按键扫描子程序CALL DISPLAY ;调用显示子程序MOV A,51HCJNE A,#01,MAIN0MOV A,52HCJNE A,#00,MAIN0CALL KSCANL2: CALL DISPLAY ;调用显示子程序CLR P1.7LCALL DL1MSSETB P1.7LCALL DL1MSLCALL DL1MSDJNZ R5,L2MAIN0: JMP MAIN5.3 :按键扫描子程序KSCAN:JB P3.0,KN ;判断P3.0是否有按下,没按跳到KN,否则接下去执行CALL DISPLAYJB P3.0,KN ;二次判断P3.0是否按下KSC3: CPL 20H.0 ;20H.0为1时进入按键操作KSC5: JB P3.0,KSC4 ;判断按键是否放开CALL DISPLAYJMP KSC5KSC4: JNB 20H.0,KN ;判断20H.0是否为1,为1向下执行KSC: JNB P3.1,SWITCH ;判断P3.1是否按下,按下执行SWTICHJNB P3.2,KINC ;判断P3.2是否按下,按下执行KINCJNB P3.3,KDEC ;判断P3.3是否按下,按下执行KDECJNB P3.0,KSC2CALL DISPLAYJMP KSCKSC2: CALL DISPLAYJB P3.0,KSC ;判断P3.0按键是否放开JMP KSC3KN: RET;//***************选择处理******************//SWITCH: CALL DISPLAYJB P3.1,KSC ;二次判断INC CNTRMOV R5,CNTRCJNE R5,#3,SW2MOV CNTR,#0SW2: JB P3.1,KSC ;等待按键放开?CALL DISPLAYJMP SW2;//**************加一********************//KINC: CALL DISPLAYJB P3.2,KSCMOV R3,CNTRCJNE R3,#0,KINCFEN ;加时INC SHIMOV R6,SHICJNE R6,#24,KINC2MOV SHI,#0KINCFEN: CJNE R3,#1,KINCMIAO ;加分INC FENMOV R6,FENCJNE R6,#60,KINC2MOV FEN,#0KINCMIAO: CJNE R3,#2,KINC2 ;加秒INC MIAOMOV R6,MIAOCJNE R6,#60,KINC2MOV MIAO,#0KINC2: JB P3.2,KSC ;等待按键放开CALL DISPLAYJMP KINC2;//*************减一******************//KDEC: CALL DISPLAYJB P3.3,KSCMOV R3,CNTRCJNE R3,#0,KDECFEN ;减时DEC SHIMOV R6,SHICJNE R6,#-1,KDEC2MOV SHI,#23KDECFEN: CJNE R3,#1,KDECMIAO ;减分DEC FENMOV R6,FENCJNE R6,#-1,KDEC2MOV FEN,#59KDECMIAO: CJNE R3,#2,KDEC2 ;减秒DEC MIAOMOV R6,MIAOCJNE R6,#0FFH,KDEC2MOV MIAO,#59KDEC2: JB P3.3,KDEC3 ;等待按键放开CALL DISPLAYJMP KDEC2KDEC3: JMP KSCRET5.4 :显示子程序5.4.2:程序系统框图开始设定位选的初值R4为01H分离时分秒,并将其放在@R0中,R0首地址为54H将@R0给P0口,将位选值给P2口延时1MSRLR4INC R0判断R0是否为5CHNO结束显示子程序YSE5.4.1:程序部分DISPLAY:MOV R0,#54HMOV A,MIAOCALL FENLIMOV A,FENCALL FENLIMOV A,SHICALL FENLIMOV DPTR,#TABMOV R0,#54HMOV R4,#01HDISLP: MOV P2,R4MOV A,@R0MOVC A,@A+DPTRMOV P0,ACALL DL1MSINC R0MOV A,R4RL AMOV R4,ACJNE R0,#5CH,DISLPRET5.5 :中断服务子程序5.5.1:系统框图 开始进入中断1S 时间是否到秒加1YES 60秒是否到分加1秒赋值个0个它YES60分是否到时加1分赋值个0个它24时是否到时赋值个0个它结束中断NO YES NOYESNO20H.0是否为15.5.2:程序部分T0_INT: JB 20H.0,INTOVERMOV TL0,#LOW(15536)MOV TH0,#HIGH(15536)DJNZ R7,INTOVERINC MIAOMOV R7,#20CPL 20H.1JB 20H.1, LIGHTONMOV 56H,#11MOV 59H,#11SJMP CONTINUELIGHTON:MOV 56H,#10MOV 59H,#10CONTINUE:MOV R6,MIAOCJNE R6,#60,INTOVERINC FENMOV MIAO,#0MOV R6,FENCJNE R6,#60,INTOVERINC SHIMOV FEN,#0MOV R6,SHICJNE R6,#24,INTOVERMOV SHI,#0INTOVER:RETI5.6:程序剩余部分5.6.1:分离子程序FENLI: MOV B,#10DIV ABMOV @R0,BINC R0MOV @R0,AINC R0INC R0RET5.6.2:1MS延时子程序DL1MS: MOV 5FH,#0DJNZ 5FH,$RET5.6.3:共阳字形码TAB: DB 0C0H,0F9H,0A4H,0B0H, 99HDB 92H, 82H, 0F8H, 80H,90H,0BFH,0FFH六、结论单片机真是一门拥有很多地方可以学习的地方,通过对电子时钟的设计分析我了解懂啊了单片机基本知识,而且最终我们设计出来了单片机电子时钟,这和我们想要的结果一致,所以单片机是可以设计出我们想要的电子产品的,只要是你想的到的,一般情况下单片机都是可以做的出来的。