找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4454|回复: 6
收起左侧

带左转的单片机红绿灯proteus仿真与源码分享

[复制链接]
ID:231116 发表于 2018-1-4 14:24 | 显示全部楼层 |阅读模式
单片机红绿灯仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)

仿真图片

仿真图片


带左转灯

单片机源程序如下:
  1. #include "use.h"
  2. #include "main.h"

  3. uchar code seg_du[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};            //七段管段码真值表  共阴                  0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f
  4. uchar code seg_we[]={0x01,0x02,0x04,0x08};                      //共阴位码           0x01,0x02,0x04,0x08                                 0xfe,0xfd,0xfb,0xf7
  5. uchar BackupGreen,BackupRed,CopyLight,CopyLLight,backupLGreen;

  6. void Seg_Display(uchar number,uchar wei)        //数码管动态显示程序
  7. {
  8.         P0=0X00;                                                                        //0XFF
  9.         we=1;        //2.7
  10.         we=0;
  11.         P0=seg_du[number];
  12.         du=1;             //2.6
  13.         du=0;
  14.         P0=seg_we[wei];
  15.         we=1;
  16.         we=0;
  17. }

  18. void UrgentScan()                                                    //设置 ???情况运行扫描
  19. {
  20.         Seg_Display(BackupGreen/10,0);
  21.         Seg_Display(BackupGreen%10,1);
  22.         Seg_Display(BackupRed/10,2);
  23.         Seg_Display(BackupRed%10,3);
  24. }

  25. void SetLGreen()
  26. {
  27.         Seg_Display(backupLGreen/10,0);
  28.         Seg_Display(backupLGreen%10,1);
  29. }

  30. void SetModel()                                                                //红绿灯设置模式
  31. {
  32.         if(StaSysterm==NormalRun)                    //正常情况下修改为设置状态
  33.         {
  34.                 StaSysterm=ResetGreen;  
  35.             BackupGreen=GreenTime;
  36.             BackupRed=RedTime;
  37.                 backupLGreen = GreenLTime;        
  38.                 CopyLight=P2;                        //对数据进行备份
  39.                 CopyLLight = P1;
  40.                 P2=0X09;
  41.         }
  42.         else if(StaSysterm==ResetGreen)             //优先设置绿灯时间
  43.         {
  44.             StaSysterm=ResetRed;
  45.         }
  46.         else if(StaSysterm==ResetRed)               //后设置红灯时间   设置完成后按键退出设置状态
  47.         {
  48.                 StaSysterm=ResetLGreen;
  49.         }
  50.         else if(StaSysterm==ResetLGreen)               //后设置红灯时间   设置完成后按键退出设置状态
  51.         {
  52.                 StaSysterm=NormalRun;
  53.                 P2=CopyLight;                        //恢复数据
  54.                 P1=CopyLLight;
  55.         }
  56. }

  57. void ADDTime()                                                            //红绿灯时间加
  58. {
  59.         if(StaSysterm==ResetGreen)
  60.         {
  61.                 BackupGreen++;
  62.                 if(BackupGreen>=BackupRed)           BackupGreen=BackupRed;            //绿灯时间不能大于红灯时间
  63.         }
  64.         else if(StaSysterm==ResetRed)
  65.         {
  66.             BackupRed++;
  67.         }
  68.         else if(StaSysterm==ResetLGreen)
  69.         {
  70.                 backupLGreen++;
  71.         }
  72. }

  73. void SUBTime()                                                                   //红绿灯时间减
  74. {
  75.         if(StaSysterm==ResetGreen)
  76.         {
  77.                 BackupGreen--;
  78.         
  79.         }
  80.         else if(StaSysterm==ResetRed)
  81.         {
  82.             BackupRed--;
  83.                 if(BackupGreen>=BackupRed)           BackupRed=BackupGreen;
  84.         }
  85.         else if(StaSysterm==ResetLGreen)
  86.         {
  87.                 backupLGreen--;
  88.         }
  89. }


  90. void UrgentModel()                                                           //紧急模式
  91. {
  92.         if(StaSysterm==NormalRun)
  93.         {        
  94.                 StaSysterm=UrgentRun;
  95.                 CopyLight=P2;                                //对数据进行备份
  96.                 CopyLLight=P1;
  97.                 P0=0XFF;                       //关闭数码管
  98.                 we=1;                          //产生下降沿 锁存数据
  99.                 we=0;
  100.         }
  101.         else if(StaSysterm==UrgentRun)
  102.         {        
  103.                 StaSysterm=NormalRun;
  104.                 P2=CopyLight;                           //恢复数据
  105.                 P1=CopyLLight;
  106.         }
  107.         else if(StaSysterm==ResetGreen || StaSysterm==ResetRed ||StaSysterm==ResetLGreen)
  108.         {
  109.                 StaSysterm=NormalRun;
  110.                 GreenTime=BackupGreen;
  111.             RedTime=BackupRed;
  112.                 GreenLTime = backupLGreen ;                   //重新设置红绿灯时间
  113.         }
  114. }
