
A39基于51单片机汇编语言交通灯Proteus设计
用51单片机汇编语言做一个十字路口交通灯:东西、南北各一组红黄绿灯,六种状态循环切换,绿灯结束前闪三秒、黄灯过渡两秒,两组数码管实时显示两个方向的剩余秒数。延时不用中断,靠查询定时器溢出标志凑出1秒,逻辑一目了然。
一、设计实现功能
本设计功能简介:使用51单片机和汇编语言设计一个交通灯控制的proteus仿真,要求以下功能:
1、使用汇编语言编写程序。
2、东西、南北各三盏灯(红、黄、绿),共六盏,接P2口。
3、六状态循环:绿灯25秒→绿灯闪3秒→黄灯2秒→另一方向重复。
4、四位数码管分别显示两个方向的倒计秒数。
二、资源汇总
1、仿真文件:Proteus工程,7.8和8.6两个版本都能直接打开。
2、程序文件:main.asm汇编源码,以及编译好的cx.hex。
3、修改日期小工具:购买资料后赠送,用于修改文件创建日期,下载地址在文章最后。
三、设计介绍
拿到压缩包之后先解压,没有解压软件的直接搜"压缩",下载解压软件后先解压文件,再运行仿真和程序。
图1 Proteus仿真总览

灯和数码管的引脚分配:
| 对象 | 引脚 | 说明 |
| 东西 绿/黄/红 | P2.1 / P2.2 / P2.3 | 高电平点亮 |
| 南北 绿/黄/红 | P2.4 / P2.5 / P2.6 | 高电平点亮 |
| 数码管数据 | P3.0 | 串行送段码 |
| 数码管时钟 | P3.1 | 上升沿移位 |
| 定时器 | T0方式1,3CB0H | 50毫秒溢出一次 |
1秒不是定时器直接定出来的,而是50毫秒数20次:MOV R2,#20,每查到一次TF0置位就减一,减到0才算1秒。这样做的代价是主程序被JNB TF0,$卡住,好处是不用中断、状态机写得像流程图一样直白。
六个状态和时长:
| 状态 | 东西方向 | 南北方向 | 持续 | 显示 |
| 1 | 绿灯常亮 | 红灯 | 25秒 | 25倒数到1 |
| 2 | 绿灯闪(200ms一次) | 红灯 | 3秒 | 5倒数到3 |
| 3 | 黄灯亮 | 红灯 | 2秒 | 2倒数到1 |
| 4 | 红灯 | 绿灯常亮 | 25秒 | 25倒数到1 |
| 5 | 红灯 | 绿灯闪 | 3秒 | 5倒数到3 |
| 6 | 红灯 | 黄灯亮 | 2秒 | 2倒数到1 |
一个完整周期60秒,两个方向严格互锁——任何时刻不会有两条道同时放行。状态切换靠DJNZ R3倒数秒数,每个状态结束就往下掉,第6个状态结束LJMP LOOP回到第1个。
灯的亮灭在六个状态子程序里写死,比如状态1:
`asm
STATE1: SETB LED_G1 ;东西绿灯亮
CLR LED_Y1
CLR LED_R1
CLR LED_G2
CLR LED_Y2
SETB LED_R2 ;南北红灯亮
RET`
每个状态进来先把六盏灯全部重新赋值一遍,不做"只改变化的灯",这样逻辑再复杂也不会残留旧状态。黄灯过渡只有2秒,是标准的"绿闪→黄→红"三段式。
倒计时显示是4位数码管串行驱动,先把秒数拆成十位个位,再查段码表,最后逐位RLC从P3.0送出去,P3.1给时钟:
`asm
DISPLAY: MOV A,SECOND1
MOV B,#10
DIV AB ;十位在A,个位在B
MOV DBUF+3,A
MOV A,B
MOV DBUF+2,A
...`
左边两位是东西方向、右边两位是南北方向,两个方向同步倒数。
特别注意: 程序里状态3和状态6的注释写的是"绿灯亮",实际SETB的是LED_Y1、LED_Y2,也就是黄灯——注释和代码不一致,看代码为准;倒计时显示比实际时间快或慢,先查晶振是不是12MHz,50毫秒初值3CB0H是按12MHz算的,11.0592MHz下要重算;状态2的显示初值设的是5秒但只维持3秒,屏幕会从5跳到3,这是原程序的写法,想对齐把MOV SECOND1,#5改成3;灯全灭或者全亮,检查P2口有没有被别的地方改写(显示用的是P3,不冲突);数码管显示乱码,检查74HC595的级联顺序和P3.0、P3.1有没有接反。
四、日期修改
资料中提供修改日期的小工具,购买资料赠送修改文件创建日期的小工具,三个下载地址都在文章最后。
五、资料下载
付费后获取下载链接,直接下载到电脑上,然后解压即可!每个链接前面都配了二维码,手机扫码可以直接跳转。
/

