秒表-六位数码管有效显示2
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
秒表-六位数码管有效显示 C51单片机
1.#include
2.#include
3.#define uchar unsigned char
1.void delay_ms(uchar ms); // 延时毫秒@12M,ms最大值255
2.void key_scan(); // 按键扫描
3.void key_to(); // 按键处理
4.
5.uchar code dis_code[11] = {0xc0,0xf9,0xa4,0xb0,0x99, //段
码表
6.//
0 1 2 3 4 对应内容
7. 0x92,0x82,0xf8,0x80,0x90,0xbf};
8.// 5 6 7 8 9 - 9.
10.uchar data dis[8]; // dis[0]为百分之一秒值,dis[1]为十分之
一秒值
11. // dis[2],dis[5]为'-'段码的偏移量
12. // dis[3]为秒个位值,dis[4]为秒十位
值
13. // dis[6]为分个位值,dis[7]为分十位
值
14.
15.uchar data dot = 0; // 百分之一秒计数器(0.00s-0.99s)
16.uchar data sec = 0; // 秒计数器(00s-59s)
17.uchar data min = 0; // 分计数器(00m-99m)
18.
19.uchar data dis_b; // dis_b为位码选通数码管
20.uchar data dis_r; // dis_r为取段码时的偏移量
21.
22.uchar data key_t = 0; // 按键次数,初始为0
23.
24.sbit K = P1^4; // K键与P1.4相连
25.
26.void main()
27.{
28. P2 = 0xff; // 关所有数码管
29. P1 = 0xff; // p1为准双向口,作输入时先写1
30. dis[2] = 10; // '-'在段码表中偏移量为10
31. dis[5] = 10; // '-'在段码表中偏移量为10
32. dis_b = 0x7f; // 初始选通P2.7口数码管
33. dis_r = 0; // 初始化偏移量为0
34.
35. TMOD = 0x11; // 定时/计数器0,1工作于方式1
36. TH0 = 0xd8; // 预置定时常数55536(d8f0),产生10ms时
基信号
37. TL0 = 0xf0;
38. TH1 = 0xfc; // 预置定时常数64536(fc18),产生1ms间
隔用于动态显示
39. TH1 = 0x18;
40. EA = 1; // 开总中断
41. ET0 = 1; // 定时/计数器0允许中断
42. ET1 = 1; // 定时/计数器1允许中断
43. TR0 = 0; // 关闭定时/计数器0
44. TR1 = 1; // 启动定时/计数器1
45. while(1)
46. {
47. if(K != 1) // 有键按下
48. {
49. delay_ms(10); // 延时10ms去抖
50. if(K != 1) // 确定是有键按下
51. {
52. while(K != 1); // 等待键松开
53. key_to(); // 按键处理
54. }
55. }
56. }
57.}
58.void key_to() // 按键处理子程序
59.{
60. key_t++; // 按键次数加1
61. if(key_t == 1) // 第一次按下
62. TR0 = 1; // 启动定时器0
63. else
64. {
65. if(key_t == 2) // 第二次按下
66. TR0 = 0; // 关闭定时器0
67. else
68. {
69. if(key_t == 3) // 第三次按下
70. {
71. dot = 0; // 三个计数器清零
72. sec = 0;
73. min = 0;
74. key_t = 0; // 按键次数清零
75. }
76. }
77. }
78.
79.}
80.void tiem0(void) interrupt 1 // T/C0中断服务程序(产生10ms时
基信号)
81.{
82. dot++; // 百分之一秒计数器加1
83. if(dot == 100) // 计数值到100
84. {
85. dot = 0; // 清零
86. sec++; // 秒计数器加1(进位
10ms*100=1s)
87. if(sec == 60) // 秒计数值到60
88. {
89. sec = 0; // 秒计数器清零
90. min++; // 分计数器加1(进位60s=1m)
91. if(min == 100) // 分计数到100
92. min = 0; // 分计数器清零
93. }
94. }
95. TH0 = 0xd8; // 重置定时常数
96. TL0 = 0xf0;
97.}
98.void time1(void) interrupt 3 // T/C1中断服务程序(延时1ms数码
管动态显示)
99.{
100. dis[0] = dot % 10; // 百分之一秒计数器个位分离出来赋绐dis[0]
101. dis[1] = dot / 10; // 百分之一秒计数器十位分离出来赋绐dis[1]
102. dis[3] = sec % 10; // 秒计数器个位赋绐dis[3] 103. dis[4] = sec / 10; // 秒计数器十位赋绐dis[4] 104. dis[6] = min % 10; // 分计数器个位赋绐dis[6] 105. dis[7] = min / 10; // 分计数器十位赋绐dis[7] 106.
107.P0 = dis_code[dis[dis_r]]; // 段码送P0口
(dis[0]...dis[7])
108.P2 = dis_b; // 位码送P2口
109.
110. dis_r++; // 偏移量加1,下次中断时显示下个数
111. dis_r &= 0x07; // dis_r增到8时自动清0(使之在0到7间循环)
112.