|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
51单片机定时做可调普通时钟源程序
% E2 N& `7 O" R4 J: P- G
/ r ~4 K: G& e
4 f# e( H/ t' h$ p5 d) t51单片机定时做普通时钟 而且可调 功能很强大 下面是源码:
# Q9 Z7 M% L1 y7 e4 r3 z3 k9 t/*-----------------------------------------------7 g J8 F# M, P! j$ c4 h9 v5 y9 P
名称:定时器时钟数码管显示
) [3 R; f# U& |1 G------------------------------------------------*/% v) V9 _- P! t1 X
: K% A- g w. `! G* f- C, O2 Q8 i6 P- j. Y: E
#include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义7 j" ~3 @% w$ v7 a& k* S
( a b$ B0 D" D0 ^ C$ }1 i
: F+ v6 O" t! |#define KeyPort P3 //定义按键端口
2 S0 |* |# m5 Q- k% e
, \: K& E, n1 j$ y% l( t1 y8 z' J; s8 M0 U
#define DataPort P0 //定义数据端口 程序中遇到DataPort 则用P0 替换+ g9 D/ v; @$ m, M8 @8 q: e3 a* V
6 Y1 {/ e4 l3 S" G" n9 A2 q* G, O, d7 U: l( D9 r5 H# B; y; V$ [
sbit LATCH1=P2^2;//定义锁存使能端口 段锁存8 v- J3 @; ]4 x3 C
sbit LATCH2=P2^3;// 位锁存
) q! e1 k i2 w! V6 |" K# H8 x, b1 Q+ ?) ?/ a, O4 {
! y" d9 ]2 s U. p# Y j
sbit SPK=P1^0; //定义喇叭端口
z2 q( F, J: J2 u; ~8 y, R" }: b+ D" _' f+ d% R# j
$ F6 I# m2 j, W
unsigned char hour,minute,second;//定义时分秒! K3 v" D* r# r! P2 [4 N
. z7 F3 {* @4 I4 { n4 k, k; A, f4 C
( S. Y% {7 `$ ^2 w+ V$ O
bit UpdateTimeFlag;//定义读时间标志
2 J o* r8 O/ M9 d) ~) d5 g7 K
) v" v* J3 J) U" k# z; A _' c$ z! E' D& q$ R
unsigned char code dofly_DuanMa[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};// 显示段码值0~9. W5 t {2 E9 A, Y _( ~* ~3 G3 k
unsigned char code dofly_WeiMa[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//分别对应相应的数码管点亮,即位码" d) Y- P- ^4 ]& J1 u+ q
unsigned char TempData[8]; //存储显示值的全局变量: h- N4 c- e8 R8 e& F- F" l1 Q
! G: l5 ~' _6 ?
, D! w T. i4 F: V
void DelayUs2x(unsigned char t);//us级延时函数声明
; {! g) T% ]4 ~3 f8 tvoid DelayMs(unsigned char t); //ms级延时
& P& X) M7 m; vvoid Display(unsigned char FirstBit,unsigned char Num);//数码管显示函数
7 [4 ^3 U( {9 ^. h- b( u) U5 _5 Gunsigned char KeyScan(void);//键盘扫描, D$ F8 T4 R7 d+ p# @6 z
void Init_Timer0(void);//定时器初始化
' J8 G! J B5 u9 p5 N# I9 S/*------------------------------------------------; v3 S2 q- h6 W' u2 I; A( w
主函数
/ S+ z. z X# e* u9 |) t7 W4 ]------------------------------------------------*/4 i% L- O4 z8 j2 X; m! u
void main (void)! Y+ a! m" i! T+ u
{+ ]# d- t& J( e' B6 D. G# ] Y2 j
unsigned char num; ' A+ O( y& C9 \" |* e0 H, v# o
* R4 m6 i4 @# h
8 q% n/ p% `' @5 c2 K1 P) Y t Init_Timer0();//定时器初始化$ c( S' M' D) z# U' i% g
7 f4 Z2 b9 y5 j$ _/ k# a3 [, O* R
9 e) o- m9 d% O* h while (1)//主循环' k# l1 c: v- c
{# ^* s9 Z/ ]2 a5 C* g$ ~ V
& p4 B) v) U& ?: U& R: ~0 u$ Z( s
( M! V" | M* w, L, |% x4 p; N
num=KeyScan();
# n+ P# `8 `* B4 R: N" } $ c2 f+ y# m' s. \6 G( N5 x
' m$ t3 S+ b, M3 }4 K+ L
switch(num) 8 w: V) ^! E8 ~8 Z; j
{ b6 }' o% x, g
case 1:hour++;if(hour==24)hour=0; //正常时间 小时 加1
6 k1 Z L5 a& H! f. k( s4 u break;
" n2 s: k) Q. N# Z5 i7 \" u8 m/ \ case 2:hour--;if(hour==255)hour=23; //正常时间 小时减1* G1 V; p9 f+ E" Q+ U+ L
break;) ~0 d& d+ {' u# y4 m) f
case 3:minute++;if(minute==60)minute=0; //分钟加1- T4 d" j, y- B0 Z+ n8 Y
break;6 }8 N9 U l5 h O
case 4:minute--;if(minute==255)minute=59; //分钟减1
! R* h5 _+ f) Y8 I' E8 N" s break;
; J; \* n" W0 o4 M) {0 X: `) P* k default:break;
, Z# U: g' ~9 @ }/* 结束switch语句 */ n! M# {8 v5 p* _+ o
7 D; @; R& j( [: G! c) A0 W8 b
* C# x1 c$ N# U$ f& N if(UpdateTimeFlag==1)
7 o3 h, _1 e# g {
7 \1 v+ }5 X2 C) c UpdateTimeFlag=0;
( j0 n j, ?! M" A5 V( X2 @ S+ j. Z& G6 D
; Z9 A8 z; Y- n7 ~ TempData[0]=dofly_DuanMa[hour/10]; //时 //数据的转换,因我们采用数码管0~9的显示,将数据分开% ?8 K( G# l/ m' K. x, e0 ^# S( U
TempData[1]=dofly_DuanMa[hour%10];
H: A4 j- I* r% p2 ~0 Z TempData[2]=0x40; //加入"-"% A4 B& M7 v3 ^
TempData[3]=dofly_DuanMa[minute/10];//分+ N" G8 y' o! s' r9 Q5 A2 D
TempData[4]=dofly_DuanMa[minute%10];
3 f0 n! h; w& |- G: m# e& K, D TempData[5]=0x40;/ a8 J: a% ?# I
TempData[6]=dofly_DuanMa[second/10];//秒
8 Q& n# U( x& m" Y0 _ TempData[7]=dofly_DuanMa[second%10];
! {+ N2 d' \6 {# w/ W
3 B1 |$ ` ^2 D* R8 B* ^1 G S* a$ h
/ f9 f/ a7 K: W: f+ q } /* 结束if语句 */7 j* f" r, {- w1 J1 F
8 \) R' k( P% A+ k
% ^% r( g; H. c- W7 q; h" h# s
9 g0 k5 q3 }6 f }/* 结束while语句 */
6 R9 f7 E" E- q/ E 6 d& [2 A1 x) E d* K* g
}/* 结束main语句 */
6 B# ?2 n: `. h$ Y E4 G" B) [7 y
7 b5 J H! e. c; M( u8 c7 }; K1 e3 o) O
: m, r+ ]) c4 p" e8 y/*------------------------------------------------
3 H( _2 j- }3 E1 {* u" N! M0 L uS延时函数,含有输入参数 unsigned char t,无返回值4 [0 w" B! X4 C' A: b2 s$ S
unsigned char 是定义无符号字符变量,其值的范围是1 A3 }+ h9 M% j
0~255 这里使用晶振12M,精确延时请使用汇编,大致延时
3 ]) \1 P6 O% A2 ~* G 长度如下 T=tx2+5 uS
9 Y/ ?; L1 P4 N) w) ^+ N------------------------------------------------*/
2 l6 {0 z. x! z' gvoid DelayUs2x(unsigned char t)
! l3 _, a3 s! _) X{
# g) `1 E: ?; q. i; Z8 Z* { while(--t);
Q- Q* k9 w+ w1 u* \5 {9 D- Q}& ~3 Q3 a! D1 L
* g+ H; t" {! ~5 l0 e' E5 y: K8 e1 ]( [" J
$ ]2 @+ E1 ]4 D, d, k/ n& `0 U) N% I" b& D1 N& W, F+ {9 _3 l
/*------------------------------------------------
, C4 G& H# \/ M* ^$ I, ` mS延时函数,含有输入参数 unsigned char t,无返回值
+ ?: Q. ?% i; _8 v unsigned char 是定义无符号字符变量,其值的范围是4 x; u0 h$ T7 q; u% X
0~255 这里使用晶振12M,精确延时请使用汇编
- ?9 Z/ l: I' q; P" W% J) i------------------------------------------------*/
( t% @+ J0 X* [8 wvoid DelayMs(unsigned char t)- T! H* [1 Q" A
{& ]5 N' `2 [( l( K) E: C
- n4 h5 T& y8 P- T; K, ^+ t while(t--) W! v& l5 n' @
{6 R& U0 l) ?1 R3 }
//大致延时1mS
; M/ k: S: U: F# Z( w6 P' ~ DelayUs2x(245);
8 Y4 `: @& K# L( { s DelayUs2x(245);) M: f9 h: U4 t Y A) C
}5 ^$ M8 s: O. s, n- m
}
# X- b3 P1 X; v; g _& C7 W' ?8 ? N4 b* W
/ K; d* V7 v3 k$ Q# Q
1 d* W; @9 ^% K* {) i, X9 E! C2 k. }' u9 T
/*------------------------------------------------* V# `5 O' `% P# z N Y
显示函数,用于动态扫描数码管
' p5 W2 w; `2 ` 输入参数 FirstBit 表示需要显示的第一位,如赋值2表示从第三个数码管开始显示( g' l B% \, n
如输入0表示从第一个显示。
8 L& x" l- }* I4 i) ~ Num表示需要显示的位数,如需要显示99两位数值则该值输入22 V, Q# v( J) |7 W# I+ Q3 O! R5 z" T
------------------------------------------------*/
* f* Y# }7 ?9 E7 Kvoid Display(unsigned char FirstBit,unsigned char Num)! |4 S* i- @9 V8 [5 h' U, D4 I
{
6 [ I+ q9 D8 S% W! R: r( N6 B static unsigned char i=0;: s/ H5 i5 k3 H- `$ [! s- _' X
4 u- h% I0 K. }4 T1 K5 J; u# B5 ]) U3 w
& n% }9 `& r% U; n DataPort=0; //清空数据,防止有交替重影
' G7 G% }& |+ ]3 H' D( c6 e# R LATCH1=1; //段锁存
?7 C! v" b" b" u7 B# e! P( e) J LATCH1=0;
1 z! g: a- d/ D6 A* l* \( `
$ U- Z: x- M2 r( z6 |
3 q! p. |7 l3 U/ Q6 _ DataPort=dofly_WeiMa[i+FirstBit]; //取位码
8 Y& s s# ?, T" q* r- k# h. n2 _" c LATCH2=1; //位锁存
% s+ \% ^6 I+ h* k LATCH2=0;; n1 L* c0 A# c- S! b+ W6 F9 `9 g
( p/ Z6 y- A; r" T0 S, p' U, ^) ]
, k4 H' g7 w6 `+ b: L1 O DataPort=TempData; //取显示数据,段码
; J$ f+ }4 v7 [! H7 G% r LATCH1=1; //段锁存 g0 R# f8 f" @) Q" R
LATCH1=0;1 {+ a. F2 M( S' u
7 P# T7 v! L* t, D! W$ Q) P4 N, N1 a i++;/ I9 t: W$ w6 I$ f6 _
if(i==Num)
+ Z# J1 G+ Y* ]9 m i=0;# `9 ]; o3 P. C1 v7 U- l, [: f ^
9 B# A8 J' t7 l/ J* d$ |
1 ]' y# _; U6 n: ~* N w6 A" C) k
+ n S& b1 ?6 C( ~, a8 f1 G
" c8 R: q: @- s4 {6 t: E* {}( q! O5 P1 | g* x: l% Y2 o( a3 A
. ?8 y! A! R- P, z Z8 h1 u: q( z( R" j6 m: L5 l/ y2 Y, O& K
) D$ \1 U/ H/ ?4 j+ I2 ~4 Q
% A, W0 V2 |7 G# m, S! z( s
/*------------------------------------------------
* L% K+ v8 G& ~0 b) p 定时器初始化子程序
/ h! J- l4 Y+ x3 k------------------------------------------------*/
9 T6 \! k2 K/ q* f8 H) Bvoid Init_Timer0(void)$ C5 H8 I! l* \1 [* O1 V6 |
{
- q; p% V& W, y- R# h TMOD |= 0x01; //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响
- b$ i3 w6 r6 D" [ //TH0=0x00; //给定初值0 I) q0 m- b( \. Y- a2 X3 h f" m8 g0 b
//TL0=0x00;
) W8 ~4 n3 c+ N; i( \. K: { EA=1; //总中断打开9 A- v* x4 n. F* b- ]- I) J7 \
ET0=1; //定时器中断打开# f1 _; r' M# a5 W, U: C. M
TR0=1; //定时器开关打开
: K8 H' F0 i! k0 L* X}$ R/ B& N, F. R0 F# h
. G; V% d" ^( K4 E# F9 m. y5 ?+ H ~3 X, H2 l" G& ]
( G. k2 F1 f4 @. @7 |6 h$ M
& s$ t. ?- Z8 r' T5 U/ s/*------------------------------------------------+ C& G4 I% j! O' s. u+ W- w
定时器中断子程序- p* \7 F1 \9 b+ Q
------------------------------------------------*/
2 Y! @- T L5 Q& Z: uvoid Timer0_isr(void) interrupt 1 : Q1 z3 I1 W3 ~; _
{* v; i8 W. I2 t9 H8 ~9 x
static unsigned int num,i;
1 Y% y/ Y( x$ c- ~9 K TH0=(65536-2000)/256; // 给THO赋初值为(65536-2000),当其加1到65535溢出中断一次 即2ms中断一次 2000为2000/1=2000(在晶振为12MHz的时候)
, Z* q1 v" a) F$ v6 y% O //重新赋值 1.8ms 即1.8ms中断一次 2000为2000/1.09=1834.86(在晶振为11.0592MHz的时候)
; s7 Z/ d5 v6 [" \8 H" e7 q TL0=(65536-2000)%256;9 F& g, j2 C( L C: P' K7 N
1 S% l" |- Y" o) F Display(0,8); // 调用数码管扫描# B; k3 q; z8 [$ Z
& x4 v: t+ M: d% U
: W; W# f& g1 S6 W i++;
8 V+ J W, ^/ |, G! s) g if(i==10) //20ms更新一次
J ^0 y1 \7 o# |! D {
0 z% H# E- }. d3 \- ~- q i=0;) r5 a6 @7 ^* ^ T
UpdateTimeFlag=1; //更新时间志位置19 m: y" ^; U9 o& v& H% a4 ]" O
}
4 Y8 z. p3 s6 p( p# r1 V. M
; Z( |) m6 C- h0 e5 a# \ - [8 t/ j5 p3 \3 P2 z! ?
1 {# H( [2 H3 t2 B3 x5 ~/ L num++;
, h- r( o2 l1 n9 V# l0 X [ if(num==500) //大致1s: ?) A' n7 ~; F8 L+ f0 D, U: V
{
" Q7 M4 q: y( v; L5 S num=0;
3 y/ o5 O: X/ ^ C+ I8 ]8 l second++;
: |4 B1 ~. S/ M + \1 f* u3 `+ o2 u- {$ q% {! Q( ]
if(minute == 59) //当分钟到59的时响蜂鸣器
+ k( I% R% ` U. e {
7 ^4 f: ]/ a' F' i! D9 M if(second >= 51) //隔一秒响一下
3 _3 U; O2 ?/ K1 F* S { 9 B" I; {: c0 p% E; k# H
SPK=0; /* 开蜂鸣器 */" i: O, |3 G C$ z! @6 b6 G
DelayMs(1000);1 @0 h6 s6 e" R6 i
SPK=1; /* 关蜂鸣器 */2 E# P+ \+ C) _# \
second++; - n: p% ~4 l" R
}
( f% ^# X+ D1 T }
! I! T) I8 A: j# `7 P) A' A , e: P: ]1 n7 [' u; _, x
if(second==60) //秒到60,分钟加1* C1 r/ Y* ]5 U5 a. ^' x& E
{- ]) G% B7 L3 L9 y. h
second=0; / B, o2 @2 R: L; B# J
minute++; 7 d9 U; F4 r: g' J8 P8 A
" h# |* f- [' ^5 n) M. L if(minute==60)//分钟到60,小时加1) }- q( D9 A# s# K5 G
{
2 C, I1 D; B* p, l% Y3 @ minute=0;8 @( ?. p2 R4 n: Z8 g4 L- P
& u- ^" m9 c- T9 ^- ~8 B' t% c6 }( V SPK=1; /* 关蜂鸣器 */
0 H$ @& `; ]% I 0 m" S' V9 G# L4 L3 G- x) U
hour++;7 I) n; h# w9 a' P
9 v4 d' m8 v6 w! i- [
if(hour==24)//小时到24,回零
9 o7 n- o9 m& v% `* B$ |4 c hour=0;% H- s1 E: t, j3 ^5 ~8 B% q* V0 y
}9 T* d% O6 j: _
9 S6 d8 g# P% S. s6 _. V }$ }- G) P, v8 y6 K/ k
x1 ^! t. ~; i5 _7 X }
2 ]3 {2 R y6 Z}* l# ^# r/ }: Z5 H
) }* W. e" P& n" ^' N
$ i- }# e7 @) Y4 {6 ?; |2 P: _' v. a: {) D8 w3 V9 {) d0 z
9 u6 u- E* R& r9 [& }3 O" [6 K/*------------------------------------------------
0 h8 s) V5 H% @2 D按键扫描函数,返回扫描键值* \1 Q$ x0 @) `# p+ O9 b- Y
------------------------------------------------*/
- s8 F0 B1 _; Q: W u* Ounsigned char KeyScan(void)
- l, y, Y0 {. j- O- r5 S8 a! k- x{/ E$ }: W H" l+ W: a5 i
unsigned char keyvalue;' I2 { D6 h& j4 N- f
if(KeyPort!=0xff)! w4 v+ O5 w! {9 F
{
9 P% j8 `/ Y$ `1 L5 w3 _) a5 U DelayMs(10);/ c- m/ { M, r" K
if(KeyPort!=0xff)7 D* X7 Y! B' B+ P: G9 B. |! _, |
{
# `. H4 L( M& q. {' K8 s5 o keyvalue=KeyPort;
% s0 ^+ ~4 U! _1 P. v , L. e1 |/ y# T+ p
while(KeyPort!=0xff);; ?2 t) G1 U H
0 H9 [. x/ O( r& g switch(keyvalue)
1 V# M* ?- z9 G7 d {
5 ]; N- f' W" |3 M" k case 0xfe:return 1;break; //单个按键控制
6 N1 v6 k: K# `% o case 0xfd:return 2;break;
& E& u% D% t! [" f }6 F case 0xfb:return 3;break;
' M) Q& E: H+ |1 o8 k0 j7 C/ |8 ? case 0xf7:return / N9 K8 A5 L7 `
9 v+ b8 D, W$ {# C) E3 c
4 t$ }" k8 Z' P( ^, h
4 k: g! v! j! z4 t* V4 ?1 q& V5 B" Y8 [/ {+ Q$ a6 p, m9 Q. x
…………限于本文篇幅 余下代码请从论坛下载附件…………/ ], R: J- t6 Y4 X
' |! X, K+ _2 ~/ Q( o1 E
J7 A" F2 _0 h y! k f |
|