51单片机作的电子钟程序在很多地方已经有了介绍, 对于单片机学习者而言这个程序基本上是一道门槛,掌握了电子钟程序, 基本上可以说51单片机就掌握了80%。常见的电子钟程序由显示部分, 计算部分, 时钟调整部分构成。 % T7 g# s7 C+ ~
时钟的基本显示原理:时钟开始显示为0时0分0秒,也就是数码管显示000000,然后每秒秒位加1 ,到9后,10秒位加1,秒位回0。10秒位到5后,即59秒 ,分钟加1,10秒位回0。依次类推,时钟最大的显示值为23小时59分59秒。这里只要确定了1秒的定时时间, 其他位均以此为基准往上累加。
4 Z# q3 Q9 T. O4 d( {1 P. J 开始程序定义了秒, 十秒, 分, 十分,小时, 十小时,共6位的寄存器, 分别存在30h,31h,32h,33h,34h,35h单元,便于程序以后调用和理解。 * }) a! |5 X3 O( c" {) ^2 ~9 l R: ?
6个数码管分别显示时、分、秒,一个功能键,可以切换调整时分秒、增加数值、熄灭节电等功能全部集一键。 ( F1 D( f7 r1 C9 a# F
1 U- h3 {4 o+ ]3 ~" q4 c1 k
% T1 _# U U6 ]( W* W! X, j( B8 i" p0 V! \0 c
以下是部分汇编源程序,购买我们产品后我们用光盘将完整的单片机汇编源程序和烧写文件送给客户。
: R/ ^1 G5 a; Y;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2 a [7 {' C0 s \
;; 中断入口程序 ;; (仅供参考)0 h( c( ` ~/ n3 P0 K9 A6 D- N
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
' y7 j" a# }9 G3 R;
& }% I% E# ^3 C" f" EORG 0000H ;程序执行开始地址9 J) d) T* a" D0 ]
LJMP START ;跳到标号START执行" M/ S0 b% C' Q- y1 T2 d, S$ l% O( A+ n
ORG 0003H ;外中断0中断程序入口# D' O1 a! r2 D
RETI ;外中断0中断返回$ F# g/ _- u, `5 w' [
ORG 000BH ;定时器T0中断程序入口
, M& U: w% o7 c/ `8 |6 F: H* sLJMP INTT0 ;跳至INTTO执行) f/ D! q9 g) H$ S7 T" R+ {
ORG 0013H ;外中断1中断程序入口
. X. L) d7 S0 HRETI ;外中断1中断返回# R) }4 l% S/ _
ORG 001BH ;定时器T1中断程序入口
$ o, n. D+ |( V5 {LJMP INTT1 ;跳至INTT1执行$ m& V9 f! t) e- a' M' }! j3 T
ORG 0023H ;串行中断程序入口地址+ J3 g; h5 Y& y3 Z+ _
RETI ;串行中断程序返回9 g& S3 e. c+ g# G2 K2 C
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7 N; o2 p& b4 @" P1 f6 X; h
;; 主 程 序 ;;
! f. J2 \9 o, r5 p;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3 q% z( P) c1 @9 z;
( R& o5 w3 G* {+ }START: MOV R0,#70H ;清70H-7AH共11个内存单元5 \* d: e. m; X+ t4 l0 f' U
MOV R7,#0BH 1 i! r; _ y3 S1 g/ j d
;clr P3.7 ;, h* P3 s# ]! Y5 ^, z
CLEARDISP: MOV @R0,#00H ;, ^6 }- Z7 R8 S# `
INC R0 ;
8 F/ u. Q& j/ z( s. E7 ADJNZ R7,CLEARDISP ;3 e1 w5 Q5 Z ], `3 _
MOV 20H,#00H ;清20H(标志用)
1 |' ]. B, n( u9 m! K, b1 xMOV 7AH,#0AH ;放入"熄灭符"数据( Y( L9 I. V- M, E# a% q+ T; O
MOV TMOD,#11H ;设T0、T1为16位定时器
' y# m6 c0 M! W' |; a6 VMOV TL0,#0B0H ;50MS定时初值(T0计时用)% i) j' b4 v+ a* J4 r0 p( Z% H% k
MOV TH0,#3CH ;50MS定时初值
, n; b+ }; W- l4 Z- WMOV TL1,#0B0H ;50MS定时初值(T1闪烁定时用)& F. k* u7 s+ _6 W, W' ^
MOV TH1,#3CH ;50MS定时初值
; j! h. a4 p1 l, |. s* rSETB EA ;总中断开放/ b4 u# @# n: N1 M
SETB ET0 ;答应T0中断; } T' F0 x4 K; ` Y y+ w
SETB TR0 ;开启T0定时器
3 }$ a6 M; G1 \. |# E1 P" N; nMOV R4,#14H ;1秒定时用初值(50MS×20)
- a" a0 `9 |- j+ j* K1 }, }8 e* NSTART1: LCALL DISPLAY ;调用显示子程序9 P/ Y' j3 T$ `! c
JNB P3.7,SETMM1 ;P3.7口为0时转时间调整程序 9 R& T/ \! l* R7 y* o% l( ?
SJMP START1 ;P3.7口为1时跳回START1) [! ?5 |! t: @. b7 S
SETMM1: LJMP SETMM ;转到时间调整程序SETMM0 _* C. @' O9 ]5 M* O4 g5 Y" C
;% E! m3 v# H2 l) N' m( [- F
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1 Z; B7 O" g% n0 c# Q7 e6 S; f;; 1秒计时程序 ;;$ E8 }; q h) Z1 |! n+ }
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7 r9 P* B( ^) B. h: ?;T0中断服务程序, j6 j8 \5 d1 ?9 q0 v( N
INTT0: PUSH ACC ;累加器入栈保护* G( K7 c2 ], ^. g, h
PUSH PSW ;状态字入栈保护1 y$ v: ~2 S- V5 X
CLR ET0 ;关T0中断答应
6 d7 a% u( F8 G1 R0 i2 ], ECLR TR0 ;封闭定时器T0
6 Z! }+ }( Q* ~$ u _8 a! z) CMOV A,#0B7H ;中断响应时间同步修正. P. s+ A( D6 X, }+ C8 B. }) k
ADD A,TL0 ;低8位初值修正8 ?# n7 Q: L# f4 h
MOV TL0,A ;重装初值(低8位修正值). i) Y: U# G% `' I
MOV A,#3CH ;高8位初值修正; g; _: y) j8 J7 {5 n B6 e. P4 u
ADDC A,TH0 ;
( O0 f) z/ i% oMOV TH0,A ;重装初值(高8位修正值). E g/ S2 D2 p: W0 A
SETB TR0 ;开启定时器T0
. \/ O& X1 B& ]% n" ?3 fDJNZ R4, OUTT0 ;20次中断未到中断退出
$ u2 u% } @# h# u9 nADDSS: MOV R4,#14H ;20次中断到(1秒)重赋初值
5 G* o0 G* @* Y% ]MOV R0,#71H ;指向秒计时单元(71H-72H)
9 v3 `' m+ X) _6 ~/ QACALL ADD1 ;调用加1程序(加1秒操作); Z. h% {2 i/ k: e' B ^" n
MOV A,R3 ;秒数据放入A(R3为2位十进制数组合)$ }0 ^3 I G* }' j0 n/ K
CLR C ;清进位标志 N6 B9 r3 d5 t( P; B- q
CJNE A,#60H,ADDMM ;. O/ v% K! g1 E/ r5 Y
ADDMM: JC OUTT0 ;小于60秒时中断退出9 q' I8 a- F9 @% E8 `
ACALL CLR0 ;大于或即是60秒时对秒计时单元清0
9 g" U5 x4 a8 K+ T8 j" zMOV R0,#77H ;指向分计时单元(76H-77H)) T8 L) J5 E: P6 r _
ACALL ADD1 ;分计时单元加1分钟4 u: C* p: {0 `6 F$ j0 E
MOV A,R3 ;分数据放入A: g# S7 N' z7 `+ K' V
CLR C ;清进位标志
. W, w& A) s0 qCJNE A,#60H,ADDHH ;
0 h2 u/ h3 j& C6 G( CADDHH: JC OUTT0 ;小于60分时中断退出
1 J! P. B, l" m5 fACALL CLR0 ;大于或即是60分时分计时单元清09 i2 E* A' o; T
MOV R0,#79H ;指向小时计时单(78H-79H)8 X7 R4 \& Q' Y9 r8 L4 M% Z
ACALL ADD1 ;小时计时单元加1小时
5 V7 S8 ?( m1 E: G& I: vMOV A,R3 ;时数据放入A
6 h6 F1 c( [& Y1 L6 @: MCLR C ;清进位标志, {- K# w- h6 w
CJNE A,#24H,HOUR ;7 D) o' e& H& E) v# F2 ~
HOUR: JC OUTT0 ;小于24小时中断退出0 L* c" D+ b& P
ACALL CLR0 ;大于或即是24小时小时计时单元清0
$ H* D0 ^3 W4 \, j OOUTT0: MOV 72H,76H ;中断退出时将分、时计时单元数据移* p4 {( D- N. z$ I9 D5 `" H
MOV 73H,77H ;入对应显示单元
4 P% f; E x2 HMOV 74H,78H ;
9 C$ p% u4 D% H# qMOV 75H,79H ;3 Q2 p) w, F) z( @* P
POP PSW ;恢复状态字(出栈)
- f' i6 I" x; b* Z+ XPOP ACC ;恢复累加器. T% i1 f" K) t* ]1 s
SETB ET0 ;开放T0中断
" X7 q# {+ H( u6 k% M9 R) @RETI ;中断返回$ x: I. C1 U# i3 A+ K' r
;7 u, g9 f; n1 {3 _! z. z
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;: o: j4 m0 d. M5 n' r' @0 v2 N P! l
;; 闪动调时 程 序 ;;& G6 ~) N' P& q6 p( }6 \5 C y: ~
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;: E+ a( Q8 Z# H
;T1中断服务程序,用作时间调整时调整单元闪烁指示
; U" |% h; Y7 F- n% YINTT1: PUSH ACC ;中断现场保护
3 Z& `* M0 X+ D6 S [7 I+ ?$ \PUSH PSW ;
; {! F+ T& w& S! _MOV TL1, #0B0H ;装定时器T1定时初值" m7 @7 {, x G I6 N
MOV TH1, #3CH ;. w7 ?! Z( P D* @
DJNZ R2,INTT1OUT ;0.3秒未到退出中断(50MS中断6次)
; `; V* e P1 G/ X! w, VMOV R2,#06H ;重装0.3秒定时用初值
; b, |. `+ M- A4 t3 D0 N0 ~, b1 vCPL 02H ;0.3秒定时到对闪烁标志取反) |9 h2 |( ]4 ]! V
JB 02H,FLASH1 ;02H位为1时显示单元"熄灭"
9 q H( L! v& \' o% VMOV 72H,76H ;02H位为0时正常显示* e# }6 A2 \8 t- F) j/ t# t( y
MOV 73H,77H ;
4 ^. a8 S* b! O6 hMOV 74H,78H ;
* L' Z! a# ^& _, z4 ?0 Y) c# kMOV 75H,79H ;
7 r' \9 Q3 d, V! A. dINTT1OUT: POP PSW ;恢复现场
# ]6 S. B7 F. l( Z- u& tPOP ACC ;% t3 b w( v" G2 `$ C7 t' W! B
RETI ;中断退出+ y$ O! z, o8 ~4 a
FLASH1: JB 01H,FLASH2 ;01H位为1时,转小时熄灭控制
6 Y/ b: Q: [3 fMOV 72H,7AH ;01H位为0时,"熄灭符"数据放入分2 O5 Q" t- q! K* X5 Z) M+ I
MOV 73H,7AH ;显示单元(72H-73H),将不显示分数据
# h! H& L& Y* ]* lMOV 74H,78H ;
& P# P1 k8 ]2 R6 U' MMOV 75H,79H ;6 ?+ o9 T# B, ]: J$ t$ G; A3 r7 f
AJMP INTT1OUT ;转中断退出& e6 j, p% R/ i( c
FLASH2: MOV 72H,76H ;01H位为1时,"熄灭符"数据放入小时
; x- C9 r, T5 V& [MOV 73H,77H ;显示单元(74H-75H),小时数据将不显示
' A. J- S# T; H4 X2 Q+ HMOV 74H,7AH ;
! v9 _ H( a: `/ D+ jMOV 75H,7AH ;3 l8 ~2 K: e$ l1 k8 m" d( h" c
AJMP INTT1OUT ;转中断退出6 v1 Q. O3 p, _7 M" o( q. D
;
" R8 h r) T: n) q6 V* E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;$ Z: U0 M0 K% v: T# {
;; 加1子 程 序 ;;) e" l8 z. i j& |: U H4 x
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
# O6 z. M" i, m;
# h+ g0 T6 U1 ^7 ]0 [% j0 A0 cADD1: MOV A,@R0 ;取当前计时单元数据到A
/ j8 W( @" ?7 P- N* C) jDEC R0 ;指向前一地址' _, B* N9 {+ x/ U
SWAP A ;A中数据高四位与低四位交换 y( s s' a9 R6 Q) W1 O
ORL A,@R0 ;前一地址中数据放入A中低四位
" }6 S4 k5 j. [, w0 A k" A- r* wADD A,#01H ;A加1操作8 d1 \/ {1 l" o( V
DA A ;十进制调整
6 h4 g5 v, C$ Z+ MMOV R3,A ;移入R3寄存器3 ~- d% ?: H& C2 a0 N" I
ANL A,#0FH ;高四位变05 w8 P* k1 ]8 O* b
MOV @R0,A ;放回前一地址单元
- @* _# _. U+ O5 J% \- |MOV A,R3 ;取回R3中暂存数据
3 z7 J8 y4 T2 Y. b3 jINC R0 ;指向当前地址单元
{5 Q* t7 f/ d# Z+ wSWAP A ;A中数据高四位与低四位交换
0 K1 f" N1 `9 W8 qANL A,#0FH ;高四位变0$ V. l1 V) n' C8 r- R
MOV @R0,A ;数据放入当削地址单元中' c3 x% F. H0 y& g1 @3 [3 D+ J
RET ;子程序返回 T# [$ W4 G+ o9 R$ Q6 G& E
;
! o% _$ o# _/ V9 ~1 d# j;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
A. \1 \' d d2 |0 N' Q;; 清零程序 ;;5 K; R# ?# L5 y2 G/ l. h
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;) y! `8 O3 Q6 s* m9 w0 G( @
;.............! i. u# a8 q1 d- [ e
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7 Z" w2 x/ ` W
;; 时钟调整程序 ;;8 A) A R+ L. l
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
' N& D1 y1 c! T* w2 k9 \;当调时按键按下时进入此程序
) D6 @* j+ R7 a4 H4 }1 L, t2 D+ WSETMM: cLR ET0 ;关定时器T0中断
( g- O) C# T6 Y& B2 DCLR TR0 ;封闭定时器T05 z& R( Z0 i! D7 z7 o$ ^8 Q7 h
LCALL DL1S ;调用1秒延时程序
1 H! q! \) i: T* _( c$ kJB P3.7,CLOSEDIS ;键按下时间小于1秒,封闭显示(省电)9 ~& g' h! n# K8 M5 h! k
MOV R2,#06H ;进入调时状态,赋闪烁定时初值$ F) L' ?3 X0 @6 L5 F; u
SETB ET1 ;答应T1中断
; H3 v A( \; ^' o6 _SETB TR1 ;开启定时器T1( @8 ]4 D' S! w
SET2: JNB P3.7,SET1 ;P3.7口为0(键未开释),等待& b! Z8 Z7 g* i: H
SETB 00H ;键开释,分调整闪烁标志置1/ S5 E# R( \' A3 W( Y% D
SET4: JB P3.7,SET3 ;等待键按下8 r0 Y+ t- }% @
LCALL DL05S ;有键按下,延时0.5秒
. V' y* h5 R$ h/ }7 RJNB P3.7,SETHH ;按下时间大于0.5秒转调小时状态4 x0 [$ J7 B5 N: N0 |& {3 L
MOV R0,#77H ;按下时间小于0.5秒加1分钟操作
* f: |* p& x' A k5 W0 e. V, FLCALL ADD1 ;调用加1子程序' O* K3 i0 y# O/ d# W# X9 ~
MOV A,R3 ;取调整单元数据" `' p4 X+ d- A( ?2 F/ R7 C
CLR C ;清进位标志
1 ~. U: ^0 L) ~7 s* x% Y( K( qCJNE A,#60H,HHH ;调整单元数据与60比较 s3 R3 B, `* w- C2 |4 l8 {' P7 J1 j( f
HHH: JC SET4 ;调整单元数据小于60转SET4循环
. O& x, y7 N, G+ p. n0 T6 kLCALL CLR0 ;调整单元数据大于或即是60时清07 w. z: R- M/ `3 B! T
CLR C ;清进位标志, x# G' {0 c \% R5 M U
AJMP SET4 ;跳转到SET4循环( X" K4 o# `. D" V
CLOSEDIS: SETB ET0 ;省电(LED不显示)状态。开T0中断3 h% D V* J8 Z# c" j6 T% O) h; |
SETB TR0 ;开启T0定时器(开时钟)
2 w. I) h+ i4 d6 T/ K; z. sCLOSE: JB P3.7,CLOSE ;无按键按下,等待。: l) y! V; ~+ v2 \$ r/ h# _
LCALL DISPLAY ;有键按下,调显示子程序延时削抖4 C* [* S8 @* B
JB P3.7,CLOSE ;是干扰返回CLOSE等待
9 f2 h' z6 }, e& BWAITH: JNB P3.7,WAITH ;等待键开释
T; a. A6 N0 O6 GLJMP START1 ;返回主程序(LED数据显示亮), q2 p7 o" p1 P+ u6 a5 M9 r
SETHH: CLR 00H ;分闪烁标志清除(进入调小时状态)( f4 u3 @) _+ l2 P
SETHH1: JNB P3.7,SET5 ;等待键开释
. i6 m6 i D* G& X& P0 T; SSETB 01H ;小时调整标志置1+ e2 @9 {0 B% z0 Z: M7 x
SET6: JB P3.7,SET7 ;等待按键按下) B/ n! w' a2 u9 ^7 F7 X
LCALL DL05S ;有键按下延时0.5秒
5 ^/ {4 o% S l, u% Y2 HJNB P3.7,SETOUT ;按下时间大于0.5秒退出时间调整9 l, F/ N, u n5 T X& x; E
MOV R0,#79H ;按下时间小于0.5秒加1小时操作, R8 \$ ]2 F& ?% s# V
LCALL ADD1 ;调加1子程序! c. V2 ?# X2 F, p* w
MOV A,R3 ;
/ l0 m& K# X* R& Z" r0 t6 @CLR C ;
" }: M0 d2 f5 ~CJNE A,#24H,HOUU ;计时单元数据与24比较! K/ ~! k. Y. }# K2 S- ~: S
HOUU: JC SET6 ;小于24转SET6循环/ a9 x( N% |! Q) ^6 I- R
LCALL CLR0 ;大于或即是24时清0操作
, J, z: n/ A% YAJMP SET6 ;跳转到SET6循环
5 @5 X$ D2 U, d, [# f9 ?7 u$ YSETOUT: JNB P3.7,SETOUT1 ;调时退出程序。等待键开释( N& k2 C3 C9 h# f2 u7 ?
LCALL DISPLAY ;延时削抖
2 o2 ?' T3 n" v6 q1 x( xJNB P3.7,SETOUT ;是抖动,返回SETOUT再等待! e, j) \9 R( w1 P$ ~1 _. e0 ~
CLR 01H ;清调小时标志9 Z( y' r3 ?7 m: V6 X3 p
CLR 00H ;清调分标志" ]& C9 w" U- T
CLR 02H ;清闪烁标志
. B; y8 U* x, `( Z& QCLR TR1 ;封闭定时器T1
/ L' I& u5 ~9 K$ ?( ICLR ET1 ;关定时器T1中断
; p( _% X# A+ _( U6 {& ?; P& cSETB TR0 ;开启定时器T07 j# G* q! p5 {7 N5 A3 o
SETB ET0 ;开定时器T0中断(计时开始)% O/ j+ ~: t8 a! H2 R
LJMP START1 ;跳回主程序
: I8 H$ [# f+ {7 ?7 t; `SET1: LCALL DISPLAY ;键开释等待时调用显示程序(调分)
. y. }+ L F. ]5 |7 oAJMP SET2 ;防止键按下时无时钟显示
B3 r/ V6 \ HSET3: LCALL DISPLAY ;等待调分按键时时钟显示用
& {2 [3 R- n5 E) e: h8 r' F' U, v; vAJMP SET4- r+ l8 h$ [1 i6 _4 w
SET5: LCALL DISPLAY ;键开释等待时调用显示程序(调小时)
; t7 Y+ P7 J2 c) lAJMP SETHH1 ;防止键按下时无时钟显示
4 Y. I0 ~" q/ v* D+ ^* jSET7: LCALL DISPLAY ;等待调小时按键时时钟显示用+ C6 H" f* T1 M" {0 Q* `
AJMP SET6
$ {( X' u1 n- l: HSETOUT1: LCALL DISPLAY ;退出时钟调整时键开释等待
" p3 t+ ~0 ?, ~4 gAJMP SETOUT ;防止键按下时无时钟显示
- o! w6 V6 K2 [;- t$ N* c' w ~/ O9 u1 j
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3 f' W0 [9 Q+ m8 u4 j4 [;; 显示程序 ;;
8 j9 d' Z4 ~( p4 n1 X% J& t( I;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
) B; \, c5 w" }* p- ^$$$$$$$$$$$$$$$$$$$$$$$$$$$
- o" n& i7 V9 H. |) J5 H( p% };1MS延时程序,LED显示程序用' h4 n& j3 `5 s0 y
DL1MS: MOV R6,#14H
9 v ]% V( ]% m1 F6 cDL1: MOV R7,#19H
% L' _( d* a( e e& KDL2: DJNZ R7,DL2& O+ v2 d: G# w; k) [
DJNZ R6,DL17 _8 t" \2 |# z4 O# |* @1 C* z
RET& W% h" y2 Z+ b
;20MS延时程序,采用调用显示子程序以改善LED的显示闪烁现象" W, i3 }- b8 T& y% z
DS20MS: ACALL DISPLAY
! x! f3 B1 n4 n. k& O4 P" i5 i. u: \ACALL DISPLAY0 t9 F, |, i1 `( [- Q/ O
ACALL DISPLAY7 @2 K( u4 t) a6 I5 Z8 I) J
RET; H- B+ @5 f [; y/ I
;延时程序,用作按键时间的长短判定
% W X! Y/ n4 q. lDL1S: LCALL DL05S
& C9 c" j; J: e4 j! x3 w3 ULCALL DL05S
9 I7 e# F# c/ e$ XRET$ ]; l- l. J/ q: u* g( f* j
DL05S: MOV R3,#20H ;8毫秒*32=0.196秒
' B" k0 `5 n; f+ uDL05S1: LCALL DISPLAY
, ]. l9 `% j- [- w0 _DJNZ R3,DL05S1
6 [4 |2 d5 R: R) {RET m) q3 n e/ V- \5 N: n9 m7 B
END ;程序结束
$ v4 o% n; c! l3 Q1 D |