|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
电子钟(可调节时间)
) I8 z% E1 O% d' m: w7 d e' }, O* o, y
) l8 |, o7 W9 j- J: X
#include<reg52.h>, d; Z( T' M: F9 s2 Y8 _
sbit KEY_ADD=P3^4; //定义按键输入端口
7 d d$ G9 q" ^- Q6 T$ c: nsbit KEY_DEC=P3^5;5 j$ m& A& U6 F$ z$ R5 p7 i
sbit k1=P3^6;! K* k! p# S1 g# f9 E% Z
sbit k2=P3^7;
, h) }9 t- Q! O/ B* [sbit k3=P3^4;' m' \0 `( g% |% a4 ?* Q
sbit km=P2^0;
8 e% N1 m( N' ?5 ~" _: I7 w6 _# ?. j7 t& R
#define DataPort P0 //定义数据端口 程序中遇到DataPort 则用P0 替换
6 |/ O; n5 z; W( E8 y7 B; xsbit LATCH1=P2^6;//定义锁存使能端口 段锁存
0 _0 [/ }3 c1 jsbit LATCH2=P2^7;// 位锁存 j* Y2 k( b. _/ c
- ]0 v8 m# g5 y7 {
unsigned char code dofly_DuanMa[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};// 显示段码值0~9% p* Q" ?# @5 A1 N1 {
unsigned char code dofly_WeiMa[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//分别对应相应的数码管点亮,即位码
1 b' J- z* ~7 Y' Dunsigned char TempData[8]; //存储显示值的全局变量% I( z$ R2 m! w
0 G6 \9 x9 B4 [. R) [3 J; c9 e
char h,m,s; //时分秒
! A' ?! N# e# t7 p. kunsigned char i;1 q7 Y6 B4 |. l- F. j
3 B! b, Y! c% Nvoid DelayUs2x(unsigned char t);//函数声明
/ k6 {) b7 x; o& x+ pvoid DelayMs(unsigned char t);; M8 l5 t; L7 H( o; U- B [- a
void Display(unsigned char FirstBit,unsigned char Num);
8 |+ o& s- k/ s% P6 D" G, L5 zvoid Init_Timer0(void);
/ f/ e3 S- i* U2 F" ?/*------------------------------------------------
$ k% s2 m$ q" I; ~& Y 主函数5 h, |/ J, ?$ y( G7 w6 D* o. P
------------------------------------------------*/
: Y! B4 n# I$ [; avoid main (void)
4 @: ^ L. F* L7 ? I% K$ q{
* i& A9 I) g$ y) H4 j unsigned char num=0; $ [8 }- Q% n) G( b* Y6 ^
KEY_ADD=1; //按键输入端口电平置高
8 x2 b) B; ^0 r KEY_DEC=1;
, P/ F' Q* E5 z% Z) M Init_Timer0();
- Z. _+ F6 W9 \, I$ l/ X
1 e9 I1 J" J6 ~ while (1) //主循环
$ F' P) P _. v% t {; u* w! ~0 R2 @
if(!KEY_ADD) //如果检测到低电平,说明按键按下
# d; m2 M0 K4 @' H1 { {
9 G# A9 q1 w2 R k DelayMs(10); //延时去抖,一般10-20ms
7 b! }3 G$ a1 I if(!KEY_ADD) //再次确认按键是否按下,没有按下则退出
. f$ d( y: C$ Y. D' {" I {
$ E1 G( W x8 m/ s/ l5 w W$ y while(!KEY_ADD);//如果确认按下按键等待按键释放,没有释放则一直执行数码管扫描,防止闪烁
6 O+ A3 c! o& ?! _3 w) } {
+ Q/ o2 I' ]& Q // if(num<99) //加操作
" z# y; c4 [& Q // num++;
) E3 V7 Q6 N0 B9 i; G3 \ h++;% p4 s) M) w+ q9 L$ Q/ M# u
if(h==24); \: }. v' l$ r/ R
h=0;
3 b3 x+ y( b# v% M1 d, [9 o for(i=0;i<30;i++)3 T2 e* J I# l$ U$ U& e
{# b! z, E8 p( K' k$ F
km=!km;
; V1 O! o% b5 C3 V DelayMs(3);' R: V1 _( Y5 m7 ~9 ~. a
}, `* {) n# G+ ^
}6 V/ w0 M9 N* T& I9 L/ Q
}
% z, k+ c2 Z8 I9 H& B }
4 G$ H: x# e) ~8 I b$ f$ b$ m% W. b5 L' R8 ?% A$ }
if(!KEY_DEC) //如果检测到低电平,说明按键按下
, f' \3 s6 k0 V3 S; C) g {
( U( d+ }( g" l# R1 P/ ?2 k+ n DelayMs(10); //延时去抖,一般10-20ms; K. _* e! e. X" q4 ?+ ^: d
if(!KEY_DEC) //再次确认按键是否按下,没有按下则退出
/ K% T' u4 u& @' ^# S, @* a {9 K, O8 D# Z! }8 v: h+ y
while(!KEY_DEC);//如果确认按下按键等待按键释放,没有释放则一直执行数码管扫描,防止闪烁: l( x: M) s" L8 `3 r* u* g$ l
{+ f4 G; @: L7 ~. o% A! a+ a2 e& o
// if(num>0) //减操作' F! f7 H. l6 f
// num--;/ D+ {8 o( J2 V1 `4 }7 {
h--;
& C, S+ f$ D8 Q9 { if(h==-1)
4 D" M) t; L. ~6 n. w+ h h=23;! L6 ~: |6 {# F7 b$ |5 j
km=!km;1 k; R0 D! }, _
DelayMs(20);* l; i7 q- [7 I
for(i=0;i<30;i++)6 R% U2 c" e. n( f
{
, w9 D/ E1 V" N2 Q6 M% J' [ km=!km;
6 F, F/ C. d3 d1 E6 d' B DelayMs(3);
- S2 X$ q P5 s; r" L5 d }
G N p) c6 V6 b9 r. B }. N: N! s6 b& K3 Q* ?9 j
}0 ~/ Y/ j5 J5 H- \$ {5 B5 G1 |+ C
}0 r1 q" a- n0 x2 c6 I+ v
if(!k1) //如果检测到低电平,说明按键按下% s9 l+ }: V6 w: |" c
{' f) L$ W; ?/ e3 Z6 ~& f/ k3 N) c
DelayMs(10); //延时去抖,一般10-20ms
9 _6 J- Y$ _) x1 t if(!k1) //再次确认按键是否按下,没有按下则退出
/ d1 c8 T& H; ^2 l6 o: o {7 ]" _* ~9 f$ J k3 Y
while(!k1);//如果确认按下按键等待按键释放,没有释放则一直执行数码管扫描,防止闪烁
' }- D2 V; a( i) O& f {
8 I9 N; D1 ` c5 o1 j m++;; J6 \7 E* _, q. P, O7 l! p. A( `2 n
if(m==60)
- w7 G3 G5 h& X) V m=0;
* c0 Z( j" Z0 O0 F; U5 F W for(i=0;i<30;i++)+ e: S3 @/ ~$ }. Q2 Q8 o) P
{, C, `0 d$ E) z
km=!km;% V6 H' p# _% x
DelayMs(3); t: \1 T) ?& C7 z6 e: O7 X
}
8 v, v0 X) w5 _ }7 u. l7 E4 `2 s0 M( Z
}
( \- L f5 X+ m) O/ ^4 l }
* H% a# X' k5 q8 I/ `& k( g$ [7 W4 O4 V, O2 d3 W
if(!k2) //如果检测到低电平,说明按键按下8 }$ b/ \( k3 W8 e& M
{
# H5 K/ |2 {9 |# D) e5 n DelayMs(10); //延时去抖,一般10-20ms
( d$ ]) b% A# I9 l if(!k2) //再次确认按键是否按下,没有按下则退出
6 a0 d) C0 L9 a* R1 A7 Z {+ z* U3 `) m. O# U8 k% C% d
while(!k2);//如果确认按下按键等待按键释放,没有释放则一直执行数码管扫描,防止闪烁% h9 w6 b* Z6 T1 v# j6 |
{9 ?0 c" L8 D% W. D: P( I
m--;
8 F2 ?+ S9 g# }" L/ X if(m==-1), r [9 b9 a) Y4 A. C- G
m=59;
: K0 _/ g% V0 W5 t; ]1 Y; w. } for(i=0;i<30;i++)
! P" \* f) A% j5 d- f2 [# O {8 p7 l h& H- `9 Z* d; ^- X
km=!km;
7 ?: x1 u( E- h0 X# D- Y1 V DelayMs(3);8 P/ y. y2 \- ^8 S8 J( i% `
}
* ]: }* o& H d ]( I6 o }1 N) ^' w1 }+ B/ e P! }4 ?3 h; S
}# W5 ^& |& O/ ^) @3 d% r
}
8 c& Z7 ^" `# N; H* U, |7 z0 [; i
$ m. q6 a5 x3 B# z+ ], D1 b" }// if(!k3)1 M' u+ l$ ^# R" v) H- ~
// {
6 R% M3 d& j: O" l; {// DelayMs(10);* [% R- J. E: ?0 ]4 k# S8 N
// if(!k3)
; Y% C/ p: g9 N& k( X// {
; W) M6 {( D5 P* d; Q# s// while(!k3);
4 v4 G2 w* Q. ~$ S4 D v3 q// s3num++;- [6 s, A0 v: T* r B2 d1 u- z
// TR0=0;
$ V5 R |$ a/ v" q7 A//
/ [1 O: [1 y/ l6 m1 R; A/ B8 _! {// if(s3num==2)( A E3 H% u: r F: W, t) b0 |
// {3 p% A; f; ]: s( m' h
// TR0=1; [) L; E% m5 Z" [2 K
// s3num=0;" _* H* ^# X" C. I
// }
& ?! s+ b% A8 M" a! G// }2 M# c" Y+ a \) {2 C B2 N8 d" ~
// }
$ H5 r- {7 n% h8 } k& S// TempData[0]=dofly_DuanMa[num/10];//分解显示信息,如要显示68,则68/10=6 68%10=8 6 h; q+ A& p5 \
// TempData[1]=dofly_DuanMa[num%10];
3 F" k: G8 |' \9 ^// Display(0,8); //显示全部8位0 Y6 K7 V4 `' t, k
// //主循环中添加其他需要一直工作的程序9 x$ L( ?; @$ G) {1 G) r
TempData[0]=dofly_DuanMa[h/10];. Z; }# R2 v; ~) w& S( B* q- h0 @
TempData[1]=dofly_DuanMa[h%10];5 m* S7 r5 J3 t$ U1 e/ [
TempData[2]=0x40;% ^2 C7 [9 V5 _/ E- S
TempData[3]=dofly_DuanMa[m/10];
" C+ R# n& A& ~: i. e; y! m% N TempData[4]=dofly_DuanMa[m%10];
b+ [# U) L6 }. ]& R2 p TempData[5]=0x40;
$ n& v2 {) j2 ^) m9 h TempData[6]=dofly_DuanMa[s/10];) n* o- V) f/ L7 e
TempData[7]=dofly_DuanMa[s%10];
; d* F3 l* I. O
* a, o+ c, d' |' t* ] }7 f# ]' S. j7 m$ f4 {: u! P3 ^9 F
}
, J, O, I8 x6 Z& t5 K6 V/*------------------------------------------------
' y' B6 l/ d: q4 ^# u& buS延时函数,含有输入参数 unsigned char t,无返回值+ I. d1 L" t( e. ]5 x
unsigned char 是定义无符号字符变量,其值的范围是) f N/ U" A+ M% {, m
0~255 这里使用晶振12M,精确延时请使用汇编,大致延时3 |2 S+ y6 _; [7 E$ E* A- O* q1 m& q
长度如下 T=tx2+5 uS 2 y) \+ q s7 R
------------------------------------------------*/! T2 H! A$ r. l- y; m. c4 h
void DelayUs2x(unsigned char t)9 w4 o3 w. ?7 q
{ " ]) b% ^& Y$ N+ `' c% E
while(--t);( m0 t5 ^3 ]+ z/ z: E
}
, U% |+ R- d& v) }/*------------------------------------------------
; ~( r# ^" U" a/ O9 m4 g5 s+ ~mS延时函数,含有输入参数 unsigned char t,无返回值
9 ~3 V! w( r, s$ t, |# P8 a# N# Uunsigned char 是定义无符号字符变量,其值的范围是. F$ _9 j5 Q8 T P& J
0~255 这里使用晶振12M,精确延时请使用汇编
$ k% L% i5 R3 w! f4 ^0 k [" u------------------------------------------------*/
' O( t" M) w( I% uvoid DelayMs(unsigned char t)$ A1 ] C: D% U6 ]- F
{" G* }8 J9 Y% h
' z: s' N; ~$ q# m9 j7 k' N7 v
while(t--)
% L6 l/ {0 J8 Z+ Q9 G8 z3 Z+ b{
; o* ] j$ Q4 q1 p //大致延时1mS
. k+ M" x. a) z. c1 |5 E DelayUs2x(245);
% `5 k- u; Q' F$ e( S Z) D* ~ DelayUs2x(245);3 z4 E, |' k7 A w7 ], n$ |. o* p
}
+ @' R0 l/ o- }+ W}
7 f0 c) C1 a) O$ |; F. \1 n/*------------------------------------------------* S0 a" v0 l9 U! J* y1 S5 o
显示函数,用于动态扫描数码管) x' @$ P" ]# n" o6 R* c( X
输入参数 FirstBit 表示需要显示的第一位,如赋值2表示从第三个数码管开始显示" E* A* H3 z2 t) s& h8 y7 ^9 F
如输入0表示从第一个显示。
& @; r: o* d! T/ m9 K! T0 j% jNum表示需要显示的位数,如需要显示99两位数值则该值输入2
; B0 V, X: F- o5 x7 ^0 }5 l------------------------------------------------*/
) @7 P) p, b+ p" A4 ^8 G& S. Lvoid Display(unsigned char FirstBit,unsigned char Num)8 j7 _2 S7 f! Z8 `9 @+ ?* V
{
$ Q6 b: j; ]# Y7 V/ } h% g static unsigned char i=0;! T; I/ U" w' K; A3 z8 n( z5 }* m
' n) l, i/ Y6 b, c, |7 _: v
: n+ Y* ]' d/ a. k7 }3 n DataPort=0; //清空数据,防止有交替重影/ I( I Z, G* o
LATCH1=1; //段锁存2 U7 t( H' D' g& C
LATCH1=0;
# ?. D5 p/ F0 ?2 ~
3 {7 A- E+ Z; }% A: H" B DataPort=dofly_WeiMa[i+FirstBit]; //取位码 ' a# W; d- ~: ?- b; g7 |
LATCH2=1; //位锁存
6 |$ x4 `% D* A" I( i, {% L LATCH2=0;
3 u( ]7 `- B; b( \6 D# W9 h9 c7 F- j% c& X/ e. A) k5 X& i
DataPort=TempData; //取显示数据,段码& n5 e8 b& i4 r+ _, e( P2 R9 L: t
LATCH1=1; //段锁存0 c, U, Y% W5 H5 Q& ]7 k) N( \) Q
LATCH1=0;
2 S I. M) |9 B$ P3 w
) C* h% ]: a+ w+ @9 i i++;% F1 j. }2 E# J7 k/ a
if(i==Num)
3 s+ P4 A6 r, P/ X i=0;: P; A3 P4 \% F, H5 v a
Z9 N' c) O0 z
$ i& h" k- w, C. V% E7 K) `) ~}
q" K" n6 v) c6 c- V+ b* t/*------------------------------------------------2 w5 M9 D# v" I8 w1 B
定时器初始化子程序
. S4 G6 s! w3 M$ n9 _+ N( t------------------------------------------------*/
$ S8 g1 X/ e# U9 E- b& c; Vvoid Init_Timer0(void)& \% ~) h3 ]. n+ x0 l4 v7 w" w
{* n% H. e1 E+ L1 z2 w0 x
TMOD |= 0x01; //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响
% g# ^( F& |$ r, k//TH0=0x00; //给定初值/ C- m3 O7 k% T% ?! q9 T6 a) z, Q" `
//TL0=0x00;: \( Q" x9 L8 G- q: o
EA=1; //总中断打开
1 g) H" |! U- b9 ^3 VET0=1; //定时器中断打开) C9 S! n+ l; D3 E
TR0=1; //定时器开关打开
# l4 ]$ `( W; W}9 W2 J+ N& F- H* |
/*------------------------------------------------7 a, u# Y! ]' v! z; P: B, F
定时器中断子程序5 {% ~& [0 b; O: r
------------------------------------------------*/, y/ @, }; d. g }6 P
void Timer0_isr(void) interrupt 1
0 z" T0 \/ h" J: w/ `{1 [3 I, P. h8 a0 O/ y' g' h
static unsigned int t,q;
/ G! f/ d" V. {TH0=(65536-2000)/256; //重新赋值 2ms
" W4 W- }1 w3 @, H: ~/ ?+ BTL0=(65536-2000)%256;
- S3 i, t0 }$ M L4 D% w
, }, K' }2 U B" U6 g0 mDisplay(0,8);
8 A; o* |3 W9 K% v$ P4 Q- Y
9 ~2 E& y. t \t++;- j0 \. e( H8 Z' F; Q
if(t==500)
4 c, W" A' d! H{
+ N6 d* r1 x0 Z t=0;
4 i4 s9 G o# V0 Y8 e6 M8 L s++;; v: s$ T+ z: ]5 N0 c+ h& C
q++;
; P7 O. W4 T v8 \9 m9 N& F( O if(s==60)3 `/ C. U! {4 d, l
{
: x0 \. J7 k5 W! q3 x+ h; z s=0;7 }9 N" N9 n6 M {
m++;, d9 f3 w2 k2 Q
if(m==60)
3 U4 I8 I" C) \3 l {
: q D" P; z: d, g! j T m=0;
9 I% T& T: [/ l$ W. T h++;
7 M$ Y6 t. n; O0 y0 o! F4 h' J if(h==24)% a) t% O7 Q: {6 {# U
{
5 c/ E3 {0 x# h3 g3 Z h=0;/ b) q- x+ P$ ]. d) R% ^
}
2 l1 z6 ~# {7 \- u) }" X7 u! a }
/ f* v( }7 i* M) D/ p# `+ V) N }
. |; K! v" X4 V7 G if(q==1)1 z( m G, G& c8 B: b# f `
{
# w* E- {) z F$ \1 J) j; x' R+ X P1=0x55;
- H6 ?& V" t9 L. } DelayMs(3);
4 E9 C7 a, [9 y' T& A }- ~% Y; t, K) N
if(q==2)
1 u6 \ c4 t n" k {
8 u+ V8 e$ O- U- U! k q=0;
. j8 k1 Z8 g/ j" x# V1 ]7 f P1=0xaa;) g. ]1 G+ ~3 O, t
DelayMs(3);( s+ t/ ?8 H( A- L- |
}
, _: W: {( P! z) \6 ~0 U& g: M}; H; L2 O# \& H+ a
} | " T% H! E5 |1 D9 b* j8 A
|
|