请使用51单片机设计秒倒计时器 要求:1.通过"设定"、"+"、"一"键设定秒定时(最多99s),按"确定"键确定倒计时时间; 2.将倒计时时间通过两位8位数码输出; 3.倒计时时间到 LED 灯闪烁报警;具体代码怎么写
时间: 2023-07-19 09:09:37 浏览: 92
好的,下面是秒倒计时器的51单片机程序,具体注释在代码中,希望能对您有所帮助:
```
#include <reg51.h>
// 定义数码管显示数组
unsigned char code LED_Disp[10] = {
0xc0, // 0
0xf9, // 1
0xa4, // 2
0xb0, // 3
0x99, // 4
0x92, // 5
0x82, // 6
0xf8, // 7
0x80, // 8
0x90 // 9
};
// 定义按键扫描函数
unsigned char Key_Scan(void)
{
unsigned char key_val = 0xff; // 定义按键返回值,默认为无按键按下
if (P3 != 0xff) { // 判断是否有按键按下
delay_ms(10); // 消抖
if (P3 != 0xff) { // 再次判断是否有按键按下
switch(P3) { // 判断按下的是哪个按键
case 0xfe: key_val = 0; break; // 设定键
case 0xfd: key_val = 1; break; // 加键
case 0xfb: key_val = 2; break; // 减键
case 0xf7: key_val = 3; break; // 确定键
}
while (P3 != 0xff); // 等待按键释放
}
}
return key_val; // 返回按键值
}
// 定义延时函数
void delay_ms(unsigned int ms)
{
unsigned int i, j;
for (i = 0; i < ms; i++) {
for (j = 0; j < 120; j++);
}
}
// 定义中断处理函数
void Timer0_ISR() interrupt 1
{
static unsigned char count = 0; // 定义计数器,每1秒加1
static unsigned char disp_data[2] = {0, 0}; // 定义数码管显示数据数组
TH0 = 0x4c; // 定时器初值,每10ms进入一次中断
TL0 = 0x00;
count++; // 计数器加1
if (count == 100) { // 如果计数器加到100,则表示1秒已过
count = 0; // 计数器清零
if (disp_data[0] == 0 && disp_data[1] == 0) { // 如果倒计时时间已到达0,则开始报警
P1 = 0xff; // LED灯闪烁
delay_ms(500);
P1 = 0x00;
delay_ms(500);
} else { // 如果倒计时时间还未到达0,则继续倒计时
if (disp_data[1] == 0) { // 判断是否需要借位
disp_data[1] = 9;
disp_data[0]--;
} else {
disp_data[1]--;
}
// 更新数码管显示数据
P0 = LED_Disp[disp_data[0]];
P2 = LED_Disp[disp_data[1]];
}
}
}
void main()
{
unsigned char key_val = 0xff; // 定义按键值,默认为无按键按下
unsigned char time_set = 0; // 定义倒计时时间(秒)
unsigned char disp_data[2] = {0, 0}; // 定义数码管显示数据数组
TMOD = 0x01; // 定时器T0使用模式1
TH0 = 0x4c; // 定时器初值,每10ms进入一次中断
TL0 = 0x00;
ET0 = 1; // 开启定时器T0中断
EA = 1; // 开启总中断
while (1) {
key_val = Key_Scan(); // 扫描按键
switch (key_val) {
case 0: // 设定键
disp_data[0] = 0;
disp_data[1] = 0;
// 更新数码管显示数据
P0 = LED_Disp[disp_data[0]];
P2 = LED_Disp[disp_data[1]];
while (Key_Scan() != 3) { // 等待确定键按下
key_val = Key_Scan();
if (key_val == 1) { // 加键
if (disp_data[0] == 9 && disp_data[1] == 9) { // 最大99秒
disp_data[0] = 9;
disp_data[1] = 9;
} else {
if (disp_data[1] == 9) { // 判断是否需要进位
disp_data[1] = 0;
disp_data[0]++;
} else {
disp_data[1]++;
}
}
// 更新数码管显示数据
P0 = LED_Disp[disp_data[0]];
P2 = LED_Disp[disp_data[1]];
delay_ms(200); // 延时200ms,防止按键抖动
} else if (key_val == 2) { // 减键
if (disp_data[0] == 0 && disp_data[1] == 0) { // 最小0秒
disp_data[0] = 0;
disp_data[1] = 0;
} else {
if (disp_data[1] == 0) { // 判断是否需要借位
disp_data[1] = 9;
disp_data[0]--;
} else {
disp_data[1]--;
}
}
// 更新数码管显示数据
P0 = LED_Disp[disp_data[0]];
P2 = LED_Disp[disp_data[1]];
delay_ms(200); // 延时200ms,防止按键抖动
}
}
time_set = disp_data[0] * 10 + disp_data[1]; // 将设定的时间保存在程序中
break;
case 3: // 确定键
TH0 = 0x4c; // 定时器初值,每10ms进入一次中断
TL0 = 0x00;
count = 0; // 计数器清零
disp_data[0] = time_set / 10; // 将设定的时间分解成两位数码管显示数据
disp_data[1] = time_set % 10;
// 更新数码管显示数据
P0 = LED_Disp[disp_data[0]];
P2 = LED_Disp[disp_data[1]];
break;
}
}
}
```
以上是秒倒计时器的51单片机程序,您可以根据需要进行修改和调试。希望能对您有所帮助。
阅读全文