找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 7429|回复: 4
打印 上一主题 下一主题
收起左侧

51单片机交通灯仿真与实物 源程序注释十分详细

  [复制链接]
跳转到指定楼层
楼主
51单片机交通灯的实物图:


本proteus仿真文件是proteus7.4版本创建的,请用7.4版本或更高版本打开,较低版本可能出现无法打开的现象。




单片机源程序如下:
  1. /***************51单片机交通灯设计*******************/

  2. #include <reg52.h>
  3. #include <intrins.h>
  4. #define        uint unsigned int
  5. #define uchar unsigned char
  6. uchar night_flag=0;                                //深夜标志位
  7. uchar time_cl=0;                                //定义时间控制标志位  取0        
  8. uchar flag=0;                                        //方向通行标志位
  9. uchar B_N_D_flag=1;                                //定义北南通灯行标志位
  10. uchar X_D_D_flag=1;                                //定义西东通灯行标志位
  11. uchar i,j;                                                //定义变量i
  12. uchar t=3;                                                //数码管动态扫描延时时间基数
  13. uchar num=0;                                        //时间基数初始化为0
  14. //uchar num_night=0;                                //深夜模式时间基数为0
  15. uchar time=30;                                        //time初始化定为30秒
  16. int bei,nan,xi,dong;            //定义  北  南  西  东
  17. uchar code Data[]={0x18,0x7B,0x89,0x49,0x6A,0x4C,0x0C,0x79,0x08,0x48,0xEF};
  18. //定义数组  数码管   0    1    2    3    4    5    6    7    8    9    -
  19. /***************定义  红黄绿灯**************/
  20. sbit    B_R=P1^2;                                //北面  红灯
  21. sbit    B_Y=P1^1;                                //北面  黄灯
  22. sbit    B_G=P1^0;                                //北面        绿灯
  23. sbit    N_R=P2^0;                                //南面        红灯
  24. sbit    N_Y=P2^1;                                //南面        黄灯
  25. sbit        N_G=P2^2;                                //南面        绿灯
  26. sbit    X_R=P2^5;//西面        红灯
  27. sbit    X_Y=P2^6;                                //西面        黄灯
  28. sbit    X_G=P2^7;                                //西面        绿灯

  29. sbit    D_R=P3^7;                                //东面  红灯
  30. sbit    D_Y=P3^6;                                //东面        黄灯
  31. sbit    D_G=P3^5;                                //东面  绿灯

  32. sbit    s1=P3^4;//时间减
  33. sbit    s2=P3^3;//时间加
  34. sbit    s3=P3^1;//白天和夜间模式控制切换口
  35. sbit    s4=P3^2;//进入时间可以设置状态的切换口
  36. /***************定义  数码管*****************/
  37. #define        SMG_XS        P0                                //数码管数据显示
  38. #define        SMG_KZ        P2                                //数码管控制显示
  39. sbit   smg1=P2^4;//定义数码管1控制口
  40. sbit   smg2=P2^3;//定义数码管2控制口
  41. void delay(uint time);// 定义延时程序
  42. void disp_init();//显示初始化
  43. void disp(bei,nan,xi,dong);




  44. void Time0_init()                                //定时器0初始化函数
  45. {
  46.         TMOD=0x01;                                        //定时器0为方式1
  47.         TL0=(65536-50000)%256;
  48.         TH0=(65536-50000)/256;                //12M晶振 定时时间50ms
  49.         ET0=1;                                                //开定时器0中断
  50.         EA=1;                                                //开总中断
  51.         TR0=1;                                                //启动定时器0
  52. }

  53. void night_mode()                                //深夜模式
  54. {
  55.         B_R=1;
  56.         B_Y=~B_Y;                                        //北 黄灯取反
  57.         B_G=1;
  58.         N_R=1;
  59.         N_Y=~N_Y;                                        //南 黄灯取反
  60.         N_G=1;

  61.         X_R=1;                                       
  62.         X_Y=~X_Y;                                        //西 黄灯取反
  63.         X_G=1;
  64.         D_R=1;
  65.         D_Y=~D_Y;                                        //东 黄灯取反
  66.         D_G=1;        
  67. }

  68. void B_N_G()                                        //北南通(绿灯)  西东(红灯)                        
  69. {
  70.         B_G=0;                                                //北  绿灯亮
  71.         N_G=0;                                                //南  绿灯亮
  72.         B_R=1;
  73.         B_Y=1;
  74.         N_R=1;
  75.         N_Y=1;

  76.         X_R=0;                                                //西  红灯亮
  77.         D_R=0;                                                //东  红灯亮
  78.         X_Y=1;
  79.         X_G=1;
  80.         D_Y=1;
  81.         D_G=1;
  82. }

  83. void X_D_G()                                        //西东通(绿灯)  北南(红灯)                        
  84. {
  85.         B_G=1;
  86.         N_G=1;
  87.         B_R=0;                                                //北  红灯亮
  88.         B_Y=1;
  89.         N_R=0;                                                //南  红灯亮
  90.         N_Y=1;

  91.         X_R=1;
  92.         D_R=1;
  93.         X_Y=1;
  94.         X_G=0;                                                //西  绿灯亮
  95.         D_Y=1;
  96.         D_G=0;                                                //东  绿灯亮
  97. }

  98. void B_N_tong()                                        //北南 通行
  99. {
  100.         if(B_N_D_flag==1)                        //当北南通灯行标志位为1
  101.         {
  102.                 B_N_G();                                //北南通(绿灯)  西东(红灯)
  103.                 B_N_D_flag=0;                        //北南通灯行标志位置0
  104.         }
  105.         while(num==20)                                //当1s时间到
  106.         {
  107.                 num=0;                                        //num清0
  108.                 bei--;                                        //北时间 减1
  109.                 nan--;                                        //南时间 减1
  110.                 xi--;                                        //西时间 减1
  111.                 dong--;                                        //东时间 减1
  112.                 if(bei<=6&&bei>=0||nan<=6&&nan>=0)                //当北和南时间在0到6秒之间
  113.                 {
  114.                         if(bei<=6&&bei>3||nan<=6&&nan>3)        //进一步判断北和南时间是否在3到6秒之间
  115.                         {
  116.                                 B_G=~B_G;                                                //北  绿灯取反
  117.                                 N_G=~N_G;                                                //南  绿灯取反
  118.                         }
  119.                         if(bei<=3&&nan<=3)                                        //进一步判断北和南时间是否在3秒以内
  120.                         {
  121.                                 B_G=1;                                                        //北  绿灯不亮
  122.                                 N_G=1;                                                        //南  绿灯不亮
  123.                                 B_Y=0;                                                        //北  黄灯亮
  124.                                 N_Y=0;                                                        //南  黄灯亮
  125.                         }
  126.                 }
  127.                 else                                                                        //否则(即北和南时间不在0到6秒之间)
  128.                 {
  129.                         B_G=0;                                                                //北  绿灯亮
  130.                         N_G=0;                                                                //南  绿灯亮
  131.                         B_Y=1;                                                                //北  黄灯不亮
  132.                         N_Y=1;                                                                //南  黄灯不亮
  133.                 }
  134.         }
  135. }

  136. void X_D_tong()                                                                        //西东  通行
  137. {
  138.         if(X_D_D_flag==1)                                                        //当西东通灯行标志位为1
  139.         {
  140.                 X_D_G();                                                                //西东通(绿灯)  北南(红灯)
  141.                 X_D_D_flag=0;                                                        //西东通灯行标志位置0
  142.         }
  143.         while(num==20)                                                                //当1s时间到
  144.         {
  145.                 num=0;                                                                        //num清0
  146.                 bei--;                                                                        //北时间 减1
  147.                 nan--;                                                                        //南时间 减1               
  148.                 xi--;                                                                        //西时间 减1
  149.                 dong--;                                                                        //东时间 减1        
  150.                 if(xi<=6&&xi>=0||dong<=6&&xi>=0)                //当西和东时间在0到6秒之间
  151.                 {
  152.                         if(xi<=6&&xi>3||dong<=6&&dong>3)        //进一步判断西和东时间是否在3到6秒之间
  153.                         {
  154.                                 X_G=~X_G;                                                //西  绿灯取反
  155.                                 D_G=~D_G;                                                //东  绿灯取反
  156.                         }
  157.                         if(xi<=3&&dong<=3)                                        //进一步判断西和东时间是否在3秒以内
  158.                         {
  159.                                 X_G=1;                                                        //西  绿灯不亮
  160.                                 D_G=1;                                                        //东  绿灯不亮
  161.                                 X_Y=0;                                                        //西  黄灯亮
  162.                                 D_Y=0;                                                        //东  黄灯亮
  163.                         }
  164.                 }
  165.                 else                                                                        //否则(即西和东时间不在0到6秒之间)
  166.                 {
  167.                         X_G=0;                                                                //西  绿灯亮
  168.                         D_G=0;                                                                //东  绿灯亮
  169.                         X_Y=1;                                                                //西  黄灯不亮
  170.                         D_Y=1;//东  黄灯不亮        
  171.                 }
  172.         }               
  173. }

  174. void Time0() interrupt 1                                                //定时器0中断服务函数
  175. {
  176.         TH0=(65536-50000)/256;                                                //重新载装初值,设置50ms中断一次
  177.         TL0=(65536-50000)%256;
  178.         num++;                                                                                //时间基数加1
  179. }
  180.                
  181. void main()                                                                                //主函数入口                                                                                       
  182. {
  183.         bei=nan=xi=dong=time;                                                //把time值赋给北 南 西 东
  184.         disp_init();                        //显示初始化
  185.         Time0_init();                //定时器0初始化函数               
  186.         while(1)                //无限循环
  187.         {  
  188.                 if(s4==0)                                                                //当P3.0按下(调整时间允许键)
  189.                 {
  190.                         delay(5);                                                        //延时去抖
  191.                         s4=1;                                                //关闭数码管显示
  192.                         if(s4==0)                                                    //再次确定按键是否按下
  193.                         {
  194.                                 time_cl=~time_cl;//时间控制标志位取反(开/关时间控制标志位)        
  195.                                 if(time_cl==0)                                        //如果时间控制标志位为0
  196.                                 {
  197.                                         TL0=(65536-50000)%256;
  198.                                         TH0=(65536-50000)/256;                //12M晶振 定时时间50ms
  199.                                         TR0=1;                                                //开启定时器0
  200.                                         num=0;                                                //num初始化为0        
  201.                                 }        
  202.                         }        
  203.                         while(s4==0);                                                //等待按键松开
  204.                 }
  205.                
  206.                 if(s3==0)                                                                //当P3.7按下(开/关 深夜模式)
  207.                 {
  208.                         delay(5);                                                        //延时去抖
  209.                     s3=1;                                                //关闭数码管显示
  210.                         if(s3==0)
  211.                         {
  212.                                 night_flag=~night_flag;                        //深夜标志位取反(开/关深夜模式),1表示开,0表示关
  213.                                 if(night_flag==1)                                //如果深夜模式开
  214.                                 {
  215.                                         TR0=0;                                                //关闭定时器0
  216.                                         num=0;                                                //时间基数清0
  217.                                         TL0=(65536-50000)%256;
  218.                                         TH0=(65536-50000)/256;                //12M晶振 定时时间50ms
  219.                                         TR0=1;                                                //开启定时器0
  220.                                         SMG_KZ=0xff;                                //关闭数码管显示        
  221.                                 }
  222.                                 else                                                         //否则night_flag=0表示深夜模式关(红绿灯正常运行)                                       
  223.                                 {
  224.                                         TR0=0;                                                //关闭定时器0
  225.                                         num=0;                                                //时间基数清0
  226.                                         TL0=(65536-50000)%256;
  227.                                         TH0=(65536-50000)/256;                //12M晶振 定时时间50ms
  228.                                         TR0=1;                                                //开启定时器0
  229.                                         B_N_D_flag=1;                                //定义北南通灯行标志位
  230.                                         X_D_D_flag=1;                                //定义西东通灯行标志位        
  231.                                         if(bei<=3&&nan<=3)                        //判断北和南时间是否在3秒以内
  232.                                         {
  233.                                                 B_Y=1;
  234.                                                 N_Y=1;
  235.                                         }
  236.                                         if(xi<=3&&dong<=3)                        //判断西和东时间是否在3秒以内
  237.                                         {
  238.                                                 X_Y=1;
  239.                                                 D_Y=1;
  240.                                         }                                
  241.                                 }
  242.                         }
  243.                         while(s3==0);                                                                        
  244.                 }
  245.                 if(night_flag==0)                                                //如果深夜标志位为0,表示关闭深夜模式,红绿灯正常运行
  246.                 {
  247.                         if(time_cl==0)                                                        //如果time_cl=0(不允许调整时间),即红绿灯正常运行
  248.                         {        
  249.                                 if(flag==0)                                                        //flag=0表示北南通行允许
  250.                                 {
  251.                                         B_N_tong();                                                //北南 通行
  252.                                         if(bei==0)                                                //北南通行时间到
  253.                                         {
  254.                                                 flag=~flag;                                        //西东 通行允许
  255.                                                 B_N_D_flag=1;                                //北南通灯行标志位置1
  256.                                         }
  257.                                 }
  258.                                 else                                                                //flag=1表示西东通行允许
  259.                                 {
  260.                                         X_D_tong();                                                //西东 通行
  261.                                         if(xi==0)                                                //西东通行时间到
  262.                                         {
  263.                                                 flag=~flag;                                        //北南 通行允许
  264.                                                 X_D_D_flag=1;                                //西东通灯行标志位置1
  265.                                         }
  266.                                 }
  267.         
  268.                                 disp(bei,nan,xi,dong);                                //显示时间数据
  269.                                 if(bei==0&&nan==0&&xi==0&&dong==0)        //如果 北 南 西 东时间到(为0)
  270.                                 {
  271.                                         TR0=0;                                                        //关闭定时器0
  272.                                         TL0=(65536-50000)%256;                        
  273.                                         TH0=(65536-50000)/256;                        //12M晶振 定时时间50ms
  274.                                         for(j=0;j<3;j++)                                //延时显示闪烁3下
  275.                                         {
  276.                                                 for(i=0;i<10;i++)                        //for语句延时
  277.                                                 {
  278.                                                         disp(bei,nan,xi,dong);  //显示函数
  279.                                                 
  280.                                                 }
  281.                                                 SMG_KZ=0xff;                                //关闭显示
  282.                                                 delay(200);                                        //延时一下
  283.                                         }
  284.                                         bei=time;                                                //time值赋给北
  285.                                         nan=time;                                                //time值赋给南
  286.                                         xi=time;                                                //time值赋给西
  287.                                         dong=time;                                                //time值赋给东
  288.                                         TR0=1;                                                        //开启定时器0
  289.                                 }
  290.                                 else                                                                //否则
  291.                                 {}                                                                        //空操作
  292.                         }
  293.                         else                                                                        //如果time_cl==1(允许时间调整)
  294.                         {
  295.                                 TR0=0;                                                                //关闭定时器
  296.                                 TL0=(65536-50000)%256;
  297.                                 TH0=(65536-50000)/256;                                //12M晶振 定时时间50ms
  298.                                 num=0;                                                                //时间基数清0
  299.                                 bei=nan=xi=dong=time;                                //time值赋给 北 南 西 东
  300.                                 disp(bei,nan,xi,dong);                                //显示时间数据
  301.                                 if(s2==0)                                                        //当P3.1按键按下(操作时间加1)
  302.                                 {
  303.                                         delay(5);                                                //延时去抖
  304.                                         if(s2==0)                                                //再次确定按键是否按下
  305.                                         {
  306.                                                 time++;                                                //时间加1
  307.                                         }        
  308.                                         while(s2==0);                                        //等待按键松开        
  309.                                 }
  310.                                 if(bei==100&&nan==100&&xi==100&&dong==100)        //如果北 南 西 东 时间到100
  311.                                 {        
  312.                                         time=1;                                                        //time等于1
  313.                                 }
  314.                                 if(s1==0)                                                        //当P3.6按键按下(操作时间减1)               
  315.                                 {                                                                                
  316.                                         delay(5);                                                //延时去抖
  317.                                         if(s1==0)                                                //再次确定按键是否按下
  318.                                         {
  319.                                                 time--;                                                //time减1
  320.                                         }
  321.                                         while(s1==0);                                        //等待按键松开
  322.                                 }
  323.                                 if(bei==0&&nan==0&&xi==0&&dong==0)        //如果北 南 西 东 时间到0
  324.                                 {
  325.                                         time=99;                                                //time等于99
  326.                                 }        
  327.                         }
  328.                 }
  329.                 else                                                                                //否则深夜标志位为1,表示开启深夜模式
  330.                 {               
  331.                         if(num==20)                                                                //当1s时间到
  332.                         {
  333.                                 num=0;                                                                //50ms时间基数清0
  334.                                 night_mode();                                                //深夜模式
  335.                         }                                
  336.                 }
  337.   //  disp(69,69,69,69);                        
  338.         }
  339.    
  340. }






  341. void disp(bei,nan,xi,dong)                 //显示(北 南 西 东)时间函数
  342. {
  343.         SMG_XS=Data[bei/10];                //显示北的十位
  344.         smg1=0;                                //允许北十位显示
  345.         delay(t);                                        //小延时一下,使数码管显示更清楚
  346.     smg1=1;                        //关闭数码管显示(消隐)
  347.         SMG_XS=Data[bei%10];                //显示北的个位
  348.         smg2=0;                        //允许北个位显示
  349.     delay(t);                                        //小延时一下,使数码管显示更清楚
  350.         smg2=1;                        //关闭数码管显示(消隐)        
  351.         SMG_XS=Data[nan/10];                //显示南的十位        
  352. //SMG_KZ=0xf7;                                //允许南十位显示
  353.     smg1=0;
  354.           delay(t);                                        //小延时一下,使数码管显示更清楚
  355.         smg1=1;
  356.     //SMG_KZ=0xff;                                //关闭数码管显示(消隐)
  357.         SMG_XS=Data[nan%10];                //显示南的个位
  358.         //SMG_KZ=0xfb;                                //允许南个位显示
  359.     smg2=0;        
  360.     delay(t);                                        //小延时一下,使数码管显示更清楚
  361.         //SMG_KZ=0xff;                                //关闭数码管显示(消隐)
  362.     smg2=1;
  363.         SMG_XS=Data[xi/10];                        //显示西的十位        
  364.   //        SMG_KZ=0xdf;                                //允许西十位显示
  365.         smg1=0;
  366.     delay(t);                                        //小延时一下,使数码管显示更清楚
  367.         smg1=1;
  368.     //SMG_KZ=0xff;                                //关闭数码管显示(消隐)
  369.         SMG_XS=Data[xi%10];                        //显示西的个位
  370.         smg2=0;
  371.     //SMG_KZ=0xef;                                //允许西个位显示
  372.         delay(t);                                        //小延时一下,使数码管显示更清楚
  373.         smg2=1;
  374.     //SMG_KZ=0xff;                                //关闭数码管显示(消隐)

  375.         SMG_XS=Data[dong/10];                //显示东的十位               
  376.         smg1=0;
  377.     //SMG_KZ=0x7f;                                //允许东十位显示
  378.         delay(t);                                        //小延时一下,使数码管显示更清楚
  379.         smg1=1;
  380.     //SMG_KZ=0xff;                                //关闭数码管显示(消隐)
  381.         SMG_XS=Data[dong%10];                //显示东的个位
  382.         smg2=0;//
  383. ……………………

  384. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

所有资料51hei提供下载:
ID216 模块相关资料 交通灯.zip (794.82 KB, 下载次数: 90)


评分

参与人数 3黑币 +15 收起 理由
阿玲玲玲 + 5 回帖助人的奖励!
bhbsh + 5 赞一个!
cccchen + 5 很给力!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏4 分享淘帖 顶1 踩
回复

使用道具 举报

沙发
ID:1 发表于 2017-6-6 04:07 | 只看该作者
好资料,51黑有你更精彩!!!
回复

使用道具 举报

板凳
ID:208951 发表于 2017-6-12 15:59 | 只看该作者
赞一个
回复

使用道具 举报

地板
ID:72444 发表于 2017-6-20 12:03 | 只看该作者
赞一个
回复

使用道具 举报

5#
ID:321448 发表于 2018-7-12 13:53 | 只看该作者
非常好的资料
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表