|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
51单片机定时做可调普通时钟源程序
$ h. w3 k' |- B) i0 t. Z3 w" }
/ o2 ^% ]- q$ }" E! Q1 N6 N51单片机定时做普通时钟 而且可调 功能很强大 下面是源码:
4 G# U, t( m; P5 r, L0 _* W/*-----------------------------------------------
: K3 }0 Y, `1 j$ d& m3 p( z' | 名称:定时器时钟数码管显示
3 I2 i& y4 i# \------------------------------------------------*/" L, K- `% ?$ X7 @% a2 b1 `: f
. z1 s7 J' q0 N! B5 L: A
* v% V+ H' A; @#include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义8 U$ q q. U8 ?* R2 w0 v
- s1 u9 V2 r% {' [5 F6 c. T( m8 J0 O4 S4 G- F! e! a
#define KeyPort P3 //定义按键端口
8 {: G. P) w& P
3 j. J3 l5 _; g5 \, D: W, [2 Z' X6 X) @4 K+ s% _
#define DataPort P0 //定义数据端口 程序中遇到DataPort 则用P0 替换
- z" ]2 F/ r4 B& L. b P4 d. w/ W7 A: Z
- E7 @+ Y7 |0 V2 ~sbit LATCH1=P2^2;//定义锁存使能端口 段锁存
' L! v# J2 W; Q) M8 ]. }sbit LATCH2=P2^3;// 位锁存
% l; x& o, @: u
! q) V1 A/ J& G T1 x
. o g# v- V2 P; J4 S# E6 G C; hsbit SPK=P1^0; //定义喇叭端口
9 N; H8 }0 X' ]! E- g- h
& L: s- g5 m' [8 E
+ y* C; L' P- |0 H; g" dunsigned char hour,minute,second;//定义时分秒
3 e! O" O% g& j! E
4 X5 l# r3 E9 e$ K7 b' M
0 E2 `+ H9 R/ O+ l% g2 l* Lbit UpdateTimeFlag;//定义读时间标志
! @$ r- g9 v# u! e: H4 `; ]- M
% j. F" j, [0 Z: i
) w* c2 s+ L; cunsigned char code dofly_DuanMa[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};// 显示段码值0~9
+ |% j$ k5 M- F u, Cunsigned char code dofly_WeiMa[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//分别对应相应的数码管点亮,即位码" v( M. f. d @) |! v
unsigned char TempData[8]; //存储显示值的全局变量
2 C0 ~- x$ R, w: H& r! f9 I' H, J0 A b6 [9 ]- S7 X8 s: s+ d! `
1 m( w9 J% c% I* t& O) O6 _3 a$ ~void DelayUs2x(unsigned char t);//us级延时函数声明
7 k+ d3 e! P4 h& V* V: |void DelayMs(unsigned char t); //ms级延时7 J& I7 ~ x% I6 w4 M" A% ]! P
void Display(unsigned char FirstBit,unsigned char Num);//数码管显示函数
+ a% W3 V) v& Gunsigned char KeyScan(void);//键盘扫描' k5 n4 P; W1 e5 z6 K
void Init_Timer0(void);//定时器初始化
" ]7 r1 E4 J5 Y! n/*------------------------------------------------4 `6 k3 Q+ T' v$ o7 U( E( r: n
主函数: |2 N; ]8 j+ T$ M9 K1 W; C
------------------------------------------------*/
- K- ?4 v/ z7 G0 d0 B3 |! Z6 Rvoid main (void)& V7 ?& @. g5 a# M! v1 ]
{* `* H* c" B& w" i4 Y, R& L
unsigned char num;
3 ^- `5 J% Q: R' d$ N
, T# z; L4 {# L& i! i' {% t$ ?7 b- d/ U
Init_Timer0();//定时器初始化. A3 g8 F) |. H& R. ~1 \
' p0 K" ~8 o" H" _( J
2 L: H" a% [* K& K1 r while (1)//主循环/ j+ Q B+ L, U3 D
{& ~. |# a1 A. e" d3 W7 X: f" a
- `, w+ ~- b4 u r& ?
# g) j5 Z: N+ L/ }- j6 O! M4 C num=KeyScan();. z; H- g; g) t' H! d, L$ y* J
* L {, _/ @: m+ S5 \' |5 ~( ~: z
# S4 ]. W5 ^) @+ z' e# f& }% j switch(num) ( l& h ^" \+ ^; h
{
8 c- ~3 K* D$ _* U Z case 1:hour++;if(hour==24)hour=0; //正常时间 小时 加1+ \/ Q4 L, j# h! T7 D: |
break;+ y0 l# A1 J" L8 o' b/ G
case 2:hour--;if(hour==255)hour=23; //正常时间 小时减17 c5 g- o. H3 q5 f) z7 {
break;
* ]+ ~ E$ y4 p' H, C case 3:minute++;if(minute==60)minute=0; //分钟加1+ C9 I5 j9 f6 h D7 h) f
break;( C) f& C- z% W: c. F8 M' }
case 4:minute--;if(minute==255)minute=59; //分钟减1
- s. Q* {4 H, k break;
3 ?9 M' e# N" Y" Y default:break;0 o( `1 ?) x* z; A6 r# t, X$ r
}/* 结束switch语句 */0 O7 ^- F/ y0 o! p
% G, E- k! A4 ~
# k2 n5 X% C) J F/ H$ D- V if(UpdateTimeFlag==1) q0 J- q- ]! L
{+ |2 ?6 s+ ?4 D( H; e
UpdateTimeFlag=0;2 f) Q8 i/ d$ r% a/ t9 N3 u
$ @1 k3 s! o; L0 l8 a4 u% N
1 m4 ~ m& o2 D; F* T5 N6 a' ^! o
TempData[0]=dofly_DuanMa[hour/10]; //时 //数据的转换,因我们采用数码管0~9的显示,将数据分开" R2 ~+ }, c) U9 q, _4 H3 b
TempData[1]=dofly_DuanMa[hour%10];$ w, y6 G0 ]& l
TempData[2]=0x40; //加入"-" ? {) M! t# Y3 q- Y
TempData[3]=dofly_DuanMa[minute/10];//分
9 `( t3 n/ {% |" {9 z8 C TempData[4]=dofly_DuanMa[minute%10];
5 P0 ]' w6 d- g8 e% p: F | TempData[5]=0x40;
w6 [" V& q2 B: f TempData[6]=dofly_DuanMa[second/10];//秒6 y; d3 u$ |9 z- n; l+ j9 l
TempData[7]=dofly_DuanMa[second%10];
5 k2 S% z# j+ w% u* ]
! X% r; C! \' T6 i2 G
" n) z2 P. N! j4 p( K } /* 结束if语句 */2 U- W# ~$ d' t* a' K
9 h' q. w0 B" t9 ^6 ~1 C; c% ~
" p0 d2 k! i8 J' ?* D# u) v$ _, I
9 n/ u0 v0 T! I: C; V& b$ E( c" ~& @ }/* 结束while语句 */% w1 W! L5 Z' r" n2 `
! C# @. z+ G7 |/ C" N h
}/* 结束main语句 */! o W; j& M+ o% A2 T
& u0 Z( d1 ] O& U
4 ]* S/ C5 k6 _6 R. Y! @
4 K: S9 \4 K. o O6 n7 o2 ^
; X; g3 h' t* j: x9 M, {; o/*------------------------------------------------$ X: `+ G: V8 {( ^
uS延时函数,含有输入参数 unsigned char t,无返回值! h: V8 O4 v1 f# x' g. Q! h
unsigned char 是定义无符号字符变量,其值的范围是
. w1 T+ O$ Y3 ?4 h, I3 M! W 0~255 这里使用晶振12M,精确延时请使用汇编,大致延时
6 h) G' \) S, | Z" \ 长度如下 T=tx2+5 uS
6 N/ F0 X- z/ }* B0 e9 C------------------------------------------------*/
4 g& ~6 f" R- `9 rvoid DelayUs2x(unsigned char t)4 { F9 @8 _3 h6 p3 l# I
{
5 C: j/ C) \1 p- G! `* s J while(--t);) X( `$ N" ^7 P. @2 q# o
}% V& i3 k. y, j
. \" p( Z) P- }. A$ @6 P4 l
6 ?' S/ b+ ?4 o
; ]8 D) c7 A# r# e
, k9 `; P, K( K5 ]: G/*------------------------------------------------
& w/ o7 e+ T3 Y6 d& @# _ mS延时函数,含有输入参数 unsigned char t,无返回值
+ G; s3 F* ]7 A: ~2 S P, a unsigned char 是定义无符号字符变量,其值的范围是$ r L" r9 k1 a" _) Y! l |
0~255 这里使用晶振12M,精确延时请使用汇编
J# z3 P8 Q8 P' y. A3 s! t# |% W; t------------------------------------------------*/
' q+ R, [* x6 dvoid DelayMs(unsigned char t)
5 p& l+ n# w: P% z{1 I6 ` l$ d. J
9 O$ e/ C' ~, u4 s4 S$ Y! V while(t--)
- G1 n* o/ ]% H8 u4 Q. _$ ~8 u {) H* Y# G( F3 e: m- K' d4 }) R% B
//大致延时1mS
# M0 M+ v" S4 E DelayUs2x(245);
2 k2 r& o3 q% l0 V" H' W; [$ v DelayUs2x(245);4 ?: O# ?/ j/ L0 i
}& K) c1 ?1 E* o- R U
}$ e& P- ^1 C6 c9 r' e
# w; d- q- l* |' \6 S( _
% {9 F( T1 t2 v1 |1 t7 c
9 A1 @* g& k( k& l v
! a$ u3 W0 P; I! z( D1 O9 B
/*------------------------------------------------' ] `2 I, B+ y; @) y
显示函数,用于动态扫描数码管3 b( v% h; k3 S* U. S
输入参数 FirstBit 表示需要显示的第一位,如赋值2表示从第三个数码管开始显示: n8 c/ N% b9 \+ j$ N# W
如输入0表示从第一个显示。, g* |2 J7 Z5 g, w
Num表示需要显示的位数,如需要显示99两位数值则该值输入22 _( M! g" Q4 ~) |' [4 U
------------------------------------------------*// {9 c# [3 S8 L' g4 o3 Q
void Display(unsigned char FirstBit,unsigned char Num)" K8 ^# K9 |5 e2 f! r" P0 t
{& D% ]# V) P) }: r! ^7 @
static unsigned char i=0;) \; x1 ^, f, N- l5 y9 q
8 ^7 w! [& \( e' L, C) c( r% W6 ~
9 x! a6 g( G3 g0 E" \: x$ e) v6 b% w0 g
# k, x) s8 o2 T) `3 {% ?
DataPort=0; //清空数据,防止有交替重影9 D) G" l/ f' ?9 q6 q
LATCH1=1; //段锁存
! b- B- Z/ W5 Z) b/ R LATCH1=0;
2 {3 z: k/ j3 G) S- _* g' @
% |+ z$ b7 H9 K7 ~$ Q2 K- i& w3 F$ R- w
DataPort=dofly_WeiMa[i+FirstBit]; //取位码
1 O) n# Q% r+ |& _# h( i LATCH2=1; //位锁存
`: n3 |4 E0 K, l# N LATCH2=0;8 K( d3 s7 P1 p" U; ?
/ y0 l( u3 U9 H# l* ~7 }4 b! G, @9 r( w% G$ s, k9 J7 {
DataPort=TempData; //取显示数据,段码
( u2 E3 x1 ] r& O, r5 N, J LATCH1=1; //段锁存
) M. O* t u4 S LATCH1=0;
! F* W ~2 d C# U N' w6 V/ @ 6 x+ s" K3 N) b; L
i++;
# m! x/ N6 v6 V! H/ k4 o9 ^% | if(i==Num)% A1 o2 n( z3 j" H: U6 H. Z! V
i=0;
& T8 f( r/ ]) \4 a+ Y, `$ |
; |6 }" A5 i5 O- {- l$ J9 c
* @: j3 f: n4 s
4 y9 M9 b) J k" a* _3 C; |+ t8 P- ~
}) r' y7 q* X" }: y1 @
* r9 b# [) W3 `! N
) J. s* x7 O) _+ ]+ m: P/ e$ i4 D# c) j' z6 F! L
5 c l( H- h O' p O/*------------------------------------------------
7 d6 z: |7 b2 |! o. D% N0 D+ P 定时器初始化子程序8 ^6 s/ I: q# C( f* A8 J+ V
------------------------------------------------*/
) l( f2 v- e8 I9 V+ F P1 a& ovoid Init_Timer0(void)
8 @6 k0 J9 h9 Q{8 y7 r; c% I4 Z/ I \% k6 R
TMOD |= 0x01; //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响 ) Z; V/ k. e6 P- E$ Q' S5 q
//TH0=0x00; //给定初值
$ g- E1 {/ b3 n( H; L //TL0=0x00;
/ e. ^: w+ ?, G# a- ~7 D& d6 L EA=1; //总中断打开, X1 p E8 C4 V p7 O) H B
ET0=1; //定时器中断打开
5 O1 v- B1 H) R; a TR0=1; //定时器开关打开
2 K- C$ H8 F1 u! c8 b}( E" D( g1 P( K) Z
* }7 u" |: b$ z3 L+ R$ V
+ x) G" X! d3 G) W$ V
5 N7 }) J# u5 S3 [: r3 @6 j. J- j p! X* u
/*------------------------------------------------
$ t/ @8 m w5 f; ? 定时器中断子程序# u; f- o& p% i0 }/ C9 j6 f
------------------------------------------------*/. l/ S9 r" B- e% c' d3 x
void Timer0_isr(void) interrupt 1 2 A( v7 ?& |; b& c' q q
{
r6 k: \2 d6 L& B1 x- r& K' o) g static unsigned int num,i;" U9 n7 _/ x2 L. ]/ p9 d' h0 N
TH0=(65536-2000)/256; // 给THO赋初值为(65536-2000),当其加1到65535溢出中断一次 即2ms中断一次 2000为2000/1=2000(在晶振为12MHz的时候) 0 L5 u. R# D/ u1 w
//重新赋值 1.8ms 即1.8ms中断一次 2000为2000/1.09=1834.86(在晶振为11.0592MHz的时候)
6 |- s1 v6 ~( ~5 t: B3 V+ | TL0=(65536-2000)%256;
, h( C* T( z5 Z. m , k) v# c( `5 h7 S( E9 q
Display(0,8); // 调用数码管扫描
+ ~8 u* Y/ {$ x3 ?; @) h6 X! | M
: _3 \* y9 [, w, B* ? " j6 v$ d* S s! }
i++;) X/ v* c v8 }3 o! h
if(i==10) //20ms更新一次
0 K# ]) l4 n' T4 J8 i {
9 Q, U7 \8 d1 z( m i=0;
3 J& P- F. O ^! U, d4 t UpdateTimeFlag=1; //更新时间志位置1! M7 s8 U0 o5 o* p- ]/ z
}
5 m$ ` R) ]( b; F B ' o, h1 b. ~+ D9 g
) d6 I$ R$ ~- U5 L& f4 T7 J% q9 N : L) p- n# ?. V. I( M6 K ?2 B' n$ }
num++;
, B; l, M: u3 x1 J1 C if(num==500) //大致1s
' E9 b. t* d% d) j; p {4 ]) s! O' Y+ J- h. b9 t
num=0;1 T7 H) i4 C3 ^& j: Q0 z) `) d
second++;
! n, O+ Z* H4 r- y" A$ K" r 1 r8 f( e( E2 G0 \; h6 K [2 e6 e
if(minute == 59) //当分钟到59的时响蜂鸣器
; U' I; v! }" a8 Y& s0 ? {3 S% Z+ w: q$ K
if(second >= 51) //隔一秒响一下$ h+ Z* a( l- [5 [* _
{
: W% ^" W: r# I3 y SPK=0; /* 开蜂鸣器 */6 o6 {9 T. s" e
DelayMs(1000);$ u7 E9 R7 C; ~* R8 ]* d
SPK=1; /* 关蜂鸣器 */
6 ^# \8 q% @0 T/ r' \) T! i second++;
; C* o% [! M8 p! T( s }
6 U& X* y+ e3 x, h$ V3 P. I# ~ } " y$ {3 w: c) m0 I$ t
+ a5 O0 ]1 P; K: r, q if(second==60) //秒到60,分钟加1
M! w2 D1 E$ O- ~$ i7 ] {# p- j* q" w5 @3 m# p
second=0; 4 q% Z1 D$ w6 T2 o: A
minute++;
4 \5 c) }6 [8 c& v$ i0 m. f 5 y, v0 ]* v3 H& s9 w' Y P
if(minute==60)//分钟到60,小时加1
& p7 L5 T* [9 N1 Q {
5 k; Z& m* X& c minute=0;
: S t* s$ `8 K; ~1 _1 p
# q5 [" g% i/ D( P( f SPK=1; /* 关蜂鸣器 */ ! ]+ ~( ?# z0 E9 `# J/ ^) W
& G0 l2 ^ O/ M5 X% A" v
hour++;8 Q) \# T5 o2 f0 }; i
7 T$ H) X7 o* A" Y if(hour==24)//小时到24,回零# Q7 j+ g& o2 V( ^
hour=0;
4 K) y1 m% x1 f0 B- y }
+ x2 J1 i, u$ [ c8 F : Q4 K7 V! O- a0 | {, ^9 ]
}' |- K x P5 X3 X' O. H
7 i- o6 x4 z; i9 [0 P! _
}
/ ~: a& w+ S: \# x$ }' z}3 n, P$ R( A& Y/ K" G
) Q% d- h& N9 W# i
+ u, T0 Y9 q) d8 ]9 \
* D5 B. v: G' U& B
/ ~% w/ c4 |4 l1 B0 i
/*------------------------------------------------
, y( o. \$ V) t" T/ F按键扫描函数,返回扫描键值
( _' G4 ]3 ~/ _) w2 L1 d+ [* M------------------------------------------------*/
; q3 B- |" g, b; [5 K% `5 p$ Y, qunsigned char KeyScan(void)$ E1 L* B4 }# ^6 ?0 v
{& O3 G7 ^# M1 ~+ o9 g
unsigned char keyvalue;
, u/ {+ R, P8 d5 Q+ n. v if(KeyPort!=0xff)
2 m* u4 y* H G' ] {
4 H" ^3 S$ a; l/ O; g, Y7 R DelayMs(10);
- |* Z! C1 I9 \9 b& g if(KeyPort!=0xff). q6 \: w" d' r/ n o+ s9 Y
{
! T4 o: L* @3 v/ \ keyvalue=KeyPort;
! U* h+ ~* U* X- W/ R! ] , F+ {1 O# `+ ^4 L6 U9 n
while(KeyPort!=0xff);
" V( @$ g6 T! y$ r7 }* g( j ) g4 \8 r z' M. M3 P# r
switch(keyvalue)
% c* O: g' s$ a; T, j1 L" v, c; D {
) \. i6 e# x0 O- W case 0xfe:return 1;break; //单个按键控制8 ?; T, _+ N; D' a6 _
case 0xfd:return 2;break;7 ]* s( Z% |, F2 A5 J
case 0xfb:return 3;break;/ |, @$ r# u6 o+ i$ H( g
case 0xf7:return 3 s; W& l, m3 p* i" m7 S1 r: y
3 o% {0 u" T- b: C& @, \' Q
+ t7 e7 X& z5 h! a: n
8 C! i0 e, }. c- d6 ~ b( P
8 W( {& h4 D; d. r, k+ V+ p…………限于本文篇幅 余下代码请从论坛下载附件…………( X; |* R3 b4 R8 o( _) L
3 l0 U/ N( Z: ?; A* \+ y
& V6 Y0 l, a, N% w* T) a5 `% Y. n
|
|