当前位置:   article > 正文

51单片机模拟交通信号灯控制系统设计_单片机交通信号灯控制系统设计

单片机交通信号灯控制系统设计

51单片机模拟交通信号灯控制系统设计

设计要求:

1.LED灯模拟十字路口交通灯控制

2.正常情况下双方向轮流通行

3.特殊情况时,A方向通行

4.紧急情况时,AB方向都不通行

本任务涉及定时控制东、南、西、北四个方向上的12盏交通信号灯,且出现特殊和紧急情况时,能及时调整交通灯的指示状态。 采用12个LED发光二极管模拟红、黄、绿交通灯,用单片机的P1口控制发光二极管的亮灭状态;而单片机的P1口只有8个控制端,如何控制12个二极管的亮灭呢? 观察LED状态表,可以发现,在不考虑左转弯行驶车辆的情况下,东、西两个方向的信号灯显示状态是一样的,所以,对应两个方向上的6个发光二极管只用P1口的3根I/O端口线控制即可。同理,南、北方向上的6个发光二极管可用P1口的另外3根I/O端口线控制。 当I/O端口线输出高电平时,对应的交通灯熄灭;反之,当I/O端口线输出低电平时,对应的交通灯点亮。

 实验原理图如下:

实验程序如下:

  1. #include <REGX52.H>
  2. #define uchar unsigned char
  3. uchar t0,t1; //关于定时器延时变量
  4. /*******************************************************************************
  5. * 函 数 名 : delay0_5s1
  6. * 函数功能 : 用T1的工作方式1编写延时0.5秒子函数,采用12MHz晶振
  7. * 输 入 : 无
  8. * 输 出 : 无
  9. ***+****************************************************************************/
  10. void delay0_5s1()
  11. {
  12. for(t0=0;t0<10;t0++)
  13. {
  14. TH1 = (65536-50000)/256;
  15. TL1 = (65536-50000)%256;
  16. TR1 = 1;
  17. while(!TF1);
  18. TF1 = 0;
  19. }
  20. }
  21. /*******************************************************************************
  22. * 函 数 名 : delay_t1
  23. * 函数功能 : 延时函数,延时时间=0.5秒 乘上 输入值t
  24. * 输 入 : t 调节延时时间
  25. * 输 出 : 无
  26. ***+****************************************************************************/
  27. void delay_t1(uchar t)
  28. {
  29. for(t1=0;t1<t;t1++)
  30. {
  31. delay0_5s1();
  32. }
  33. }
  34. /*******************************************************************************
  35. * 函 数 名 : int_0
  36. * 函数功能 : 外部中断0,紧急情况中断,东西南北禁止通行
  37. * 输 入 : 无
  38. * 输 出 : 无
  39. *******************************************************************************/
  40. void int_0() interrupt 0
  41. {
  42. uchar i,j,k,I,m; //保护现场锁存数据
  43. EA=0; //关闭总中断允许,该时间不能被中断
  44. i=P0; //把P0口中断前的数据保存到 i
  45. j=t0; //把中断前的定时t0数据保存给 j
  46. k=t1; //把中断前的定时t1数据保存给 k
  47. I=TH1; //把中断前的定时器初值数据保存给 I 和 m
  48. m=TL1;
  49. EA=1; //开启总中断
  50. P0=0xf6; //给P0赋值实现的结果,东西南北都是红灯亮其他灯灭
  51. delay_t1(10); //延时5秒后恢复中断前数据
  52. EA=0;
  53. P0=i; //恢复现场恢复数据
  54. t0=j;
  55. t1=k;
  56. TH1=I;
  57. TL1=m;
  58. EA=1;
  59. }
  60. /*******************************************************************************
  61. * 函 数 名 : int_1
  62. * 函数功能 : 外部中断1,特殊情况中断,只允许南北通行
  63. * 输 入 : 无
  64. * 输 出 : 无
  65. ***+****************************************************************************/
  66. void int_1() interrupt 2
  67. {
  68. uchar i,j,k,I,m;
  69. i=P0; //保护现场锁存数据
  70. j=t0;
  71. k=t1;
  72. I=TH1;
  73. m=TL1;
  74. EA=1;
  75. P0=0xf3;
  76. delay_t1(10);
  77. EA=0;
  78. P0=i; //恢复现场恢复数据
  79. t0=j;
  80. t1=k;
  81. TH1=I;
  82. TL1=m;
  83. EA=1;
  84. }
  85. /*******************************************************************************
  86. * 函 数 名 : main
  87. * 函数功能 : 数码管倒计时30秒显示,南北方向绿灯常亮26秒后,闪烁3秒,在变黄灯亮3秒。
  88. 黄灯灭后,东西方向绿灯常亮26秒后,闪烁3秒,在变黄灯亮3秒。循环显示
  89. * 输 入 : 无
  90. * 输 出 : 无
  91. ***+****************************************************************************/
  92. void main()
  93. {
  94. uchar k;
  95. TMOD = 0X10; //定时器T1设置工作模式1
  96. EA = 1; //开总中断运许
  97. IT0 = 0; //外部中断0设置为负跳变触发方式
  98. EX0 = 1; //开启外部中断0中断允许位
  99. PX0 = 1; //外部中断0中断优先级高
  100. IT1 = 0; //外部中断1设置为负跳变触发方式
  101. EX1 = 1; //开启外部中断1中断允许位
  102. PX1 = 0; //外部中断1中断优先级低于外部中断0
  103. while(1)
  104. {
  105. P0=0xf3; //1111 0011南北通行
  106. delay_t1(48); //延时24秒
  107. for(k=0;k<3;k++) //绿灯闪烁3秒
  108. {
  109. P0=0xf7;
  110. delay_t1(1); //0.5秒延时
  111. P0=0xf3; //1111 0111 南北绿灯熄灭,东西红灯常亮
  112. delay_t1(1);
  113. }
  114. P0=0xf5; //1111 0101 南北黄灯亮3秒,东西红灯常量
  115. delay_t1(6);
  116. P0=0xde; //1101 1110 南北红灯亮起,东西绿灯亮
  117. delay_t1(48);
  118. for(k=0;k<3;k++)
  119. {
  120. P0=0xfe;
  121. delay_t1(1);
  122. P0=0xde;
  123. delay_t1(1);
  124. }
  125. P0=0xee;
  126. delay_t1(6);
  127. }
  128. }

 注意事项:

    1. 所遇到的问题:

问题1、定时器延时时间不准确比正常时间更快。for(t0=0;t0<2;t0++)

问题2、外部中断0的中断函数int_0 ()结束后,返回值出现误差。

问题3、紧急情况不能打断特殊情况中断

    1. 解决的方法:

问题1、最后发现是定时器延时函数delay0_5s1的程序设置错误, for(t0=0;t0<10;t0++) ,中间误差0.4秒时间。

问题2、原因在于int_0 ()函数中在写保护及恢复数据时没有对中断进行

关闭及打开导致,可能程序在写保护的时候就被紧急情况中断了,导致 写保护没能全部完成。加上EA总中断开关即可。

问题3、该问题分很多原因,原程序出现该问题在于没有对外部中断进行, 中断优先级设置,只需要在main主函数里面的加上:

PX0 = 1;  //外部中断0中断优先级高

PX1 = 0;  //外部中断1中断优先级低于外部中断0

还有一种更高级的带数码管显示倒计时时间的交通灯,但我的实验要求作业是这样所以没写那个,需要的可以关注私信,我写一下。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/495072
推荐阅读
相关标签
  

闽ICP备14008679号