找回密码
 立即注册

QQ登录

只需一步,快速开始

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

C51单片机+MAX7219十字路口交通灯Proteus仿真程序设计

[复制链接]
跳转到指定楼层
楼主
设计要求: 用单片机控制LED模拟交通灯。东西向通行时间为80s,南北向通行时间为60s,缓冲时间为3s。
本项目为典型的LED显示和中断定时电路。利用定时器T0产生每10ms一次的中断,每100次中断为1s。对两个方向分别显示红、绿、黄灯,并显示相应的剩余时间。

本设计基于AT89C52单片机,可用单片机控制信号灯的状态变化,基本可以指挥交通的基本通行。用单片机控制红、黄、绿LED灯模拟指示,模拟东西方向的十字路口交通信号控制情况。东西向通行时间为80s,南北向通行时间为60s,缓冲时间为3s,并将时间倒计时输出,方便行人的观看。
本设计主要设计指标:
  • 红绿灯状态提示模块。
  • T0定时器模块,实现三种时间的定时。
  • 驱动显示模块,利用MAX7219驱动数码管的显示倒计时。
1.3 系统结构图

图1  系统结构图

系统正常运行后,5V的稳压源给MAX7219芯片、LED信号灯和单片机供电,通过单片机内部的定时器T0产生每10ms一次的中断,每100次中断为1s。所计的时间以秒为单位,通过MAX7219驱动七段显示器倒计时输出,计满时间后产生中断,中断产生后信号灯发生相应的变化,以达到自动控制的目的。


2  理论分析与计算
定时器初值的计算,并掌握十进制到十六进制的转化。在进行通行时间上的控制时应注意生活中的常识。
2.1 定时器初值的计算
通过单片机内部的定时器T0产生每10ms一次的中断,每100次中断为1s。在本设计中所用的晶振为12MHZ,定时器              T0为工作方式一。其中初值为X,定时间为m us。

                 (1)
计算可得,定时m=10ms=10000us时,X=55536,转化为十六进制,X=D8F0H。即写入定时器的初值TH0=0xD8,TL0=0xF0。
2.2 通行时间的计算
A方向红灯时间=B方向绿灯时间+黄灯缓冲时间              (2)
3  硬件设计
  根据系统结构图,系统由MAX7219驱动电路、显示电路、晶振电路、复位电路、单片机供电电路、单片机电路组成。
3.1显示电路
通过该电路, 行人可以清楚的看见各路口状态灯的亮灭情况,判断是否通行。同时,数码管显示剩下通行的时间,提示行人。
数码管显示方面,东西南北各个方向分别用两位7段数码管,南北方向接DIG0、DIG1,东西方向接DIG2、DIG3,进行位选控制,如图2。
         
图2 显示电路1
红绿灯采用三个共阳二极管作为指示灯,南北、东西方向各个一组,分别对应数码管的倒计时。东西方向接单片机的P1^0 , P1^1 , P1^2口,南北方向接单片机的P0^0 , P0^1 , P0^2口,如图3。
图3 显示电路2

首先东西方向通行时间为80s,东西绿灯亮,南北红灯亮。时间到后,东西南北黄灯亮3s。然后南北方向通行时间为60s,南北绿灯亮,东西红灯亮。时间到后3s,东西南北黄灯亮3s。

3.2MAX7219驱动电路

采用专用数码管显示控制芯片MAX7219。MAX7219是美国MAXI生产的串行输入/输出共阴极显示驱动器,该芯片最多可驱动8位7段数字LED显示器或多个LED和条形图显示器。   

图4 MAX7219驱动电路

4  软件设计

在硬件的基础上对软件进行设计,本程序由主程序,定时中断子程序和显示驱动子程序组成。主程序主要负责系统初始化和等待中断,以及红黄绿灯各种状态判断。定时中断子程序主要负责各个状态的定时要求,以及状态的跳转。显示驱动子程序负责倒计时时间的显示。

