51单片机红绿灯(十字路口智能控制系统)

在CSDN看了许多文章,也学到了不少偏门知识,这学期结束做了课设,就是题目所说,在这里分享一下我的经验。

代码学习,永无止境。因为疫情课程安排被改的面目全非,为了应对马上来的考试,顺便问一下偶尔点进来的大佬,Java和数据结构前期怎样进行简单的入门学习,在这里小弟不胜感激。

下面就进入正文。

正常运行

变灯

 

中断

具体功能下面代码已经展示了,如有不足请指出。

		ORG		0000H
		AJMP	MAIN			;转主程序
		
		ORG		0003H			;外部中断0入口地址
		AJMP	INTZ			;中断服务子程序
		
		ORG		0013H			
		AJMP	INTO
		
		ORG		0030H
MAIN:	MOV		SP,#60H
		MOV		DPTR,#TAB		;表头
		MOV		R1,#0F0H		
		
		SETB	IT0				;外部中断0跳沿触发
		SETB	EX0				;允许外部中断0中断			
		SETB	IT1				
		SETB	EX1				
		SETB	EA				;CPU开总中断
		LJMP	LNS				;跳主运行程序
		
INTZ:	MOV		A,P1			;保存红绿灯状态
		MOV		R7,A
		MOV		C,P3.4			;保存人行道红绿灯状态
		MOV		34H,C
		MOV		C,P3.5
		MOV		35H,C
		MOV		C,P3.6
		MOV		36H,C
		MOV		C,P3.7
		MOV		37H,C
INZ:	;JB		P3.2,IDZ			
		MOV		P0,#7FH			;显示器置八
		MOV		P1,#11H			;南北红绿灯全红,东西特种车辆通行
		MOV		P2,#7FH			
		SETB	P3.4
		SETB	P3.7
		CLR		P3.5
		CLR		P3.6
		JNB		P3.2,INZ		;判断中断是否停止,循环
IDZ:	MOV		A,R7			;恢复状态
		MOV		P1,A
		MOV		C,34H
		MOV		P3.4,C
		MOV		C,35H
		MOV		P3.5,C
		MOV		C,36H
		MOV		P3.6,C
		MOV		C,37H
		MOV		P3.7,C
		RETI					;返回中断处
		
INTO:	MOV		A,P1			
		MOV		R7,A
		MOV		C,P3.4			
		MOV		34H,C
		MOV		C,P3.5
		MOV		35H,C
		MOV		C,P3.6
		MOV		36H,C
		MOV		C,P3.7
		MOV		37H,C
INO:	;JB		P3.2,IDO			
		MOV		P0,#7FH			
		MOV		P1,#0AH			
		MOV		P2,#7FH
		SETB	P3.4
		SETB	P3.7
		CLR		P3.5
		CLR		P3.6
		JNB		P3.3,INO			
IDO:	MOV		A,R7		
		MOV		P1,A
		MOV		C,34H
		MOV		P3.4,C
		MOV		C,35H
		MOV		P3.5,C
		MOV		C,36H
		MOV		P3.6,C
		MOV		C,37H
		MOV		P3.7,C
		RETI					
		
LNS:	MOV		A,R1			;设置R1,调用不同方向红绿灯后取反,以此循环亮起
		CPL		A
		MOV		R1,A
		CJNE	R1,#0F0H,LWE	;调用子程序,亮东西
		LCALL	SONO			;调用子程序,亮南北
		AJMP	LNS
		
LWE:	LCALL	EAWE
		AJMP	LNS
			
;东西红灯、南北绿灯	
	
EAWE:	MOV		R4,#63		;红灯时间
		MOV		R0,#10
		MOV		P1,#0AH		;东西红灯、南北绿灯
		MOV		P3,#5CH		;人行道:东西绿灯、南北红灯
EW:		MOV		R5,#10		;循环次数,人眼余辉
		
LEW:	MOV		A,R4
		MOV		B,R0
		DIV		AB			;取东西亮起的数字
		MOV		R2,B
		
		CLR		P1.7		;控制位选线1,左
		MOVC	A,@A+DPTR
		MOV		P2,A		;东西显示器
		
		MOV		A,R4		
		SUBB	A,#04H
		JNC		L2			;有进位顺序执行
		MOV		A,R4		;3S内,南北黄灯和东西红灯剩余时间保持一样
		AJMP	L3
L2:		ADD		A,#01H
L3:		MOV		B,R0
		DIV		AB			;取南北亮起的数字
		MOV		R3,B	
		MOVC	A,@A+DPTR
		MOV		P0,A		;南北显示器
		LCALL	DEL
		SETB	P1.7		;关闭位选线,左

		
		MOV		A,R2		;恢复东西显示器右侧数值
		CLR		P1.6		;控制位选线2		
		MOVC	A,@A+DPTR
		MOV		P2,A

		MOV		A,R3		;恢复南北显示器右侧数值
		MOVC	A,@A+DPTR
		MOV		P0,A
		LCALL	DEL
		SETB	P1.6		;关闭位选线,右
		
		
		DJNZ	R5,LEW		;循环次数判断
		CJNE	R4,#04H,L1	;判断是否3S内,改变灯的状态
		MOV		P1,#0CH		;东西红灯、南北黄灯
