51单片机作的电子钟程序在很多地方已经有了介绍, 对于单片机学习者而言这个程序基本上是一道门槛,掌握了电子钟程序, 基本上可以说51单片机就掌握了80%。常见的电子钟程序由显示部分, 计算部分, 时钟调整部分构成。
5 Q% H& j5 f' v. a4 d 时钟的基本显示原理:时钟开始显示为0时0分0秒,也就是数码管显示000000,然后每秒秒位加1 ,到9后,10秒位加1,秒位回0。10秒位到5后,即59秒 ,分钟加1,10秒位回0。依次类推,时钟最大的显示值为23小时59分59秒。这里只要确定了1秒的定时时间, 其他位均以此为基准往上累加。 9 @" A+ q1 x' Q7 i3 t- h
开始程序定义了秒, 十秒, 分, 十分,小时, 十小时,共6位的寄存器, 分别存在30h,31h,32h,33h,34h,35h单元,便于程序以后调用和理解。 $ u0 ? [8 n$ o& p
6个数码管分别显示时、分、秒,一个功能键,可以切换调整时分秒、增加数值、熄灭节电等功能全部集一键。 ; g E) P/ t+ Y" E5 N) p
- p+ p: f. j- [
, w) |; T. D( K2 T3 g& M4 V9 N J# L* R! ~3 {1 s+ }
以下是部分汇编源程序,购买我们产品后我们用光盘将完整的单片机汇编源程序和烧写文件送给客户。% b1 a6 w/ g+ ~
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;) O V4 d; ~2 F0 v. `
;; 中断入口程序 ;; (仅供参考)- \) m, ?- f$ S+ d
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;, @ X( h, e0 {
;
. v" ^7 ^) N. l" fORG 0000H ;程序执行开始地址+ K4 E6 u" x8 w, R# ^) S! q8 L8 N
LJMP START ;跳到标号START执行
+ ~$ v, o$ [: H' r- PORG 0003H ;外中断0中断程序入口+ Q, b& t4 [+ f. x' |" ^3 j: `
RETI ;外中断0中断返回
% _( \9 F/ E, l6 \ORG 000BH ;定时器T0中断程序入口3 o* ~* P! O& e& U- S' P
LJMP INTT0 ;跳至INTTO执行3 n; L; X% S. J5 s( }9 O* V( G
ORG 0013H ;外中断1中断程序入口/ F: @6 {3 K8 V% X9 ~) z/ g' D! A6 j
RETI ;外中断1中断返回9 t4 o1 R5 ?' L/ m
ORG 001BH ;定时器T1中断程序入口
, M+ i L/ J. U" wLJMP INTT1 ;跳至INTT1执行
( v+ M" G% k" ]4 XORG 0023H ;串行中断程序入口地址
; B4 u) p4 d; ORETI ;串行中断程序返回
5 Q" Z# W( B F- d: ^1 U;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;0 a6 R1 z. J2 m) i
;; 主 程 序 ;;
; H7 v# |9 m( V' _8 ^, K;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5 Y& C4 S o* x
;- j" i. |2 B0 G9 b: \* i
START: MOV R0,#70H ;清70H-7AH共11个内存单元+ ?6 q1 T) r: J! c
MOV R7,#0BH & p; L! ~$ j# p+ t, z2 R
;clr P3.7 ;9 b( u, b/ i. I, @# o+ R3 i- R1 l
CLEARDISP: MOV @R0,#00H ;% V' W6 [' K/ |4 Y9 } }
INC R0 ;( d# A' K' G7 d: m6 h
DJNZ R7,CLEARDISP ;
4 l; r; k1 K, j+ z. J8 YMOV 20H,#00H ;清20H(标志用)
9 m+ l+ B8 J$ ^; ]# b) DMOV 7AH,#0AH ;放入"熄灭符"数据: V' N3 u( `4 `: ^, Z9 l
MOV TMOD,#11H ;设T0、T1为16位定时器0 M* e- T+ o7 l! Q. j, _
MOV TL0,#0B0H ;50MS定时初值(T0计时用)
4 `3 v. @2 Y* y2 T# g9 N% dMOV TH0,#3CH ;50MS定时初值5 f# E* \' v1 J" l- y: `
MOV TL1,#0B0H ;50MS定时初值(T1闪烁定时用)
! M* e4 e0 \% wMOV TH1,#3CH ;50MS定时初值' l& c8 j0 u! q1 p1 R
SETB EA ;总中断开放
8 p. k) Q8 G1 g7 sSETB ET0 ;答应T0中断9 K1 I8 J$ |& f/ W6 R2 H
SETB TR0 ;开启T0定时器" m* N' ^" \- _: o% k3 Z% @) S; r
MOV R4,#14H ;1秒定时用初值(50MS×20), [; u+ s! r" W( v& @
START1: LCALL DISPLAY ;调用显示子程序- m6 T9 Y" E7 R# r4 p$ i; z. A
JNB P3.7,SETMM1 ;P3.7口为0时转时间调整程序 & N7 Z% I! T# l0 [
SJMP START1 ;P3.7口为1时跳回START1
8 J$ {$ ?5 e! {* ~8 u& wSETMM1: LJMP SETMM ;转到时间调整程序SETMM
; a# w& J$ I6 _, r! {$ J;& R, G: _7 |4 D& T6 G7 y
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; b# l0 g* m! s9 D9 m9 Z
;; 1秒计时程序 ;;
' f4 H- _7 w- j, R; z4 D3 J;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
9 R$ m& {# w& ~. t;T0中断服务程序; U# n: W; d8 w% Q. S
INTT0: PUSH ACC ;累加器入栈保护
" L6 B& t( X( t6 ?/ nPUSH PSW ;状态字入栈保护
) r6 j. W& |- \! b2 f4 c+ K, DCLR ET0 ;关T0中断答应% p2 F, O# u1 y0 `: D
CLR TR0 ;封闭定时器T0
+ f7 H5 P1 w" Y$ b: x" GMOV A,#0B7H ;中断响应时间同步修正: R, _. a3 L$ W/ z2 X
ADD A,TL0 ;低8位初值修正
4 S7 s f# D0 d* N0 P" dMOV TL0,A ;重装初值(低8位修正值)% C, ]1 X$ `, z6 J" W+ x$ i4 }
MOV A,#3CH ;高8位初值修正" f3 a$ l6 ]; g- K9 c8 H
ADDC A,TH0 ;
2 V. H9 q+ P7 {9 m0 gMOV TH0,A ;重装初值(高8位修正值)
3 P6 Y& ?4 n; p: U: H7 q0 H! n& B* jSETB TR0 ;开启定时器T0
# o* [# g4 v; `, h$ j6 HDJNZ R4, OUTT0 ;20次中断未到中断退出
$ @' V. T c: X" R& m6 [( W' jADDSS: MOV R4,#14H ;20次中断到(1秒)重赋初值
9 N" d+ J' B0 P& I8 ^$ kMOV R0,#71H ;指向秒计时单元(71H-72H)) p3 J# h0 S' @* ^ [
ACALL ADD1 ;调用加1程序(加1秒操作)) a+ G- P# r5 n$ r. J# n4 ^
MOV A,R3 ;秒数据放入A(R3为2位十进制数组合), F7 K) |9 x" S9 W! E
CLR C ;清进位标志2 ]& X% H8 k0 G6 C* `& d& K
CJNE A,#60H,ADDMM ;1 a& y% W) O' R E4 t9 U& r4 V( f
ADDMM: JC OUTT0 ;小于60秒时中断退出
0 H; u$ J1 o8 [- l+ i3 EACALL CLR0 ;大于或即是60秒时对秒计时单元清0
- | x; c- I5 |9 N$ qMOV R0,#77H ;指向分计时单元(76H-77H)
# F9 c7 M( H) g9 K) b$ qACALL ADD1 ;分计时单元加1分钟
, w. J0 }3 d6 l: N3 tMOV A,R3 ;分数据放入A
$ J5 t8 ^1 ]% t5 ~CLR C ;清进位标志
; S5 ]- H" \$ I) {CJNE A,#60H,ADDHH ;
7 [# b) q/ x, v; n0 K# t8 B! ]5 ^9 e* ?ADDHH: JC OUTT0 ;小于60分时中断退出5 K. V/ Q/ ~7 Q
ACALL CLR0 ;大于或即是60分时分计时单元清0
6 q4 M9 f* i7 O9 D% {1 N0 yMOV R0,#79H ;指向小时计时单(78H-79H)6 G3 G; a- p7 l2 r0 S/ T4 p9 r% N ]
ACALL ADD1 ;小时计时单元加1小时3 C; p! h# V' e
MOV A,R3 ;时数据放入A* K/ w# z& v9 \3 M3 D) i
CLR C ;清进位标志4 e/ U( l5 _, X7 Q
CJNE A,#24H,HOUR ;0 H, P1 G( o; R, y
HOUR: JC OUTT0 ;小于24小时中断退出5 T" ^2 o, N: P4 b) t; u
ACALL CLR0 ;大于或即是24小时小时计时单元清01 q* q) S# N# H, m' R6 p$ f# z7 Y9 u& u
OUTT0: MOV 72H,76H ;中断退出时将分、时计时单元数据移
/ L# {+ [- n$ T) kMOV 73H,77H ;入对应显示单元& W& O3 D- y- G! I$ K) n {: {
MOV 74H,78H ;
) ^8 n. M0 @ l/ j" r" x* ^MOV 75H,79H ;$ `+ g" G9 s7 l; W
POP PSW ;恢复状态字(出栈)
3 \ n- T. o( I1 k2 ZPOP ACC ;恢复累加器
4 i4 s# t# v. T* e: i2 v0 Q" SSETB ET0 ;开放T0中断+ U& _: r# ^8 y i; A$ ^
RETI ;中断返回
+ o! m# t0 Z- ?. {# T" ~! [;
/ c% X6 x5 G w* ?;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;: o& [0 Y" q+ q; X9 c
;; 闪动调时 程 序 ;;
2 B* i. T+ g- ], G;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;- z/ W* p; @/ n% K
;T1中断服务程序,用作时间调整时调整单元闪烁指示. Z" K7 p+ r% K
INTT1: PUSH ACC ;中断现场保护2 B/ R! V/ s5 s9 X1 b4 [
PUSH PSW ;+ A% m: f0 H+ w0 b g
MOV TL1, #0B0H ;装定时器T1定时初值
# _0 [1 }$ X* b* r0 @: m* ]1 XMOV TH1, #3CH ;
4 I5 h. F2 f! e [! l- E' W- }/ NDJNZ R2,INTT1OUT ;0.3秒未到退出中断(50MS中断6次)% M3 o' c! t) @
MOV R2,#06H ;重装0.3秒定时用初值
7 H( J5 j5 g8 C$ D5 XCPL 02H ;0.3秒定时到对闪烁标志取反 B6 v# H S% j ?4 n5 _6 A2 _
JB 02H,FLASH1 ;02H位为1时显示单元"熄灭"
" L) ~) B. E) l. kMOV 72H,76H ;02H位为0时正常显示2 y( Y U3 \+ ?; P5 O
MOV 73H,77H ;2 n% Z3 E3 x( I
MOV 74H,78H ;
6 j8 P0 F4 _* d* D7 y, aMOV 75H,79H ;
& Z- G' {) a5 k7 W7 ~* \+ eINTT1OUT: POP PSW ;恢复现场; e: B: s- R* ^- l+ I/ N
POP ACC ;
- B2 d, P" R/ }' x4 vRETI ;中断退出, `7 ?+ ^0 F/ x4 Z: V3 R* `- U
FLASH1: JB 01H,FLASH2 ;01H位为1时,转小时熄灭控制% x7 M3 K7 t4 L" G% }
MOV 72H,7AH ;01H位为0时,"熄灭符"数据放入分
4 G5 j5 B8 ^, i* m& YMOV 73H,7AH ;显示单元(72H-73H),将不显示分数据
+ r# q- \, e4 Y" |+ fMOV 74H,78H ;# J! l u0 V( Y2 y+ X3 [
MOV 75H,79H ;
, v8 m* ~, @ p% ?2 L, R) QAJMP INTT1OUT ;转中断退出- k2 c1 o1 ^* T9 X
FLASH2: MOV 72H,76H ;01H位为1时,"熄灭符"数据放入小时
6 b, `7 Q8 N- U, ~& l8 Q3 wMOV 73H,77H ;显示单元(74H-75H),小时数据将不显示0 n$ V Z3 ~- c. O% A5 V
MOV 74H,7AH ;0 A1 \+ e0 U8 i$ k5 r% V
MOV 75H,7AH ;1 @+ r0 V% v! c
AJMP INTT1OUT ;转中断退出2 V7 j* e7 h$ t
;
, D( t& J- ~! `;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;" j+ P) K; ~- n" F3 V/ s
;; 加1子 程 序 ;;; d. K9 f! q; w
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4 z& u5 `9 Q3 L. J: v; P;. L" a1 }; n& J, x! |; \) e
ADD1: MOV A,@R0 ;取当前计时单元数据到A
; U5 {4 \5 D5 QDEC R0 ;指向前一地址+ j9 X* D* I% L6 {) V4 j
SWAP A ;A中数据高四位与低四位交换+ S- H5 w6 h6 N! D1 w% v- K1 C
ORL A,@R0 ;前一地址中数据放入A中低四位& u7 V5 E/ u% Z4 J0 P3 r, ^6 z
ADD A,#01H ;A加1操作9 M5 ~/ }: G# M8 |; L
DA A ;十进制调整! L* X* f# ~2 h1 b+ L [+ ?
MOV R3,A ;移入R3寄存器' l4 c% x6 [) v3 M X
ANL A,#0FH ;高四位变0
, k9 N+ v, e# H# }$ R1 ]MOV @R0,A ;放回前一地址单元0 s; y8 H, X+ {$ y* b2 H, P
MOV A,R3 ;取回R3中暂存数据
4 l* I5 M+ p+ o! r3 V' P) gINC R0 ;指向当前地址单元
% ^ l C6 J; Q' X* ]' zSWAP A ;A中数据高四位与低四位交换; f, g/ b' `- }7 d* p* J# }
ANL A,#0FH ;高四位变0
9 ? Z$ e5 o0 J. iMOV @R0,A ;数据放入当削地址单元中" {/ ]# U+ ?3 I, {
RET ;子程序返回- g' [7 s: x( S: q% R" E
;
$ ~3 t; u2 S' m3 L3 s1 ~3 @0 v8 v;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;. L+ |' }' \% h8 y/ Z8 }! h* A6 \- d
;; 清零程序 ;;+ _/ I6 q+ I- c: A
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7 X$ j3 A% O) t$ N) p;.............$ x4 [0 B- y' A! ~- P
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4 ]$ ~ ?0 [" D+ s;; 时钟调整程序 ;;* a9 F# N" t; q( E0 u1 j
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7 X3 ~( v9 Z" X k! S;当调时按键按下时进入此程序 Y* {* ^6 N# q W
SETMM: cLR ET0 ;关定时器T0中断& _/ O4 z- e6 Y# ]* u
CLR TR0 ;封闭定时器T0
3 G t d% b+ i$ w) B, BLCALL DL1S ;调用1秒延时程序* S% U* e6 ^/ s8 V
JB P3.7,CLOSEDIS ;键按下时间小于1秒,封闭显示(省电)' @4 ]! y( ^- f) r( a/ q. v
MOV R2,#06H ;进入调时状态,赋闪烁定时初值
- |: T' d7 k5 }7 s& I4 hSETB ET1 ;答应T1中断 O1 J% X7 `( a4 d5 P
SETB TR1 ;开启定时器T1" |8 R0 J8 f* }
SET2: JNB P3.7,SET1 ;P3.7口为0(键未开释),等待
" w/ g+ O' |1 R6 @5 l) k6 q' P+ bSETB 00H ;键开释,分调整闪烁标志置1
+ f h* \) Y1 E7 w# jSET4: JB P3.7,SET3 ;等待键按下
) Y* A/ B) u+ t$ K. aLCALL DL05S ;有键按下,延时0.5秒
y* ~% E6 z0 e+ ]& l6 ]+ JJNB P3.7,SETHH ;按下时间大于0.5秒转调小时状态
8 V& U9 d( b5 d0 X9 E5 [3 jMOV R0,#77H ;按下时间小于0.5秒加1分钟操作3 R' D! e; ~& @- ?9 u8 U: x
LCALL ADD1 ;调用加1子程序
4 V- U, ?; [1 cMOV A,R3 ;取调整单元数据) P0 A, O. L" g9 U$ h" U0 B7 d
CLR C ;清进位标志
# m3 k# t! n# V3 V& W5 r. l% g1 ECJNE A,#60H,HHH ;调整单元数据与60比较) G$ i7 J) @0 ~9 g1 M# f
HHH: JC SET4 ;调整单元数据小于60转SET4循环
/ E \: _+ A% A$ ALCALL CLR0 ;调整单元数据大于或即是60时清07 z6 U# E, B! o$ A9 [& F
CLR C ;清进位标志
$ [( `( x6 r: m/ f, cAJMP SET4 ;跳转到SET4循环4 z; [+ }- d/ i+ A8 L. P. o
CLOSEDIS: SETB ET0 ;省电(LED不显示)状态。开T0中断8 H1 R, V. P; j- }
SETB TR0 ;开启T0定时器(开时钟)
7 ]2 v7 j G* @CLOSE: JB P3.7,CLOSE ;无按键按下,等待。
. @- Q5 b( J# C6 kLCALL DISPLAY ;有键按下,调显示子程序延时削抖
! t4 ?$ a' b/ q. N0 `JB P3.7,CLOSE ;是干扰返回CLOSE等待
+ t, y1 ?' H6 g& qWAITH: JNB P3.7,WAITH ;等待键开释
5 N. Y4 g; Q( w" V" ILJMP START1 ;返回主程序(LED数据显示亮)" M, V$ b& r; [
SETHH: CLR 00H ;分闪烁标志清除(进入调小时状态) z% G$ D0 f' A6 ^; f6 w! u
SETHH1: JNB P3.7,SET5 ;等待键开释
: @4 b2 ], r. y$ D* c( \" mSETB 01H ;小时调整标志置1) V% K! L, V& s1 ^4 n! G
SET6: JB P3.7,SET7 ;等待按键按下
3 t' T4 k8 U2 c& E. I" Y" lLCALL DL05S ;有键按下延时0.5秒3 |( _% H$ `9 x1 ? {
JNB P3.7,SETOUT ;按下时间大于0.5秒退出时间调整, Y4 x" w2 e7 s3 ]) w _( t& e
MOV R0,#79H ;按下时间小于0.5秒加1小时操作
" O9 j: @$ ?$ o: z( ^2 P; TLCALL ADD1 ;调加1子程序
6 C: l+ q' h R" YMOV A,R3 ;
9 ?2 C0 v: ~, Q1 sCLR C ;
& Z, g6 f/ `) s# @( D8 E- `7 ]CJNE A,#24H,HOUU ;计时单元数据与24比较
1 h; @+ E# E, _HOUU: JC SET6 ;小于24转SET6循环/ d5 X+ b% y8 Y+ V. E- C* E- \
LCALL CLR0 ;大于或即是24时清0操作
* q# }# B, X. _; Z9 @: R4 w2 l/ g5 b/ C" kAJMP SET6 ;跳转到SET6循环6 \+ S" J' G4 r7 Q1 p
SETOUT: JNB P3.7,SETOUT1 ;调时退出程序。等待键开释
9 B. G$ J' l7 z8 }4 F5 HLCALL DISPLAY ;延时削抖
+ I1 |9 h" P0 A* z$ Z7 eJNB P3.7,SETOUT ;是抖动,返回SETOUT再等待
( {: ^# k' ^8 fCLR 01H ;清调小时标志0 [1 h2 |' s1 v/ ~
CLR 00H ;清调分标志
+ a/ C7 X4 s; t* r7 ACLR 02H ;清闪烁标志( |" J/ A- L4 Y, p2 @8 a
CLR TR1 ;封闭定时器T1$ ?) w) A, I7 R
CLR ET1 ;关定时器T1中断 b. w5 l; F, ~5 i1 S; b
SETB TR0 ;开启定时器T0& k& t1 R% M3 E+ V- i5 G# {) g
SETB ET0 ;开定时器T0中断(计时开始)3 d5 q# {7 W6 R: B6 M
LJMP START1 ;跳回主程序
- \6 |0 c% s. L' M1 PSET1: LCALL DISPLAY ;键开释等待时调用显示程序(调分)) M$ K6 C% i l& x( g, a
AJMP SET2 ;防止键按下时无时钟显示1 ?% x" S9 Q/ _# H( @
SET3: LCALL DISPLAY ;等待调分按键时时钟显示用 Q! T% B8 Z/ h" f: m0 B" `6 c' {. q% r
AJMP SET4
# C( Q2 T5 U7 _9 r5 P" X" z, O) PSET5: LCALL DISPLAY ;键开释等待时调用显示程序(调小时); u, C: n8 w K" C
AJMP SETHH1 ;防止键按下时无时钟显示6 O" g$ {, i; v6 A
SET7: LCALL DISPLAY ;等待调小时按键时时钟显示用- P* N; m9 w! [7 M
AJMP SET67 `9 B# k, X9 S- j8 K! d; m
SETOUT1: LCALL DISPLAY ;退出时钟调整时键开释等待8 B- e& z0 d7 U; x& J9 i M r
AJMP SETOUT ;防止键按下时无时钟显示% k& {3 O7 c$ F
;' @6 u% X9 U `! _# h+ c
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;" R' u! R2 g0 \5 x! o. J5 D( C
;; 显示程序 ;;* l8 I7 t4 L6 z, D. {
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
) D# d* c/ s6 V8 J- g$$$$$$$$$$$$$$$$$$$$$$$$$$$
6 {$ \+ w. k9 l;1MS延时程序,LED显示程序用
- U/ ~. j2 i, V9 T* P+ P0 TDL1MS: MOV R6,#14H2 S Q8 n2 n2 p- f! R5 Z
DL1: MOV R7,#19H) h8 H# @! M6 s& V5 H0 r5 B1 {+ L
DL2: DJNZ R7,DL2. @! J/ u7 \. b) C! U( D
DJNZ R6,DL1. g9 p, H) y# D6 @% B2 f
RET
9 R" K$ D, y% n0 i) e$ w4 [;20MS延时程序,采用调用显示子程序以改善LED的显示闪烁现象- ^% ~" [3 q# {! i0 I
DS20MS: ACALL DISPLAY
- m+ Z; n5 g0 ^* T- O* V: c8 |! yACALL DISPLAY8 B% b* _8 I1 l1 A# w
ACALL DISPLAY
8 r( `" m) ] {! E* ?& E; W, nRET3 t7 J# @) A8 m3 w) }* Q2 \
;延时程序,用作按键时间的长短判定6 C) P+ U4 T9 D _
DL1S: LCALL DL05S3 R2 H: h/ \" [
LCALL DL05S# s+ e0 q- k: `! ?+ V+ H% F3 i# h
RET
- F# b, |/ s9 }* y$ oDL05S: MOV R3,#20H ;8毫秒*32=0.196秒( l6 y$ }+ g1 t" V6 I& t1 [ E
DL05S1: LCALL DISPLAY
, n' M( ~+ Z0 ]+ g9 A0 M6 ~DJNZ R3,DL05S1$ m+ e; |6 L! A$ i& S3 O: f
RET
$ L2 V9 S( X p5 o7 E! Q6 r* REND ;程序结束! V: }( H, I6 o3 ~
|