如何通过代码实现51单片机交通灯; (考察知识: LED, 串口,定时器中断的综合应用) 单片机上电后,红灯亮,高10s,前7秒常高,后3秒闪烁,串口给上位机发送“禁止通行”红灯灭后,绿灯亮8s,前5秒常高,后3秒闪烁,串口给上位机发送“允许通行” 绿灯灭后,黄灯高6s,前3秒常亮,后3秒闪烁,串口给上位机发送“等待通行
时间: 2023-12-07 07:05:38 浏览: 64
以下是一个可能的实现代码,仅供参考:
```
#include <reg51.h>
#define LED_RED P0_0
#define LED_GREEN P0_1
#define LED_YELLOW P0_2
#define UART_BAUDRATE 9600
#define UART_TIMER_PRESCALER 12
// 定义定时器计数值
#define TIMER_1S 1000
#define TIMER_3S 3000
#define TIMER_5S 5000
#define TIMER_7S 7000
#define TIMER_8S 8000
#define TIMER_10S 10000
// 定义串口发送的消息
#define MSG_RED "禁止通行"
#define MSG_GREEN "允许通行"
#define MSG_YELLOW "等待通行"
// 定义当前的灯的状态
typedef enum {
STATE_RED,
STATE_GREEN,
STATE_YELLOW
} State;
// 定义当前的灯的状态、计时器、闪烁计数器等变量
volatile State g_state = STATE_RED;
volatile unsigned int g_timer = TIMER_10S;
volatile unsigned int g_blink_count = 0;
volatile unsigned char g_blink_state = 0;
// 初始化定时器
void timer_init() {
TMOD |= 0x10; // 设置定时器1为工作方式1
TH1 = 0xFC; // 设置定时器1的初始值,使定时器1开始计时时为1ms
TL1 = 0x18;
ET1 = 1; // 打开定时器1中断
TR1 = 1; // 启动定时器1
}
// 定时器1中断,每隔1ms执行一次
void timer1_isr() interrupt 3 {
g_timer--;
if (g_timer == 0) {
switch (g_state) {
case STATE_RED:
g_state = STATE_GREEN;
g_timer = TIMER_8S;
g_blink_count = 0;
LED_RED = 0;
LED_GREEN = 1;
SBUF = MSG_GREEN;
break;
case STATE_GREEN:
g_state = STATE_YELLOW;
g_timer = TIMER_6S;
g_blink_count = 0;
LED_GREEN = 0;
LED_YELLOW = 1;
SBUF = MSG_YELLOW;
break;
case STATE_YELLOW:
g_state = STATE_RED;
g_timer = TIMER_10S;
g_blink_count = 0;
LED_YELLOW = 0;
LED_RED = 1;
SBUF = MSG_RED;
break;
default:
break;
}
} else {
switch (g_state) {
case STATE_RED:
if (g_timer == TIMER_7S) {
LED_RED = 0;
} else if (g_timer == TIMER_3S) {
g_blink_state = 1;
}
break;
case STATE_GREEN:
if (g_timer == TIMER_5S) {
LED_GREEN = 0;
} else if (g_timer == TIMER_3S) {
g_blink_state = 1;
}
break;
case STATE_YELLOW:
if (g_timer == TIMER_3S) {
LED_YELLOW = 0;
} else if (g_timer == TIMER_6S) {
g_blink_state = 1;
}
break;
default:
break;
}
if (g_blink_state && g_blink_count < 6) {
g_blink_count++;
if (g_state == STATE_RED) {
LED_RED = ~LED_RED;
} else if (g_state == STATE_GREEN) {
LED_GREEN = ~LED_GREEN;
} else {
LED_YELLOW = ~LED_YELLOW;
}
} else {
g_blink_state = 0;
}
}
}
// 初始化串口
void uart_init() {
SCON = 0x50; // 设置串口为工作方式1,允许接收
TMOD |= 0x20; // 设置定时器1为工作方式2
TH1 = 256 - (11059200 / 12 / UART_BAUDRATE); // 设置波特率
TL1 = TH1;
ET1 = 0; // 关闭定时器1中断
TR1 = 1; // 启动定时器1
}
// 串口发送一个字符
void uart_send_char(unsigned char c) {
SBUF = c;
while (!TI); // 等待发送完成
TI = 0;
}
// 串口发送一个字符串
void uart_send_string(const char* s) {
while (*s) {
uart_send_char(*s++);
}
}
void main() {
LED_RED = 1;
timer_init();
uart_init();
SBUF = MSG_RED;
while (1);
}
```
该代码中使用了定时器1来控制交通灯状态的切换和LED闪烁,使用串口发送消息。注意,由于定时器1需要和串口使用同一个计数器,因此串口发送消息时需要关闭定时器1中断。同时,在发送完消息后,需要重新打开定时器1中断。
阅读全文