|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
自作的1602数字时钟(带温度带单片机程序带电路图)
& H% n/ E9 A' `6 B) y" I* k
/ H4 J$ G8 U( ~1 y
; e6 d7 m3 R! Y
; J' ?+ R- E4 U' Y2 m( H- L Z2 S8 H3 n0 i
单片机源程序: | , t) N- b( D4 g E
/ e8 ]. d k1 ?$ \* x' C#include <REG51.H>
) \* t D/ Z. v' x) E6 f#include <intrins.h>* b% q6 c) f8 B4 w ^! h: [
//#include "LCD1602.h"" H0 q6 P/ H' R* o/ X! r5 e9 F
//#include "DS1302.h"5 p9 H0 G; W3 K7 o9 }
#define uint unsigned int
W$ x: D5 c4 a3 r#define uchar unsigned char
! R9 [) b* n$ \7 Z8 l% psbit DS1302_CLK = P1^7; //实时时钟时钟线引脚
; Q. l: c& S- Z* ksbit DS1302_IO = P1^6; //实时时钟数据线引脚 ' x# d4 h! \1 Q7 g9 R
sbit DS1302_RST = P1^5; //实时时钟复位线引脚
8 \1 t# R% ~7 I7 K w5 \% ~; |sbit wireless_1 = P3^0;$ `3 L2 B6 W8 N9 l2 ~+ F
sbit wireless_2 = P3^1;, v& h3 ], {$ {, s) s
sbit wireless_3 = P3^2;
3 y# I2 b7 |. C% G' @sbit wireless_4 = P3^3;
" f D( y. e: [9 ssbit ACC0 = ACC^0;' ?6 O' t5 | r
sbit ACC7 = ACC^7;9 A. S' S, @9 m8 \3 o+ @" p+ q
char hide_sec,hide_min,hide_hour,hide_day,hide_week,hide_month,hide_year; //秒,分,时到日,月,年位闪的计数8 C/ i& V x0 J! t( V
sbit Set = P2^0; //模式切换键* _8 Y% r# F; C( |- X! D
sbit Up = P2^1; //加法按钮; f7 ~/ N- e, p6 v
sbit Down = P2^2; //减法按钮
x" Y9 f/ t, N+ zsbit out = P2^3; //立刻跳出调整模式按钮1 b+ O, C6 L5 W0 R$ E1 k7 K% |
sbit DQ = P1^0; //温度传送数据IO口
0 e0 |; K* p, ]1 C, Ichar done,count,temp,flag,up_flag,down_flag;) P' \, B: G* S# G1 T; ]2 R) _( _
uchar temp_value; //温度值
- d, ^6 E6 `0 O' V- c( t: Yuchar TempBuffer[5],week_value[2];
- z9 W6 o0 z$ H: D8 E% q
6 Z& d) R9 [/ Q& z; T4 i! U2 T/ q- S& {& O3 i4 R# L
void show_time(); //液晶显示程序* M6 C1 ~0 T, ~8 x2 j
/***********1602液晶显示部分子程序****************/
0 f! z9 |1 A& W& a1 P0 w4 W6 l! c( |
) k9 H, U/ m. V7 ~! P+ A- Y3 h
9 f; X2 {, |3 [) Q//Port Definitions**********************************************************
& ]+ T0 e( e9 r( X5 n# ksbit LcdRs = P2^5;
& V2 C: L" N8 I' [; ?: hsbit LcdRw = P2^6;
* D: P0 e) S4 S2 ?' \sbit LcdEn = P2^7;( c" U4 R9 b: ]! _8 d: Q
sfr DBPort = 0x80; //P0=0x80,P1=0x90,P2=0xA0,P3=0xB0.数据端口
, y2 k2 T. ^% s, Y4 C; h3 d% s6 U7 o7 x t
//内部等待函数**************************************************************************
7 K) T9 b8 S! c, ~% _5 aunsigned char LCD_Wait(void)( @3 e1 {2 |% y
{, z [' G0 l4 a0 i
LcdRs=0;% F B, V% H! W0 B/ @
LcdRw=1; _nop_();5 X" o; P4 O" n
LcdEn=1; _nop_();, f( i1 S% q& @* U: x( T
* S- e4 ~, L1 |8 K& g LcdEn=0;
- ?" Q' S" x: b/ j& g* p. [ return DBPort;
! D/ T7 y* ^; }+ j}4 y6 T, ` N: I0 E- k8 r
//向LCD写入命令或数据************************************************************4 r L; P( b+ H* \: Q! \ i0 d
#define LCD_COMMAND 0 // Command l' K, T8 ~1 h- B* |9 J
#define LCD_DATA 1 // Data! x9 P$ _3 X1 K% A9 ]2 r/ u
#define LCD_CLEAR_SCREEN 0x01 // 清屏( w `5 D- M2 h( u% ?
#define LCD_HOMING 0x02 // 光标返回原点
2 L* g8 A# X" i3 y5 Rvoid LCD_Write(bit style, unsigned char input)2 ^" U! S3 n% U# r7 b. Z3 h
{
/ H+ D5 H, l5 b% B: t L9 F LcdEn=0;
5 `# D+ W8 N% _! f1 ?( _( d v LcdRs=style;
. s* w2 M: U5 ~5 v, f$ H. { LcdRw=0; _nop_();9 a4 J+ ~3 _; {: L W$ h* m
DBPort=input; _nop_();//注意顺序) B& K8 w; t( M# M
LcdEn=1; _nop_();//注意顺序
% p* z0 i7 Q, i& v: v; J9 C LcdEn=0; _nop_();
. M& Y1 o5 k8 g' ` LCD_Wait();
$ _) f7 Q! Q( `: B9 _! A3 A) N! r}3 B; [# @2 e' v! t# x
3 Z- x2 V1 I( E" ?& L//设置显示模式************************************************************
* V% o4 b7 y2 O: s( k. \: L9 x#define LCD_SHOW 0x04 //显示开
, L- J" x5 q2 J3 |2 v4 G. s7 p# Z#define LCD_HIDE 0x00 //显示关 4 d5 ^* |8 I: X4 A, R% r8 D
, ]9 O; [0 W$ A. ?: M#define LCD_CURSOR 0x02 //显示光标
4 U/ _( w* P5 l- H/ ?4 y1 q#define LCD_NO_CURSOR 0x00 //无光标
. p; a, H( ~1 p4 ?( b- D- S" }1 m7 c7 i9 N
#define LCD_FLASH 0x01 //光标闪动: T8 g7 K. W/ ^, {% _
#define LCD_NO_FLASH 0x00 //光标不闪动/ u: {- x7 b0 Q
# x0 m. H& {5 Y* l1 h
void LCD_SetDisplay(unsigned char DisplayMode)
: L# y3 l1 Q1 Z, q4 M{
/ c& a/ u5 Z2 a* ?. M9 q LCD_Write(LCD_COMMAND, 0x08|DisplayMode); - C* c' n' p( b# m1 l" D3 p6 P
}+ d8 `' Y! E `! p) N
/ e3 b2 ^4 H: s! F- O4 R//设置输入模式************************************************************1 v% ^* w0 x( Q. L1 ^: {
#define LCD_AC_UP 0x02
" B8 O" p( v+ H) E, J8 V#define LCD_AC_DOWN 0x00 // default
- a- B3 t' p( o: R, j
) Y3 m, n+ i6 ~& _- g* @#define LCD_MOVE 0x01 // 画面可平移. W3 v H# H* \; j& u' s; E' b' g1 H
#define LCD_NO_MOVE 0x00 //default. p$ C5 U, ?7 n5 J
& `( f2 S) c% x3 U3 vvoid LCD_SetInput(unsigned char InputMode)$ I3 G5 j/ S" E, N" \
{
1 u; E0 M p( M; @. x LCD_Write(LCD_COMMAND, 0x04|InputMode);
2 k" \1 [8 m* L( F% v2 D}
! P: h2 r9 E, O" z& i; H
( T. B; X( E8 k5 O8 a//初始化LCD************************************************************2 c8 |! M% j& r, `; \: J
void LCD_Initial(). R; M; P$ b) y, T0 }8 b! J
{
( n9 E9 |) p5 [4 o# D LcdEn=0;
^4 v! P( u$ j/ B1 ?5 J LCD_Write(LCD_COMMAND,0x38); //8位数据端口,2行显示,5*7点阵
- l/ b* |7 R+ B2 U! L1 e: a# ` LCD_Write(LCD_COMMAND,0x38);
* u e/ t! J' A6 h LCD_SetDisplay(LCD_SHOW|LCD_NO_CURSOR); //开启显示, 无光标6 K4 V6 D/ }& r, d d3 E+ T' Q
LCD_Write(LCD_COMMAND,LCD_CLEAR_SCREEN); //清屏( q% q, r" P( C @0 X0 d+ t" F7 k# S
LCD_SetInput(LCD_AC_UP|LCD_NO_MOVE); //AC递增, 画面不动1 y' Y! a3 v7 ]
}
# Q) b' d0 K9 e3 _' v6 P% k) P) \ x6 H/ y) f
//液晶字符输入的位置************************
, C9 N' u1 \" e- Pvoid GotoXY(unsigned char x, unsigned char y)
+ @+ V" H6 L$ a% @7 S. n! S{2 } C1 O/ S- b& ]5 J6 Y
if(y==0)4 V( |0 n% _) z7 H3 Z! ~
LCD_Write(LCD_COMMAND,0x80|x);
& q- Y# b. P* H( c' h7 \ Y2 I2 z if(y==1)6 T0 ]' m: B( \* U7 N
LCD_Write(LCD_COMMAND,0x80|(x-0x40));* i5 O- }5 v) I+ `, t
}
- P7 o( {0 b" y- k. K5 p6 T' K7 k; l& K+ X: S1 B2 z% P
//将字符输出到液晶显示. a4 i' d$ f2 m' D) Y5 X
void Print(unsigned char *str)
8 O2 ]8 ~. q' i- l$ @* J6 V{7 @" W/ s6 ^) V, a4 h3 i# |
while(*str!='\0')
: x4 N1 s+ R0 [ {$ Y4 @- a' X: B2 @: i& g" C# ^
LCD_Write(LCD_DATA,*str);
( o# ?7 g$ p9 r& U @ str++;( q0 L5 r* R& h5 i& Y1 u8 |" X
}& c8 a1 k1 q# o
}0 y* @/ _% y5 G4 b+ |% M
% T8 `, B) |( g" J' l3 k$ y V
& |1 i# ?5 x6 Y1 B0 ^, u2 f( n8 M/ u4 Q) b. d' S4 Y
Y5 t+ |) a8 Y2 S4 Q
* F4 P( T8 E) T4 e1 N. L1 O
; L9 ^$ n) {1 T. r( c9 Y+ `/***********DS1302时钟部分子程序******************/. r) } T1 a# }1 K6 ^
typedef struct __SYSTEMTIME__
/ b9 L! s7 E5 d' t( o{: l" r5 ?3 |7 v7 ` K
unsigned char Second;+ g5 n9 N; |) r; \* v
unsigned char Minute;
) W! Z; d" ?2 Y2 ?. ~) S' G unsigned char Hour;& X' g0 _5 z+ h* d% X1 k2 F' \
unsigned char Week;
. }$ b8 f5 J0 o; h: r unsigned char Day;7 n, S; z8 _$ A5 U9 I! m3 @0 x$ x
unsigned char Month;
7 E' Z9 [& I; ?) ^! X1 X- l unsigned char Year;
6 z2 {6 F% x% n# O unsigned char DateString[11];# Q3 n& h# A& m! G! G
unsigned char TimeString[9];$ c. l2 p# g- a5 d/ s! @( b) d! p0 ?
}SYSTEMTIME; //定义的时间类型6 q( N5 ^! v6 T; m% y9 y, U
SYSTEMTIME CurrentTime;* D/ x/ v0 N% `% D8 D; R
5 @9 W! B' r1 g$ a0 _1 S- s: Y+ Y
: l8 O# b: M2 Q/ T
#define AM(X) X+ V; b& K& i }5 W
#define PM(X) (X+12) // 转成24小时制! A6 s. U5 D, J, P" ]# O* f+ J$ G) B
#define DS1302_SECOND 0x80 //时钟芯片的寄存器位置,存放时间0 r: T8 Q( v8 K' b3 e5 ]. A
#define DS1302_MINUTE 0x821 t: p5 |; G% ^3 Z/ }# B W' I
#define DS1302_HOUR 0x84
P) A$ f2 Z3 r+ j#define DS1302_WEEK 0x8A ]7 X; l9 C, V4 a
#define DS1302_DAY 0x86( x S/ j. o, U" Y5 u
#define DS1302_MONTH 0x885 n7 d; k: [$ {) u
#define DS1302_YEAR 0x8C . p+ \7 k1 y9 i
P0 m. d8 b: I, B! K$ T% `; }( B* ? L
void DS1302InputByte(unsigned char d) //实时时钟写入一字节(内部函数)
! P2 _/ I1 A3 L4 ?# S3 V{ 1 L! |2 g0 m2 d# n" |/ T
unsigned char i;" D9 g- l6 M1 m. {
ACC = d;/ y1 t. t) N h* ~/ o. o( S
for(i=8; i>0; i--)
9 x0 o! x5 e! U: H/ K {7 N4 t6 z; s! Z& Q- P* \& ^4 a
DS1302_IO = ACC0; //相当于汇编中的 RRC
% }( _1 ]! J9 X0 Z7 A) f DS1302_CLK = 1;
" R+ ~1 G) N4 B! X DS1302_CLK = 0;3 I: Q/ } _5 l
ACC = ACC >> 1;
' t B! @( c. [! ]& X* V- [ } ( B3 P: U1 p8 K# Z* O0 ]
}( |9 P# g: U: J) a& Q+ |
( l% K4 k* z6 S: B7 Cunsigned char DS1302OutputByte(void) //实时时钟读取一字节(内部函数)* \5 E9 X( l) m B
{
' O. [/ I, P9 v& P! b unsigned char i;
: R2 S$ z& G0 z for(i=8; i>0; i--)
6 t6 _; r* E/ U9 y3 w {
# O' G i6 j' w x; v% n: H ACC = ACC >>1; //相当于汇编中的 RRC ' `. i* j2 L- u8 [$ e( B9 T; @
ACC7 = DS1302_IO;2 _) ]' o8 i6 }- c# [- p
DS1302_CLK = 1;
8 K) E' Y. m2 | DS1302_CLK = 0;
% D1 V/ D& T$ O/ R# n }) ^: A+ ~ } 3 M4 s/ k/ w0 n' H3 p4 Q: P$ Y
return(ACC);
( J% ?: L$ i3 b4 Y F}8 s: y4 u, p' B: G) p5 ]- {3 x
8 [4 N6 x5 q( Y% |& S& c0 ivoid Write1302(unsigned char ucAddr, unsigned char ucDa) //ucAddr: DS1302地址, ucData: 要写的数据& z7 \8 z& z# ^# S% Y
{$ W# u8 ?& i: ]& I* ]3 ?2 E
DS1302_RST = 0;- j3 n' k( \ B
DS1302_CLK = 0;" f+ L( a+ G8 k3 W1 S
DS1302_RST = 1;
6 ]* v# P [3 R DS1302InputByte(ucAddr); // 地址,命令
7 K1 H0 \- \0 C( E DS1302InputByte(ucDa); // 写1Byte数据
+ e# U3 ^( Q2 [# D5 M DS1302_CLK = 1;
8 u5 R6 w8 M, s0 u DS1302_RST = 0;( z$ ?8 w" W7 j3 ]' J6 z, p; s
} " Z0 d4 c# `* s$ ~0 Y8 X
( R' n' \ x" V/ r2 a6 ?unsigned char Read1302(unsigned char ucAddr) //读取DS1302某地址的数据
+ n& S+ t9 R! Y8 Y( _5 O; c7 [{
# O) q: {' x ?/ d* i unsigned char ucData;
% G* f! m. } u DS1302_RST = 0;3 f0 L6 X5 [7 z0 U8 v' R3 W
DS1302_CLK = 0;/ z3 a1 _% S0 m* F {
DS1302_RST = 1;
3 Y0 v( i9 x8 {& I: Q* ` DS1302InputByte(ucAddr|0x01); // 地址,命令
3 w2 k/ v; | i5 w2 F ucData = DS1302OutputByte(); // 读1Byte数据
8 k$ H4 O7 I) D6 a% e DS1302_CLK = 1;
/ A4 u! N' Z! e# X/ P3 T DS1302_RST = 0;# a( C1 x2 H% f( {. k
return(ucData);
: { z* N5 H& X3 w' _}: t8 E8 \( q: |4 B: `( q: E: X( r
/ @9 |! |, P: Q5 S+ M; Q1 w$ C$ q, }5 J2 w4 p' c' y- d/ `4 X
! `" [: J( S5 z O5 G5 pvoid DS1302_GetTime(SYSTEMTIME *Time) //获取时钟芯片的时钟数据到自定义的结构型数组, F1 Z5 M$ X8 a( [
{8 u& J, J7 z4 J- o6 }$ s5 G) _
unsigned char ReadValue;
( h! B# |3 m1 e/ ~ ReadValue = Read1302(DS1302_SECOND);
# \3 g! K4 }2 n6 ^5 Y% m Time->Second = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
% L: v; G8 a6 `; e9 R3 Z ReadValue = Read1302(DS1302_MINUTE);) v" N1 t, X' b/ S; a- l
Time->Minute = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); J) b2 P- i' {* O
ReadValue = Read1302(DS1302_HOUR);7 U! _/ u) E- h1 h) V* z' d
Time->Hour = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
1 ~3 r% \' i1 Z M ReadValue = Read1302(DS1302_DAY);5 q( z. K" o" ?7 ?3 L4 V: L( c7 B) }
Time->Day = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
2 A, C4 k% d# C( D ReadValue = Read1302(DS1302_WEEK);
6 [% ^( V( j, Y6 ~3 H Time->Week = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
4 H1 f0 @+ ^# D# ^ l% A! f: J4 C ReadValue = Read1302(DS1302_MONTH);
# a( b* P0 c- t$ J( W Time->Month = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
9 n3 U& s8 q& b ReadValue = Read1302(DS1302_YEAR);
4 C# Z ], i6 _6 r+ c Time->Year = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); 1 I7 P$ l( c1 n
}
0 D; ~3 n p) D9 b2 _* F+ ^- r/ m
5 D' L+ W0 Y# Ivoid DateToStr(SYSTEMTIME *Time) //将时间年,月,日,星期数据转换成液晶显示字符串,放到数组里DateString[]
x9 \% H$ T" x* U, m{ if(hide_year<2) //这里的if,else语句都是判断位闪烁,<2显示数据,>2就不显示,输出字符串为 2007/07/22: A0 }( d/ s2 R0 W! O; A: ^
{
6 I. I3 N- p: I, r$ ]7 g2 \ Time->DateString[0] = '2';
3 ^ ]5 M* s- Y' S& j- K: n Time->DateString[1] = '0';
8 h0 I9 l1 h$ K! f! T Time->DateString[2] = Time->Year/10 + '0';
; u4 }( o$ N( B5 D4 c Time->DateString[3] = Time->Year%10 + '0';
/ I. F7 { ?8 U* M5 g+ K }
2 [! M2 V f6 M& ~ T( Y+ e; y" H else
7 z" y; o$ o1 S( J5 L2 h {
5 c% }& f) c8 F; G ^& r Time->DateString[0] = ' ';1 j: D9 e8 s/ }' @; h
Time->DateString[1] = ' ';
& O/ h1 S8 J; ?$ I Time->DateString[2] = ' ';6 {6 t4 Q) o- Q j$ L
Time->DateString[3] = ' ';
5 m& p7 A" m8 t8 P! I1 ]" i% C( w }
, f4 J( H, \8 N( q% p* K1 C Time->DateString[4] = '/';, e& g. K4 Y1 r e
if(hide_month<2)
7 n+ V- K$ G9 f% s2 D2 A% a8 \ {
$ e) [, H0 _- ~ ^* P Time->DateString[5] = Time->Month/10 + '0'; J- ^3 J/ T4 |
Time->DateString[6] = Time->Month%10 + '0';
* V U$ Z- Y$ s) I6 e6 k2 F# z1 q/ ] }
8 D9 K2 s+ I: V, ~8 O7 g' F; { else
7 ^) W) w7 c5 c% J6 b {* h! {4 ~& G/ X
Time->DateString[5] = ' ';
) ?6 ~ o3 N6 B4 P, b Time->DateString[6] = ' ';" v* y ]. C8 r! P) h
}
8 V s7 k; L# d% }/ k8 b. B Time->DateString[7] = '/';) M8 t# h. l& `$ m, n3 \
if(hide_day<2)
, n' P3 B9 E3 b0 B: k {4 \: ? j+ N7 N2 {' z' W
Time->DateString[8] = Time->Day/10 + '0';
; L: t9 u" W6 [- n3 r7 Y Time->DateString[9] = Time->Day%10 + '0';
2 i$ L# F6 v: F4 l4 X* ?3 y, a }
0 `2 H. c( j& ~- g0 s else0 A% x9 h+ @: \6 ?3 f# w
{, p: o' I' l; }! o9 {* I
Time->DateString[8] = ' ';
5 o Y+ a; a2 W$ g+ u8 T/ B1 c7 j Time->DateString[9] = ' ';
& R/ p' ?% S! ]' d- z% x }8 ]' e2 P- J: ?9 t
if(hide_week<2)
7 d. { B- r" P+ `% e {- d! c9 ^3 z" Q: b( ^, z; {6 z
week_value[0] = Time->Week%10 + '0'; //星期的数据另外放到 week_value[]数组里,跟年,月,日的分开存放,因为等一下要在最后显示+ i2 E2 V5 G7 |( f( Q7 \
}4 j8 ]: W% \( |: n% n
else
% [% o2 B' e0 Y {
- w" I9 a. O0 f4 M5 h week_value[0] = ' ';
2 l! N @5 c; h% z/ v" D }( y: K* o; g, x5 A; h5 z
week_value[1] = '\0';
8 r0 {5 M/ B8 {8 R* \2 a" N. f, h& E7 `0 w' H/ D
Time->DateString[10] = '\0'; //字符串末尾加 '\0' ,判断结束字符( Y- d! c) [4 ^6 o. P
}
! Y+ d6 z, d5 w
; ?2 J( B% j3 E& nvoid TimeToStr(SYSTEMTIME *Time) //将时,分,秒数据转换成液晶显示字符放到数组 TimeString[];
9 q" C) b! c2 M{ if(hide_hour<2)
- o1 v# I4 i4 ^: `9 J1 e0 {- A { d% }, z9 C: e
Time->TimeString[0] = Time->Hour/10 + '0';
$ u7 v" g4 X, e) ]( p Time->TimeString[1] = Time->Hour%10 + '0';: ~, O0 g, R( v( t
}: E# O o5 f$ G0 A. s, w
else1 a6 d+ |; } I% x. [
{
* o4 d1 m6 Y7 a/ } Time->TimeString[0] = ' ';
5 k/ R& Z2 K7 }2 |$ X/ P Time->TimeString[1] = ' ';
! x2 ]3 l. K9 }, {7 I& b1 J9 e& q9 _ }' H0 b( n7 j+ N6 V4 L% y/ y8 q' N
Time->TimeString[2] = ':';
3 u4 N( U V, h if(hide_min<2) n. Z c( c7 u: D
{
0 N/ d* `: a! y* p Time->TimeString[3] = Time->Minute/10 + '0';9 n9 n2 `& K( a' ~& p m
Time->TimeString[4] = Time->Minute%10 + '0';( x; i# a/ N; U
}3 r: ^: T$ t7 }
else$ N4 }$ d' A7 B, b7 p
{$ A) H' q1 G1 p# O
Time->TimeString[3] = ' ';. v" U2 R4 P& A' U
Time->TimeString[4] = ' ';1 o' K! v* r- i/ s' X( u9 S
}! X$ D: t/ p9 b' F0 y: _) J
Time->TimeString[5] = ':';/ m9 _- O% ^0 S
/ `2 H4 b& v5 |+ ~; e& Q
1 Z/ y* Z0 a5 O6 v& w…………限于本文篇幅 余下代码请从论坛下载附件…………1 g0 W2 ~5 W) d+ Q1 U0 Y
; F5 v0 q9 T; E
: k9 C- w3 G( y! l8 n" _; @, h
|
|