51单片机作的电子钟程序在很多地方已经有了介绍, 对于单片机学习者而言这个程序基本上是一道门槛,掌握了电子钟程序, 基本上可以说51单片机就掌握了80%。常见的电子钟程序由显示部分, 计算部分, 时钟调整部分构成。
. Y: b$ S/ G, Y, e0 Q 时钟的基本显示原理:时钟开始显示为0时0分0秒,也就是数码管显示000000,然后每秒秒位加1 ,到9后,10秒位加1,秒位回0。10秒位到5后,即59秒 ,分钟加1,10秒位回0。依次类推,时钟最大的显示值为23小时59分59秒。这里只要确定了1秒的定时时间, 其他位均以此为基准往上累加。 6 `( S* G0 m* ]
开始程序定义了秒, 十秒, 分, 十分,小时, 十小时,共6位的寄存器, 分别存在30h,31h,32h,33h,34h,35h单元,便于程序以后调用和理解。 : M2 f0 [: |! w& }
6个数码管分别显示时、分、秒,一个功能键,可以切换调整时分秒、增加数值、熄灭节电等功能全部集一键。![]()
( c& a% f2 G: X
0 m% b7 v4 I7 [$ W* ?
8 C% ~- ?5 F4 W9 n" L
3 B' `' h0 L, }" M 以下是部分汇编源程序,购买我们产品后我们用光盘将完整的单片机汇编源程序和烧写文件送给客户。4 w9 T# o2 n6 g3 g. l8 H
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
/ ?8 _; |' r* G2 S;; 中断入口程序 ;; (仅供参考)& m0 D1 V* e7 w# {; }
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2 G; o! Z3 w; q+ g' d" m6 M
;
6 |# E! y: N4 ?& jORG 0000H ;程序执行开始地址/ w$ S% I3 ]% }
LJMP START ;跳到标号START执行
7 n9 m$ u: R9 o$ W$ n( z5 W. C0 eORG 0003H ;外中断0中断程序入口
9 A% g" w7 T# i' LRETI ;外中断0中断返回
* r4 Y, p; g2 ^ORG 000BH ;定时器T0中断程序入口+ _# V' u9 ^5 p6 b7 f/ T7 x
LJMP INTT0 ;跳至INTTO执行
4 V2 O; Z9 l- S% z: X( r! Q6 dORG 0013H ;外中断1中断程序入口4 g% w B% i5 Y9 [, G
RETI ;外中断1中断返回
7 o2 d9 o6 K7 OORG 001BH ;定时器T1中断程序入口3 r# k$ {$ ], I- S- j% o2 j
LJMP INTT1 ;跳至INTT1执行( l1 c! t" H' u# X( b% I6 j2 N
ORG 0023H ;串行中断程序入口地址. J9 B5 \, r' R7 u
RETI ;串行中断程序返回
8 u; u5 J$ f; J5 v1 f/ b;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;( g" O4 ^: J t% c
;; 主 程 序 ;;6 k l/ N! b) p$ F0 o2 T: M( W
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;( G7 U; F2 n0 C5 ~7 D9 r7 x
;: T: f8 X$ M& A3 e
START: MOV R0,#70H ;清70H-7AH共11个内存单元) B8 r2 B; n$ v. d
MOV R7,#0BH : A, j! h3 M. a1 F# V
;clr P3.7 ;
* c. ]! m& |7 K5 f0 oCLEARDISP: MOV @R0,#00H ;6 d- O6 L' L9 ]/ V
INC R0 ;% q/ u% F9 e# D
DJNZ R7,CLEARDISP ;7 m; C9 B& n/ M) T+ o, l* h& N
MOV 20H,#00H ;清20H(标志用)% x7 B) {8 }. C0 P! i$ w
MOV 7AH,#0AH ;放入"熄灭符"数据. R, }0 G0 A1 W9 e: a9 f% n
MOV TMOD,#11H ;设T0、T1为16位定时器; k. F r/ e1 O( E
MOV TL0,#0B0H ;50MS定时初值(T0计时用)
4 h6 P6 `, A' d& x6 Q, L( UMOV TH0,#3CH ;50MS定时初值
9 B D. O6 w8 B- y( RMOV TL1,#0B0H ;50MS定时初值(T1闪烁定时用)( i7 q" L$ n9 K% d% [5 v
MOV TH1,#3CH ;50MS定时初值
" D8 L! B+ |/ z+ l0 C) n9 O$ WSETB EA ;总中断开放' j- K: W% v5 _# y# N5 Q6 p
SETB ET0 ;答应T0中断
: i" T7 m' |9 i! \- b0 _( XSETB TR0 ;开启T0定时器
' h4 w$ a1 P0 b6 V' [8 _MOV R4,#14H ;1秒定时用初值(50MS×20)- M+ \7 Q8 H3 \ C, H4 j
START1: LCALL DISPLAY ;调用显示子程序
1 |$ t1 |. c& R zJNB P3.7,SETMM1 ;P3.7口为0时转时间调整程序 8 G1 w K7 _2 v
SJMP START1 ;P3.7口为1时跳回START1% q) |5 z6 [ m( V' _8 r
SETMM1: LJMP SETMM ;转到时间调整程序SETMM
) B8 W) P# P4 L: X;% L1 q* V' P/ ]5 D8 V% v7 {6 @5 d
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;- x' G. ], m s9 ~
;; 1秒计时程序 ;;! J0 e. B6 z6 w$ u
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
! P- c. v/ w' f6 Y: W;T0中断服务程序' z1 n6 g* K( O. ?! Z1 _
INTT0: PUSH ACC ;累加器入栈保护9 q" D$ H* H$ z. K
PUSH PSW ;状态字入栈保护
1 c2 l5 H) {, N+ @( [* Z3 aCLR ET0 ;关T0中断答应
. m) ~: Q0 x& b5 aCLR TR0 ;封闭定时器T0
8 w7 `# C: U5 ~5 \MOV A,#0B7H ;中断响应时间同步修正
5 Z6 s. d8 n4 W- A* G' {ADD A,TL0 ;低8位初值修正
; t$ q' r0 P! m& m$ p- ~% S8 M+ aMOV TL0,A ;重装初值(低8位修正值)
& C8 v. @4 I; d1 S7 ]' g) ` hMOV A,#3CH ;高8位初值修正
, t. L! G- L: VADDC A,TH0 ;, R( g; i3 {2 O! A* u
MOV TH0,A ;重装初值(高8位修正值)
, q2 t" u. X4 n* s7 mSETB TR0 ;开启定时器T0
5 }$ {$ e8 S& G4 Y! \0 ?) WDJNZ R4, OUTT0 ;20次中断未到中断退出* E4 B% F6 m6 o& b0 W
ADDSS: MOV R4,#14H ;20次中断到(1秒)重赋初值9 Q4 k- s9 E" M9 l2 @
MOV R0,#71H ;指向秒计时单元(71H-72H)4 {3 u7 F& y9 H3 Y% h% T8 V w
ACALL ADD1 ;调用加1程序(加1秒操作)3 S* s# z& l: o6 g6 {2 g
MOV A,R3 ;秒数据放入A(R3为2位十进制数组合)+ a1 ~. E0 A d
CLR C ;清进位标志1 {7 M0 j7 y/ ^3 x, J2 B
CJNE A,#60H,ADDMM ;
9 V* A( p; ~) @ADDMM: JC OUTT0 ;小于60秒时中断退出
8 v5 p t* W# aACALL CLR0 ;大于或即是60秒时对秒计时单元清0
! V3 A4 w+ T9 H1 pMOV R0,#77H ;指向分计时单元(76H-77H)
2 { f* a+ k9 w8 w; C2 Q3 CACALL ADD1 ;分计时单元加1分钟
$ M+ L( y0 n- VMOV A,R3 ;分数据放入A0 v ~4 V4 v* ~
CLR C ;清进位标志 m; V) ^/ o8 T2 t
CJNE A,#60H,ADDHH ;
9 ]& R `! h; r2 u* T0 XADDHH: JC OUTT0 ;小于60分时中断退出' r. |9 L- U; y! j2 _' K
ACALL CLR0 ;大于或即是60分时分计时单元清02 W% P; W" e/ Q
MOV R0,#79H ;指向小时计时单(78H-79H)
' ?. b% o, }& x9 a7 |0 cACALL ADD1 ;小时计时单元加1小时3 Q# b; K: W# B; \# V, e5 G/ K
MOV A,R3 ;时数据放入A
4 \& E; n* K6 D; H0 T, mCLR C ;清进位标志4 Q& i8 Z: r4 t; N+ |
CJNE A,#24H,HOUR ;2 ?8 J. y; M' A3 T( N2 s
HOUR: JC OUTT0 ;小于24小时中断退出
$ k: W- V# W6 b' zACALL CLR0 ;大于或即是24小时小时计时单元清0
8 p* ~% D0 s' x! K4 v/ F; VOUTT0: MOV 72H,76H ;中断退出时将分、时计时单元数据移& T0 w8 l9 l5 h# b" |% i9 ]
MOV 73H,77H ;入对应显示单元
( B: R. f, W) v) Z- b/ ]* w! \MOV 74H,78H ;0 m9 Q, j/ U8 t) o2 h) _2 D
MOV 75H,79H ;
+ g/ S: d, D0 e$ x6 S8 M2 ^POP PSW ;恢复状态字(出栈)
- H" g' j' X' z- I8 }POP ACC ;恢复累加器4 B2 e# E" J$ j# A) W' d; u1 M
SETB ET0 ;开放T0中断
! X$ J: n$ O+ P3 C! _# A) u: ERETI ;中断返回7 J2 ~- u. w4 @7 y3 ~2 T
;
# O( ~, _3 D+ a' j- K% j' }( a;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6 N z6 {# A& \( E5 p. k+ i;; 闪动调时 程 序 ;;' M- D% {- K. q* ?' u' J
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;% ?+ c- t8 M) a) K) @
;T1中断服务程序,用作时间调整时调整单元闪烁指示
4 g8 i9 I! r# T1 }3 p! x+ R! {" v- v: qINTT1: PUSH ACC ;中断现场保护% i% u# t% r& R* E4 w
PUSH PSW ;7 t; r5 n0 X7 Z) ~6 V) M# b; S
MOV TL1, #0B0H ;装定时器T1定时初值
2 }( ^! i8 ~% VMOV TH1, #3CH ;( k6 W: Y2 L& r* m
DJNZ R2,INTT1OUT ;0.3秒未到退出中断(50MS中断6次)
- n& F# L9 J! G8 P3 N3 WMOV R2,#06H ;重装0.3秒定时用初值" J7 O7 v/ S) ?' I2 b
CPL 02H ;0.3秒定时到对闪烁标志取反! K; L( F1 r3 v& A
JB 02H,FLASH1 ;02H位为1时显示单元"熄灭"4 I3 |0 N3 ^$ A2 O- ]$ {
MOV 72H,76H ;02H位为0时正常显示
9 L4 g `1 }% J! K/ \* C) P; ?MOV 73H,77H ;" c, D5 x9 H6 q
MOV 74H,78H ;
1 r7 s2 K* u9 h: n% ~$ Z# l5 NMOV 75H,79H ;- V2 @% R c% _+ X
INTT1OUT: POP PSW ;恢复现场" @7 M; }3 E# N: c9 d, B0 S; a1 z: ?. L1 |
POP ACC ; T1 Y! |: p4 k! R
RETI ;中断退出
( k2 I0 h% l) i, Z" K b6 h yFLASH1: JB 01H,FLASH2 ;01H位为1时,转小时熄灭控制) _2 ~+ ~( }# N
MOV 72H,7AH ;01H位为0时,"熄灭符"数据放入分3 p" N. R0 L# V" H b
MOV 73H,7AH ;显示单元(72H-73H),将不显示分数据
5 l3 D V* M' c/ BMOV 74H,78H ;
2 }) q6 |3 g/ V) p6 S7 wMOV 75H,79H ;
7 p- l$ Y9 i( Q6 |$ L- S aAJMP INTT1OUT ;转中断退出
* ?+ a' i, |# S4 w% Y; a& NFLASH2: MOV 72H,76H ;01H位为1时,"熄灭符"数据放入小时/ _- G' i% ]9 t3 `0 k
MOV 73H,77H ;显示单元(74H-75H),小时数据将不显示
( \4 f( g: K9 s X8 k! W! H2 \MOV 74H,7AH ;
; [2 n3 u. f' q, q% y* c4 u4 T& vMOV 75H,7AH ;
7 S" t& c: ~2 F/ l- Z) UAJMP INTT1OUT ;转中断退出$ {, O" ?0 E: g1 M7 e$ |
;+ A4 I' ~. W' D3 X3 S
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
$ P( g" @+ Q6 K( n: f; {;; 加1子 程 序 ;;
9 q, z( _ q7 A; w4 n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6 p+ K; c, ]% l- J7 f( N: ~' Y4 Q9 a- U) Z;
: E' P- M6 x! [- m9 ^5 IADD1: MOV A,@R0 ;取当前计时单元数据到A
3 R7 F5 ^+ P5 [4 v& FDEC R0 ;指向前一地址4 [7 H* Z( @( z9 B3 e$ l
SWAP A ;A中数据高四位与低四位交换
2 U9 h9 V% W; b1 Y- hORL A,@R0 ;前一地址中数据放入A中低四位
( B; F* N E4 Y! S$ dADD A,#01H ;A加1操作3 p+ t( U. k$ {' g D% ^
DA A ;十进制调整# }' N3 n6 ^! Q1 X& N) v* z. T0 W
MOV R3,A ;移入R3寄存器
" W: R1 b5 P# ~6 V @ANL A,#0FH ;高四位变04 B* ?; T( k0 H" M
MOV @R0,A ;放回前一地址单元
8 F* t; Y0 a/ ^& H+ rMOV A,R3 ;取回R3中暂存数据
# ^9 h j1 k& l- K7 T4 TINC R0 ;指向当前地址单元- m6 Z1 q2 M- w7 \3 b
SWAP A ;A中数据高四位与低四位交换
; U q; z8 b' H1 w5 F( \ANL A,#0FH ;高四位变05 j" f, e! A& L
MOV @R0,A ;数据放入当削地址单元中1 `; c8 g! p+ a$ @% e/ P
RET ;子程序返回
! h% F& Q! ^( f;1 `% C- y! v! t8 [% L
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
( q& N7 J* H+ N" c G;; 清零程序 ;;1 l# ?( C9 \9 G" }5 W8 O3 g+ T1 e; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; i7 Y: S! [4 E( ^4 Q
;.............9 R: @% C) w5 n, V3 V2 J: D# B
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3 J' |/ h2 Q+ z9 H
;; 时钟调整程序 ;;2 q4 m6 [4 O2 l m2 q
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3 i1 f) Z8 i& e8 E' F;当调时按键按下时进入此程序( V/ ?( b( U5 D. b3 W
SETMM: cLR ET0 ;关定时器T0中断- x+ J$ k; f! z3 u7 q7 n
CLR TR0 ;封闭定时器T0
1 W1 Z! H. c' W* j- j; PLCALL DL1S ;调用1秒延时程序, y# l, U$ N' `* |6 b( a2 V$ ]1 z. H
JB P3.7,CLOSEDIS ;键按下时间小于1秒,封闭显示(省电)# o9 @+ a) F. K' f' ?3 `
MOV R2,#06H ;进入调时状态,赋闪烁定时初值 v: c( H, O& J* s. {
SETB ET1 ;答应T1中断) }* W) T1 p l) A* u
SETB TR1 ;开启定时器T14 [: ~% M; E4 F6 e8 n' D
SET2: JNB P3.7,SET1 ;P3.7口为0(键未开释),等待
' U$ D; @! x" G* z1 rSETB 00H ;键开释,分调整闪烁标志置17 I4 b' U( s, W
SET4: JB P3.7,SET3 ;等待键按下
: E$ u+ `' P& M0 l4 `# D; N" LLCALL DL05S ;有键按下,延时0.5秒3 Q1 a( }+ ^: Q4 n. O- c
JNB P3.7,SETHH ;按下时间大于0.5秒转调小时状态
: V1 u8 }* y/ }MOV R0,#77H ;按下时间小于0.5秒加1分钟操作
; R' c( G+ J, Q6 N! ALCALL ADD1 ;调用加1子程序
* R& a1 C6 O$ C5 p4 pMOV A,R3 ;取调整单元数据
5 E* Y% B& v, YCLR C ;清进位标志# s3 S; S' x7 a' C/ `: K7 s
CJNE A,#60H,HHH ;调整单元数据与60比较
( F* u' Y' Q0 v8 f8 f; }1 XHHH: JC SET4 ;调整单元数据小于60转SET4循环$ U: l1 X) w2 t1 b
LCALL CLR0 ;调整单元数据大于或即是60时清0, q& J* x9 F* w, t: ~' w
CLR C ;清进位标志4 |2 t, R6 e$ u7 j9 E, \0 E
AJMP SET4 ;跳转到SET4循环
8 I9 e" p5 m0 Z" s/ A& n2 i6 u5 lCLOSEDIS: SETB ET0 ;省电(LED不显示)状态。开T0中断% q1 f. D/ U9 r- W) g2 ?0 |$ I2 y ^
SETB TR0 ;开启T0定时器(开时钟)
. i4 Q0 D7 |! t# |9 [3 e% V# QCLOSE: JB P3.7,CLOSE ;无按键按下,等待。0 A" R# @& _6 g4 j" |- l1 J
LCALL DISPLAY ;有键按下,调显示子程序延时削抖
6 d% b4 @) U2 L, J& }JB P3.7,CLOSE ;是干扰返回CLOSE等待- r8 U3 W. i2 M. `5 \
WAITH: JNB P3.7,WAITH ;等待键开释
$ v: s7 Q, G& a2 eLJMP START1 ;返回主程序(LED数据显示亮)
4 k+ Y6 R+ C' e; S* h9 S* cSETHH: CLR 00H ;分闪烁标志清除(进入调小时状态) ]! x( R$ ], H! m3 l! p( W- B4 r( \
SETHH1: JNB P3.7,SET5 ;等待键开释, r: L/ n# t2 B) L
SETB 01H ;小时调整标志置15 O# w W+ i9 v9 k/ ]
SET6: JB P3.7,SET7 ;等待按键按下
" f) n- |5 @) YLCALL DL05S ;有键按下延时0.5秒
; J$ r/ r, A; l$ f/ b3 `1 hJNB P3.7,SETOUT ;按下时间大于0.5秒退出时间调整
) T5 b1 }( h& I; t& Q* UMOV R0,#79H ;按下时间小于0.5秒加1小时操作! }4 c2 N: z6 e9 q6 r9 v" ^3 J
LCALL ADD1 ;调加1子程序4 x4 ]5 \, C" u# o& q9 Q
MOV A,R3 ;( V4 P( k h: d! g) z
CLR C ;* a- ? u7 [" y$ r
CJNE A,#24H,HOUU ;计时单元数据与24比较: L& D$ |* b/ F! z# \1 X
HOUU: JC SET6 ;小于24转SET6循环4 h- w \) j$ M2 I% X. D5 W
LCALL CLR0 ;大于或即是24时清0操作; d/ `" |4 }$ [- U
AJMP SET6 ;跳转到SET6循环# ^; v$ H( k2 @; _6 p8 J
SETOUT: JNB P3.7,SETOUT1 ;调时退出程序。等待键开释9 i( ?: _. x, l! L: \
LCALL DISPLAY ;延时削抖# a% Q' \& A/ F) U
JNB P3.7,SETOUT ;是抖动,返回SETOUT再等待" x; u: D, C6 H, c0 O
CLR 01H ;清调小时标志
, ^3 O1 j8 K4 z) v$ U" |CLR 00H ;清调分标志2 M/ u& k$ S- q. ?' |2 i3 G( y/ L
CLR 02H ;清闪烁标志
; c1 ]4 G" {" k b" H( ]CLR TR1 ;封闭定时器T14 A7 n) a5 y2 ?. y& y' c9 q$ ]
CLR ET1 ;关定时器T1中断
: ?' \3 ~ V RSETB TR0 ;开启定时器T08 Y) B' O# u9 W+ N7 w: J! c E, ^# c
SETB ET0 ;开定时器T0中断(计时开始)
: A5 a$ j' Q% u# {- o5 E1 HLJMP START1 ;跳回主程序
' r. a" R u# q g m2 k, f* }SET1: LCALL DISPLAY ;键开释等待时调用显示程序(调分)- \; h7 N- e" [. |1 M) `2 J4 e
AJMP SET2 ;防止键按下时无时钟显示+ D" M4 ?9 s. ~ O5 A1 V
SET3: LCALL DISPLAY ;等待调分按键时时钟显示用7 ^' j$ Y4 O a5 w6 I4 r
AJMP SET4# Q: {/ N" K. y; O( v
SET5: LCALL DISPLAY ;键开释等待时调用显示程序(调小时)
( J" s/ |1 ^# j, X- IAJMP SETHH1 ;防止键按下时无时钟显示
2 ~* m1 @8 W8 z3 J9 k5 I NSET7: LCALL DISPLAY ;等待调小时按键时时钟显示用. ?( U/ s( {- l$ H- k; W
AJMP SET6
: J! e$ \% ?. l" z, R+ S- BSETOUT1: LCALL DISPLAY ;退出时钟调整时键开释等待7 d' H( | s3 V: y9 u: ^
AJMP SETOUT ;防止键按下时无时钟显示
. _ @: X2 t1 c" K. |;
# C2 A' l# j, d' I; K* Z1 |;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9 m, m7 k2 w8 |3 @; d. e1 S. |
;; 显示程序 ;;- S# H a' ` {+ g" w) P" H. l
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1 q! m: U% u. b2 B% g/ u3 |6 }$$$$$$$$$$$$$$$$$$$$$$$$$$$
6 M/ @$ f; `1 p4 S: q* x# A3 };1MS延时程序,LED显示程序用: W2 Z5 L# f! _
DL1MS: MOV R6,#14H
, D9 _2 g& V8 K- QDL1: MOV R7,#19H
' C! p2 T- f1 G7 a i! oDL2: DJNZ R7,DL2/ {1 r5 ?& ?1 ?% C4 t. C* m
DJNZ R6,DL1: y& G0 h7 P9 b' S3 w) D' m
RET
' |6 i' f7 E5 h5 a# ^* ?;20MS延时程序,采用调用显示子程序以改善LED的显示闪烁现象
" W3 h2 }: x8 l$ M: {8 ]# YDS20MS: ACALL DISPLAY$ [/ ]& K8 C" o1 ^7 V7 Z
ACALL DISPLAY2 o& s1 E9 P, M% m' n) s" @+ a
ACALL DISPLAY P1 r( T3 {. b+ J3 Y: B2 a) `
RET
9 `! d2 P" t- V: [8 T9 e* W" Z' a;延时程序,用作按键时间的长短判定
' v; Q, I' ]% D% NDL1S: LCALL DL05S
- o) |- L6 c7 F! rLCALL DL05S
2 j% k$ ?' R a0 g4 e5 Q; Q7 GRET
- F0 J" `6 e$ n0 h2 Q- `9 e$ M5 KDL05S: MOV R3,#20H ;8毫秒*32=0.196秒0 v9 B4 `1 t2 k
DL05S1: LCALL DISPLAY* V, i/ t q4 u6 [. l
DJNZ R3,DL05S1' [2 N- f% r2 h% I( Z9 Z# `
RET
7 {8 L* Q7 T- }$ rEND ;程序结束
* W' x0 p1 y I: F1 G |