复制代码
  1. #define _MAIN_C
  2. #include "use.h"
  3. #include "main.h"
  4. #include "time.h"
  5. #include "key.h"

  6. bit flag1s;                //0时时间不变   1时时间减小
  7. uchar count1s,NS_time,WE_time;         
  8. uchar GreenTime=30,RedTime=50,GreenLTime = 10;                //30s和35s
  9. uchar index=0;               //状态
  10. enum eStaSysterm StaSysterm=NormalRun;

  11. void main()
  12. {
  13.         EA=1;                                                                  //开总中断
  14.         InintTimer0();                                                  //初始化定时器0
  15.         while(1)
  16.         {        
  17.                 LEDScan();                                                  //数码管即LED扫描
  18.                 KeyDriver();                                          //键盘驱动扫描
  19.                 if(flag1s)                          //判断时间是否到 1s
  20.                 {
  21.                         flag1s=0;
  22.                         NS_time--;                                          //红绿灯倒计时时间减
  23.                         WE_time--;
  24.                 }        
  25.         }
  26. }

  27. void InintTimer0()           //初始化T0定时器
  28. {
  29.         TMOD=0X01;           
  30.         TH0=0X4C;             //  初始化为50ms
  31.         TL0=0X00;
  32.         ET0=1;         //开TO中断
  33.         TR0=1;            //开始计数
  34. }

  35. void Timer0() interrupt 1         
  36. {
  37.         TH0=0XB8;              //0.019 s 约为20ms
  38.         TL0=0X00;
  39.         KeyScan();
  40.         if(++count1s<50)        return;           //判断定时是否到1S
  41.         count1s=0;
  42.         if(StaSysterm==NormalRun) flag1s=1;            //非正常运行时,不红绿灯数值不减一        
  43. }

  44. void LEDScan()
  45. {
  46.          if(StaSysterm==NormalRun)                         //正常运行
  47.          {
  48.                 if(NS_time==0 || WE_time==0)
  49.                 {
  50.                         switch(index)                                 //改变红绿灯的状态,状态机
  51.                         {
  52.                                 case 0:
  53.                                 {
  54.                                         index = 1;                                           //东西红灯
  55.                                         NS_time = GreenTime;                                  //南北绿灯30
  56.                                         WE_time = RedTime;                                    //红灯50
  57.                                         P2 = 0X09;
  58.                                         P1 = 0X0C;                                                 //输出
  59.                                 }break;
  60.                                 case 1:
  61.                                 {
  62.                                         index = 2;
  63.                                         NS_time=5;                                            //南北黄灯东西红灯
  64.                                         P2 = 0X0A;
  65.                                         P1 = 0X0C;
  66.                                 }break;
  67.                                 case 2:
  68.                                 {
  69.                                         index = 3;
  70.                                         NS_time=GreenLTime;                                   //南北左转东西红灯
  71.                                         P2 = 0X0C;
  72.                                         P1 = 0X09;
  73.                                 }break;
  74.                                 case 3:
  75.                                 {
  76.                                         index = 4;
  77.                                         NS_time=5;                                            //南北黄灯东西红灯
  78.                                         P2 = 0X0C;
  79.                                         P1 = 0X0A;
  80.                                 }break;
  81.                
  82.                                 case 4:
  83.                                 {
  84.                                         index=5;
  85.                                         NS_time = RedTime;
  86.                                         WE_time = GreenTime;
  87.                                         P2 = 0X24;
  88.                                         P1 = 0X0C;
  89.                                 }break;
  90.                                 case 5:
  91.                                 {
  92.                                         index = 6;
  93.                                         WE_time=5;                                            
  94.                                         P2 = 0X14;
  95.                                         P1 = 0X0C;
  96.                                 }break;
  97.                                 case 6:
  98.                                 {
  99.                                         index = 7;
  100.                                         WE_time = GreenLTime;        
  101.                                         P2 = 0X0C;
  102.                                         P1 = 0X24;        
  103.                                 }break;
  104.                                 case 7:
  105.                                 {
  106.                                         index = 0;
  107.                                         WE_time=5;                                            //南北黄灯东西红灯
  108.                                         P2 = 0X0C;
  109.                                         P1 = 0X14;
  110.                                 }break;

  111.                                 default:break;
  112.                         }
  113.                 }
  114.                 Seg_Display(NS_time/10,0);
  115.                 Seg_Display(NS_time%10,1);
  116.                 Seg_Display(WE_time/10,2);
  117.                 Seg_Display(WE_time%10,3);
  118.         }
  119.         else if(StaSysterm==UrgentRun)
  120.         {                                                                   //紧急情况运行   黄灯闪烁
  121.                 P2=0x12;
  122.                 P1 = 0X12;                                    //所有黄灯亮
  123.                 Delayms(200);                               //延迟200毫秒
  124.                 P2=0x00;
  125.                 P1 = 0X00;                                        //所有黄灯灭
  126.                 Delayms(200);                                 
  127.         }
  128.         else if(StaSysterm==ResetGreen || StaSysterm==ResetRed)                                                           //设置调整红绿灯时间
  129.         {
  130.                 index=0;
  131.                 NS_time=0;
  132.                 WE_time=0;                           //重新初始化红绿灯并运行
  133.                 UrgentScan();
  134.         }
  135.         else
  136.         {
  137.                 SetLGreen();
  138.         }
  139. }