L1:		DEC		R4			;改变下一次显示的数字
		CJNE	R4,#00H,EW	;循环1~63的数值

		RET					;返回调用


;南北红灯、东西绿灯

SONO:	MOV		R4,#83		;以下逻辑同上		
		MOV		R0,#10
		MOV		P1,#11H		;东西绿灯、南北红灯
		MOV		P3,#0ACH	;人行道:东西红灯、南北绿灯
SN:		MOV		R5,#10
		
LSN:	MOV		A,R4
		MOV		B,R0
		DIV		AB
		MOV		R2,B
		
		CLR		P1.7		;控制位选线1
		MOVC	A,@A+DPTR
		MOV		P0,A
		
		MOV		A,R4
		SUBB	A,#04H
		JNC		L5
		MOV		A,R4
		AJMP	L6
L5:		ADD		A,#01H
L6:		MOV		B,R0
		DIV		AB
		MOV		R3,B
		MOVC	A,@A+DPTR
		MOV		P2,A
		LCALL	DEL
		SETB	P1.7

		
		MOV		A,R2
		CLR		P1.6		;控制位选线2		
		MOVC	A,@A+DPTR
		MOV		P0,A

		MOV		A,R3		
		MOVC	A,@A+DPTR
		MOV		P2,A
		LCALL	DEL
		SETB	P1.6
		
		
		DJNZ	R5,LSN
		CJNE	R4,#04H,L4
		MOV		P1,#21H		;东西黄灯、南北红灯
L4:		DEC		R4
		CJNE	R4,#00H,SN
		
		RET
		
;延时50ms,受调用延时次数和循环次数R5影响,S=200*(123*2++2+1+1)+1=50.001ms
DEL:	MOV		R6,#200		;1us	
DEL1:	MOV		R7,#123		;1us
		NOP					;1us
DEL2:	DJNZ	R7,DEL2		;2us
		DJNZ	R6,DEL1		;2us
		RET
				
TAB:	DB		3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH
				;存放0~9共阴极数字
		END

阅读终点,创作起航,您可以撰写心得或摘录文章要点写篇博文。去创作
  • 0
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
以下是一个基于C51单片机十字路口红绿灯C语言程序,它使用了定时器和外部中断来控制红绿灯的亮灭,模拟了十字路口的交通信号控制。 ``` #include <reg52.h> // 定义端口地址 #define PORT_LIGHT P0 #define PORT_BTN P3 // 定义端口位掩码 #define RED 0x01 #define YELLOW 0x02 #define GREEN 0x04 // 定义定时器初值和重载值 #define TIMER_INIT 65536-10000 // 10ms #define TIMER_RELOAD 65536-10000 // 10ms // 定义中断向量 #define INT_VECTOR_T0 1 // 定义延时函数 void delay(int time) { int i, j; for (i = 0; i < time; i++) { for (j = 0; j < 50; j++); } } // 定义定时器中断处理函数 void timer0_isr(void) interrupt INT_VECTOR_T0 { static unsigned char cnt = 0; cnt++; if (cnt == 50) { // 500ms cnt = 0; // 红绿灯状态切换 if (PORT_LIGHT == RED) { PORT_LIGHT = GREEN; } else if (PORT_LIGHT == GREEN) { PORT_LIGHT = YELLOW; } else if (PORT_LIGHT == YELLOW) { PORT_LIGHT = RED; } } TH0 = TIMER_INIT / 256; TL0 = TIMER_INIT % 256; } // 定义外部中断处理函数 void int0_isr(void) interrupt 0 { // 检测按钮是否按下 if (PORT_BTN == 0) { // 切换红绿灯状态 if (PORT_LIGHT == RED) { PORT_LIGHT = GREEN; } else if (PORT_LIGHT == GREEN) { PORT_LIGHT = YELLOW; } else if (PORT_LIGHT == YELLOW) { PORT_LIGHT = RED; } } delay(20); // 消除按键抖动 while (PORT_BTN == 0); } // 程序入口 void main() { // 初始化定时器 TMOD = 0x01; // 定时器0,模式1 TH0 = TIMER_INIT / 256; TL0 = TIMER_INIT % 256; TR0 = 1; // 启动定时器 ET0 = 1; // 允许定时器中断 // 初始化外部中断 IT0 = 1; // 下降沿触发 EX0 = 1; // 允许外部中断 // 初始化端口 PORT_LIGHT = RED; PORT_BTN = 0xff; // 上拉 // 无限循环 while (1); } ``` 上述程序使用了定时器和外部中断来控制红绿灯的亮灭,模拟了十字路口的交通信号控制。定时器中断处理函数timer0_isr每500ms切换一次红绿灯状态,外部中断处理函数int0_isr检测到按钮按下后切换红绿灯状态,并使用延时函数消除按键抖动。程序入口是main函数,初始化定时器、外部中断和端口后,进入无限循环等待中断事件的发生。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

长安永恒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值