51单片机作的电子钟程序在很多地方已经有了介绍, 对于单片机学习者而言这个程序基本上是一道门槛,掌握了电子钟程序, 基本上可以说51单片机就掌握了80%。常见的电子钟程序由显示部分, 计算部分, 时钟调整部分构成。 # Z9 ? `, I8 w# {4 w, \- a1 D$ q
时钟的基本显示原理:时钟开始显示为0时0分0秒,也就是数码管显示000000,然后每秒秒位加1 ,到9后,10秒位加1,秒位回0。10秒位到5后,即59秒 ,分钟加1,10秒位回0。依次类推,时钟最大的显示值为23小时59分59秒。这里只要确定了1秒的定时时间, 其他位均以此为基准往上累加。
`* a. d4 u& Z$ F 开始程序定义了秒, 十秒, 分, 十分,小时, 十小时,共6位的寄存器, 分别存在30h,31h,32h,33h,34h,35h单元,便于程序以后调用和理解。 ) U( a7 e+ } i# ^3 s6 r$ l, b
6个数码管分别显示时、分、秒,一个功能键,可以切换调整时分秒、增加数值、熄灭节电等功能全部集一键。 x- h- E: I6 V7 x3 X8 S7 o
: _, c# B2 n6 k# R+ @ |, n- S
+ q i" ]* j8 X6 V w; ^3 Z2 ~1 l
以下是部分汇编源程序,购买我们产品后我们用光盘将完整的单片机汇编源程序和烧写文件送给客户。
; _: f# C# |5 M;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5 G, H3 B0 G5 G8 b! o* k$ |
;; 中断入口程序 ;; (仅供参考)0 K J6 b+ A4 a2 y6 O+ r9 B) }/ S
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
: D, T, C$ g- I7 G$ d* H;, e9 v2 j' V8 w* k3 `
ORG 0000H ;程序执行开始地址! h5 K2 z( n( A
LJMP START ;跳到标号START执行9 N0 N2 v; N3 D3 X" y( p! U3 @) Z# @
ORG 0003H ;外中断0中断程序入口
3 U Y! r3 `8 m/ ZRETI ;外中断0中断返回
! N! T! k" V, e2 K6 b6 k6 {ORG 000BH ;定时器T0中断程序入口! A m* d: h7 H2 e
LJMP INTT0 ;跳至INTTO执行
# C4 B" L+ x; r0 U1 wORG 0013H ;外中断1中断程序入口* N% B# k2 T7 o( T) }, u
RETI ;外中断1中断返回3 D9 o1 N3 w/ C& ]
ORG 001BH ;定时器T1中断程序入口
: t& ?# B; h' L' ], r7 HLJMP INTT1 ;跳至INTT1执行2 F1 L% j: z" ~" b) L( A
ORG 0023H ;串行中断程序入口地址
4 F! C0 l/ [8 S: hRETI ;串行中断程序返回
( C0 D- k2 F' T7 ~8 V. ^$ L;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;. ~1 d/ W' m( t/ h% u
;; 主 程 序 ;;$ r. d' W# {4 {
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
# t/ k9 o" ?/ ~# f;
) E% o) ]) A r; M$ g+ `START: MOV R0,#70H ;清70H-7AH共11个内存单元
8 c- D( d9 C U7 E1 X ?0 |/ ZMOV R7,#0BH
% ?8 L' d' \) e4 @, H3 E;clr P3.7 ;
* q0 _1 o3 y: z0 J! m& BCLEARDISP: MOV @R0,#00H ;7 B5 G% e1 Z$ Z4 |
INC R0 ;
z+ d) y- n ^2 E; yDJNZ R7,CLEARDISP ;
6 O9 D ]# c2 l4 ^8 f- W( y6 Z# pMOV 20H,#00H ;清20H(标志用)
8 N$ r K- k/ ^MOV 7AH,#0AH ;放入"熄灭符"数据% C1 ?" r& ]' e T
MOV TMOD,#11H ;设T0、T1为16位定时器
) |) {: S. x4 Q1 vMOV TL0,#0B0H ;50MS定时初值(T0计时用)# m4 B0 y# ]) L! N
MOV TH0,#3CH ;50MS定时初值
% C9 W; q' i7 V7 VMOV TL1,#0B0H ;50MS定时初值(T1闪烁定时用)) }7 m- V+ q% g
MOV TH1,#3CH ;50MS定时初值
( S) n K: d' J7 F" j. y+ \1 J& PSETB EA ;总中断开放
, r) K- \/ S1 v3 D4 W7 J. [SETB ET0 ;答应T0中断
: u' Z+ }! ^8 ?" Q! CSETB TR0 ;开启T0定时器 k! J; A& r% z
MOV R4,#14H ;1秒定时用初值(50MS×20). F# O2 r: N( m" z
START1: LCALL DISPLAY ;调用显示子程序
4 k. H- m) I$ ^; X, wJNB P3.7,SETMM1 ;P3.7口为0时转时间调整程序
: c5 H/ E. m, k, a. B8 `SJMP START1 ;P3.7口为1时跳回START1& T! q- C: d5 } o" o% I# C' ]6 c
SETMM1: LJMP SETMM ;转到时间调整程序SETMM
2 A+ Q# {1 p& c j% X5 h;* j0 l0 f/ @! W% V8 T# o
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
$ z0 A1 K% h+ \9 `/ d0 P" o;; 1秒计时程序 ;;
& O- b0 w9 @# M: t0 t;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5 [ s9 c6 s/ v/ f6 D: p
;T0中断服务程序
3 z$ }; w# x; A4 _* i+ q# i4 ?' EINTT0: PUSH ACC ;累加器入栈保护
: O$ ] |, H6 f3 A7 p- n3 b& jPUSH PSW ;状态字入栈保护
4 H( ^" g S7 M/ g' s7 ] O# \CLR ET0 ;关T0中断答应5 n4 W( l! J# r D
CLR TR0 ;封闭定时器T0
4 ~/ z! |$ ]1 d( M4 u- W/ dMOV A,#0B7H ;中断响应时间同步修正0 I8 c8 A# P- |0 F; v
ADD A,TL0 ;低8位初值修正
: g, D( o2 T# P+ \3 [# W: X, A: _8 {MOV TL0,A ;重装初值(低8位修正值)
0 I% B3 s& K6 K$ T3 KMOV A,#3CH ;高8位初值修正% S% U: [2 N+ g9 b0 R; v
ADDC A,TH0 ;
" [) ?" v6 A! j6 U KMOV TH0,A ;重装初值(高8位修正值)$ J2 h% A) t: T' i$ V) @" C e
SETB TR0 ;开启定时器T0 y1 m0 x/ ^3 D; e1 R. p- c
DJNZ R4, OUTT0 ;20次中断未到中断退出
6 Y- U' `! C2 Z/ d. CADDSS: MOV R4,#14H ;20次中断到(1秒)重赋初值/ Q1 N* d/ I ~6 G9 O) i
MOV R0,#71H ;指向秒计时单元(71H-72H)1 u* |% @: C6 |5 d1 L l
ACALL ADD1 ;调用加1程序(加1秒操作)
, r$ ?( }2 u" p; S. L) VMOV A,R3 ;秒数据放入A(R3为2位十进制数组合)
+ P- _' k% r) ?# X( {CLR C ;清进位标志
! g7 q- j0 I" N$ lCJNE A,#60H,ADDMM ;; T& ~- g+ m( R, j& V
ADDMM: JC OUTT0 ;小于60秒时中断退出 q8 W, s, {9 z" t0 W
ACALL CLR0 ;大于或即是60秒时对秒计时单元清0
0 }) ?$ L/ k1 K5 D( T1 a: qMOV R0,#77H ;指向分计时单元(76H-77H)$ w w# s0 b6 J1 k/ ?
ACALL ADD1 ;分计时单元加1分钟) L/ @, J3 w+ b* @" g, i$ l
MOV A,R3 ;分数据放入A9 T$ y1 j9 a0 y0 f* n* h: V( c; o
CLR C ;清进位标志
[. _# S9 b6 l3 Q" wCJNE A,#60H,ADDHH ;7 v# e$ L8 g8 F3 Y( c
ADDHH: JC OUTT0 ;小于60分时中断退出# T" m7 m- C9 l6 M1 b
ACALL CLR0 ;大于或即是60分时分计时单元清08 F1 h) m: B: G' O# Z5 ]8 J2 k
MOV R0,#79H ;指向小时计时单(78H-79H)' b; h' S, T! m+ u2 H; g6 U' F2 Z# Y) V7 W
ACALL ADD1 ;小时计时单元加1小时
3 b) E, v* U& \+ L- O# H# YMOV A,R3 ;时数据放入A
- ^3 {3 O4 N' _0 |2 tCLR C ;清进位标志% \/ b! `# ?' D9 Q8 a8 |1 ]' p, m& H
CJNE A,#24H,HOUR ;7 `% c" {- m( c* E
HOUR: JC OUTT0 ;小于24小时中断退出# a+ o% P- D6 W# x( l+ c
ACALL CLR0 ;大于或即是24小时小时计时单元清0( N+ o. b1 o7 R" E, T7 [
OUTT0: MOV 72H,76H ;中断退出时将分、时计时单元数据移% I, [5 f' E4 x9 n
MOV 73H,77H ;入对应显示单元
8 ?3 k7 c5 b) I" b( qMOV 74H,78H ;; E- k( ~7 a T8 y
MOV 75H,79H ;! `( s/ H5 Z3 K* |& m
POP PSW ;恢复状态字(出栈): B: o4 [5 W# S- b* |
POP ACC ;恢复累加器+ ]# z4 q5 o' \ b& L: M! o
SETB ET0 ;开放T0中断
+ p( T% P2 @) i% vRETI ;中断返回+ w2 T+ ]9 l$ y& I, S8 o+ b
;
# W/ f0 M% X q$ `; \0 J1 ~;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3 b7 N# ]4 S. I3 }5 z9 B
;; 闪动调时 程 序 ;;
' z; ^7 `& P8 m: a8 d;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
) ^( n# q' q# P0 s;T1中断服务程序,用作时间调整时调整单元闪烁指示% S6 Z/ O* E+ B/ f \5 N7 s8 l
INTT1: PUSH ACC ;中断现场保护6 y8 ~! k' }, f- |# U
PUSH PSW ;7 ^5 l5 Q" Z% B) W& t
MOV TL1, #0B0H ;装定时器T1定时初值" i3 p* O& A3 {
MOV TH1, #3CH ;) G( F, E- \8 a4 L C- \% \9 Y
DJNZ R2,INTT1OUT ;0.3秒未到退出中断(50MS中断6次)% N1 w$ v- l5 ~3 \. `
MOV R2,#06H ;重装0.3秒定时用初值
% Z' \* R n4 O/ }- Q2 _CPL 02H ;0.3秒定时到对闪烁标志取反- ? Q! E J, M, O
JB 02H,FLASH1 ;02H位为1时显示单元"熄灭"' n7 y1 p" r6 N: |+ U \% C
MOV 72H,76H ;02H位为0时正常显示
# m0 {5 I0 \' U" \$ CMOV 73H,77H ;* r2 T; Y- P# c8 H
MOV 74H,78H ;; w1 n8 y% k% h8 S
MOV 75H,79H ;: C% J+ h; a! F0 f
INTT1OUT: POP PSW ;恢复现场0 ^: S4 Y+ j0 J
POP ACC ;/ C( w5 E5 i' W$ ]0 j! ]( _7 B
RETI ;中断退出
6 _0 ^1 `) N* XFLASH1: JB 01H,FLASH2 ;01H位为1时,转小时熄灭控制 @* M) G* d# [/ |' y m E, H' f
MOV 72H,7AH ;01H位为0时,"熄灭符"数据放入分
( T* c& N! Y+ T! N! O1 C7 Z1 rMOV 73H,7AH ;显示单元(72H-73H),将不显示分数据
u0 G( R9 J, U# ?5 J5 DMOV 74H,78H ;4 J6 f7 s, [- u& B: J
MOV 75H,79H ;
5 i* I! X) w% r" h* J# E: m! G$ {6 lAJMP INTT1OUT ;转中断退出
4 m5 |) f" v3 c3 J5 s7 AFLASH2: MOV 72H,76H ;01H位为1时,"熄灭符"数据放入小时; C# \6 F6 }" {
MOV 73H,77H ;显示单元(74H-75H),小时数据将不显示$ d5 X' z. h) |$ W
MOV 74H,7AH ;
1 f2 m- H9 z7 A0 t7 kMOV 75H,7AH ;
3 V+ N) b4 I. B9 e# s A- D) dAJMP INTT1OUT ;转中断退出
: `+ k' A6 B" m( |4 \7 B6 G+ X6 E;& S' L& ^- l0 O$ K( @6 E
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1 x5 ^2 Y5 s# D. U3 h6 M
;; 加1子 程 序 ;;. X: u+ q- A( C% S
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
& g) R, @/ R) m# k4 ]* c+ ~" b( d;$ x- I- d& I6 F/ C
ADD1: MOV A,@R0 ;取当前计时单元数据到A
2 Z" ]3 ?, E7 WDEC R0 ;指向前一地址' p6 C( [; `: R# I4 D
SWAP A ;A中数据高四位与低四位交换/ r5 O6 _3 I$ o5 T. H; \, w
ORL A,@R0 ;前一地址中数据放入A中低四位2 s' |/ W: R: B* L) T) w
ADD A,#01H ;A加1操作! E8 L0 i6 c# r6 |4 n
DA A ;十进制调整! s! L! G+ U1 \4 u
MOV R3,A ;移入R3寄存器
% H8 Z+ e+ d8 P+ lANL A,#0FH ;高四位变0
; A. V. c! P+ o% r& a- nMOV @R0,A ;放回前一地址单元 \% X" B* x3 H7 }+ O
MOV A,R3 ;取回R3中暂存数据- X& U. z, n0 F; r
INC R0 ;指向当前地址单元; l; Z! ?$ e2 N8 y8 W
SWAP A ;A中数据高四位与低四位交换
- i: f0 ?1 {3 o' EANL A,#0FH ;高四位变0
( N3 w1 H r) a5 B, M2 jMOV @R0,A ;数据放入当削地址单元中5 ]' {2 s# ?: q! z/ I% ~$ \- D
RET ;子程序返回
6 D! m" ~. l. z/ _; @;
# X4 D! I1 C) |8 E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;% n) N! i) _% x% w" B/ J$ j% \7 G
;; 清零程序 ;;
) ~8 D7 R: e1 {; u2 l;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8 e- t- t0 b5 q! r
;............./ B9 R5 e* m8 }' d! v; R
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;. g7 m* V( s( P% S; _
;; 时钟调整程序 ;;
2 _. Q5 w( b- C' I;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1 P! ^) y, [) u9 m- t: q
;当调时按键按下时进入此程序
) `5 |' g: T- A' Y, ? I; {! M7 O/ jSETMM: cLR ET0 ;关定时器T0中断8 w" z: _" h3 Z- D* _
CLR TR0 ;封闭定时器T0$ u+ c1 ]4 o( Y0 S
LCALL DL1S ;调用1秒延时程序
0 x% s: Y% a j0 H% M {' ZJB P3.7,CLOSEDIS ;键按下时间小于1秒,封闭显示(省电)* e8 }% c8 c5 [
MOV R2,#06H ;进入调时状态,赋闪烁定时初值
; Z; X# W( e/ A$ P5 CSETB ET1 ;答应T1中断; T- z. M, y7 e3 G/ G, ~# I
SETB TR1 ;开启定时器T1
4 Y- U+ C8 T/ K) S. J( MSET2: JNB P3.7,SET1 ;P3.7口为0(键未开释),等待% o; W; o2 g9 E' o5 [
SETB 00H ;键开释,分调整闪烁标志置1
- ~0 j' l* z9 Q7 c# M ]SET4: JB P3.7,SET3 ;等待键按下" \7 x# K4 d9 N$ M; d8 j Z$ e
LCALL DL05S ;有键按下,延时0.5秒& {- r$ d1 y( P: @
JNB P3.7,SETHH ;按下时间大于0.5秒转调小时状态
2 s* x; v8 S) | Y) g# pMOV R0,#77H ;按下时间小于0.5秒加1分钟操作
# m& N5 c% q* h ]! iLCALL ADD1 ;调用加1子程序
- {7 b0 a/ p# x8 S5 P' bMOV A,R3 ;取调整单元数据
1 t" N/ {' _9 H1 \% N7 D" @, ICLR C ;清进位标志
- p, f# D& B+ T" a. D# v/ kCJNE A,#60H,HHH ;调整单元数据与60比较; _: N# E$ x* W5 V' K& _! ~# {
HHH: JC SET4 ;调整单元数据小于60转SET4循环
- e% L3 O+ g$ _6 v& I" x% M }$ oLCALL CLR0 ;调整单元数据大于或即是60时清0$ y+ [3 F. V- J& a' I; G* Z2 b
CLR C ;清进位标志/ r% X6 H/ r1 Z- _- [
AJMP SET4 ;跳转到SET4循环
/ ] o) W" `) `CLOSEDIS: SETB ET0 ;省电(LED不显示)状态。开T0中断( i% ~7 h; R2 p, M
SETB TR0 ;开启T0定时器(开时钟)& a4 u: p2 t6 c8 Y: F4 w
CLOSE: JB P3.7,CLOSE ;无按键按下,等待。
/ I) a1 r; d5 wLCALL DISPLAY ;有键按下,调显示子程序延时削抖/ |6 G( z) F5 b W3 g! l, I7 u
JB P3.7,CLOSE ;是干扰返回CLOSE等待
! W; V8 C% l; t& @' _) y6 p/ UWAITH: JNB P3.7,WAITH ;等待键开释2 i7 O2 [9 d1 |0 p. j3 E
LJMP START1 ;返回主程序(LED数据显示亮)
8 r( O2 {! V, _ A/ |; B# pSETHH: CLR 00H ;分闪烁标志清除(进入调小时状态)" q6 u0 G4 V. P& M, Q
SETHH1: JNB P3.7,SET5 ;等待键开释
/ e! O- w# J9 U, F+ K9 M, t, d/ CSETB 01H ;小时调整标志置1
& n! n8 ]- l" w0 d8 f9 `SET6: JB P3.7,SET7 ;等待按键按下" z1 {6 J- b& m6 Q. s# Y
LCALL DL05S ;有键按下延时0.5秒
' s+ z2 _3 p" N- }9 Z# W! JJNB P3.7,SETOUT ;按下时间大于0.5秒退出时间调整
. ^3 j7 S! k' ~6 r4 r& \MOV R0,#79H ;按下时间小于0.5秒加1小时操作
& x) E, T8 ?" Q+ J5 n9 WLCALL ADD1 ;调加1子程序5 W- W3 A( p, }0 Z4 D& S: \. u2 h: i
MOV A,R3 ;
, j1 K& x/ P% r& K$ N$ u. }CLR C ;
8 \$ `" n3 K1 R: v6 W; b1 lCJNE A,#24H,HOUU ;计时单元数据与24比较 s) i2 R: u" r0 g9 e, [) V' K4 M
HOUU: JC SET6 ;小于24转SET6循环+ N% V+ ?: L& p" R1 G+ J- t
LCALL CLR0 ;大于或即是24时清0操作
# Z1 B9 T, u* O7 K% ]AJMP SET6 ;跳转到SET6循环. R) ?6 I% m7 ~
SETOUT: JNB P3.7,SETOUT1 ;调时退出程序。等待键开释8 k% U+ S, i" I" t) `
LCALL DISPLAY ;延时削抖
& O) Q' x' ?. E. a6 u; b/ qJNB P3.7,SETOUT ;是抖动,返回SETOUT再等待
& t6 R, c- u$ G2 ~& w/ V! iCLR 01H ;清调小时标志/ |2 `$ o% x. f
CLR 00H ;清调分标志9 N m5 w3 b* I( F% E8 j
CLR 02H ;清闪烁标志3 V$ h$ M/ H4 n& {
CLR TR1 ;封闭定时器T1' L: l# z- {5 o5 \6 ]) o* {
CLR ET1 ;关定时器T1中断
* }8 Q7 o9 s2 ^, xSETB TR0 ;开启定时器T0
& W" f7 P0 J0 c% s1 FSETB ET0 ;开定时器T0中断(计时开始)" Z, h; q( n. V7 |* e% F
LJMP START1 ;跳回主程序
/ V7 l- f& P/ B6 @4 s1 LSET1: LCALL DISPLAY ;键开释等待时调用显示程序(调分)8 F4 N3 d- F7 O" R) l8 ?& n% Y
AJMP SET2 ;防止键按下时无时钟显示
7 I0 j- p2 [1 P: X$ FSET3: LCALL DISPLAY ;等待调分按键时时钟显示用' A0 q7 ^: p/ m' t2 C: K" [
AJMP SET4
. A: g% P. d8 f" iSET5: LCALL DISPLAY ;键开释等待时调用显示程序(调小时)
8 B7 ~7 k, Q2 Y/ I" c: R! U* r3 kAJMP SETHH1 ;防止键按下时无时钟显示
0 Z) n4 X/ P Z& P9 t+ q3 OSET7: LCALL DISPLAY ;等待调小时按键时时钟显示用
; v- |& C9 j$ ~9 w7 o" ?AJMP SET6
3 o2 g D( }0 M& ESETOUT1: LCALL DISPLAY ;退出时钟调整时键开释等待
! M( t* J: I) e* w# ^, rAJMP SETOUT ;防止键按下时无时钟显示 E/ ] R# U. J6 a5 V- f
;6 R' o( S& g; t( V) k/ x8 m
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;+ B3 h: V) \. q3 n3 G
;; 显示程序 ;;
% z) m( w- c$ m, i;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;" y- q4 p$ g) [3 Y
$$$$$$$$$$$$$$$$$$$$$$$$$$$
# Z u5 q; Y4 I; @4 r/ v6 r;1MS延时程序,LED显示程序用
( D, z9 z9 ?( p8 J/ q1 [" z2 hDL1MS: MOV R6,#14H
7 e/ J3 s) N1 g6 @0 ~DL1: MOV R7,#19H! y/ U4 e/ d5 v6 [
DL2: DJNZ R7,DL2* R |+ P. T! o; t% F: V
DJNZ R6,DL1
# l. D: |" x) j: Y" [RET1 h7 z: x* m, `. i5 o
;20MS延时程序,采用调用显示子程序以改善LED的显示闪烁现象
7 n `: ?4 s; v5 _! C7 Q) @, V1 ?DS20MS: ACALL DISPLAY4 ^; Q/ A4 X( e1 k# g+ D. r
ACALL DISPLAY
6 q% u$ H& x/ j, `4 D- tACALL DISPLAY
4 W, i0 s! x! K( v. iRET
" B0 {9 m& |3 l) Q" ^4 q" o;延时程序,用作按键时间的长短判定
2 v/ t( |* W5 LDL1S: LCALL DL05S/ j- J& i* c e! X
LCALL DL05S
2 ~; U* _" {) x. d- i3 `# p* DRET
) Q, h+ x' L( V( f) c6 ?4 zDL05S: MOV R3,#20H ;8毫秒*32=0.196秒; n" `( T& b' `3 S
DL05S1: LCALL DISPLAY/ ?" V+ m' J6 s( C1 o u
DJNZ R3,DL05S1
0 Y& ^* y f8 [/ YRET8 l1 j- k4 u; N0 O
END ;程序结束2 @# Y2 O4 a }* R
|