复制代码
  1. #include "use.h"
  2. #include "time.h"

  3. sbit KEY1=P3^4;                                                                                         //设置 退出设置
  4. sbit KEY2=P3^5;                                          //加
  5. sbit KEY3=P3^6;                                          //减
  6. sbit KEY4=P3^7;                                          //紧急情况  退出紧急情况
  7. uchar keystr[]={1,1,1,1},backup[]={1,1,1,1};

  8. void KeyScan()                                                                //键盘扫描
  9. {
  10.         static uchar keybuf[4]={0XFF,0XFF,0XFF,0XFF};
  11.         uchar i;
  12.         keybuf[0]=(keybuf[0]<<1)|KEY1;
  13.         keybuf[1]=(keybuf[1]<<1)|KEY2;
  14.         keybuf[2]=(keybuf[2]<<1)|KEY3;
  15.         keybuf[3]=(keybuf[3]<<1)|KEY4;
  16.         for(i=0;i<4;i++)
  17.         {
  18.                 if(keybuf[i]==0X00)                        keystr[i]=0;                   //连续8次扫描值为0
  19.                 else if(keybuf[i]==0XFF)         keystr[i]=1;
  20.         }
  21. }

  22. void KeyAction(uchar key)                                                 //键盘执行
  23. {
  24.         switch(key)
  25.         {
  26.                 case 0:        SetModel();                break;        
  27.                 case 1:        ADDTime();                break;
  28.                 case 2:        SUBTime();                break;
  29.                 case 3: UrgentModel();        break;
  30.                           default:break;
  31.         }
  32. }

  33. void KeyDriver()                                                                 //键盘驱动
  34. {
  35.         uchar i;
  36.         for(i=0;i<4;i++)
  37.         {
  38.                 if(keystr[i]!=backup[i])
  39.                 {
  40.                         if(keystr[i]==0)
  41.                                 KeyAction(i);
  42.                 }
  43.                 backup[i]=keystr[i];
  44.         }
  45. }
复制代码

全部资料51hei下载地址:
Proteus 仿真.rar (150.83 KB, 下载次数: 84)
回复

使用道具 举报

ID:295446 发表于 2018-3-22 13:26 | 显示全部楼层
东西不错,代码也很工整,给老哥打电话
回复

使用道具 举报

ID:295656 发表于 2018-3-22 19:35 | 显示全部楼层
东西挺好的,谢谢分享
回复

使用道具 举报

ID:296923 发表于 2018-3-25 20:50 | 显示全部楼层
学习学习 支持一下
回复

使用道具 举报

ID:607684 发表于 2019-9-4 23:40 | 显示全部楼层
很好,辛苦了,谢谢
回复

使用道具 举报

ID:607684 发表于 2019-9-4 23:42 | 显示全部楼层
感激不尽
回复

使用道具 举报

ID:675875 发表于 2019-12-28 13:44 来自手机 | 显示全部楼层
总说code前少分号,怎么回事?
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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