做一个电子钟,利用六个数码管显示分、秒。

做一个电子钟,利用六个数码管显示分、秒。中间两个数码管显示两个横线**--**(例如45--10表示45分10秒)用到段锁存器74LS273、位锁存器(8031CPU的P1口当位锁存器使用)同时显示多位数字技术。利用定时器定时中断
单片机程序 和 原理图 分到60直接显示00--00,再开始!!!

第1个回答  2009-11-29
/*************************时钟程序**************************/
/*此程序为用采用51单片机实现的一个24小时循环显示程序*/
/*主要功能由时钟显示(00-00-00格式)、时间调整功能*/
/*程序采用定时查询方式实现时间更新,键盘查询方式实现时间调整*/
/********彭思良2008-12-27于长江大学电子创新实验室**********/
ORG 00H
AJMP MAIN
/*主程序开始,初始化、定义变量*/
MAIN:

MOV 30H,#00H ;按键缓冲区
MOV 40H,#00H ;1S标志缓冲
MOV 50H,#00H ;延时子程用
MOV 51H,#00H ;延时子程用

MOV 61H,#00H ;秒个位缓冲区
MOV 62H,#00H ;秒十位缓冲区
MOV 63H,#00H ;分个位缓冲区
MOV 64H,#00H ;分十位缓冲区
MOV 65H,#00H ;时个位缓冲区
MOV 66H,#00H ;时十位缓冲区

KEY EQU 30H ;按键
FLAG EQU 40H ;1S标志
SECL EQU 61H ;秒个位
SECH EQU 62H ;秒十位
MINL EQU 63H ;分个位
MINH EQU 64H ;分十位
HOUL EQU 65H ;时个位
HOUH EQU 66H ;时十位

MOV DPTR, #TBL ;查表指针
COUNT1 EQU 20 //20*50000uS
COUNT2 EQU -46000 //定时器预置数

//显示初始化00-00-00
START:
MOV R0, #07H ;秒个位偏移地址
MOV A, #00H ;0笔画在表中地址
LCALL DISPLAY ;显示秒个位
MOV A, #00H
LCALL DISPLAY
MOV A, #0BH
LCALL DISPLAY
MOV A, #00H
LCALL DISPLAY
MOV A, #00H
LCALL DISPLAY
MOV A, #0BH
LCALL DISPLAY
MOV A, #00H
LCALL DISPLAY
MOV A, #00H
LCALL DISPLAY

MOV TMOD, #01H ;使用计时器0,模式1
TIMER1: MOV FLAG, #01H ;清除1S标志,置为1,表示不到1S
TIMER2: MOV R7, #COUNT1 ;设置定时次数
AGAIN: MOV TH0, #HIGH COUNT2 ;定时器预置
MOV TL0, #LOW COUNT2
SETB TR0 ;计时开始

/*********键盘扫描模块**********/
/*K1是否按下*/

LCALL SCAN ;扫描0
MOV A, KEY
ANL A, #0FFH
ADD A, #02H
JZ SCAN1 ;按键K1按下,转到SCAN1
LJMP DIS ;没有按下,转到显示模块

/****************K1第一次按下,进入时间调整程序*************/
SCAN1:
;-----------以下实现秒闪烁两次
LCALL DIS02 ;秒显示一次
LCALL DEL ;延时
MOV A, #0AH ;秒个位黑屏
MOV R0, #07H
LCALL DISPLAY1
MOV A, #0AH ;秒十位黑屏
MOV R0, #06H
LCALL DISPLAY1
LCALL DEL
LCALL DIS02 ;秒再次显示
LCALL DEL

LCALL SCAN ;扫描1
MOV A, KEY
SECK2:
ANL A, #0FFH
CJNE A, #0FDH, SECK3 ;K2是否按下,没有则转到SECK3
;-----------K2按下,以下为秒+1更新显示
INC SECL ;秒+1
MOV A, SECL
LCALL CMP10
JZ SEC11
LJMP DIS001
SEC11:
MOV SECL, #00H
INC SECH
MOV A, SECH
LCALL CMP06
JZ SEC12
LJMP DIS002
SEC12:
MOV SECH, #00H
LJMP DIS002
SECK3:
CJNE A, #0FBH, MINK1 ;是否K3按下,没有则转到MINK1
;-----------K3按下,以下为秒-1更新显示
DEC SECL ;秒-1
MOV A, SECL
ADD A, #1
JZ SEC13
LJMP DIS001
SEC13:
MOV SECL, #09H
DEC SECH
MOV A, SECH
ADD A, #1
JZ SEC14
LJMP DIS002
SEC14:
MOV SECH, #05H
LJMP DIS002

MINK1:

