项目8:倒计时定时提醒装置 任务1:通过串口下发倒计时定时提醒,定时时间范围(0-999s) 倒计时过程中无法更新定时时间;任务2:动态数码管显示定时时间; 任务3:按下独立按键K1,利用定时器按秒开始倒计时; 任务4:倒计时大于20s时,绿灯闪烁,10s—20s时黄灯闪烁,10s内红灯闪烁; 任务5:按下独立按键K2,停止倒计时提醒,倒计时零; 任务6:倒计时结束后,蜂鸣器发声 任务7:按下独立按键K3,蜂鸣器停止发声;
时间: 2023-07-18 18:29:25 浏览: 57
以下是使用C语言在51单片机上实现倒计时定时提醒、动态数码管显示、闪烁灯、蜂鸣器的代码:
```c
#include <reg51.h>
#include <stdio.h>
#define LED_GREEN P1_0
#define LED_YELLOW P1_1
#define LED_RED P1_2
#define KEY_K1 P3_1
#define KEY_K2 P3_2
#define KEY_K3 P3_3
#define BUZZER P3_7
#define DIO P2_0
#define RCLK P2_1
#define SCLK P2_2
unsigned char code SEG_TAB[] = { // 数码管段码表
0x3F, // 0
0x06, // 1
0x5B, // 2
0x4F, // 3
0x66, // 4
0x6D, // 5
0x7D, // 6
0x07, // 7
0x7F, // 8
0x6F // 9
};
int count = 0; // 倒计时计数器
int time = 0; // 定时时间
int sec = 0; // 秒数
int min = 0; // 分钟数
int hour = 0; // 小时数
void delay(unsigned int t) // 延时函数
{
unsigned int i, j;
for (i = t; i > 0; i--)
for (j = 110; j > 0; j--);
}
void timer0() interrupt 1 // 定时器0中断函数
{
TH0 = 0xFC; // 定时器重装值,时钟频率为11.0592MHz,定时1ms
TL0 = 0x67;
count--; // 每次中断计数器减1
}
void init() // 初始化函数
{
TMOD = 0x01; // 定时器0,模式1
TH0 = 0xFC; // 定时器重装值,时钟频率为11.0592MHz,定时1ms
TL0 = 0x67;
TR0 = 1; // 启动定时器0
ET0 = 1; // 允许定时器0中断
EA = 1; // 全局中断允许
SCLK = 0;
RCLK = 0;
DIO = 1;
}
void writeData(unsigned char dat) // 数码管写数据函数
{
unsigned char i;
for (i = 0; i < 8; i++)
{
DIO = dat & 0x80;
dat <<= 1;
SCLK = 1;
SCLK = 0;
}
}
void writeByte(unsigned char dat, unsigned char num) // 数码管写字节函数
{
unsigned char i;
RCLK = 0;
for (i = 0; i < num; i++)
{
writeData(dat);
}
RCLK = 1;
RCLK = 0;
}
void displayTime() // 数码管动态显示时间函数
{
unsigned char seg1 = sec % 10;
unsigned char seg2 = sec / 10;
unsigned char seg3 = min % 10;
unsigned char seg4 = min / 10;
unsigned char seg5 = hour % 10;
unsigned char seg6 = hour / 10;
writeByte(SEG_TAB[seg1], 1);
writeByte(SEG_TAB[seg2] | 0x80, 1);
writeByte(SEG_TAB[seg3], 1);
writeByte(SEG_TAB[seg4] | 0x80, 1);
writeByte(SEG_TAB[seg5], 1);
writeByte(SEG_TAB[seg6], 1);
}
void main()
{
init();
while (1)
{
if (time == 0) // 无定时时间时等待串口下发
{
unsigned char dat;
while (1)
{
if (RI == 1) // 接收到串口数据
{
dat = SBUF;
if (dat >= '0' && dat <= '9') // 数字字符
{
time = time * 10 + dat - '0'; // 组合定时时间
}
else if (dat == '\r') // 回车字符,接收完成
{
printf("定时时间:%d秒\r\n", time);
break;
}
}
}
}
if (KEY_K1 == 0 && count == 0) // 按下K1并且倒计时未开始
{
printf("倒计时开始\r\n");
count = time;
sec = 0;
min = 0;
hour = 0;
}
if (count > 0) // 倒计时过程中
{
displayTime(); // 数码管动态显示时间
if (count > 20) // 倒计时大于20s时,绿灯闪烁
{
LED_GREEN = ~LED_GREEN; // 绿灯闪烁
LED_YELLOW = 0;
LED_RED = 0;
delay(500);
}
else if (count > 10 && count <= 20) // 10s—20s时,黄灯闪烁
{
LED_YELLOW = ~LED_YELLOW; // 黄灯闪烁
LED_GREEN = 0;
LED_RED = 0;
delay(500);
}
else if (count > 0 && count <= 10) // 10s内,红灯闪烁
{
LED_RED = ~LED_RED; // 红灯闪烁
LED_GREEN = 0;
LED_YELLOW = 0;
delay(500);
if (count == 1) BUZZER = 1; // 最后1秒,蜂鸣器响
}
else // 倒计时结束
{
LED_GREEN = 0;
LED_YELLOW = 0;
LED_RED = 0;
BUZZER = 0;
while (1)
{
if (KEY_K2 == 0) // 按下K2,停止倒计时提醒
{
printf("倒计时停止\r\n");
count = 0;
time = 0;
sec = 0;
min = 0;
hour = 0;
break;
}
else if (KEY_K3 == 0) // 按下K3,蜂鸣器停止发声
{
BUZZER = 0;
}
else // 倒计时结束,蜂鸣器发声
{
BUZZER = ~BUZZER;
delay(100);
}
}
}
}
if (count > 0 && count % 1000 == 0) // 每1000ms计算一次时间
{
count--;
sec++;
if (sec == 60)
{
sec = 0;
min++;
}
if (min == 60)
{
min = 0;
hour++;
}
if (hour == 24)
{
hour = 0;
}
}
}
}
```
在代码中,使用串口接收下发的定时时间,并在倒计时开始前等待串口下发。使用定时器0中断来实现倒计时,每次中断计数器减1,并使用数码管动态显示倒计时的时间。根据倒计时的时间,判断灯的状态和是否响蜂鸣器。当倒计时结束后,使用while循环来判断是否按下了K2或K3按键,以实现停止倒计时提醒或停止蜂鸣器发声的功能。在每1000ms中断中计算时间,并实现时分秒的累加。