根据系统软件设计要求将软件划分为:延时模块,状态判断模块,中断服务模块,驱动显示模块。
4.1 主程序
主程序完成MAX7219的初始化,定时器的初始化,状态灯的初始化并进行状态的判断。



图 5  程序流程图
进入主程序后,先初始化并开启定时器1和MAX7219芯片,再装入初始状态和初始值,然后等待中断响应。根据收到的中断响应,主程序依次判断。首先南北绿灯亮,东西红灯亮,倒计时60S;定时结束后,由中断跳转到下一个状态,再东西南北黄灯亮,倒计时3S;定时结束后,由中断跳转到下一个状态,东西绿灯亮,南北红灯亮,倒计时80S;定时结束后,再由中断跳转到下一个状态,东西南北黄灯亮,倒计时3S。依次循环执行。

主要(关键)代码:
  1. void main()
  2. {
  3.               T0_init();
  4.               MAX7219_init();
  5.               EA=1;
  6.               NS=60;                                                                                                                                               //初始南北通行60秒
  7.               EW=63;                                                                                                                  
  8.    R2=0,G1=0;                                                                                                       //南北绿灯亮,东西红灯亮
  9. while (1)
  10.         {
  11.                             uint k;
  12.                             display();      
  13.       switch(i)
  14.                {
  15.               case 1:               R2=1,G1=1;                                          //关闭南北绿灯,东西红灯
  16.                                                                                                     Y1=0,Y2=0;                                          //黄灯闪烁
  17.                       for(k=0;k<3;k++)
  18.                         {
  19.                               Y1=~Y1;
  20.                                                                                                                                 Y2=~Y2;
  21.                               delay(10000);
  22.                            }      
  23.                                   break;
  24.               case 2: G2=0,R1=0;                                          //东西绿灯亮,南北红灯亮
  25.                                                                               break;
  26.               case 3: G2=1,R1=1;
  27.                                                                                            Y1=0,Y2=0;                                          //黄灯闪烁
  28.                       for(k=0;k<3;k++)              //循环三次进行延时闪烁
  29.                         {
  30.                               Y1=~Y1;
  31.                                                                                                                                 Y2=~Y2;
  32.                               delay(10000);
  33.                             }
  34.                                   break;
  35.               case 4: R2=0,G1=0;                                           //东西红灯亮,南北绿灯亮
  36.                                                                     break;
  37.              }                       
  38.          }
  39. }
复制代码


此段程序是对状态的判断,利用switch()....case语句对状态进行判断。
4.2 定时中断子程序
定时器子程序是进行时间的设定,并实现状态的自动跳转。跳转过后产生的中断送入主程序进行判断并输出。

图 6  定时中断子程序流程图
设置通行时间,并利用定时器进行倒计时,其中状态一60S,其中状态二3S,其中状态三80S,其中状态四3S。
关键代码介绍:
void T0_(void)interrupt 1
{
  temp++;
  TH0=0XD8;
  TL0=0XF0;
  if(temp==100)
    {
      temp=0;
      NS--;
      EW--;
          if((NS==0)&&(EW==3))
         {
          NS=3;
          EW=3;
          i=1;
         }
      if((NS==0)&&(EW==0)&&(i==1))
         {
          NS=83;
          EW=80;
          i=2;
         }
     if((NS==3)&&(EW==0))
         {
          NS=3;
          EW=3;
          i=3;
         }
     if((NS==0)&&(EW==0)&&(i==3))
         {
          NS=60;
          EW=63;
          i=4;
         }
              }
              display();
}
利用if语句对计时是否完毕进行判断,如计时完毕,执行if中的内容。
4.2 MAX7219驱动程序
      MAX7219采用串行寻址方式,在传送的串行数据中包含内部RAM的地址。加在DIN脚上的串行数据,必须在LOAD信号为高电平的前提下,以每个字节为一个数据包,在CLK信号上升沿移入16位的移位寄存器。然后在LOAD信号的上升沿锁存进数字或控制寄存器中。LOAD信号必须在第16个CLK信号上升沿的同时,或在下一个CLK信号上升沿之前升高,否则,数据会丢失。DIN脚上的串行数据在16.5个CLK信号后出现在DOUT脚上,以便级联应用时传到下一个MAX7219上。
