单片机练习 - 计时器
利用单片机的定时/计数器(单片机练习 - 定时器 ), 这天写了一个计时器, 精确到小数0.01秒, 拥有一个开始/暂停键, 一个清零键...
6位数码管与单片机的连接电路图
按键S2, S3与单片机的连接电路图: 其中S2与P3.4连, S3与P3.5连接...
效果图:
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, 工作方式1
5
6sbit wela = P2^7; //数码管位选
7sbit dula = P2^6; //数码管段选
8sbit ds = P2^2;
9unsigned char th, tl;
10unsigned char datas[] = {0, 0, 0, 0, 0, 0};//分秒毫秒
11
12//0-F数码管的编码(共阴极)
13unsigned char code table[]={0x3f,0x06,0x5b,0x4f,0x66,
14 0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
15//0-9数码管的编码(共阴极), 带小数点
16unsigned char code tableWidthDot[]={0xbf, 0x86, 0xdb, 0xcf, 0xe6, 0xed, 0xfd,
17 0x87, 0xff, 0xef};
18
19//延时函数, 对于11.0592MHz时钟, 例i=5,则大概延时5ms.
20void delay(unsigned int i)
21{
22 unsigned int j;
23 while(i--)
24 {
25 for(j = 0; j < 125; j++);
26 }
27}
28
29void 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
58sbit S2 = P3^4; //键S2, 作开始/暂停
59sbit S3 = P3^5; //键S3, 清零
60sbit S4 = P3^6; //键S4
61sbit S5 = P3^7; //键S5
62unsigned char tmp;
63
64//等待键被释放
65void waitFreeKey()
66{
67 while(!S2 || !S3)
68 {
69 display(); // 等待期间要显示
70 }
71}
72
73//检测是否有键按下, 并执行相应功能
74void 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
103void 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中断响应函数
120void 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}
1#include <reg52.H>
2#include <intrins.H>
3//秒表, 精确到小数1%秒, 即10ms, 一个开始/暂停键, 一个停止清零键
4//准确定时采用定时器1, 工作方式1
5
6sbit wela = P2^7; //数码管位选
7sbit dula = P2^6; //数码管段选
8sbit ds = P2^2;
9unsigned char th, tl;
10unsigned char datas[] = {0, 0, 0, 0, 0, 0};//分秒毫秒
11
12//0-F数码管的编码(共阴极)
13unsigned char code table[]={0x3f,0x06,0x5b,0x4f,0x66,
14 0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
15//0-9数码管的编码(共阴极), 带小数点
16unsigned char code tableWidthDot[]={0xbf, 0x86, 0xdb, 0xcf, 0xe6, 0xed, 0xfd,
17 0x87, 0xff, 0xef};
18
19//延时函数, 对于11.0592MHz时钟, 例i=5,则大概延时5ms.
20void delay(unsigned int i)
21{
22 unsigned int j;
23 while(i--)
24 {
25 for(j = 0; j < 125; j++);
26 }
27}
28
29void 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
58sbit S2 = P3^4; //键S2, 作开始/暂停
59sbit S3 = P3^5; //键S3, 清零
60sbit S4 = P3^6; //键S4
61sbit S5 = P3^7; //键S5
62unsigned char tmp;
63
64//等待键被释放
65void waitFreeKey()
66{
67 while(!S2 || !S3)
68 {
69 display(); // 等待期间要显示
70 }
71}
72
73//检测是否有键按下, 并执行相应功能
74void 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
103void 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中断响应函数
120void 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秒