1. 项目概述与设计思路
这个基于8086处理器和51单片机的交通灯控制系统,是我在嵌入式开发课程中的实践项目。系统核心功能包括常规红绿灯切换、两位数码管倒计时显示,以及两种特殊模式——紧急模式和夜间模式。这种设计在实际交通控制中非常实用,比如救护车通过时的优先通行,或者深夜车流量稀少时的安全警示。
硬件架构上,8086作为主控制器负责逻辑运算,通过8255并行接口芯片扩展I/O端口,连接LED交通灯模块和数码管显示。51单片机则作为协处理器,专门处理数码管的动态扫描显示。这种双MCU分工设计既发挥了8086强大的数据处理能力,又利用了51单片机在实时控制方面的优势。
系统工作流程如下:正常情况下,东西和南北方向的红绿灯按预设时间交替切换,数码管同步显示剩余时间。当检测到紧急信号(如按钮触发),立即进入紧急模式——东西方向常绿,南北方向常红,确保应急车辆快速通过。夜间模式则让所有方向黄灯闪烁,提醒司机注意安全通过路口。
关键设计要点:双MCU架构需要特别注意通信同步问题。我在8086和51之间采用并行通信方式,通过8位数据线+3条控制线(忙/闲、读、写)实现可靠的数据传输。
2. 硬件电路设计详解
2.1 核心器件选型与连接
主控芯片选用Intel 8086微处理器,工作在5MHz主频下,通过74LS373锁存器构成典型的8086最小系统。扩展一片8255A可编程并行接口芯片,其三个端口分配如下:
- Port A:控制东西方向交通灯(3位:红、黄、绿)
- Port B:控制南北方向交通灯(3位:红、黄、绿)
- Port C:低4位连接数码管段选,高4位作为紧急/夜间模式检测输入
数码管显示部分采用AT89C51单片机独立控制,通过P0口输出段码,P2口控制位选。两个数码管采用共阳极管,通过9012三极管驱动增强电流能力。这种设计减轻了8086的I/O负担,使显示更加稳定。
2.2 特殊模式触发电路
紧急模式通过一个常开按钮接入8255的PC4引脚,按下时产生高电平信号。夜间模式则使用光敏电阻配合LM393比较器,当环境光低于阈值时自动输出高电平到PC5引脚。两个信号都经过RC滤波电路消除抖动,确保触发可靠。
电源部分采用7805稳压芯片提供5V电压,并在各IC的VCC引脚附近放置0.1μF去耦电容。特别要注意的是,LED交通灯的驱动电流较大(约15mA每个),因此使用ULN2003达林顿阵列作为驱动,避免直接使用8255端口驱动导致过热。
3. 软件设计与实现
3.1 8086主程序流程
主程序采用循环扫描结构,核心代码如下(MASM语法):
assembly复制MAIN PROC FAR
MOV AX, @DATA
MOV DS, AX
CALL INIT_8255 ; 初始化8255为模式0,PA/PB输出,PC高4位输入
MAIN_LOOP:
CALL CHECK_MODE ; 检测特殊模式
CMP AL, 1
JE EMERGENCY_MODE
CMP AL, 2
JE NIGHT_MODE
; 正常模式流程
MOV CX, 30 ; 东西绿灯30秒
CALL EAST_GREEN
MOV CX, 5 ; 东西黄灯5秒
CALL EAST_YELLOW
MOV CX, 30 ; 南北绿灯30秒
CALL SOUTH_GREEN
MOV CX, 5 ; 南北黄灯5秒
CALL SOUTH_YELLOW
JMP MAIN_LOOP
EMERGENCY_MODE:
MOV AL, 09H ; 东西绿(00001001),南北红(00001001)
OUT PORT_A, AL
OUT PORT_B, AL
MOV CX, 0FFFFH ; 长延时
CALL DELAY
JMP MAIN_LOOP
NIGHT_MODE:
MOV BL, 0 ; 闪烁计数器
NIGHT_LOOP:
MOV AL, 12H ; 双黄(00010010)
OUT PORT_A, AL
OUT PORT_B, AL
CALL DELAY_500MS
MOV AL, 0 ; 全灭
OUT PORT_A, AL
OUT PORT_B, AL
CALL DELAY_500MS
INC BL
CMP BL, 200 ; 闪烁约2分钟
JB NIGHT_LOOP
JMP MAIN_LOOP
MAIN ENDP
3.2 51单片机数码管显示
51单片机通过中断方式接收8086发送的时间数据,采用定时器0实现1ms中断进行动态扫描。关键显示代码如下:
c复制unsigned char code SEG_TAB[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90}; // 共阳数码管0-9
void timer0() interrupt 1 {
TH0 = 0xFC; TL0 = 0x18; // 重装1ms定时
P2 = 0xFF; // 关闭显示
switch(disp_pos) {
case 0:
P0 = SEG_TAB[time/10];
P2 = 0xFE;
break;
case 1:
P0 = SEG_TAB[time%10];
P2 = 0xFD;
break;
}
disp_pos = (disp_pos+1)%2;
}
void serial_int() interrupt 4 {
if(RI) {
time = SBUF; // 接收8086发送的时间值
RI = 0;
}
}
4. 系统调试与优化
4.1 常见问题排查
-
数码管显示闪烁或不亮:
- 检查三极管驱动电路是否正常工作,测量数码管公共端电压
- 确认动态扫描频率在100Hz以上(每个数码管点亮时间1-5ms)
- 检查段码表是否正确,共阳/共阴配置是否匹配
-
模式切换不灵敏:
- 测量8255 PC4/PC5引脚电平是否稳定
- 增加硬件消抖电路(典型值:10k电阻+0.1μF电容)
- 软件上采用多次采样确认的方式避免误触发
-
双MCU通信异常:
- 用逻辑分析仪捕捉通信时序
- 检查双方波特率设置是否一致(建议4800bps)
- 添加应答机制,8086发送后等待51的确认信号
4.2 性能优化技巧
-
降低功耗:
- 夜间模式采用50%占空比的闪烁,减少LED发热
- 数码管亮度通过限流电阻调整到适中水平(通常2-5mA)
- 空闲时让8086进入HLT状态,通过外部中断唤醒
-
提高稳定性:
- 所有输出端口增加100Ω串联电阻保护
- 关键数据变量采用三模冗余存储
- 看门狗定时器防止程序跑飞(可用MAX813L芯片)
-
扩展功能建议:
- 增加串口通信,可连接上位机修改定时参数
- 添加红外遥控功能实现远程模式切换
- 使用DS1302时钟芯片实现按时间段自动切换模式
5. 关键参数计算与验证
5.1 定时器参数计算
8086的延时子程序基于指令周期计算。假设系统时钟5MHz(200ns周期),典型延时程序:
assembly复制DELAY PROC ; CX传入延时毫秒数
PUSH DX
MOV DX, 600 ; 校准系数
DELAY_LOOP:
MOV SI, DX
INNER_LOOP:
DEC SI
JNZ INNER_LOOP
LOOP DELAY_LOOP
POP DX
RET
DELAY ENDP
校准方法:用示波器测量实际延时,调整DX值直到1ms误差<5%。在我的测试中,DX=600时测得1.002ms延时。
5.2 数码管亮度平衡
数码管亮度由限流电阻和点亮时间共同决定。计算公式:
code复制亮度 ∝ (驱动电流) × (点亮占空比)
对于共阳数码管,段电流计算:
code复制R_limit = (Vcc - Vled - Vce) / Iseg
其中Vled≈2V(红色LED),Vce≈0.2V(三极管饱和压降)。若需要5mA段电流:
code复制R = (5-2-0.2)/0.005 = 560Ω
实际选用470Ω电阻,测得3.8mA电流,配合1ms×2的扫描周期,亮度适中无闪烁。
6. 项目总结与改进方向
这个项目让我深刻体会到嵌入式系统中软硬件协同设计的重要性。最初版本将所有功能都放在8086上实现,导致数码管显示闪烁严重。后来采用双MCU架构后,不仅显示稳定,还提高了系统响应速度。
几个值得记录的教训:
- I/O端口驱动能力常被忽视,直接驱动LED导致8255发热严重,后来改用ULN2003后问题解决
- 双MCU通信开始时没有同步机制,导致数据显示错乱,添加握手信号后可靠性大幅提升
- 环境光检测电路最初使用固定阈值,在不同天气下误触发,改为可调电阻后适应性强很多
如果时间允许,下一步我打算增加这些功能:
- 通过ADC检测车流量,实现自适应红绿灯时长
- 加入故障自检功能,自动检测烧坏的LED
- 设计太阳能供电系统,提高能源效率
这个项目虽然基于传统的8086和51架构,但涵盖的嵌入式开发核心技能——硬件设计、接口编程、多任务处理等,对现代嵌入式开发仍然具有重要参考价值。
