用51单片机实现一个交通灯的控制
交通灯的变化模式为:初始化状态为东西红灯都亮→延迟 3s 变为东西方向绿灯,南北方向红灯→过 20S 后,东西方向变黄灯,南北方向依然是红灯→过 3S,东西方向变红灯,南北方向变绿灯→过 30S 后,东西方向依然为红灯,南北方向变黄灯→过 3S 后变为东西绿灯, 南北红灯,依次循环。
交通灯模块电路板如图
其中, J0 和 J0’是电源插座, POWER 为电源开关, P0 为 P0.0~P0.7 插座,对就数码管段码(a~f), P1 为 P1.0~P1.7 插。
P1.0 连接东西红灯, P1.1 连接南北红灯, P1.2 连接东西绿灯, P1.3 连接南北绿灯, P1.4连接东西黄灯, P1.5 连接南北黄灯, P1.6 连接东西车 , P1.7 连接南北车; P2.0 为 LED1和 LED3 的位选, P2.1 为 LED2 和 LED4 的位选, P2.2 为 LED5 和 LED7 的位选, P2.3 为LED6 和 LED8 的位选; P3.2 东西紧急按钮, P3.3 南北紧急按钮
当按下紧急按钮,对应的通路会变为常绿,同时本方向表示车的LED亮起,用以表示有救护车通过等紧急情况
通过汇编语言基于KEILC51实现
通过实际观察发现 由于按键是中断实现,故没有添加去抖,导致按下紧急按钮后可能没有进入中断状态,这个可以通过数码管的显示来判断,当数码管显示暂停,说明进入紧急中断;当再次按下时,数码管继续跑数字,则退出了中断。还有一点做的不太好,没有做好现场保存,当退出紧急中断的时候,红绿灯无法立刻恢复到原状态,当此状态时间跑过,LED会直接显示下一个状态。
初学单片机的新手欢迎各位大佬指正
代码放入了附件部分 备有详细的注释
单片机源程序如下:
- ORG 0000H;程序起始地址
- LJMP START;初始化标号
- ORG 0003H;外部中断地址--东西紧急按钮触发
- LJMP DXJJ;东西紧急标号
- ORG 0013H;外部中断地址--南北紧急按钮触发
- LJMP NBJJ;南北紧急标号
- ORG 000BH;定时器T0中断地址
- LJMP OT ;定时器T0标号
- ORG 0100H;程序起始位置
- START: SETB EA ;中断允许
- SETB ET0 ;允许定时器T0中断
- CLR IT0 ;设置外部中断为电平触发
- CLR IT1 ;同上
- SETB EX0 ;允许外部中断
- SETB EX1 ;同上
- SETB PX0 ;设置外部中断优先级高于定时器中断
- SETB PX1 ;
- CLR PT0 ;
- MOV TMOD,#01H;设置定时器模式1
- MOV TH0,#3CH ;
- MOV TL0,#0B0H;设置定时器初值--50ms
- SETB TR0 ;开启定时器
- MAIN: MOV R0,#20;设置R0 记录20个50ms 产生1s
- MOV R1,#56;设置主时间判断时间轴 表示循环周期
- MOV R2,#3 ;
- MOV R3,#3 ;东西南北初始红灯时间为3S
- MOV R4,#0FCH;初始全红 1111 1100
- MOV 70H,#0;判断是否按下了紧急按钮的标志位 0 第一次按(进入紧急状态) 1 第二次按(退出紧急状态)
- MOV R7,#00H ;判断是要执行紧急程序还是正常交通灯显示 00H正常交通灯 01H 东西紧急 02H南北紧急
- XS: LCALL DISPLAY;调用显示程序
- LJMP XS ;循环进行显示
- SJMP $ ;死循环 保护程序执行? 可能没用
- OT: CJNE R7,#00H,PD ;R7不等于0跳转判断是哪个紧急,R7=0 说明未中断正常跑程序
- ZCP: DJNZ R0,OVER2; ;R0 不为零说明没有记够20个50ms即没有产生1s,跳出中断等待下一次50ms产生中断信号
- MOV TH0,#3CH ;
- MOV TL0,#0B0H;记完一次50ms 重新装载定时器初值
- DEC R1 ;进入此部分说明已经经过了1s 那么总时间-1
- DEC R2 ;显示时间-1
- DEC R3 ;显示时间-1
- KK1: CJNE R1,#53,KK2 ;判断是否经过了3s 到达了第一个状态(初始状态全红为第状态)
- MOV R2,#20 ;
- MOV R3,#23 ;赋值显示
- MOV R4,#0F9H;DX绿,NB红 1111 1001
- RETI
- KK2: CJNE R1,#33,KK3 ;判断是否又经过了20s 到达了第二个状态
- MOV R2,#3 ;赋值显示
- MOV R4,#0EDH;DX黄,NB红 1110 1101
- RETI
- KK3: CJNE R1,#30,KK4 ;判断是否又经过了3s 到达了第三个状态
- MOV R2,#33 ;
- MOV R3,#30 ;赋值显示
- MOV R4,#0F6H;DX红,NB绿 1111 0110
- RETI
- KK4: CJNE R1,#0,OVER1 ;判断是否又经过了30s 到达了第四个状态 此时为了跳出中断 还不能重新赋值记录50ms的个数 采用了OVER1和OVER2
- MOV R3,#3 ;赋值显示
- MOV R4,#0DEH;DX红,NB黄 1101 1110
- MOV R1,#56 ;重新赋值总时间
- OVER1: MOV R0,#20 ;重新赋值20 以产生1s
- OVER2: RETI ;跳出中断 如果用ERT是跳出子程序调用 两者有区别!
- PD: CJNE R7,#01H,NB;判断是哪种紧急 01H 是DX紧急 02H是NB紧急
- DX: MOV R4,#0B9H;DXJJ将东西车和绿灯打开,将南北灯变红 1011 1001
- MOV P2,#0FFH;关掉数码管选通 达到暂停数码管效果
- RETI
- NB: MOV R4,#76H;NBJJ将南北车和南北绿灯打开,将东西灯变红 0111 0110
- MOV P2,#0FFH;关掉数码管选通 达到暂停数码管效果
- RETI
- DXJJ: JB 70H,OFF1;判断是否第一次按下紧急按钮
- ON1: CPL 70H ;按下一次后就翻转 下次就能检测出是第二次
- MOV R7,#01H;第一次按下说明开启中断 那么进入紧急状态 紧急状态标志变为#01H表示产生东西中断
- LJMP OUT1
- OFF1: CPL 70H ;如果要关掉中断那么也要对标志位取反 下次就能检测出是要开启
- MOV R7,#00H;第二次按下说明是关闭中断 紧急标志变为#00H进入正常交通灯显示
- OUT1: RETI
- NBJJ: JB 70H,OFF2;道理同上
- ON2: CPL 70H
- MOV R7,#02H
- LJMP OUT2
- OFF2: CPL 70H
- MOV R7,#00H
- OUT2: RETI
- DISPLAY:MOV DPTR,#TAB;东西的数码管十位显示
- MOV A,R2;
- MOV B,#10
- DIV AB
- MOVC A,@A+DPTR;
- MOV P2,#11111101B;
- MOV P0,A
- LCALL YS
- MOV DPTR,#TAB;东西的数码管个位显示
- MOV A,B;
- MOVC A,@A+DPTR;
- MOV P2,#11111110B
- MOV P0,A;
- LCALL YS
- MOV DPTR,#TAB;南北的数码管十位显示
- MOV A,R3;
- MOV B,#10
- DIV AB
- MOVC A,@A+DPTR;
- MOV P2,#11110111B;
- MOV P0,A
- LCALL YS
- MOV DPTR,#TAB;南北的数码管个位显示
- MOV A,B;
- MOVC A,@A+DPTR;
- MOV P2,#11111011B
- MOV P0,A;
- LCALL YS
-
- MOV P1,R4;红绿灯的显示
- LCALL YS
- RET
- YS: MOV R5,#150 ;延时函数
- JY: DJNZ R5,JY ;减一操作
- RET
- TAB: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH;数码管共阴极
- END
复制代码 代码下载:
交通灯汇编代码.zip
(14.31 KB, 售价: 1 E币)
【必读】版权免责声明
1、本主题所有言论和内容纯属会员个人意见,与本论坛立场无关。2、本站对所发内容真实性、客观性、可用性不做任何保证也不负任何责任,网友之间仅出于学习目的进行交流。3、对提供的数字内容不拥有任何权利,其版权归原著者拥有。请勿将该数字内容进行商业交易、转载等行为,该内容只为学习所提供,使用后发生的一切问题与本站无关。 4、本网站不保证本站提供的下载资源的准确性、安全性和完整性;同时本网站也不承担用户因使用这些下载资源对自己和他人造成任何形式的损失或伤害。 5、本网站所有软件和资料均为网友推荐收集整理而来,仅供学习用途使用,请务必下载后两小时内删除,禁止商用。6、如有侵犯你版权的,请及时联系我们(电子邮箱1370723259@qq.com)指出,本站将立即改正。
|
|