基于C51单片机的丁字路口交通灯控制系统

前提是你 提交于 2020-08-07 21:38:55

基于C51单片机的丁字路口交通灯控制系统


项目要求:用单片机设计一套丁字路口的交通灯显示系统,如图所示,有三组相同的道路显示系统

undefined

项目概述:采用多机通讯实现对多个红绿灯的控制

  1. 主机功能:主机,用于在特殊情况下操纵从机,和对从机的时间统一。

  2. 从机功能:从机,每隔10s红灯亮、每隔10s绿灯亮,绿灯到红灯时黄灯闪烁3秒。

项目图纸:

  1. 概览图:

undefined

2. C51单片机连图:

undefined

3. 丁字路口模拟图:

undefined

4. 紧急情况处理按钮:

undefined

项目代码

代码注释较为详细,自行观看

  1. 程序中断图:

    undefined

  2. 主机代码:

    // 程序说明 
    ; 主机,用于在特殊情况下操纵从机,和对从机的时间统一。
    ; 采用串口通信方式二,波特率固定fosc/64
    ; SCON = 1000 0000B = 80H, PCON = 00H 波特率不加倍	
    ; 定时器T0,方式1,50ms中断一次,20次为1s。
    ; 初值:X = 2^16 - (50 * 10^-3) / (1 * 10^-6) = 15536D = 3CB0H
    // 变量定义 
     START	EQU	30H
     STOP	EQU	31H	
    // 程序起点
    	ORG		0000H			; 复位入口
    	LJMP	MAIN			; 转到主程序
    	ORG		000BH			; T0中断入口
    	LJMP	COUNTTIME		; 转到T0中断服务程序
    	ORG		0023H			; 串行中断入口
    	LJMP	CONNECT			; 转到串行中断服务程序
    	ORG		0100H			; 主程序入口
    // 主函数
    MAIN:	
    ; 1.启动检查
    ; 2.初始化定时器0,开中断
    	MOV		TMOD, #01H		; 设置T0工作方式
    	MOV		TCON, #05H		; 中断触发方式
    	MOV		SCON, #80H		; 设置串行口工作方式
    	MOV		PCON, #00H		; 设置波特率不加倍	
    	MOV		TH0, #3CH		; 装入T0初值
    	MOV 	TL0, #0B0H
    	SETB	TR0				; 启动T0
    	SETB 	EA				; 开中断
    	SETB	ES
    	SETB	ET0				; 允许T0中断	
    ; 3.定义变量初值
    	MOV 	SP, #60H		; 设置堆栈指针
    	MOV		START, #00H		; 传入从机的数据,控制开始运行中断信号
    	MOV		STOP, #01H		; 传入从机的数据,控制终止运行中断信号
    AGAIN:
    	JNB		P1.0, SET_NM1	; 启动键按下?
    	JNB		P1.1, SET_NM2	; 停止键按下?
    	SJMP	AGAIN
    SET_NM1:
    	LCALL	DELAY500		; 延时消抖
    	LCALL	DELAY500
    	MOV		R0, START		; 数据起始地址
    	CPL		P2.1
    	LCALL	TRS				; 数据发送
    	MOV		R5, #0			; 重新计时
    	SJMP	AGAIN
    SET_NM2:
    	LCALL	DELAY500		; 延时消抖
    	MOV		R0, STOP
    	LCALL	TRS				; 数据发送				
    	SJMP	AGAIN	
    TRS:
    	MOV		C, P
    	MOV		TB8, C
    	MOV		A, @R0
    	MOV		SBUF, A	
    WAIT:
    	JNB 	TI, WAIT		; 一帧输出完,TI=1时发送中断
    	CLR		TI
    	RET	
    DELAY500:
    	MOV 	R6, #2000		;DELAY500MS子程序(2000*125*1*10^-3=500ms)	
    H2:
    	MOV 	R0, #125	
    H1:	
    	DJNZ 	R0, H1
    	DJNZ 	R6, H2
    	RET
    // -----定时器0中断用于定时-----
    	ORG 	0300H
    COUNTTIME:	
    	MOV 	TH0, #3CH		; 重装T0初值
    	MOV 	TL0, #0B0H
    	CPL		P1.4
    	INC		R5				; 中断次数加一	
    // -----串行中断用于主机发送信号-----
    CONNECT:
    	CLR		TI				; TI=0发送中断结束
    	CPL		P2.2
    	RETI	
    	END
    
    
    
    
    
  3. 从机代码:

    ; 从机南北方向与东西方向基本一致
    
    // 程序说明
    ; 东西方向交通信号灯。
    ; 每隔10s绿灯亮、每隔10s红灯亮、绿灯到红灯时黄灯闪烁3秒。
    ; CPU晶振频率12MHz状态周期,1个机器周期为12个时钟振荡周期,即1μs。
    ; 定时器T0,方式1,50ms中断一次,20次为1s。
    ; 初值:X = 2^16 - (50 * 10^-3) / (1 * 10^-6) = 15536D = 3CB0H
    
    // 变量定义
    	REDTIME		EQU	30H
    	YELLOWTIME	EQU	31H	
    	GREENTIME	EQU 32H	
    	MASTERDATA	EQU	50H	
    // 程序起点
    	ORG		0000H			; 复位入口
    	LJMP	MAIN			; 转到主程序
    	ORG		0003H			; INT0中断入口地址
    	LJMP	SEVER0			; 转到INT0中断服务程序
    	ORG		000BH			; T0中断入口
    	LJMP	COUNTTIME		; 转到T0中断服务程序
    	ORG		0013H			; INT1中断入口地址
    	LJMP	SEVER1			; 转到INT1中断服务程序
    	ORG		0023H			; 串行中断入口
    	LJMP	CONNECT			; 转到串行中断服务程序		
    	ORG 	0100H			; 主程序入口
    // 主函数
    MAIN:	
    ; 1.启动检查
    ; 2.初始化定时器0
    	MOV		IE, #9FH		; 开中断
    	MOV		IP, #91H		; 中断优先级,0>1,使0中断触发,保证恢复正常工作
    	MOV		TMOD, #01H		; 设置T0工作方式
    	MOV		TCON, #05H		; 中断触发方式
    	MOV		SCON, #90H		; 设置串行口工作方式
    	MOV		PCON, #00H		; 设置波特率不加倍	
    	MOV		TH0, #3CH		; 装入T0初值
    	MOV 	TL0, #0B0H
    	SETB	TR0				; 启动T0	
    ; 3.定义变量初值
    	MOV 	SP, #60H		; 设置堆栈指针
    	MOV 	REDTIME, #10	; 记录红灯总时长10s
    	MOV		YELLOWTIME, #3	; 记录黄灯总时长3s
    	MOV		GREENTIME, #10	; 记录绿灯总时长10s
    	MOV		P0, #00H		; 共阴极数码管每段都不亮 
    	MOV		P1, #00H		; 每个发光二级管都不亮
    	MOV		P2, #00H		; 数码管每个都不显示
    	// 方式寄存器R0-R5的初始化
    	MOV		R0, #10		; 用于存储数码管显示数据,初始时从REDTIME开始
    	MOV 	R1, REDTIME		; 记录红灯实时的时间变化
    	MOV		R2,	YELLOWTIME	; 记录黄灯实时的时间变化
    	MOV 	R3,	GREENTIME	; 记录绿灯实时的时间变化
    	MOV 	R4, #0			; 记录数码管位选信号
    	MOV		R5, #0			; 记录定时器中断次数
    	MOV		R6, #0			; 记录外部中断类型
    	MOV		R7, #0			; 记录通信数据传输
    	// 灯光状态初始化
    	SETB	P1.0			; 初始红灯亮
    	CLR		P1.1			; 初始黄灯暗
    	CLR		P1.2			; 初始绿灯暗	 
    ; 4.LED开始工作和SEG开始倒计时工作
    WORK:	
    	CJNE 	R5, #10, WORK	; 中断次数检验,当R5=10则为0.5s进行倒计时时间的变化
    	CJNE	R1, #1, RED		; 未到10s,红灯	
    	CJNE	R3, #0, GREEN	; 黄灯结束,跳转到绿灯,未到10s,绿灯
    	CJNE	R2, #0, YELLOW	; 绿灯结束,跳转到黄灯,未到3s,黄灯
    // -----灯光周期结束后的重新赋值-----
    REFRESH:
    	CJNE	R5, #20, REFRESH; 中断次数检验,当R5=20则为1s进行倒计时时间的变化
    	MOV 	R5, #0			; 重置中断次数
    	MOV		R1, REDTIME		; 时间寄存器重新赋值	
    	MOV		R2, YELLOWTIME
    	MOV 	R3, GREENTIM	
    	MOV		R0, #10			; 初始化时间
    	SETB	P1.0			; 初始红灯亮
    	CLR		P1.1			; 初始黄灯暗
    	CLR		P1.2			; 初始绿灯暗
    	JMP		WORK			; 重新开始工作
    // -----红黄绿灯的灯光操作-----
    ; 1.红灯亮REDTIME秒数
    RED:
    	CJNE	R5, #20, RED	; 中断次数检验,当R5=20则为1s进行倒计时时间的变化
    	MOV 	R5, #0			; 重置中断次数
    	DEC		R1				; 秒数减一
    	MOV 	A, R1			; R0作为显示时间
    	MOV		R0, A
    	SETB	P1.0			; 红灯亮
    	CLR		P1.1			; 黄灯暗
    	CLR		P1.2			; 绿灯暗
    	JMP		WORK
    ; 2.黄灯闪烁YRLLOWTIME秒数	
    YELLOW:	
    	CJNE	R2, #3, DARK 	; 第一次进入黄灯延迟0.5s,以免时间偏差	
    	CJNE	R5, #20, YELLOW
    	MOV 	R5, #0			; 重置中断次数
    	DEC		R2				; 秒数减一
    	MOV 	A, R2			; R0作为显示时间
    	INC		A				; 从YELLOWTIME开始倒计时
    	MOV		R0, A
    	CLR		P1.0			; 红灯暗
    	SETB	P1.1			; 黄灯亮0.5s
    	CLR		P1.2			; 绿灯暗
    	JMP		WORK
    DARK:	
    	CJNE	R5, #10, DARK	 ; 每秒闪烁
    	CLR		P1.0			; 红灯暗
    	CLR		P1.1			; 黄灯暗0.5s
    	CLR		P1.2			; 绿灯暗
    LIGHT:	
    	CJNE	R5, #20, LIGHT	 ; 中断次数检验,当R5=20则为1s进行倒计时时间的变化
    	MOV 	R5, #0			; 重置中断次数
    	DEC		R2			    ; 秒数减一
    	MOV 	A, R2			; R0作为显示时间
    	INC		A			    ; 从YELLOWTIME开始倒计时
    	MOV		R0, A
    	CLR		P1.0			; 红灯暗
    	SETB	P1.1			; 黄灯亮0.5s
    	CLR		P1.2			; 绿灯暗
    WAIT:
    	CJNE	R2, #0, WORK
    	CJNE	R5, #10, WAIT
    	CLR		P1.0			; 红灯暗
    	CLR		P1.1			; 黄灯暗0.5s
    	CLR		P1.2			; 绿灯暗	
    	JMP		WORK
    ; 3.绿灯亮GREENTIME秒数
    GREEN:	
    	CJNE	R5, #20, GREEN	; 中断次数检验,当R5=20则为1s进行倒计时时间的变化
    	MOV 	R5, #0		    ; 重置中断次数
    	DEC		R3			    ; 秒数减一
    	MOV 	A, R3			; R0作为显示时间
    	INC		A			    ; 从GREENTIME开始倒计时
    	MOV		R0, A
    	CLR		P1.0			; 红灯暗
    	CLR		P1.1			; 黄灯暗
    	SETB	P1.2			; 绿灯亮
    	JMP		WORK
    // -----外部中断0用于恢复正常工作-----
    	ORG		0200H
    SEVER0:
    	MOV		R6, #1			; 结束中断1的标志,退出停止状态,继续正常工作
    	RETI
    // -----外部中断1用于紧急情况处理-----
    	ORG		0220H
    SEVER1:		
    	MOV		R5, #0			; 时间初始化
    	MOV		R6, #0			; 状态初始化
    	MOV		P0, #6FH		; 数码管显示99秒
    	MOV		P2, #00H
    	SETB	P1.0			; 红灯亮
    	CLR		P1.1			; 黄灯暗
    	CLR		P1.2			; 绿灯暗	
    T1WAIT:	
    	CJNE	R6, #1, T1WAIT	; 原地等待,维持停止状态	
    	RETI
    // -----定时器0中断用于定时-----
    	ORG 	0300H
    COUNTTIME:	
    	MOV 	TH0, #3CH		; 重装T0初值
    	MOV 	TL0, #0B0H
    	CPL		P1.4
    	INC		R5				; 中断次数加一
    STEPRO:	
    	INC 	R4				;R4为片选信号
    	CJNE 	R4, #2,TODISP
    	MOV 	R4, #0
    TODISP:	
    	LCALL 	DISPSEG			;根据数码管的片选信号进行显示		
    DONTIME:
    	RETI					; 中断返回
    DISPSEG: 
    	MOV 	A, R4
    	MOV 	DPTR, #SEGCON
    	MOVC 	A, @A+DPTR
    	MOV 	P2, A
    	CJNE 	R4, #0, SEG1	 ;判断是哪一位数码管亮
    	MOV 	A, R0			;如果是第一个数码管亮
    	MOV 	B, #10			
    	DIV 	AB
    	MOV 	DPTR, #NUM		
    	MOVC 	A, @A+DPTR
    	MOV 	P0, A			;显示秒数的十位	
    SEG1: 
    	CJNE	R4, #1, FINDISP
    	MOV 	A, R0
    	MOV 	B, #10
    	DIV 	AB
    	MOV 	A, B
    	MOV 	DPTR, #NUM
    	MOVC 	A, @A+DPTR
    	MOV 	P0, A			;显示秒数的个位
    FINDISP:
    	RET						;结束显示,程序返回	
    // -----串行中断用于接收主机信号-----
    ; 0 恢复正常处理
    ; 1 紧急情况处理
    ; 2 时间减五秒操作
    ; 3 时间加五秒操作
    CONNECT:
    	JBC     RI, READ
    	SJMP	CONNECT
    READ:	
    	MOV		A, SBUF			; 数据接收 
    	MOV		C, P			; 奇偶校验
    	JNC		LP0				; 奇偶校验位位0?
    	JNB		RB8, ERR		; RB8=0禁止接收
    	SJMP	LP1				; 将数据放入指定位置	
    LP0:	
    	JB		RB8,ERR	
    LP1:	
    	CLR		RI				; 接收中断清零
    	JZ		TT0	 			; 恢复正常处理
    	DEC		A
    	JZ		TT1				; 紧急情况处理
    	DEC		A
    	JZ		TT2				; 时间减五秒操作
    	JMP		LP1
    	DEC		A
    	JZ		TT3				; 时间加五秒操作
    TT0:
    	CLR		RI			; 接受中断结束标志
    	CLR		P3.2		; 触发T0中断
    	SETB	P3.2			; 恢复T0中断
    	CPL		P1.6	
    	RETI
    TT1:	
    	;CLR		P3.3		; 触发T1中断
    	;SETB	P3.3			; 恢复T1中断
    	SETB	P1.5
    	RETI
    TT2:	
    	RETI
    TT3:
    	RETI
    ERR:
    	SETB	P1.3
    	RETI		
    ;数组:NUM控制数码管显示数字,SEGCON控制数码管使能信号(数码管低电平亮)
    NUM: 
    	DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH
    SEGCON: 
    	DB 02H, 01H	
    	END
    
    
    
    
    

运行效果:

  • 开机运行:

  • 紧急情况处理按钮按下:

  • 恢复正常情况按钮按下:

网盘链接:

包含项目概述、项目图纸、项目代码、项目报告及项目PPT需要自取

本人初学C51如上功能暂不完善,欢迎指正!

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!