CJNE A, #0FEH, SCAN1 ;按键K1是否第二次按下,没有继续扫描
;-------------------------------------------K1第二次按下
SCAN2:
LCALL DIS04 ;分显示一次
LCALL DEL ;延时
MOV A, #0AH ;分个位黑屏
MOV R0, #04H
LCALL DISPLAY1
MOV A, #0AH ;分十位黑屏
MOV R0, #03H
LCALL DISPLAY1
LCALL DEL
LCALL DIS04 ;分再次显示
LCALL DEL

LCALL SCAN ;扫描2
MOV A, KEY
MINK2:
ANL A, #0FFH
CJNE A, #0FDH, MINK3 ;K2是否按下 ,没有按下则转到MINK3
;-----------K2按下,以下为分+1更新显示
INC MINL
MOV A, MINL
LCALL CMP10
JZ MIN21
LJMP DIS003
MIN21:
MOV MINL, #00H
INC MINH
MOV A, MINH
LCALL CMP06
JZ MIN22
LJMP DIS004
MIN22:
MOV MINH, #00H
LJMP DIS004
MINK3:
CJNE A, #0FBH, HOUK1 ;K3是否按下 ,没有按下则转到HOUK1
;-----------K3按下,以下为分-1更新显示
DEC MINL
MOV A, MINL
ADD A, #1
JZ MIN23
LJMP DIS003
MIN23:
MOV MINL, #09H
DEC MINH
MOV A, MINH
ADD A, #1
JZ MIN24
LJMP DIS004
MIN24:
MOV MINH, #05H
LJMP DIS004

HOUK1:
CJNE A, #0FEH, SCAN2
;-------------------------------------------K1第二次按下
SCAN3:
LCALL DIS06 ;时显示一次
LCALL DEL ;延时
MOV A, #0AH ;时个位黑屏
MOV R0, #01H
LCALL DISPLAY1
MOV A, #0AH ;时十位黑屏
MOV R0, #00H
LCALL DISPLAY1
LCALL DEL
LCALL DIS06 ;时再次显示
LCALL DEL

LCALL SCAN ;扫描3
MOV A, KEY
HOUK2:
ANL A, #0FFH
CJNE A, #0FDH, HOUK3 ;K2是否按下 ,没有则转到HOUK3
;-----------K2按下,以下为时+1更新显示
INC HOUL
MOV A, HOUL
LCALL CMP04
JZ SCAN31 ;HOUL=4,转到HOUH=2?
LJMP CM110 ;HOUL!=4,转到HOUL=10?
SCAN31:
MOV A, HOUH
LCALL CMP02
JZ SCAN32 ;HOUH=2,转到SCAN32
LJMP DIS005 ;HOUH!=2,显示更新
SCAN32:
MOV HOUL, #00H
MOV HOUH, #00H
LJMP DIS006
CM110:
MOV A, HOUL
LCALL CMP10
JZ SCAN33 ;等于10,转到SCAN33
LJMP DIS005
SCAN33:
MOV HOUL, #00H
INC HOUH
LJMP DIS006
HOUK3:
CJNE A, #0FBH, EXITK1 ;K3是否按下 ,没有按下则转到EXITK1
;-----------K3按下,以下为时-1更新显示
DEC HOUL
MOV A, HOUL
ADD A, #1
JZ SCAN34 ;HOUL=FFH,
LJMP DIS005 ;HOUL!=FFH显示更新
SCAN34:
MOV HOUL, #09H
DEC HOUH
MOV A, HOUH
ADD A, #1
JZ SCAN35
LJMP DIS006
SCAN35:
MOV HOUL, #03H
MOV HOUH, #02H
LJMP DIS006

EXITK1:
CJNE A, #0FEH, SCAN3//按键K1是否第四次按下
//K1第四次按下
LCALL DEL

;............1S显示更新模块
DIS:
MOV A, FLAG
JNZ WAIT //检测1S标志显示处理
INC SECL //秒加1
MOV A, SECL
LCALL CMP10
JNZ DIS0001 //是否为0,为0则下一步秒处理,不为0则跳转
MOV SECL, #00H
INC SECH
MOV A, SECH
LCALL CMP06
JNZ DIS0002 //是否为0,为0则下一步分处理,不为0则跳转
MOV SECH, #00H
INC MINL
MOV A, MINL
LCALL CMP10
JNZ DIS0003 //是否为0,为0则下一步分处理,不为0则跳转
MOV MINL, #00H
INC MINH
MOV A, MINH
LCALL CMP06
JNZ DIS0004 //是否为0,为0则下一步时处理,不为0则跳转
MOV MINH, #00H
INC HOUL
MOV A, HOUL
LCALL CMP04
JNZ CM10 //是否为0,为0则下一步时处理,不为0则跳转
MOV A, HOUH
LCALL CMP02
JNZ DIS0005
AJMP MAIN

