怎么用代码实现:交通灯; (考察知识: LED, 串口,定时器中断的综合应用) 单片机上电后,红灯亮,高10s,前7秒常高,后3秒闪烁,串口给上位机发送“禁止通行”红灯灭后,绿灯亮8s,前5秒常高,后3秒闪烁,串口给上位机发送“允许通行” 绿灯灭后,黄灯高6s,前3秒常亮,后3秒闪烁,串口给上位机发送“等待通行
时间: 2023-10-20 20:07:13 浏览: 137
以下是基于51单片机的交通灯代码,使用了定时器中断和串口通信:
```
#include <reg51.h>
#define uchar unsigned char
#define uint unsigned int
sbit RED_LED = P1^0; // 红灯
sbit YELLOW_LED = P1^1; // 黄灯
sbit GREEN_LED = P1^2; // 绿灯
uchar time_count = 0; // 计时器计数器
uchar state = 0; // 当前状态,0为红灯,1为绿灯,2为黄灯
uchar allow_cross = 0; // 是否允许通行
void init_timer(void);
void init_uart(void);
void send_data(uchar data);
void delay(uint t);
void main(void)
{
init_timer();
init_uart();
RED_LED = 1;
allow_cross = 0;
while (1)
{
switch (state)
{
case 0: // 红灯
if (time_count >= 100) // 等待10秒
{
time_count = 0;
YELLOW_LED = 0;
RED_LED = 0;
GREEN_LED = 1;
state = 1;
allow_cross = 1; // 允许通行
send_data('a'); // 发送允许通行信号
}
else if (time_count < 70) // 前7秒常亮
{
YELLOW_LED = 0;
RED_LED = 1;
}
else // 后3秒闪烁
{
if (time_count % 10 < 5)
{
YELLOW_LED = 0;
RED_LED = 1;
}
else
{
YELLOW_LED = 1;
RED_LED = 0;
}
}
break;
case 1: // 绿灯
if (time_count >= 80) // 等待8秒
{
time_count = 0;
YELLOW_LED = 1;
GREEN_LED = 0;
RED_LED = 1;
state = 2;
allow_cross = 0; // 禁止通行
send_data('b'); // 发送禁止通行信号
}
else if (time_count < 50) // 前5秒常亮
{
YELLOW_LED = 0;
GREEN_LED = 1;
}
else // 后3秒闪烁
{
if (time_count % 10 < 5)
{
YELLOW_LED = 0;
GREEN_LED = 1;
}
else
{
YELLOW_LED = 1;
GREEN_LED = 0;
}
}
break;
case 2: // 黄灯
if (time_count >= 60) // 等待6秒
{
time_count = 0;
YELLOW_LED = 0;
RED_LED = 1;
state = 0;
allow_cross = 0;
send_data('c'); // 发送等待通行信号
}
else if (time_count < 30) // 前3秒常亮
{
YELLOW_LED = 1;
RED_LED = 0;
}
else // 后3秒闪烁
{
if (time_count % 10 < 5)
{
YELLOW_LED = 1;
RED_LED = 0;
}
else
{
YELLOW_LED = 0;
RED_LED = 0;
}
}
break;
default:
break;
}
}
}
void init_timer(void)
{
TMOD = 0x01; // 定时器0工作在模式1
TH0 = 0x4C; // 计时器初值,1ms计时一次
TL0 = 0x00;
ET0 = 1; // 允许定时器0中断
EA = 1; // 开启全局中断
TR0 = 1; // 启动定时器0
}
void init_uart(void)
{
SCON = 0x50; // 8位数据,可变波特率
TMOD &= 0x0F; // 清零定时器1的控制位
TMOD |= 0x20; // 定时器1工作在模式2
TH1 = 0xFD; // 波特率9600,定时器1初值
TL1 = 0xFD;
TR1 = 1; // 启动定时器1
}
void send_data(uchar data)
{
SBUF = data; // 发送数据
while (!TI); // 等待发送完成
TI = 0; // 清除发送完成标志位
}
void delay(uint t)
{
uint i, j;
for (i = 0; i < t; i++)
{
for (j = 0; j < 500; j++);
}
}
void timer0_isr(void) interrupt 1
{
TH0 = 0x4C;
TL0 = 0x00;
time_count++;
if (allow_cross == 1) // 如果允许通行,则每秒向上位机发送一次数据
{
if (time_count % 100 == 0)
{
send_data('d');
}
}
}
```
需要注意的是,此代码中的串口通信部分只是给出了发送数据的函数,并没有接收数据的部分,需要根据实际情况进行修改。另外,定时器中断的具体实现方式可能因芯片型号而异,需要参考具体的芯片手册。
阅读全文