51单片机时钟程序设计

51单片机时钟程序设计,第1张

朋友以下是本人历时一个月殚精竭虑自主开发的一个8位51单片机时钟程序,望吾之兄弟姐妹习之,此程序乃采用一键控制,通过感知按下键持续时间的长短来进行调整时间,闹铃,6只共搜晌改阳数码管输出显示,此外还包括整点铃世判声功能,在看程序之前我先交代一下运行该谨纤程序的硬件要求:12M晶振,P0端口驱动显示,P2.0到P2.5控制显示扫描,P2.7输出铃声,注意:铃声功放三极管应采用pnp管。以下是该程序:

ORG 00H

SETB TR0

JMP START

ORG 000BH

LJMP T0

START: MOV IE,#82H

MOV TMOD,#01H

MOV DPTR,#TAB

MOV SP,#60H

MOV 20H,#0

MOV R0,#0

MOV R1,#0

MOV R2,#0

MOV R3,#0

MOV R4,#0

MOV R5,#0

MOV R6,#0

MOV R7,#0

MOV 50H,#0

MOV 51H,#0

MOV 52H,#0

MOV 53H,#0

MOV 54H,#0

MOV 55H,#0

MOV A,TL0

ADD A,0B5H

MOV TL0,A

MOV TH0,#3CH

LOOP: ANL 20H,#08H

UNSV: MOV R1,#0

LCALL DISPLAY

JB 03H,LOP1

LCALL SOUND

LCALL HDLY

LOP1: MOV P3,#0FEH 按键监视

MOV A,P3

CJNE A,#0FEH,LOP2

MOV R1,#0

JMP LOOP

LOP2: MOV R1,#2 误按判断

LOP3: LCALL HD

DJNZ R1,LOP3

JNB 04H,LOOP

CLR 04H

LOP4: INC R1

MOV C,00H 调秒

CPL C

MOV 00H,C

LCALL HDLY

CJNE R1,#40,LOP5

JMP LOOP

LOP5: JNB 05H,LOP4

CLR 05H

MOV R1,#0

LCALL HD

CLR 00H

JB 04H,TF

MOV R2,#0

MOV R3,#0

JMP LOP4

TF: CLR 04H

LOP6: INC R1

MOV C,01H 调分

CPL C

MOV 01H,C

LCALL HDLY

CJNE R1,#40,LOP7

JMP LOOP

LOP7: JNB 05H,LOP6

CLR 05H

MOV R1,#0

LCALL HD

CLR 01H

JB 04H,TS

INC R4

MOV R1,#0

CJNE R4,#10,LOP6

MOV R4,#0

INC R5

CJNE R5,#6,LOP6

MOV R5,#0

JMP LOP6

TS: CLR 04H

LOP8: INC R1

MOV C,02H 调时

CPL C

MOV 02H,C

LCALL HDLY

CJNE R1,#40,LOP9

JMP LOOP

LOP9: JNB 05H,LOP8

CLR 05H

MOV R1,#0

LCALL HD

CLR 02H

JB 04H,TN

INC R6

CJNE R7,#2,NO2

CJNE R6,#4,LOP8

MOV R7,#0

MOV R6,#0

NO2: CJNE R6,#10,LOP8

MOV R6,#0

INC R7

JMP LOP8

TN: CLR 04H 调闹铃

SETB RS0

CLR RS1

MOV R2,#0

MOV R3,#0

MOV R4,#0

MOV R5,#0

MOV R6,#0

MOV R7,#0

NS: INC R1 闹铃秒调整

MOV C,00H

CPL C

MOV 00H,C

LCALL HDLY

CJNE R1,#40,NS1

JMP NH2

NS1: JNB 05H,NS

CLR 05H

MOV R1,#0

LCALL HD

CLR 00H

JB 04H,NF

INC R2

CJNE R2,#10,NS

MOV R2,#0

INC R3

CJNE R3,#6,NS

MOV R3,#0

JMP NS

NF: CLR 04H 闹铃分

NF1: INC R1

MOV C,01H

CPL C

MOV 01H,C

LCALL HDLY

CJNE R1,#40,NF2

LJMP NH2

NF2: JNB 05H,NF1

CLR 05H

MOV R1,#0

LCALL HD

CLR 01H

JB 04H,NH

INC R4

CJNE R4,#10,NF1

MOV R4,#0

INC R5

CJNE R5,#6,NF1

MOV R5,#0

JMP NF1

NH: CLR 04H 闹铃时调整

NH1: INC R1

MOV C,02H

CPL C

MOV 02H,C

LCALL HDLY

CJNE R1,#40,NH3

NH2: MOV 50H,R2

MOV 51H,R3

MOV 52H,R4

MOV 53H,R5

MOV 54H,R6

MOV 55H,R7

CLR RS0

CLR RS1

LJMP LOOP

NH3: JNB 05H,NH1

CLR 05H

MOV R1,#0

LCALL HD

CLR 02H

JB 04H,NH2

INC R6

CJNE R7,#2,NOT2

CJNE R6,#4,NH1

MOV R6,#0

MOV R7,#0

JMP NH1

NOT2: CJNE R6,#10,NH1

MOV R6,#0

INC R7

JMP NH1

子程序区

TIMES: CJNE R0,#20,LOOP16

MOV R0,#0

INC R2

CJNE R2,#10,LOOP16

MOV R2,#0

INC R3

CJNE R3,#6,LOOP16

