用52单片机代码实现设计一个0.01秒精度的秒表,从00.00秒~19.99秒循环正计时并显示在数码管上,设置一个报警门限值,范围08~12,初始门限值为10,选取两个按键可以对其进行加、减操作,并显示在数码管上当秒表数值大于该门限值,则发出声光报警,即用一个发光二极管指示灯闪烁,点亮0.1s,熄灭0.3s表示光报警;用蜂鸣器响0.1s,静音0.3s表示声报警;再增加一个按键用于控制秒表暂停或继续计时。暂停期间,声光报警失效
时间: 2023-04-10 21:03:10 浏览: 451
单片机秒表并能实现报警
以下是一个可能的实现,仅供参考:
```c
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit beep = P1^5; // 蜂鸣器
sbit led = P1^6; // 发光二极管
uchar code table[] = { // 数码管显示表
0x3f, 0x06, 0x5b, 0x4f, 0x66,
0x6d, 0x7d, 0x07, 0x7f, 0x6f
};
uchar second = 0; // 秒表计数器
uchar limit = 10; // 报警门限值
bit paused = 0; // 秒表是否暂停
void delay(uint ms) { // 延时函数,单位毫秒
uint i, j;
for (i = 0; i < ms; i++) {
for (j = 0; j < 125; j++);
}
}
void display(uchar num) { // 数码管显示函数
P0 = table[num / 10];
P2 = 0xfe;
delay(1);
P0 = table[num % 10];
P2 = 0xfd;
delay(1);
}
void timer0() interrupt 1 { // 定时器0中断函数,每1ms执行一次
static uchar cnt = 0;
TH0 = (65536 - 1000) / 256; // 重新设置定时器初值
TL0 = (65536 - 1000) % 256;
cnt++;
if (cnt == 10) { // 每10ms更新一次秒表计数器
cnt = 0;
if (!paused) second++;
if (second >= 200) second = 0; // 循环计时
if (second == limit * 10) { // 达到门限值,触发报警
beep = 1;
led = 1;
delay(100);
beep = 0;
led = 0;
delay(300);
}
}
}
void main() {
TMOD = 0x01; // 定时器0工作在模式1
TH0 = (65536 - 1000) / 256; // 初值
TL0 = (65536 - 1000) % 256;
ET0 = 1; // 允许定时器0中断
EA = 1; // 允许总中断
TR0 = 1; // 启动定时器0
while (1) {
if (second % 10 == 0) { // 每100ms更新一次数码管显示
display(second / 10);
}
if (!paused && (second == 199 || second == 99)) { // 暂停期间不响报警
beep = 1;
delay(100);
beep = 0;
delay(300);
}
if (P3_0 == 0) { // 按键1,门限值加1
while (P3_0 == 0);
limit++;
if (limit > 12) limit = 12;
display(limit);
}
if (P3_1 == 0) { // 按键2,门限值减1
while (P3_1 == 0);
limit--;
if (limit < 8) limit = 8;
display(limit);
}
if (P3_2 == 0) { // 按键3,暂停或继续计时
while (P3_2 == 0);
paused = !paused;
if (paused) {
beep = 0;
led = 0;
}
}
}
}
```
这个程序使用了定时器0来实现毫秒级的计时,每10ms更新一次秒表计数器。数码管显示和按键检测都在主循环中完成。报警时,发光二极管和蜂鸣器都会闪烁一段时间。按键1和2分别用于增加和减少门限值,按键3用于暂停或继续计时。
阅读全文