图 7   数据串行传送时序图

关键代码介绍:
  1. void MAX_write(uchar ch)                            //以8位一个字节进行写值

  2. {

  3.               uchar j,ads;

  4.     for(j=0;j<8;j++)                                             //8位

  5.               {

  6.       ads=ch&0x80;                                   //取最高位

  7.       CLK = 0;                             //时钟线置低

  8.       if(ads)  DIN = 1;

  9.       else      DIN = 0;

  10.       ch=ch<<1;                               //左移一位

  11.       CLK=1;                                                            //上升沿,DIN的数据写入到7219

  12.     }

  13. }

  14. void MAX7219(uchar addr, uchar num)                            //写地址,写数据

  15. {

  16.     LOAD = 0;        

  17.               _nop_();

  18.     MAX_write(addr);

  19.               _nop_();

  20.     MAX_write(num);

  21.               _nop_();

  22.     LOAD = 1;                                                    //锁存

  23. }                     
复制代码

系统测试

5.1 倒计时状态测试
由Proteus仿真软件进行系统测试。

                                                                                                                  图8  60S、80S计时
结论:单片机内部定时器能够进行定时。
5.2 红绿灯状态测试
由Proteus仿真软件进行系统测试。
表1  红绿灯状态测试

60S
3S
80S
3S
东西方向
红灯亮
黄灯闪烁
绿灯亮
黄灯闪烁
南北方向
绿灯亮
黄灯闪烁
红灯亮
黄灯闪烁

结论:每个状态能够正常的跳转。
5.3 系统联机测试
1、接硬件图接线,为了确保东西南北红黄绿灯能够对应显示,实验时,对P1口的接线做了调整。即,P1.0接G2绿灯,P1.1接Y2黄灯,P1.2接R2红灯,P0.1接G1绿灯,P0.2接Y1黄灯,P0.3接R1红灯。
2、从第一个状态开始连续运行,观察六个LED灯是否与交通显示情况对应,如果有偏差,则单步运行或断点运行,进行调试,直至满足设计要求。
3、调试完灯的显示后,从第一个状态开始连续运行,观察数码管显示的是否正常,如果不正常,则运用单步运行或断点运行进行分析和调试,直至满足要求。
4、整体运行,观察灯显示和时间显示是否都符合要求,如果不符合,则再调试。直至满足要求



6  总结以及展望

本设计实现设计要求。

本设计在实现相应功能的时候主要是考虑到现有的条件,采用成熟度高的STC89C52作为CPU的解决方案,同时用LED灯和双位数码管作为显示模块,软件则使用了移植性好的C语言。从功能需求上来看,已经能够满足简单的应用需要。
在设计过程中,从开始设计该系统的功能,到方案的论证,再到最后的调试,每一步都显得是那么的重要,在这个过程中学习到了比这次设计本身更多的知识,除此之外,在这次设计中也奠定了我对一个工业产品设计的思维,收获颇丰。
展望,由于时间有限,本设计还需要做很多的改进才能作为产品进入市场,如:在对单片机供电方案中可以改为更简单的电容降压电路;在状态的多样性方面还很单一,可以增加一些更加符合实际情况的状态,如弯道时的状态、拥堵时的状态、应急状态;在PCB元器件布局还可以更科学使线的宽度做的更宽等元器件选择方面的问题,使其能够通过一些标准。

  • 系统原理图

图9  系统原理图

  • 系统PCB版图
本系统的PCB版图为双重布线。
图10  系统PCB图


全部资料51hei下载地址:
通信交通灯.7z (981.18 KB, 下载次数: 121)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

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

使用道具 举报

沙发
ID:479983 发表于 2020-5-15 00:02 | 只看该作者
不错的程序
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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