|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
51单片机定时做可调普通时钟源程序
* y, O' X% D! L5 v5 p
3 {7 R- i+ c o5 E! |- x3 m7 J
, Z* [ n' o) C% k4 v R2 D* T51单片机定时做普通时钟 而且可调 功能很强大 下面是源码:6 w( E z( i0 u; d: B
/*-----------------------------------------------( Q( f, y$ |: [* O# _# b% H, n/ S
名称:定时器时钟数码管显示
+ h7 P- M/ E, s9 G7 K------------------------------------------------*/
: o0 n) ~1 f A+ E
7 ]6 e( T$ R- |7 i- S0 W/ `4 h4 _
& h: b# p, }8 \: h4 d% w#include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
, t* o/ X; F& @* S
! S# Q# h2 P; f) b1 j4 K
, b9 B" h- Z" E#define KeyPort P3 //定义按键端口
' l1 H) \# `7 ?0 F+ u4 s( o- l* w4 S2 z/ E" K9 r( c- g
/ l3 V- q/ A7 Z4 J5 O: F
#define DataPort P0 //定义数据端口 程序中遇到DataPort 则用P0 替换1 K" K7 q$ U) W" P7 m# A3 A
9 s, e3 \3 y# J* \5 w, ]6 U& y
* g$ r( V! U$ G4 g! d0 esbit LATCH1=P2^2;//定义锁存使能端口 段锁存# w$ J" S n- l. B2 G) U
sbit LATCH2=P2^3;// 位锁存4 z1 ^1 N, h' S h! L
5 ]: K1 M( K4 _; C9 M9 ^! {" n; P/ S' ^( Q0 H$ N& T
sbit SPK=P1^0; //定义喇叭端口8 v, g9 c( w1 m$ _; F/ G4 Y7 v
: [+ Y; [" X* d# L1 s
9 I" b0 A! B0 E; [! Funsigned char hour,minute,second;//定义时分秒6 F; G/ R; Y) P, p, A3 X
* D5 }- f2 m' a* n# ~$ v* p& Q5 P- s) `" a
bit UpdateTimeFlag;//定义读时间标志
9 N' P& @& E2 l5 h6 U4 T' ?8 p: l! M; E$ s+ q6 |
7 T3 V9 K6 H4 x+ x) ^unsigned char code dofly_DuanMa[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};// 显示段码值0~9. E) N! q C! r
unsigned char code dofly_WeiMa[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//分别对应相应的数码管点亮,即位码
- b+ u+ C; d4 o' h3 B2 iunsigned char TempData[8]; //存储显示值的全局变量3 P, p- ?: @1 b# t& L2 P" P5 j) b
) G0 M$ a' U; u
9 O* A; X7 R, ^; r9 T$ |void DelayUs2x(unsigned char t);//us级延时函数声明
$ [ ~; k/ |6 v5 qvoid DelayMs(unsigned char t); //ms级延时# |& u5 Y8 W2 B3 e2 w
void Display(unsigned char FirstBit,unsigned char Num);//数码管显示函数" U* z8 ]- v0 X6 V6 S
unsigned char KeyScan(void);//键盘扫描/ q4 i/ J! h/ t/ Q0 \ r j7 F
void Init_Timer0(void);//定时器初始化7 _/ n3 T7 F! R' E
/*------------------------------------------------$ X& @' P' X" V, [$ j& h
主函数4 V& ?# D, p. K* c! _) ^
------------------------------------------------*/" M( r1 ?# P1 j$ m, Y
void main (void)
/ X7 K4 V E4 T8 D{
2 r+ Y. F% m0 b$ j0 e& G) b unsigned char num;
( Z8 r1 Z4 G7 g4 s' e6 u! }" E u- H# D) A4 e. K9 Q p
1 O7 j4 u2 ~, S! Y1 Q. I% ]% S
Init_Timer0();//定时器初始化
6 ]3 t; z8 f4 K& P0 `, P
( H D; m3 d: I3 U5 g0 U
) D* K8 L; G7 d while (1)//主循环
+ C" h8 |5 j( q8 E7 u6 g {2 |( I2 R# L5 h! v
2 X" u! b/ F; J& _) m; x5 V: S
' J v! _; V! [4 q7 d" Y: ` num=KeyScan();- `# ]; q3 s; b$ K$ F4 h0 x$ q
, m% `; H" O2 w3 y7 F' \) \ , u( K: X! A" y. Q$ w8 g
switch(num)
- V, L' q, [+ d; V7 c5 C/ ~ {) I3 u$ H* A9 ~9 ]" [7 A
case 1:hour++;if(hour==24)hour=0; //正常时间 小时 加1
: }1 z$ U3 {& j: |; }, S% x break;
. f3 q) a. g$ Y# M* z case 2:hour--;if(hour==255)hour=23; //正常时间 小时减1' m; r9 t; P) N6 C
break;6 T+ L' a1 [7 A# l
case 3:minute++;if(minute==60)minute=0; //分钟加12 d& Z4 Z4 `9 S9 y% O% r3 d3 g
break;
9 f u: Q7 O$ |$ x) P( s2 q5 @ case 4:minute--;if(minute==255)minute=59; //分钟减1
) A d) A6 `% S% r1 U break;/ n3 c# _/ w/ U" ?4 Z& l
default:break;
$ W& ]; c; _# ^6 w }/* 结束switch语句 */
' ], K- _! j, o( b! K
/ O- \/ c8 o) I! j 5 \" M: ]3 S! p2 l
if(UpdateTimeFlag==1)' ]5 K+ t9 H$ l5 x
{
1 L- n& L- |# H9 d9 O r# A5 a3 ^ UpdateTimeFlag=0;
# N6 u, }( {2 O4 T6 g
7 g7 v3 n- e1 o* w7 {
* y0 X: ~% R$ i1 l& `6 o TempData[0]=dofly_DuanMa[hour/10]; //时 //数据的转换,因我们采用数码管0~9的显示,将数据分开
) P. T% _2 o* M% q) k2 n TempData[1]=dofly_DuanMa[hour%10];* t0 q! {' M Z" S1 h
TempData[2]=0x40; //加入"-"
5 ?9 i# ^+ @( C h TempData[3]=dofly_DuanMa[minute/10];//分5 D5 |# y; X9 _6 d
TempData[4]=dofly_DuanMa[minute%10];, k$ k b7 G& N1 f0 L
TempData[5]=0x40;
4 r" n3 ]( Y% L; ?5 b TempData[6]=dofly_DuanMa[second/10];//秒* l/ Y( w3 e# k$ [1 d$ @; X: m( T
TempData[7]=dofly_DuanMa[second%10];
8 [; ]9 [& S/ u% I U9 f3 h7 G! x8 C4 a
1 B; T! [+ o3 Y/ V& M9 W
} /* 结束if语句 */
( }8 a, u4 Y7 P8 @* i & Q$ O: f" w9 H/ f$ n3 r8 V% p
! @( p1 p$ r, ^" {5 A6 T' H 5 |0 _2 F% M# b
}/* 结束while语句 */" h" N+ f/ X- @( ^# Z6 ?1 I
, I. ~9 _! I6 O6 Q4 {: a( T2 h' f}/* 结束main语句 */9 A# S. R' _9 U+ ]
7 S* D- _! p+ A
, t8 `' g* r8 A& z
+ M6 p+ W N) F/ A
, X3 M; |+ ]+ k+ @& q( |: G! p9 R( D/*------------------------------------------------
! ]. Y; a j- f6 ^. d& U# u1 ]$ x9 n uS延时函数,含有输入参数 unsigned char t,无返回值. j1 a9 U! a2 O9 U
unsigned char 是定义无符号字符变量,其值的范围是
2 n. J. }* d; R3 F 0~255 这里使用晶振12M,精确延时请使用汇编,大致延时
4 i& M4 C6 y' J! I: x+ j4 C' a 长度如下 T=tx2+5 uS & K9 D2 k9 M6 u$ l) w. h
------------------------------------------------*/
K& C8 Q, B9 O. P% m( Qvoid DelayUs2x(unsigned char t) k5 v. G6 P" }3 M0 @5 L0 K4 L
{
" m. V/ d; F, [+ L while(--t);
7 R% ?9 ]/ C+ J; I}7 @# @ [ R5 V3 D
, p' h2 H* |4 \4 T
( d+ M& A' `: R9 t- s U
& X* M3 u r2 j% J2 Y, V
3 Q! L8 u: M( S8 e% a/*------------------------------------------------# r; S0 a6 ]( A/ c E
mS延时函数,含有输入参数 unsigned char t,无返回值; Q4 h& M* d" V- {8 x; }
unsigned char 是定义无符号字符变量,其值的范围是; @" _' |' g# U4 ?3 v. T
0~255 这里使用晶振12M,精确延时请使用汇编) l2 b: u$ T2 o8 ? x; T, x
------------------------------------------------*/
0 o e7 _- [6 J- I, y8 M; k& fvoid DelayMs(unsigned char t)* a1 I& c& W* }3 }" O8 k; n' l
{
/ g' l4 m' p/ D
( R' O8 T G: H# e7 X9 a while(t--)% |: F [' e* ]! B7 O
{
( d- X c" k7 A7 H- c/ O //大致延时1mS
4 Z8 m. t/ t5 V' m4 u1 a& q% j& v7 C DelayUs2x(245);& O" W; I$ D5 G3 h- z
DelayUs2x(245);- K9 o3 S0 Y. j) J: ~; M
}
( b4 e- x6 X9 O& Z}
6 T4 d$ e2 R) w+ T5 O$ }
. s8 g$ B5 u0 B# ?0 P6 V; Y, S# q5 ~0 m. G
0 _9 ?8 Q a' B) R- s- y3 e
! j9 a& S( U; W: S! n: g/*------------------------------------------------
+ b" E. x5 }6 R5 |, s/ E: c" \ 显示函数,用于动态扫描数码管
5 l S: [$ W3 j8 p 输入参数 FirstBit 表示需要显示的第一位,如赋值2表示从第三个数码管开始显示
3 Z0 @1 ]* C- b# _* Z, d 如输入0表示从第一个显示。, {, V4 J2 `' ?; P
Num表示需要显示的位数,如需要显示99两位数值则该值输入2
/ B _' q2 n9 d' T9 g' ^* J$ `" ?------------------------------------------------*/
8 n& U4 n/ H9 Y7 t8 uvoid Display(unsigned char FirstBit,unsigned char Num)
|; m/ ~0 M" S# a9 l/ K/ A( ^8 O{4 x; r" y5 r" i2 M: |5 F
static unsigned char i=0;) [, q# O; ?/ w! r) S( ^
, m. E; W7 m2 d- g
9 W2 D# [( K" ^ y
* S3 h$ |# ]% T/ P DataPort=0; //清空数据,防止有交替重影
8 f7 J5 x0 b( E1 F9 }, [- z LATCH1=1; //段锁存
! ~ @: x, E4 n9 x5 D8 L8 L7 K LATCH1=0;7 v r' @! V$ l6 h& |
2 R. O& h* {( ] A$ \
: [. b% f+ _: ] DataPort=dofly_WeiMa[i+FirstBit]; //取位码 9 E' J9 K- Y/ Z8 s7 a* {
LATCH2=1; //位锁存
5 h! c! Q: D* N$ G* K LATCH2=0;& }5 U7 m* L: K% ?
- S3 T! \$ t- W7 s' I: A' q
: F I% z( Q( Q1 f+ x DataPort=TempData; //取显示数据,段码
3 B$ J4 O3 ]% `+ @ LATCH1=1; //段锁存% C* ~+ Y; Q2 P9 p) w& a
LATCH1=0;
1 f, C) G- J O
, b1 J3 A/ K( T3 b6 b) G. Q i++;
$ ]8 _& G; U: r+ e0 p if(i==Num). n7 Z `# }7 |1 T4 f( ?$ }
i=0;
2 C: o1 |7 K; E/ V
$ d( p6 ~5 k/ c j1 W6 f) o1 J5 V8 u2 Q/ ]6 [" c B
8 n1 X( Q9 Y9 G0 e& u3 g& E
) F! [' l" E$ Z1 z2 v2 J}! ]5 P8 r4 ]* c3 l
& K6 b3 r8 q' C6 f. v. ~2 p
! r2 s& G+ F( T$ }7 x
C1 A- J0 ]- ?1 e4 \: A4 Z6 |7 F- ?, i6 Y9 i% X: P
/*------------------------------------------------9 V: w) x5 w% F0 J
定时器初始化子程序
' e( X7 i0 ]: e------------------------------------------------*/+ j% E6 C3 l, }8 [# m
void Init_Timer0(void)0 M0 m: n4 w/ {+ r( _
{/ R/ Z: Q1 g% H F; f3 ?; L" o
TMOD |= 0x01; //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响 4 @$ y; R6 U6 ^- k. {/ s4 f
//TH0=0x00; //给定初值; Z' N* R! V: V W
//TL0=0x00;
: j0 p! ^9 m9 e0 p+ t$ ]" } EA=1; //总中断打开/ U2 t6 t' n5 I g
ET0=1; //定时器中断打开7 v$ z3 X8 |; C! m& z
TR0=1; //定时器开关打开
- Q+ x# q- {/ w2 O5 W}
$ ?4 _# j# Z+ h4 ]2 w+ W$ U. N, f8 V
8 z. K' s4 B9 t# W/ t
2 o& f4 p" `8 c5 w. T
5 |! G8 }& B% W) _/ O9 h+ Y
( t1 V% y0 g7 y7 a/ D/*------------------------------------------------ N& P3 Q/ s: M# C1 X( M
定时器中断子程序2 ]4 v* g7 j4 K. k" t
------------------------------------------------*/# N6 q7 ^# D8 U. b
void Timer0_isr(void) interrupt 1 * V# E( G, O$ \0 X+ T
{
) u4 m( d7 @# V static unsigned int num,i; {) i* }6 Z& ^" g
TH0=(65536-2000)/256; // 给THO赋初值为(65536-2000),当其加1到65535溢出中断一次 即2ms中断一次 2000为2000/1=2000(在晶振为12MHz的时候)
) ]8 s) ~3 \0 e% a- e' i2 _ //重新赋值 1.8ms 即1.8ms中断一次 2000为2000/1.09=1834.86(在晶振为11.0592MHz的时候) ! S. k- b6 A1 ]# \$ X
TL0=(65536-2000)%256;1 K: p& `2 [& r1 f, t
) {2 L1 p" a6 s3 m- _: ?( [! k H/ O
Display(0,8); // 调用数码管扫描
$ \: K6 m4 g( k; Y( D2 h
2 o U7 W7 V3 c, D3 J 2 l7 \' V R0 j% S. H9 e
i++;
% i9 Y6 g' w- }" K% N: Q& v if(i==10) //20ms更新一次) n# ~0 `8 j; f5 C% j+ i
{
3 M$ P- V$ q: R$ L# U* D y: }' W i=0;
! B. b: }- \+ t2 z- z1 t UpdateTimeFlag=1; //更新时间志位置10 m8 m* H" Z- [; X
}3 M0 v- F: r7 Q0 j# m7 e5 m# n
2 d- N! j6 v/ s6 x) v3 l8 O
3 e, N. s2 P" a. f
* @4 C' K3 J2 w$ o4 F% A' L num++;0 x: _( c R" M' }, |
if(num==500) //大致1s
3 L: W) y+ e# {, z {
. M o, g% F- n+ ~ num=0;
3 q. M+ E/ `1 U* C second++;
3 ~9 b' _" r L 4 i p& W. p$ q. _- ^: ]
if(minute == 59) //当分钟到59的时响蜂鸣器
( U1 F, d; q ~9 p6 g {
; g3 Z1 w# q7 R& p6 Q if(second >= 51) //隔一秒响一下7 {1 q" K8 t; n& B/ G
{
8 K6 V s6 W2 h6 {9 i! r SPK=0; /* 开蜂鸣器 */& Q$ T8 q/ S$ |
DelayMs(1000);& j! M% K/ h* T/ q0 w5 ?
SPK=1; /* 关蜂鸣器 */, [0 A8 R( z# Y2 u: ^! Z3 ^
second++;
+ w1 A; y, T, E8 _7 G4 R }% e3 c: w9 v7 L5 N/ n6 F X1 h+ z
}
6 P+ K. ?2 j, ?( E& x1 D8 E % ^$ O1 b/ {6 d8 H" C
if(second==60) //秒到60,分钟加1& b1 |0 D8 j$ B* E
{( B: s; \; r0 e$ @0 b
second=0;
: s* G1 t- @% E( B: G minute++;
6 t1 `1 M: H9 [$ V$ @$ l! A% U$ G : U$ i! k! p6 d" U" p
if(minute==60)//分钟到60,小时加1
1 N* ~7 Q1 U5 l" k {. Q3 V4 K2 U8 X; j: F0 T) Y
minute=0;1 p6 X. F2 H$ t+ ]- Z' q S. g
4 ?9 W, z" \" b, r
SPK=1; /* 关蜂鸣器 */ 6 K6 u% x6 B) W( z2 ^0 u
) }4 Y/ A- A, e% s; l9 q1 o5 H
hour++;& U0 f/ ~4 U) x/ i( L9 B) A
" S. ~. p% o. J4 f i/ f! w3 N
if(hour==24)//小时到24,回零# K/ o5 y# W, Z
hour=0;; F5 _# A5 D! T; t6 x+ X" }
}6 z; t9 u3 A' X3 v
6 X3 T$ Y/ s6 o, z
}$ z9 p) p+ X, b2 `% w# i4 j
, ?4 B ^" V# _+ [1 u& Z }
Q; ]$ l% N" M5 V7 F}6 k( C2 A$ d' b
) Z, w* ]3 b5 V& J# ]8 _
+ P+ G5 c5 y6 ^: a$ s8 e
' q! d& j+ q$ J6 f
- Z: q, }! p% k
/*------------------------------------------------
0 D; o, A% F- v3 O( p* O按键扫描函数,返回扫描键值% I R1 @2 ~) b# d' G1 v; F
------------------------------------------------*/
5 \2 x3 H* |! m: o6 p/ r9 D6 H8 Zunsigned char KeyScan(void)/ ^* z6 j8 z- [8 q
{4 d$ s2 \$ v: z7 V& ~1 n
unsigned char keyvalue;
2 C, v2 J' r8 _9 ]) j if(KeyPort!=0xff)
- y2 l0 h+ R/ m$ j( Y1 ^" J {
; y' ?9 i% L+ m) C DelayMs(10);% I4 b( F6 n% [; U9 i9 |7 D
if(KeyPort!=0xff)
$ i, T6 l0 ?9 }$ ]7 M( e {
5 A; H4 l/ \) C keyvalue=KeyPort;
$ B0 E$ l3 J9 ?3 M4 c/ ?- k) l0 j 5 D& ~) q S9 v9 j' x8 U
while(KeyPort!=0xff);
' x- k6 G' J! L7 R2 o$ R2 y 9 [+ p3 f6 E# ], Q
switch(keyvalue)
/ \# J) N0 i$ Y: q. p {, M1 l) {' U3 O8 e! R2 X& q& D
case 0xfe:return 1;break; //单个按键控制4 ?2 X* c6 z) I: F0 K' ~
case 0xfd:return 2;break;
; r$ T3 M! I8 Y. [ case 0xfb:return 3;break;
3 U! j8 v3 F2 r case 0xf7:return
J) ] A6 R3 k4 c! x9 P2 d0 m
+ v: {" }* c/ s: a" Q% j- ]) S j9 b4 v) _" Z4 U6 _" @
# h: A4 M1 p+ J s8 p! Y6 V/ b8 V8 F
0 e4 M7 ?) @, F; b5 U; L; B* j…………限于本文篇幅 余下代码请从论坛下载附件…………
: U7 E: _/ I! u
- G7 r% w- @4 x) u. y& Z: I( j0 p; G! g* n4 o
|
|