项目8:倒计时定时提醒装置 任务1:通过串口下发倒计时定时提醒,定时时间范围(0-999s) 倒计时过程中无法更新定时时间;任务2:动态数码管显示定时时间; 任务3:按下独立按键K1,利用定时器按秒开始倒计时; [任务4:倒计时大于20s时,绿灯闪烁,10s—20s时黄灯闪烁,10s内红灯闪烁; 任务5:按下独立按键K2,停止倒计时提醒,倒计时零; 任务6:倒计时结束后,蜂鸣器发声 任务7:按下独立按键K3,蜂鸣器停止发声;用c语言代码编写使它能够在AT89C52单片机上实现效果
时间: 2023-07-04 11:18:19 浏览: 99
qrs.rar_0-999_999秒倒计时器_countdown 999_qrs_时间 继电器
好的,下面是基于AT89C52单片机的代码实现:
```c
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
// 定义数码管位选端口
sbit LED_COM = P2^7;
// 定义数码管段选端口
sbit LED_A = P0^0;
sbit LED_B = P0^1;
sbit LED_C = P0^2;
sbit LED_D = P0^3;
sbit LED_E = P0^4;
sbit LED_F = P0^5;
sbit LED_G = P0^6;
sbit LED_DP = P0^7;
// 定义LED灯端口
sbit LED_RED = P1^0;
sbit LED_YELLOW = P1^1;
sbit LED_GREEN = P1^2;
// 定义按键端口
sbit K1 = P3^0;
sbit K2 = P3^1;
sbit K3 = P3^2;
// 定义蜂鸣器端口
sbit BUZZER = P3^3;
// 定义常量
#define MAX_TIME 999 // 最大倒计时时间
#define FREQ 11059200UL // 晶振频率
#define TIMER0_LOAD (65536 - FREQ / 12 / 1000) // 定时器0装载值,1ms中断
// 定义全局变量
uint time_count = 0; // 倒计时时间
uint red_count = 0; // 红灯闪烁计数器
uint yellow_count = 0; // 黄灯闪烁计数器
uint green_count = 0; // 绿灯闪烁计数器
uchar flag = 0; // 倒计时标志位
// 数码管显示函数
void display(uint num)
{
uchar i, j, k;
uchar dis_num[4] = {0};
dis_num[0] = num / 1000;
dis_num[1] = num % 1000 / 100;
dis_num[2] = num % 100 / 10;
dis_num[3] = num % 10;
for(i = 0; i < 4; i++)
{
LED_COM = 1 << i; // 选择数码管位
for(j = 0; j < 8; j++)
{
k = dis_num[i] >> j & 0x01; // 取出数码管段控制
switch(j)
{
case 0: LED_A = k; break;
case 1: LED_B = k; break;
case 2: LED_C = k; break;
case 3: LED_D = k; break;
case 4: LED_E = k; break;
case 5: LED_F = k; break;
case 6: LED_G = k; break;
case 7: LED_DP = k; break;
default: break;
}
}
delay_ms(1); // 数码管刷新延时
LED_A = LED_B = LED_C = LED_D = LED_E = LED_F = LED_G = LED_DP = 0; // 数码管段控制清零
}
}
// 延时函数,1ms
void delay_ms(uint ms)
{
uint i, j;
for(i = 0; i < ms; i++)
{
for(j = 0; j < 114; j++);
}
}
// 定时器0中断服务函数
void timer0_isr() interrupt 1
{
static uint count = 0;
TH0 = TIMER0_LOAD / 256;
TL0 = TIMER0_LOAD % 256;
count++;
if(count >= 1000) // 1s计数
{
count = 0;
if(flag) // 倒计时标志位为1时,开始倒计时
{
if(time_count > 0) // 时间未到
{
time_count--; // 时间减1
}
else // 时间到,触发蜂鸣器
{
BUZZER = 1; // 蜂鸣器响
delay_ms(500); // 延时500ms
BUZZER = 0; // 蜂鸣器停止
flag = 0; // 倒计时标志位清零
}
}
else // 倒计时标志位为0时,LED灯闪烁
{
if(time_count > 20000) // 大于20s,绿灯闪烁
{
green_count++;
if(green_count >= 50)
{
LED_GREEN = !LED_GREEN;
green_count = 0;
}
}
else if(time_count > 10000) // 10-20s,黄灯闪烁
{
yellow_count++;
if(yellow_count >= 50)
{
LED_YELLOW = !LED_YELLOW;
yellow_count = 0;
}
}
else if(time_count > 0) // 0-10s,红灯闪烁
{
red_count++;
if(red_count >= 50)
{
LED_RED = !LED_RED;
red_count = 0;
}
}
}
}
}
// 主函数
void main()
{
TMOD = 0x01; // 定时器0工作在模式1
TH0 = TIMER0_LOAD / 256;
TL0 = TIMER0_LOAD % 256;
ET0 = 1; // 定时器0中断允许
EA = 1; // 总中断允许
TR0 = 1; // 定时器0开始计时
while(1)
{
if(!flag) // 倒计时标志位为0时,检测按键
{
if(K1 == 0) // 按下K1,开始倒计时
{
flag = 1;
time_count = 999;
}
if(K2 == 0) // 按下K2,停止倒计时
{
flag = 0;
time_count = 0;
LED_RED = LED_YELLOW = LED_GREEN = 0;
}
}
else // 倒计时标志位为1时,显示倒计时时间
{
display(time_count);
}
if(K3 == 0) // 按下K3,停止蜂鸣器
{
BUZZER = 0;
}
}
}
```
需要注意的是,这个代码只是提供了一种实现思路,具体的硬件设计和代码实现需要根据实际情况进行调整。
阅读全文