51单片机汇编语言实现交通灯 代码有详细注释

[复制链接]
查看2 | 回复0 | 2021-4-13 23:54:13 | 显示全部楼层 |阅读模式
用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会直接显示下一个状态。
初学单片机的新手欢迎各位大佬指正
代码放入了附件部分 备有详细的注释
205549t1mc6eyj0mzc6zc0.jpg

单片机源程序如下:
  1. ORG 0000H;程序起始地址
  2.         LJMP START;初始化标号
  3.         ORG 0003H;外部中断地址--东西紧急按钮触发
  4.         LJMP DXJJ;东西紧急标号
  5.         ORG 0013H;外部中断地址--南北紧急按钮触发
  6.         LJMP NBJJ;南北紧急标号
  7.         ORG 000BH;定时器T0中断地址       
  8.         LJMP OT         ;定时器T0标号
  9.         ORG 0100H;程序起始位置
  10. START:        SETB EA         ;中断允许       
  11.         SETB ET0 ;允许定时器T0中断
  12.         CLR IT0 ;设置外部中断为电平触发
  13.         CLR IT1 ;同上
  14.         SETB EX0 ;允许外部中断
  15.         SETB EX1 ;同上
  16.         SETB PX0 ;设置外部中断优先级高于定时器中断
  17.         SETB PX1 ;
  18.         CLR PT0         ;
  19.         MOV TMOD,#01H;设置定时器模式1
  20.         MOV TH0,#3CH ;
  21.         MOV TL0,#0B0H;设置定时器初值--50ms
  22.         SETB TR0     ;开启定时器       

  23. MAIN:        MOV R0,#20;设置R0 记录20个50ms 产生1s
  24.         MOV R1,#56;设置主时间判断时间轴 表示循环周期
  25.         MOV R2,#3 ;
  26.         MOV R3,#3 ;东西南北初始红灯时间为3S
  27.         MOV R4,#0FCH;初始全红 1111 1100
  28.         MOV 70H,#0;判断是否按下了紧急按钮的标志位 0 第一次按(进入紧急状态) 1 第二次按(退出紧急状态)
  29.         MOV R7,#00H ;判断是要执行紧急程序还是正常交通灯显示  00H正常交通灯 01H 东西紧急 02H南北紧急
  30. XS:        LCALL DISPLAY;调用显示程序
  31.         LJMP XS     ;循环进行显示
  32.         SJMP $      ;死循环 保护程序执行? 可能没用

  33. OT:        CJNE R7,#00H,PD ;R7不等于0跳转判断是哪个紧急,R7=0 说明未中断正常跑程序
  34. ZCP:        DJNZ R0,OVER2;        ;R0 不为零说明没有记够20个50ms即没有产生1s,跳出中断等待下一次50ms产生中断信号
  35.         MOV TH0,#3CH ;
  36.         MOV TL0,#0B0H;记完一次50ms 重新装载定时器初值
  37.         DEC R1        ;进入此部分说明已经经过了1s 那么总时间-1
  38.         DEC R2        ;显示时间-1
  39.         DEC R3        ;显示时间-1
  40. KK1:        CJNE R1,#53,KK2        ;判断是否经过了3s 到达了第一个状态(初始状态全红为第状态)
  41.         MOV R2,#20        ;
  42.         MOV R3,#23        ;赋值显示
  43.         MOV R4,#0F9H;DX绿,NB红 1111 1001
  44.         RETI
  45. KK2:        CJNE R1,#33,KK3        ;判断是否又经过了20s 到达了第二个状态
  46.         MOV R2,#3        ;赋值显示
  47.         MOV R4,#0EDH;DX黄,NB红 1110 1101
  48.         RETI
  49. KK3:        CJNE R1,#30,KK4        ;判断是否又经过了3s 到达了第三个状态
  50.         MOV R2,#33        ;
  51.         MOV R3,#30        ;赋值显示
  52.         MOV R4,#0F6H;DX红,NB绿 1111 0110
  53.         RETI
  54. KK4:        CJNE R1,#0,OVER1 ;判断是否又经过了30s 到达了第四个状态   此时为了跳出中断 还不能重新赋值记录50ms的个数 采用了OVER1和OVER2
  55.         MOV R3,#3        ;赋值显示
  56.         MOV R4,#0DEH;DX红,NB黄 1101 1110
  57.         MOV R1,#56        ;重新赋值总时间
  58. OVER1:        MOV R0,#20        ;重新赋值20 以产生1s
  59. OVER2:        RETI                 ;跳出中断 如果用ERT是跳出子程序调用 两者有区别!

  60. PD:        CJNE R7,#01H,NB;判断是哪种紧急 01H 是DX紧急  02H是NB紧急
  61. DX:        MOV R4,#0B9H;DXJJ将东西车和绿灯打开,将南北灯变红 1011 1001
  62.         MOV P2,#0FFH;关掉数码管选通 达到暂停数码管效果
  63.         RETI
  64. NB:        MOV R4,#76H;NBJJ将南北车和南北绿灯打开,将东西灯变红 0111 0110
  65.         MOV P2,#0FFH;关掉数码管选通 达到暂停数码管效果
  66.         RETI

  67. DXJJ:        JB 70H,OFF1;判断是否第一次按下紧急按钮
  68. ON1:        CPL 70H           ;按下一次后就翻转 下次就能检测出是第二次
  69.         MOV R7,#01H;第一次按下说明开启中断 那么进入紧急状态 紧急状态标志变为#01H表示产生东西中断
  70.         LJMP OUT1
  71. OFF1:        CPL 70H           ;如果要关掉中断那么也要对标志位取反 下次就能检测出是要开启
  72.         MOV R7,#00H;第二次按下说明是关闭中断 紧急标志变为#00H进入正常交通灯显示
  73. OUT1:        RETI

  74. NBJJ:        JB 70H,OFF2;道理同上
  75. ON2:        CPL 70H
  76.         MOV R7,#02H
  77.         LJMP OUT2
  78. OFF2:        CPL 70H
  79.         MOV R7,#00H
  80. OUT2:        RETI

  81. DISPLAY:MOV DPTR,#TAB;东西的数码管十位显示
  82.         MOV A,R2;
  83.         MOV B,#10
  84.         DIV AB
  85.         MOVC A,@A+DPTR;
  86.         MOV P2,#11111101B;
  87.         MOV P0,A
  88.         LCALL YS
  89.         MOV DPTR,#TAB;东西的数码管个位显示
  90.         MOV A,B;
  91.         MOVC A,@A+DPTR;
  92.         MOV P2,#11111110B
  93.         MOV P0,A;
  94.         LCALL YS
  95.         MOV DPTR,#TAB;南北的数码管十位显示
  96.         MOV A,R3;
  97.         MOV B,#10
  98.         DIV AB
  99.         MOVC A,@A+DPTR;
  100.         MOV P2,#11110111B;
  101.         MOV P0,A
  102.         LCALL YS
  103.         MOV DPTR,#TAB;南北的数码管个位显示
  104.         MOV A,B;
  105.         MOVC A,@A+DPTR;
  106.         MOV P2,#11111011B
  107.         MOV P0,A;
  108.         LCALL YS
  109.        
  110.         MOV P1,R4;红绿灯的显示
  111.         LCALL YS
  112.         RET

  113. YS:        MOV R5,#150 ;延时函数
  114. JY:        DJNZ R5,JY ;减一操作
  115.         RET

  116. TAB: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH;数码管共阴极


  117. END
复制代码
代码下载: 交通灯汇编代码.zip (14.31 KB, 售价: 1 工控币)
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则