单片机练习 - 计时器
利用单片机的定时/计数器(单片机练习 - 定时器 ), 这天写了一个计时器, 精确到小数0.01秒, 拥有一个开始/暂停键, 一个清零键...
6位数码管与单片机的连接电路图
![]()
按键S2, S3与单片机的连接电路图: 其中S2与P3.4连, S3与P3.5连接...
![]()
计时器
1
#include <reg52.H>
2
#include <intrins.H>
3
//秒表, 精确到小数1%秒, 即10ms, 一个开始/暂停键, 一个停止清零键
4
//准确定时采用定时器1, 工作方式1
5![]()
6
sbit wela = P2^7; //数码管位选
7
sbit dula = P2^6; //数码管段选
8
sbit ds = P2^2;
9
unsigned char th, tl;
10
unsigned char datas[] = {0, 0, 0, 0, 0, 0};//分秒毫秒
11![]()
12
//0-F数码管的编码(共阴极)
13
unsigned char code table[]={0x3f,0x06,0x5b,0x4f,0x66,
14
0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
15
//0-9数码管的编码(共阴极), 带小数点
16
unsigned char code tableWidthDot[]={0xbf, 0x86, 0xdb, 0xcf, 0xe6, 0xed, 0xfd,
17
0x87, 0xff, 0xef};
18![]()
19
//延时函数, 对于11.0592MHz时钟, 例i=5,则大概延时5ms.
20
void delay(unsigned int i)
21
{
22
unsigned int j;
23
while(i--)
24
{
25
for(j = 0; j < 125; j++);
26
}
27
}
28![]()
29
void display()
30
{
31
unsigned char count;
32
for(count = 0; count < 6; count++)
33
{
34
//关位选, 去除对上一位的影响
35
P0 = 0xff;
36
wela = 1; //打开锁存, 给它一个下降沿量
37
wela = 0;
38
//段选
39
if(count == 1 || count == 3)
40
{
41
P0 = tableWidthDot[datas[count]]; //显示带小数点数字, 作为分秒, 秒与毫秒的分隔
42
}
43
else
44
{
45
P0 = table[datas[count]]; //显示数字
46
}
47
dula = 1; //打开锁存, 给它一个下降沿量
48
dula = 0;
49![]()
50
//位选
51
P0 = _crol_(0xfe, count); //选择第(count + 1) 个数码管
52
wela = 1; //打开锁存, 给它一个下降沿量
53
wela = 0;
54
delay(1);
55
}
56
}
57![]()
58
sbit S2 = P3^4; //键S2, 作开始/暂停
59
sbit S3 = P3^5; //键S3, 清零
60
sbit S4 = P3^6; //键S4
61
sbit S5 = P3^7; //键S5
62
unsigned char tmp;
63![]()
64
//等待键被释放
65
void waitFreeKey()
66
{
67
while(!S2 || !S3)
68
{
69
display(); // 等待期间要显示
70
}
71
}
72![]()
73
//检测是否有键按下, 并执行相应功能
74
void checkKey()
75
{
76
if(!S2)
77
{
78
delay(7); //延时大约10ms, 去抖动
79
if(!S2) //开始/暂停键按下
80
{
81
TR1 = ~TR1;
82
}
83
}
84![]()
85
if(!S3)
86
{
87
delay(14); //延时大约10ms, 去抖动
88
if(!S3) //清零键按下
89
{
90
TR1 = 0;
91
TH1 = th;
92
TL1 = tl;
93
for(tmp = 0; tmp < 6; tmp++)
94
{
95
datas[tmp] = 0;
96
}
97
}
98
}
99
//等待键被释放
100
waitFreeKey();
101
}
102![]()
103
void main()
104
{
105
th = (65536 - 10000/1.085) / 256; //定时10ms
106
tl = (65536 - 10000/1.085) - th * 256;
107
TH1 = th;
108
TL1 = tl;
109
EA = 1; //开中断
110
ET1 = 1; //允许定时器1中断请求
111
TMOD = 0x10; //定时器工作方式1
112
while(1)
113
{
114
checkKey(); //检测是否就键按下
115
display(); //显示计时值
116
}
117
}
118![]()
119
//定时器1中断响应函数
120
void time1() interrupt 3
121
{
122
TH1 = th; //重置计数值
123
TL1 = tl;
124![]()
125
datas[5]++; //0.01秒
126
if(datas[5] == 10)
127
{
128
datas[5] = 0;
129
datas[4]++; //0.1秒
130
if(datas[4] == 10)
131
{
132
datas[4] = 0;
133
datas[3]++; //秒
134
if(datas[3] == 10)
135
{
136
datas[3] = 0;
137
datas[2]++; //10秒
138
if(datas[2] == 6)
139
{
140
datas[2] = 0;
141
datas[1]++; //分
142
if(datas[1] == 10)
143
{
144
datas[1] = 0;
145
datas[0]++; //10分
146
if(datas[0] == 6)
147
{
148
datas[0] = 0;
149
P1 <<= 1;
150
}
151
}
152
}
153
}
154
}
155
}
156
}
效果图:
6小时23分44.98秒
![]()
0时0分30.73秒
6位数码管与单片机的连接电路图

按键S2, S3与单片机的连接电路图: 其中S2与P3.4连, S3与P3.5连接...
1
#include <reg52.H>2
#include <intrins.H>3
//秒表, 精确到小数1%秒, 即10ms, 一个开始/暂停键, 一个停止清零键4
//准确定时采用定时器1, 工作方式15

6
sbit wela = P2^7; //数码管位选7
sbit dula = P2^6; //数码管段选8
sbit ds = P2^2;9
unsigned char th, tl;10
unsigned char datas[] = {0, 0, 0, 0, 0, 0};//分秒毫秒11

12
//0-F数码管的编码(共阴极)13
unsigned char code table[]={0x3f,0x06,0x5b,0x4f,0x66,14
0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};15
//0-9数码管的编码(共阴极), 带小数点16
unsigned char code tableWidthDot[]={0xbf, 0x86, 0xdb, 0xcf, 0xe6, 0xed, 0xfd, 17
0x87, 0xff, 0xef};18

19
//延时函数, 对于11.0592MHz时钟, 例i=5,则大概延时5ms.20
void delay(unsigned int i)21
{22
unsigned int j;23
while(i--)24
{25
for(j = 0; j < 125; j++);26
}27
}28

29
void display() 30
{31
unsigned char count;32
for(count = 0; count < 6; count++)33
{34
//关位选, 去除对上一位的影响35
P0 = 0xff; 36
wela = 1; //打开锁存, 给它一个下降沿量37
wela = 0;38
//段选39
if(count == 1 || count == 3)40
{41
P0 = tableWidthDot[datas[count]]; //显示带小数点数字, 作为分秒, 秒与毫秒的分隔42
}43
else44
{45
P0 = table[datas[count]]; //显示数字46
}47
dula = 1; //打开锁存, 给它一个下降沿量48
dula = 0;49

50
//位选 51
P0 = _crol_(0xfe, count); //选择第(count + 1) 个数码管52
wela = 1; //打开锁存, 给它一个下降沿量53
wela = 0;54
delay(1); 55
}56
}57

58
sbit S2 = P3^4; //键S2, 作开始/暂停 59
sbit S3 = P3^5; //键S3, 清零60
sbit S4 = P3^6; //键S461
sbit S5 = P3^7; //键S562
unsigned char tmp; 63

64
//等待键被释放 65
void waitFreeKey()66
{67
while(!S2 || !S3)68
{69
display(); // 等待期间要显示70
}71
}72

73
//检测是否有键按下, 并执行相应功能74
void checkKey()75
{76
if(!S2)77
{78
delay(7); //延时大约10ms, 去抖动79
if(!S2) //开始/暂停键按下80
{81
TR1 = ~TR1;82
}83
}84

85
if(!S3)86
{87
delay(14); //延时大约10ms, 去抖动88
if(!S3) //清零键按下89
{90
TR1 = 0;91
TH1 = th;92
TL1 = tl;93
for(tmp = 0; tmp < 6; tmp++)94
{95
datas[tmp] = 0;96
}97
}98
}99
//等待键被释放 100
waitFreeKey();101
}102

103
void main()104
{105
th = (65536 - 10000/1.085) / 256; //定时10ms106
tl = (65536 - 10000/1.085) - th * 256;107
TH1 = th;108
TL1 = tl;109
EA = 1; //开中断110
ET1 = 1; //允许定时器1中断请求111
TMOD = 0x10; //定时器工作方式1112
while(1)113
{114
checkKey(); //检测是否就键按下115
display(); //显示计时值116
}117
}118

119
//定时器1中断响应函数120
void time1() interrupt 3121
{122
TH1 = th; //重置计数值123
TL1 = tl;124

125
datas[5]++; //0.01秒126
if(datas[5] == 10)127
{128
datas[5] = 0;129
datas[4]++; //0.1秒130
if(datas[4] == 10)131
{132
datas[4] = 0;133
datas[3]++; //秒134
if(datas[3] == 10)135
{136
datas[3] = 0;137
datas[2]++; //10秒138
if(datas[2] == 6)139
{140
datas[2] = 0;141
datas[1]++; //分142
if(datas[1] == 10)143
{144
datas[1] = 0;145
datas[0]++; //10分146
if(datas[0] == 6)147
{148
datas[0] = 0;149
P1 <<= 1;150
}151
}152
}153
}154
}155
}156
}效果图:
6小时23分44.98秒

0时0分30.73秒


unsigned 
浙公网安备 33010602011771号