CM10:
MOV A, HOUL
LCALL CMP10
JNZ DIS0005 //是否为10,为10则下一步处理,不为10则跳转
MOV HOUL, #00H
INC HOUH
LJMP DIS0006 //跳转,更新所有位数

/*等待计时器的一次循环是否完毕*/
WAIT:
JNB TF0, WAIT
CLR TF0
CLR TR0
DJNZ R7, AGAIN1
/*1S计时完毕,时间显示标志R0置0,进行加时处理*/
MOV FLAG, #00H
LJMP TIMER2

AGAIN1:
LJMP AGAIN

DIS0001:
LCAll DIS01
LJMP TIMER1
DIS0002:
LCALL DIS02
LJMP TIMER1

DIS0003:
LCALL DIS03
LJMP TIMER1
DIS0004:
LCALL DIS04
LJMP TIMER1
DIS0005:
LCALL DIS05
LJMP TIMER1
DIS0006:
LCALL DIS06
LJMP TIMER1

;------------- DIS001
DIS001:
LCALL DIS01
LJMP SCAN1

DIS002:
LCALL DIS02
LJMP SCAN1

DIS003:
LCALL DIS03
LJMP SCAN2

DIS004:
LCALL DIS04
LJMP SCAN2
DIS005:
LCALL DIS05
LJMP SCAN3

DIS006:
LCALL DIS06
LJMP SCAN3

;-------------
DIS01:
LCALL DIS1
RET

DIS02:
LCALL DIS1
LCALL DIS2
RET

DIS03:
LCALL DIS1
LCALL DIS2
LCALL DIS3
RET

DIS04:
LCALL DIS1
LCALL DIS2
LCALL DIS3
LCALL DIS4
RET
DIS05:
LCALL DIS1
LCALL DIS2
LCALL DIS3
LCALL DIS4
LCALL DIS5
RET

DIS06:
LCALL DIS1
LCALL DIS2
LCALL DIS3
LCALL DIS4
LCALL DIS5
LCALL DIS6
RET

DIS1:
MOV A, SECL //显示秒个位
MOV R0, #07H
LCALL DISPLAY1
RET
;-------------
DIS2:
MOV A, SECH //显示秒十位
MOV R0, #06H
LCALL DISPLAY1
RET
;-------------
DIS3:
MOV A, MINL //显示分个位
MOV R0, #04H
LCALL DISPLAY1
RET
;-------------
DIS4:
MOV A, MINH //显示分十位
MOV R0, #03H
LCALL DISPLAY1
RET
;-------------

DIS5:
MOV A, HOUL //显示时个位
MOV R0, #01H
LCALL DISPLAY1
RET
;-------------

DIS6:
MOV A, HOUH //显示时十位
MOV R0, #00H
LCALL DISPLAY1
RET

;-------------
DISPLAY: //显示初始化
MOVC A, @A+DPTR //查外存数据表中A+DPTR内容送A
MOV P2, #80H //立即数80H(10000000)送P2口,经U2译码后,使U13有效
MOVX @R0,A //累加器内容送外部R0存储地址单元,使相应数码管显
DEC R0
RET
;-------------显示查表数据
DISPLAY1:
MOVC A, @A+DPTR //查外存数据表中A+DPTR内容送A
MOV P2, #80H //立即数A0H(10100000)送P2口,经U2译码后,使U16有效
MOVX @R0,A //累加器内容送外部R0存储地址单元,使相应数码管显
RET
;-------------
CMP10: //比较A中的数是否等于10
ADD A, #0F6H
RET
;-------------
CMP06: //比较A中的数是否等于6
ADD A, #0FAH
RET
;-------------
CMP05: //比较A中的数是否等于5
ADD A, #0FBH
RET
;-------------
CMP04: //比较A中的数是否等于4
ADD A, #0FCH
RET
;-------------
CMP02: //比较A中的数是否等于2
ADD A, #0FEH
RET
;------------- 数码管笔画表
TBL:
DB 3FH,06H,5BH,4FH,66H ;01234
DB 6DH,7DH,07H,7FH,6FH ;56789
DB 00H,40H ; -

;------------- 键盘扫描子程序
SCAN:
MOV P2,#0A0H
MOVX A,@R0
MOV KEY,A
RET

;-------------延时子程序

DEL:
DJNZ 50H,DEL
DJNZ 51H,DEL
RET

END本回答被提问者采纳
第2个回答  2009-11-24
对呀,你想问什么?
第3个回答  2009-11-24
你想问什么?
第4个回答  2009-11-24
你想问什么?