MOV R3,#0

ADMINI: INC R4

CJNE R4,#10,LOOP16

MOV R4,#0

INC R5

CJNE R5,#6,LOOP16

MOV R5,#0

HOUR: INC R6

LCALL SOUND 整点铃声

CJNE R7,#2,LOOP14

CJNE R6,#4,LOOP16

MOV R6,#0

MOV R7,#0

JMP LOOP16

LOOP14: CJNE R6,#10,LOOP16

MOV R6,#0

INC R7

LOOP16: RET

DISPLAY:MOV P2,#0FFH

MOV A,R2

MOVC A,@A+DPTR

MOV P0,A

MOV C,00H

MOV P2.0,C

MOV P2,#0FFH

MOV A,R3

MOVC A,@A+DPTR

MOV P0,A

MOV P2.1,C

MOV P2,#0FFH

MOV A,R4

MOVC A,@A+DPTR

MOV P0,A

MOV C,01H

MOV P2.2,C

MOV P2,#0FFH

MOV A,R5

MOVC A,@A+DPTR

MOV P0,A

MOV P2.3,C

MOV P2,#0FFH

MOV A,R6

MOVC A,@A+DPTR

MOV P0,A

MOV C,02H

MOV P2.4,C

MOV P2,#0FFH

MOV A,R7

MOVC A,@A+DPTR

MOV P0,A

MOV P2.5,C

MOV P2,#0FFH

RET

HDLY: MOV 40H,#2

HDL1: MOV 41H,#25

HDL2: MOV 42H,#100

HDL3: DJNZ 42H,HDL4

DJNZ 41H,HDL2

DJNZ 40H,HDL1

JMP HDOT

SOUT: SETB 05H

HDOT: RET

HDL4: MOV P3,#0FEH

MOV A,P3

CJNE A,#0FEH,SOUT

CLR 05H

LCALL DISPLAY

JMP HDL3

HD: MOV 30H,#5

HD1: MOV 31H,#50

HD2: MOV 32H,#100

HD3: LCALL DISPLAY

DJNZ 32H,HD4

DJNZ 31H,HD2

DJNZ 30H,HD1

SETB 04H 计满标志位

JMP HDOUT

HD4: MOV P3,#0FEH

MOV A,P3

CJNE A,#0FEH,HD3

MOV 33H,#50

HD5: MOV 34H,#100

DJNZ 34H,$

DJNZ 33H,HD5

MOV P3,#0FEH

MOV A,P3

CJNE A,#0FEH,HD3

CLR 04H

HDOUT: RET

SOUND: MOV 30H,#10

SO1: MOV 31H,#100

SO2: MOV 32H,#3

MOV C,P2.7

CPL C

MOV P2.7,C

SO3: MOV 33H,#25

DJNZ 33H,$

DJNZ 32H,SO3

DJNZ 31H,SO2

DJNZ 30H,SO1

RET

T0: PUSH PSW

PUSH ACC

CLR RS1

CLR RS0

MOV A,TL0

ADD A,#0B5H

MOV TL0,A

MOV TH0,#3CH

INC R0

LCALL TIMES

MOV A,R2

CJNE A,50H,TO

SETB 03H

MOV A,R3

CJNE A,51H,TO

MOV A,R7

CJNE A,55H,TO

MOV A,R6

CJNE A,54H,TO

MOV A,R5

CJNE A,53H,TO

MOV A,R4

CJNE A,52H,TO

MOV A,R2

ADD A,R3

ADD A,R4

ADD A,R5

ADD A,R6

ADD A,R7

JZ TO

CLR 03H

TO: POP ACC

POP PSW

RETI

TAB: DB 0C0H 0F9H 0A4H 0B0H 099H

DB 092H 082H 0F8H 080H 090H

END

#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) //判断P00口的按键是否按下

{

for(i=5i>0i--)

for(j=248j>0j--)//延时消抖

if (P0_0==0) //判断按键真的按下了

{

second++//秒加1

if(second==60) //秒加到60?

{

second=0//秒清零

}

dispbuf[0]=second%10//取秒的个位放在显示缓冲

dispbuf[1]=second/10//取秒的十位放在显示缓冲

while(P0_0==0)//等待,知道按键松开

}

}

if(P0_1==0) //p01的按键按下,设置分钟,请参考秒的程序,一样的

{

for(i=5i>0i--)

for(j=248j>0j--)

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) //p02的按键按下,设置小时,请参考秒的程宽亏中序,一样的

{

for(i=5i>0i--)

for(j=248j>0j--)

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) //计时满8毫秒?

{

mstcnt=0//累加器清零

P1=dispcode[dispbuf[dispbitcnt]]//送显示段码

P3=dispbitcode[dispbitcnt]//送显示位码

dispbitcnt++//显示位加1

if(dispbitcnt==8) //8位都显示完了?

{

dispbitcnt=0//从第一位开始显示

}

}

tcnt++ //累加器加一

if(tcnt==4000) //记满1秒

{

tcnt=0//累加器清零

second++//秒加一

if(second==60) //秒满60?

{

second=0//秒清零

minite++//分钟加一

if(minite==60) //分钟满60

{

minite=0//分空磨钟清零

hour++//小时加1

if(hour==24) //小时满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

}

}

其实这个程序不难,仔细想想,有不懂的再问我吧


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/12553508.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-26
下一篇 2023-05-26

发表评论

登录后才能评论

评论列表(0条)

保存