Proteus-可通过串口控制的51单片机智能交通灯系统(汇编)

一、方案设计

1. 系统需求分析

1.1 功能需求

        设计一个能够模拟实际交通灯运行的系统,包括四个路口红灯、黄灯、绿灯的状态转换,以及数码管的倒计时功能。除此之外,能够通过接收串口数据,人为地修改红绿灯状态、每个灯点亮的时长,修改成功后串口回传应答信号表示修改成功。

1.2 性能需求

        系统应能稳定运行,交通灯转换逻辑清晰,响应时间短。接收到串口数据后能迅速做出响应,以解决实际生活中突发的紧急状况,确保交通流畅。

2. 系统设计

2.1 硬件设计

        使用Proteus软件(Proteus 8.16 P3版本)绘制电路图,主要包括AT89C51单片机(一个用来控制红绿灯系统,另一个用来模拟上位机进行串口通讯)、交通灯、两位共阴极数码管(显示倒计时)、LED灯(调试串口数据是否发送/接收成功)、按钮(触发串口数据发送事件)。

2.2 软件设计

        使用Keil C51 (uVision V5.38.0.0版本)编写汇编代码控制51单片机(两个单片机分别控制),实现交通灯的基本逻辑控制,包括状态转换、动态数码管的刷新,以及串口数据收发、处理紧急状况的额外功能。

3. 各功能实现思路

3.1 定时

        使用定时器0进行读秒,由于定时时间较长,采用定时器工作方式1的16位计数,由TH0和TL0各提供8位计数初值,是几种方式中计数值最大的方式。

        使用6MHz的晶振频率,单片机的机器周期MC = 2us,16位计数方式最大可计65536个脉冲,也就是最大能计131ms的时长, 为了实现读秒,将定时器周期设置为100ms,这样每触发10次定时器溢出中断就能说明经过了1秒。根据公式计算出计数初值为10000H - C350H = 3CB0H,TH0应设置为高八位3CH,TL0设置为低八位0B0H。在定时器0的中断服务函数中用寄存器R7作为计数器,每触发一次定时器溢出中断R7自增1,当R7 = 10,就说明经过了10个定时器周期,也就是1秒。最后使能定时器中断,应注意采用方式1还需要在中断服务函数中手动重装载定时器初值。

3.2 红绿灯状态切换

        使用Proteus中的交通灯器件模拟实际红绿灯,当一个引脚给高电平,另外两个引脚给低电平时,高电平对应的灯点亮。

 

将四个这样的交通灯摆在每个路口处,由于相对的交通灯亮灭状况相同,只需6个IO口进行控制。

四个交通灯总共有四种状态:

                状态0:南北向红灯、东西向绿灯。

                 状态1:南北向红灯、东西向黄灯。

                 状态2:南北向绿灯、东西向红灯。

                 状态3:南北向黄灯、东西向红灯。

        每种状态都对应了P2口不同的输出信号,可对这四种状态进行宏定义编码:

                 STATE0                   EQU                 21H         //状态0:南北向红灯、东西向绿灯

                 STATE1                   EQU                 11H         //状态1:南北向红灯、东西向黄灯

                 STATE2                   EQU                 0CH         //状态2:南北向绿灯、东西向红灯

                 STATE3                   EQU                 0AH         //状态3:南北向黄灯、东西向红灯

        当想要切换到某个状态时,只需执行以下代码:

MOV P2, #STATEx  (x = 0, 1, 2, 3)

        为了能实现与上位机串口通信随时改变红绿灯的四种状态,用寄存器R5保存当前状态0-3。

STATE_REG          EQU                 R5           //状态寄存器

通过调用SET_STATE子函数,可以根据寄存器R5的值切换状态,子函数初步设计如下:

SET_STATE:  //状态切换函数

                 CJNE STATE_REG, #00H, NEXT1               // 状态0

                         MOV P2, #STATE0

                         RET

NEXT1:  CJNE STATE_REG, #01H, NEXT2               // 状态1

                         MOV P2, #STATE1

                         RET

NEXT2:  CJNE STATE_REG, #02H, NEXT3               // 状态2

                         MOV P2, #STATE2

                         RET

NEXT3:  CJNE STATE_REG, #03H, END1                 // 状态3

                         MOV P2, #STATE3

END1:

                 RET

3.3 动态数码管显示

实现倒计时功能,需要用到四个这样的2位数码管(共阴极),一共要控制八位数码管,而由于IO口数量有限,只能采用动态扫描的方式。

将八位数码管的A-G、DP都连到P0口(作为IO口使用,要外加上拉电阻),东西、南北相对的数码管显示相同,因此阴极只需4个IO口,S0为南北向低位,S1为南北向高位,S2为东西向低位,S3为东西向高位。用寄存器R3、R4分别存储东西向、南北向的倒计时时长,在主循环中经过十进制转换,实现数码管动态扫描显示功能,代码设计如下:

LOOP:     //主循环 动态数码管刷新

                 //16进制转10进制(南北向数码管R4)

                 MOV P1, #0FFH

                 MOV A, R4

                 MOV B, #0AH

                 DIV AB                   //A(除以10后的商)对应高位,B(除以10后的余数)对应低位

                 //设置S1数码管

                 MOVC A, @A+DPTR

                 MOV P1, #0FDH

                 MOV P0, A

                 ACALL DELAY1

                 //设置S0数码管

                 MOV A, B

                 MOVC A, @A+DPTR

                 MOV P1, #0FEH

                 MOV P0, A

                 ACALL DELAY1

                 //16进制转10进制(东西向数码管R3)

                 MOV P1, #0FFH

                 MOV A, R3

                 MOV B, #0AH

                 DIV AB                   //A(除以10后的商)对应高位,B(除以10后的余数)对应低位

                 //设置S4数码管

                 MOVC A, @A+DPTR

                 MOV P1, #07H

                 MOV P0, A

                 ACALL DELAY1

                 //设置S3数码管

                 MOV A, B

                 MOVC A, @A+DPTR

                 MOV P1, #0BH

                 MOV P0, A

                 ACALL DELAY1

                 SJMP LOOP

        定时器每经过1秒(10次中断)都需要更新数码管倒计时R3、R4的值。当R3、R4任意一个为0的时候需要切换下一状态,代码设计如下:

T0IN:      //定时器0中断服务函数

                 INC R7                                                      //R7-计数器

                 CJNE R7, #0AH, NEXT5

                 //每10次中断经过1秒,更新数码管显示数字

                 MOV R7, #00H

                 DEC R3                                      

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值