单片机交通信号灯编程_单片机交通信号灯程序 - CSDN
  • 【51单片机学习笔记】基于STC89C52制作的交通信号灯

    万次阅读 多人点赞 2017-10-23 15:52:30
    基于51单片机交通信号灯模型
       
    一、简介

        近来学(玩)了下已经好久没碰的51,心血来潮自己DIY了一个交通信号灯模型。没有什么创新之处,就是复(dao)习(gu)复(dao)习(gu)了下51的定时器中断、外部中断以及最小系统电路,熟悉了下74HC595的用法和数码管。因为好久没碰51了导致数码管的顺序记反了难过懒得再改电路了,于是将错就错就按反着的顺序搞下去了。由于快考试了事情也比较多,基本是隔三差五得做,时间战线拉得比较长。。。当然这些都无关紧要了,主要还是培养下自己分文件模块化编程的习惯嘛,文件分的比较细致,看上去舒服大笑.

        因为是完全自己设计的嘛难免很多疏漏之处。当然由于这个电路比较简单方案和其他人雷同了也是正常现象,说明英雄所见略同嘛~生气。在此开源大家共同学习,希望各路大神能指点迷津,欢迎大家来喷~~~~


        废话不多说了。先介绍下功能:

    1)为了可拓展性,我将单片机所有的引脚全部引出,后期可拓展或改做它用,每个IO引出两排排针接线更舒服。
    2)为了后期如果能做其他实验不产生干扰,外围电路基本全部采用杜邦线接线,不直接接在IO上了。其中595的VCC放置了一个跳线帽作为VCC供电。
    3)本人本着尽量少地用飞线地原则,能往正面跳就先跳线,但是到了2位数码管空间不算多了,也做的比较累了,就偷懒全用了飞线。
    4)晶振用了12MHz插在了单片机旁。采用12MHz地原因是定时器时间好计算,没用串口不需要很精确地波特率。插在外面没焊死仅仅因为板子空间不够了,而我不像飞线。。。
    5)因为东西向的灯是同步的,南北向的灯也是同步的,所以一个方向上的三色交通灯我选择了分别并联的方式,没全部并联是斟酌了下IO的驱动能力和后期的可拓展性还有一定条件下节省IO接口,故总共用了6个IO口控制交通灯,欢迎大家来喷~~~
    6)本次模拟仅为理想情况,以一分钟为一周期红绿交替指示。在还剩3秒时黄灯闪烁,当然也是为了简化程序所有的黄灯一起闪。
    7)通过外部中断选择工作/休息模式。休息模式下所有LED(包括数码管)同步闪烁,直到将拨盘开关拨回(有延误时间。。。)。

        想到的大概就这么多吧,详细功能不介绍了,直接上代码参考。

    二、原理图


          
         元件清单:

    STC89C52RC  x1
    74HC595  x1
    10K排阻  x1
    12Mhz晶振  x1
    选择开关  x1
    独立按键  x1
    30pF电容  x3
    10K电阻  x1
    1K电阻  x1
    220Ω电阻  x20
    红色LED  x3
    黄色LED  x3
    绿色LED  x3
    2位数码管  x1

          
         proteus 8 仿真原理图


             

    三、部分源程序

        程序基于Keil 5 C语言编写,部分程序有注释

    1.文件结构


                               

    所有头文件均放置在USER_Config.h头文件中

    main.c                   主函数
    it.c                         中断服务函数
    delay.c                  延时函数
    74HC595.c           595驱动函数
    LED.c                   交通灯
    SEG.c                   数码管

    2.头文件

    USER_Config.h
    /******************************************
    
    			USER HEARD		2017/6/4
    
    *******************************************/
    
    #ifndef _USERCONFIG_H_
    #define _USERCONFIG_H_
    /*    定义数据类型    */
    #define uchar unsigned char
    #define uint unsigned int
    #define NOP() _nop_()
    	
    #include <reg52.h>
    #include <intrins.h>
    #include "interrupt.h"
    #include "delay.h"
    #include "74HC595.h"
    #include "SEG.h"
    #include "LED.h"
    
    
    /*    宏定义引脚    */
    #define SEG   P0
    #define LEDs  P2
    	
    /*    74HC595驱动    */
    sbit S_CLK  =  P1^0;
    sbit R_CLK  =  P1^1;
    sbit MOSIO  =  P1^2;
    
    /*    数码管位选    */
    sbit SEG1   =  P0^0;
    sbit SEG2   =  P0^1;
    
    /*    交通灯    */
    sbit XR     =  P2^0;
    sbit XY     =  P2^1;
    sbit XG     =  P2^2;
    sbit YR     =  P2^3;
    sbit YY     =  P2^4;
    sbit YG     =  P2^5;
    
    /*    选择开关    */
    sbit SW			=	 P3^2;
    
    #endif
    

    其他头文件大同小异就不贴了。

    3.it.c

    /******************************************
    
    				中断服务程序
    				
    				by LZK    2017/6/17
    				
    ******************************************/
    #include "USER_Config.h"
    
    uint Num_Min = 0;//分钟计数器
    uchar Num_Sec = 0;//秒钟计数器
    uchar Number = 60;//计数器
    uchar Mark = 0;//标记
    
    void Timer_Init()
    {
    	TMOD = 0x11;//定时器0定时器1为工作方式1
    	/*  装载初值  */
    	TH0 = (65536-50000)/256;
    	TL0 = (65536-50000)%256;
    	TH1 = (65536-50000)/256;
    	TL1 = (65536-50000)%256;
    	
    	EA = 1;//开总中断
    	/*  开启定时器中断  */
    	ET0 = 1;//定时器0
    	ET1 = 1;//定时器1
    	/*  启动定时器  */
    	TR0 = 1;//定时器0
    	TR1 = 1;//定时器1
    	/*  外部中断  */
    	EX0 = 1;
    	IT0 = 0;
    }
    
    void Int0_Select() interrupt 0
    {
    	Num_Min = 0;
    	Num_Sec = 0;
    	Number = 60;
    	Mark = 0;
    	Calculate(Number);
    	LED_Relax();
    }
    
    void T0_Time() interrupt 1 
    {
    	/*  重装初值  */
    	TH0 = (65536-50000)/256;
    	TL0 = (65536-50000)%256;
    	Num_Sec++;
    	if(Num_Sec==20)
    	{
    		Num_Sec = 0;
    		Number--;
    		Calculate(Number);
    	}
    }
    
    void T1_Time() interrupt 3
    {
    	
    	/*  重装初值  */
    	TH1 = (65536-50000)/256;
    	TL1 = (65536-50000)%256;
    	Num_Min++;
    	if(Num_Min==60*20)
    	{
    		Num_Min = 0;
    		Number = 60;
    		Mark = ~Mark;
    	}	
    }

    4.delay.c

    /*************************************
    
    		延时函数库	By LZK
    		
    		频率:12MHz
    
    
    *************************************/
    #include "USER_Config.h"
    
    /*    延时x*9us    */
    void delay_8us(uint x)
    {							
    	uint i,j;
    	for(i=0;i<x;i++)
    		for(j=0;j<1;j++);	
    }
    
    /*    延时xms    */
    void delay_ms(uint x)
    {							
    	uint i,j;
    	for(i=0;i<x;i++)
    		for(j=0;j<120;j++);
    }
    
    /*    延时显示    */
    void delay(uint x)
    {
    	while(x--)  Display();
    }

    /*************************************
    
    		595发送数据	By LZK
    		
    		频率:12MHz
    		
    		2017/6/5
    
    
    *************************************/
    #include "USER_Config.h"
    
    void HC595SendData(uchar SendVal)
    {
    	unsigned char i;
    
    	for(i=0;i<8;i++)
    	{
    		MOSIO=SendVal>>7;
    		SendVal<<=1;
    
    		S_CLK=0;
    		NOP();
    		NOP();
    		S_CLK=1;
    
    	}
    
    	R_CLK=0;
    	NOP();
    	NOP();
    	R_CLK=1;
    
    }

    6.LED.c

    /**********************************
    
    		LEDs Control
    		
    		控制交通灯
    		
    		by LZK    2017/6/17
    		
    **********************************/
    #include "USER_Config.h"
    
    extern uchar Number;
    extern uchar Mark;
    
    void LED_Init()
    {
    	LEDs = 0xff;
    	//SW = 0;
    }
    
    void Select()
    {
    	uchar sw = SW;
    	switch(sw)
    	{
    		case 0:
    			LED_Relax();
    		break;
    		case 1:
    			LED_Control();
    		break;
    	}
    }
    
    void LED_Relax()
    {
    	uint x = 10000;
    	SEG = 0xff;
    	LEDs = 0xff;
    	while(x--)
    		HC595SendData(~0x00);
    	
    	x = 10000;
    	SEG = 0x00;
    	LEDs = 0x00;
    	while(x--)
    		HC595SendData(~0x00);
    }
    	
    void LED_Control()
    {
    	/*  黄灯判断  */
    	if(Number <= 3)
    	{
    		XY=~XY;
    		YY=~YY;
    		delay(100);
    	}
    	else
    	{
    		XY = 1;
    		YY = 1;
    	}
    	
    	/*  路口选择  */
    	XR =  Mark;
    	XG = ~Mark;
    	YR = ~Mark;
    	YG =  Mark;
    	
    	/*  显示  */
    	Display();
    }

    7.SEG.c
    /*************************************
    
    		数码管显数	By LZK
    		
    		频率:12MHz
    		
    		2017/6/5
    
    
    *************************************/
    #include "USER_Config.h"
    
    uchar code NUM[]={0x3f,0x30,0x6d,0x79,0x72,0x5b,0x5f,0x31,0x7f,0x7b,0x77,0x7c,0x39,0x5e,0x79,0x71};
    uchar value[2];
    
    void Calculate(uint num)
    {
    	value[0] = num%10;
    	value[1] = num/10;
    }
    
    void Display()
    {
    	//发送十位数
    	HC595SendData(NUM[value[1]]);
    	SEG = 0x01;
    	delay_8us(25);
    	//消隐
    	HC595SendData(0x00);
    	delay_8us(25);
    	//发送个位数
    	HC595SendData(NUM[value[0]]);
    	SEG = 0x02;
    	delay_8us(25);
    	//消隐
    	HC595SendData(0x00);
    	delay_8us(25);
    }

    8.main.c

    /*************************************************
    
    		交通信号灯			by LZK
    		
    		Date:2017/6/4
    		
    		通过定时器0读秒,通过定时器1换方向
    		通过Calculate传送数字
    		
    **************************************************/
    
    #include <reg52.h>
    #include "USER_Config.h"
    
    extern uchar Number;
    
    void main()
    {
    	
    	Timer_Init();
    	LED_Init();
    	
    	while(1)
    	{
    		LED_Control();
    	}
    }
    
    
    



    四、成果展示


    五、总结

        第一次发博客,如有不妥的地方请大家多指教可怜


    网盘分享:





    展开全文
  • 基于51单片机交通灯控制系统设计

    万次阅读 多人点赞 2020-03-06 13:30:46
    本设计为基于51单片机交通灯系统的设计,采用模块化、层次化设计。运用单片机AT89C51进行数据的分析和处理,为显示提供信号,显示部分采用8位数码管显示倒计时值。系统电路简单、集成度高、工作稳定、调试方便、检测...

    第一章 硬件设计与原理
    以AT89C51单片机为核心,起着控制作用。系统包括数码管显示电路、复位电路、时钟电路、发光二级管电路和按键电路。设计思路分为六个模块:复位电路、晶振电路模块、AT89C51、数码管显示电路、发光二级管电路和按键电路这六个模块。

    在这里插入图片描述

    1.2 硬件设计分析
    1.2.1 电源的设计
    系统电源使用直流5伏。
    由电脑USB接口提供电源。
    USB是通用串行总线(Universal Serial Bus)接口的简称。它是目前使用比较广泛的电脑接口之一,主要版本有1.0、1.1和最新的2.0三种版本。根据USB总线的工业标准,它可以提供额定功率为5V/500mA的电源供USB设备使用。
    1.2.2 单片机最小系统
    51单片机是对目前所有兼容intel 8031指令系统的单片机的统称。该系列单片机的始祖是intel的8031单片机,后来随着技术的发展,成为目前广泛应用的8为单片机之一。单片机是在一块芯片内集成了CPU、RAM、ROM、定时器/计数器和多功能I/O口等计算机所需要的基本功能部件的大规模集成电路,又称为MCU。51系列单片机内包含以下几个部件:
    一个8位CPU;一个片内振荡器及时钟电路;
    4KB的ROM程序存储器;
    一个128B的RAM数据存储器;
    寻址64KB外部数据存储器和64KB外部程序存储空间的控制电路;
    32条可编程的I/O口线;
    两个16位定时/计数器;
    一个可编程全双工串行口;
    5个中断源、两个优先级嵌套中断结构。
    如图1-2-1所示为AT89C51单片机基本构造,其基本性能介绍如下:
    图1-2-1 AT89C51单片机

    AT89C51本身内含40个引脚,32个外部双向输入/输出(I/O)端口,同时内含2个外中端口,3个16位可编程定时计数器,2个全双工串行通信口,STC89C51RC可以按照常规方法进行编程,但不可以在线编程。其将通用的微处理器和Flash存储器结合在一起,特别是可反复擦写的Flash存储器可有效地降低开发成本。
    AT89C51的主要特性如下表所示:

    在这里插入图片描述

    AT89C51为40脚双列直插封装的8位通用微处理器,采用工业标准的C51内核,在内部功能及管脚排布上与通用的8xc52相同,其主要用于会聚调整时的功能控制。功能包括对会聚主IC内部寄存器、数据RAM及外部接口等功能部件的初始化,会聚调整控制,会聚测试图控制,红外遥控信号IR的接收解码及与主板CPU通信等。主要管脚有:XTAL1(19脚)和XTAL2(18脚)为振荡器输入输出端口,外接12MHz 晶振。RST/Vpd(9脚)为复位输入端口,外接电阻电容组成的复位电路。VCC(40脚)和VSS(20脚)为供电端口,分别接+5V电源的正负端。P0~P3 为可编程通用I/O脚,其功能用途由软件定义,在本设计中,P0端口(32~39脚)被定义为N1功能控制端口,分别与N1的相应功能管脚相连接,13脚定义为IR输入端,10脚和11脚定义为I2C总线控制端口,分别连接N1的SDAS(18脚)和SCLS(19脚)端口,12脚、27脚及28脚定义为握手信号功能端口,连接主板CPU的相应功能端,用于当前制式的检测及会聚调整状态进入的控制功能。
    P0口:P0口是一组8位漏极开路型双向I/O 口,也即地址/数据总线复用口。作为输出口用时,每位能吸收电流的方式驱动8个TTL逻辑门电路,对端口P0写“1”时,可作为高阻抗输入端用。在访问外部数据存储器或程序存储器时,这组口线分时转换地址(低8位)和数据总线复用,在访问期间激活内部上拉电阻。在Flash 编程时,P0口接收指令字节,而在程序校验时,输出指令字节,校验时,要求外接上拉电阻。
    P1口:P1是一个带内部上拉电阻的8位双向I/O口,P1的输出缓冲级可驱动(吸收或输出电流)4个TTL逻辑门电路。对端口写“1”,通过内部的上拉电阻把端口拉到高电平,此时可作输入口。作输入口使用时,因为内部存在上拉电阻,某个引脚被外部信号拉低时会输出一个电流(IIL)。与AT89C51不同之处是,P1.0和P1.1还可分别作为定时/计数器2 的外部计数输入(P1.0/T2)和输入(P1.1/T2EX)。Flash编程和程序校验期间,P1接收低8位地址。
    P2口:P2是一个带有内部上拉电阻的8 位双向I/O口,P2的输出缓冲级可驱动(吸收或输出电流)4个TTL逻辑门电路。对端口P2写“1”,通过内部的上拉电阻把端口拉到高电平,此时可作输入口,作输入口使用时,因为内部存在上拉电阻,某个引脚被外部信号拉低时会输出一个电流(IIL)。在访问外部程序存储器或16位地址的外部数据存储器(例如执行MOVX @DPTR指令)时,P2口送出高8位地址数据。在访问8位地址的外部数据存储器(如执行MOVX @RI指令)时,P2口输出P2锁存器的内容。Flash编程或校验时,P2亦接收高位地址和一些控制信号。
    P3口:P3口是一组带有内部上拉电阻的8位双向I/O口。P3口输出缓冲级可驱动(吸收或输出电流)4个TTL逻辑门电路。对P3口写入“1”时,它们被内部上拉电阻拉高并可作为输入端口。此时,被外部拉低的P3口将用上拉电阻输出电流(IIL)。P3口除了作为一般的I/O口线外,更重要的用途是它的第二功能P3口还接收一些用于Flash 闪速存储器编程和程序校验的控制信号。
    RST:复位输入。当振荡器工作时,RST引脚出现两个机器周期以上高电平将使单片机复位。
    ALE/PROG:当访问外部程序存储器或数据存储器时,ALE(地址锁存允许)输出脉冲用于锁存地址的低8位字节。一般情况下,ALE仍以时钟振荡频率的1/6输出固定的脉冲信号,因此它可对外输出时钟或用于定时目的。要注意的是:每当访问外部数据存储器时将跳过一个AL脉冲。对Flash存储器编程期间,该引脚还用于输入编程脉冲(PROG)。如有必要,可通过对特殊功能寄存器(SFR)区中的8EH单元的D0位置位,可禁止ALE操作。该位置位后,只有一条 MOVX 和MOVC指令才能将ALE激活。此外,该引脚会被微弱拉高,单片机执行外部程序时,应设置ALE禁止位无效。
    PSEN:程序储存允许(PSEN)输出是外部程序存储器的读选通信号,当AT89C51由外部程序存储器取指令(或数据)时,每个机器周期两次PSEN有效,即输出两个脉冲。在此期间,当访问外部数据存储器,将跳过两次PSEN信号。
    EA/VPP:外部访问允许。欲使CPU仅访问外部程序存储器(地址为0000H—FFFFH),EA端必须保持低电平(接地)。需注意的是:如果加密位LB1被编程,复位时内部会锁存EA端状态。如EA端为高电平(接Vcc端),CPU则执行内部程序存储器中的指令。Flash存储器编程时,该引脚加上+12V的编程允许电源Vpp,当然这必须是该器件是使用12V编程电压Vpp。
    XTAL1:振荡器反相放大器的及内部时钟发生器的输入端。
    XTAL2:振荡器反相放大器的输出端。
    单片机最小原理图如图1-2-2所示。
    图1-2-2 单片机最小系统

    单片机最小系统说明:
    时钟信号的产生:在MCS-51芯片内部有一个高增益反相放大器,其输入端为芯片引脚XTAL1,其输出端为引脚XTAL2。而在芯片的外部,XTAL1和XTAL2之间跨接晶体振荡器和微调电容,从而构成一个稳定的自激振荡器,这就是单片机的时钟振荡电路。
    时钟电路产生的振荡脉冲经过触发器进行二分频之后,才成为单片机的时钟脉冲信号。
    一般地,电容C2和C3取30pF左右,晶体的振荡频率范围是1.2-12MHz。如果晶体振荡频率高,则系统的时钟频率也高,单片机的运行速度也就快。
    单片机复位使CPU和系统中的其他功能部件都处在一个确定的初始状态下,并从这个状态开始工作。单片机复位条件:必须使9脚加上持续两个机器周期(即24个振荡周期)的高电平。
    1.2.3 显示系统
    数码管是一种半导体发光器件,其基本单元是发光二极管。
    数码管按段数分为七段数码管和八段数码管,八段数码管比七段数码管多一个发光二极管单元(多一个小数点显示);按能显示多少个“8”可分为1位、2位、4位等等数码管;按发光二极管单元连接方式分为共阳极数码管和共阴极数码管。共阳数码管是指将所有发光二极管的阳极接到一起形成公共阳极(COM)的数码管。共阳数码管在应用时应将公共极COM接到+5V,当某一字段发光二极管的阴极为低电平时,相应字段就点亮。当某一字段的阴极为高电平时,相应字段就不亮。。共阴数码管是指将所有发光二极管的阴极接到一起形成公共阴极(COM)的数码管。共阴数码管在应用时应将公共极COM接到地线GND上,当某一字段发光二极管的阳极为高电平时,相应字段就点亮。当某一字段的阳极为低电平时,相应字段就不亮。
    数码管要正常显示,就要用驱动电路来驱动数码管的各个段码,从而显示出我们要的数字,因此根据数码管的驱动方式的不同,可以分为静态式和动态式两类。
    1) 静态显示驱动:静态驱动也称直流驱动。静态驱动是指每个数码管的每一个段码都由一个单片机的I/O端口进行驱动,或者使用如BCD码二-十进制译码器译码进行驱动。静态驱动的优点是编程简单,显示亮度高,缺点是占用I/O端口多,如驱动5个数码管静态显示则需要5×8=40根I/O端口来驱动(要知道一个89C51单片机可用的I/O端口才32个呢),实际应用时必须增加译码驱动器进行驱动,增加了硬件电路的复杂性。
    2) 动态显示驱动:数码管动态显示接口是单片机中应用最为广泛的一种显示方式之一,动态驱动是将所有数码管的8个显示笔划"a,b,c,d,e,f,g,dp"的同名端连在一起,另外为每个数码管的公共极COM增加位选通控制电路,位选通由各自独立的I/O线控制,当单片机输出字形码时,所有数码管都接收到相同的字形码,但究竟是那个数码管会显示出字形,取决于单片机对位选通COM端电路的控制,所以我们只要将需要显示的数码管的选通控制打开,该位就显示出字形,没有选通的数码管就不会亮。通过分时轮流控制各个数码管的的COM端,就使各个数码管轮流受控显示,这就是动态驱动。
    本设计中数码管采用的是动态驱动方式。
    数码管外形如图1-2-3,数码管电路结构如图1-2-4。

    图1-2-3 数码管外形图
    图1-2-4 数码管电路结构示意图

    在这里插入图片描述
    图1-2-5 数码管显示电路
    1.2.4 发光二级管电路

    图1-2-6 发光二级管电路
    1.2.5 按键电路
    图1-2-7 按键电路

    第二章 软件设计与分析
    2.1 软件设计的组成
    该系统由延时子函数、数码管显示子函数、定时器0中断子函数、主函数和数据定义这几部分组成。
    在这里插入图片描述

    在这里插入图片描述

    //----------------------------------------------------------------------//
    上传过程感觉繁琐,里面可能有不全面的地方,请见谅。下面的是实现的目的。以及电路原理图

    **本次设计的主要目的是设计一个城市十字路口的交通灯控制系统,设计中将交通灯控制系统分为东西方向(主干道)和南北方向(次干道)两个方向,且在东西南北四个路口的每个路口设置红、绿、黄三个交通信号灯(用发光二极管模拟)和一个二位的LED数码显示管。设计的要求是规定在每一段时间内东西和南北两个方向中只有一个方向能够通行,另一个方向处于禁行状态,然后在经过一段时间后,禁行的方向和通行的方向互相转换状态,原来通行的状态变禁行状态,原来禁行的状态变为通行状态,如此循环下去。详细过程如下图2-1:
    状态① 状态②
    图 1图2-1 交通灯状态图
    状态①:东西方向的交通灯黄灯闪烁3秒后,红灯熄灭,绿灯点亮(东西方向允许车辆和行人通行),同时南北方向绿灯熄灭,红灯点亮(南北方向禁止车辆和行人通行),LED数码管倒计时显示40秒,在倒计时3秒时进入状态②。
    状态②:南北方向黄灯闪烁3秒后,红灯熄灭绿灯点亮(南北允许车辆和行人通行);同时东西方向绿灯熄灭,红灯点亮
    (东西方向禁止车辆和行人通行),LED数码管倒计时显示40秒,在倒计时3秒时进入状态①。
    接下来在没有人为干涉下将会一直按照上述进行循环。设计中还外设6个按键实现对交通灯控制系统的调控作用。

    电路原理图

    在这里插入图片描述

    在这里插入图片描述

    //——————————————————————————-——————————//
    相应的代码已经上传

    下载地址
    https://download.csdn.net/download/weixin_43442020/12231456

    下载链接里可以下载,解压后里面有压缩文件,压缩文件里面的资料更详细

    展开全文
  • 51单片机交通灯(十字路口演示),包括紧急情况 本项目中采用单片机 AT89C52为中心器件来设计交通信号灯控制器, 系统实用性强、操作简单、扩展性强。本设计系统就是由单片机最小系统、交通灯状态显示系统、 LED...

    51单片机交通灯(十字路口演示),包括紧急情况

    系统仿真图:
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    本项目中采用单片机 AT89C52为中心器件来设计交通信号灯控制器, 系统实用性强、操作简单、扩展性强。本设计系统就是由单片机最小系统、交通灯状态显示系统、 LED数码显示系统、复位电路和按键操作电路等几大部分组成。系统除具有基本的交通信号灯功能外,还具有倒计时和紧急情况处理功能,较好的模拟实现了十字路口可能出现的状况。软件上采用 KEIL C 编程,主要编写了主程序, LED数码管显示程序,中断程序,延时程序等。经过整机调试,实现了对十字路口交通灯的模拟。
    组合完成效果图:
    在这里插入图片描述
    系统硬件框图:
    在这里插入图片描述
    在这里插入图片描述
    主程序框图:
    在这里插入图片描述
    程序代码:

    #include<reg52.h> 
    #define uchar unsigned char 
    #define uint unsigned int 
    #define ON 0 
    #define OFF 1 
    sbit NS_G=P2^5; // 南北绿灯 
    sbit NS_Y=P2^4; // 南北黄灯 
    sbit NS_R=P2^3; // 南北红灯
    
    sbit EW_G=P2^2; // 东西绿灯 
    sbit EW_Y=P2^1; // 东西黄灯 
    sbit EW_R=P2^0; // 东西红灯
    
    sbit LED_D1=P3^7; // 南北方向数码管位控制 
    sbit LED_C1=P3^6; // 南北方向数码管位控制
    
    sbit LED_B1=P3^1; // 东西方向数码管为控制 
    sbit LED_A1=P3^0; // 东西方向数码管位控制
    
    sbit key1=P3^2;				//开关位定义
    sbit key2=P3^3;
    
    /********* 倒计时赋初值 *************/ 
    uchar EWF=30,NSF=25,X=30,Y=25,Z=30,SHU=30;
    uchar count; 
    void keyscan1()		//南北紧急制动按键函数
    {
    	if(!key1)
    	{
    		while(!key1);		//松手检测
    	}
    }
    void keyscan2()		//东西紧急制动按键函数
    {
    	if(!key2)
    	{
    		while(!key2);		//松手检测
    	}
    }
    void init(void) 
    	{ 
    	TMOD=0x01; 
    	TH0=(65536-40000)/256; 
    	TL0=(65536-40000)%256; 
    	EA=1; 
    	ET0=1; 
    	TR0=1;	
    	} 
    void timer1(void) interrupt 1 
    	{ 
    	TMOD=0x01; 
    	TH0=(65536-40000)/256; 
    	TL0=(65536-40000)%256; 
    	EA=1; 
    	ET0=1; 
    	TR0=1; 
    	count++; 
    	if(count>29) 
    			{ 
    			EWF--; 
    			NSF--; 
    			X--; 
    			Y--; 
    			Z--; 
    			SHU--; 
    			count=0; 
    			} 
    
    	}
     
    /****************** 延时 **********************/ 
    void delay(uchar z) 
    		{ 
    		uchar x,y; 
    		for(x=z;x>0;x--) 
    		for(y=110;y>0;y--); 
    		}
    
    /******************led 控制 *******************/ 
    unsigned char table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};// 共阴极数码管赋值
    void display1(uchar num1,uchar num2) //控制东西方向 led 显示 
    { 
    	P0=table[num1]; 
    	LED_A1=ON; 
    	delay(1); 
    	LED_A1=OFF; 
    
    	P0=table[num2]; 
    	LED_B1=ON; 
    	delay(1); 
    	LED_B1=OFF;
    
    	if(!key1)//南北紧急制动
    	{
    	   while(1)
    		{
    			P0=0x00;
    			EW_G=EW_Y=OFF;
    			NS_G=NS_Y=OFF;
    			EW_R=NS_R=ON;			
    			keyscan1();
    				EW_R=NS_R=OFF;
    				EW_Y=NS_Y=OFF;
     				NS_G=ON;
    				EW_R=ON;
    			break;
    		}
    	} 
    } 
    void display2(uchar num3,uchar num4) // 控制南北方向 led 显示
    { 
    	P0=table[num3]; 
    	LED_C1=ON; 
    	delay(1); 
    	LED_C1=OFF; 
    
    	P0=table[num4]; 
    	LED_D1=ON; 
    	delay(1); 
    	LED_D1=OFF;
    if(!key2)//东西紧急制动
    	{
    	   while(1)
    		{
    			P0=0x00;
    			EW_G=EW_Y=OFF;
    			NS_G=NS_Y=OFF;
    			EW_R=NS_R=ON;			
    			keyscan2();
    				EW_R=NS_R=OFF;
    				EW_Y=NS_Y=OFF;
     				EW_G=ON;
    				NS_R=ON;
    			break;
    		}
    	} 
    } 
    
    void main() 
    { 
    	int i;
    /************ 初始状态东西南北禁止通行 ************/ 
    	NS_R=ON; //南北方向红灯打开 
    	EW_R=ON; //东西方向红灯打开
    	for(i=0;i<210;i++) 
    		{ 
    		delay(10); 
    		} 
    	NS_R=OFF;// 南北方向红灯关闭 
    	EW_R=OFF;// 东西方向红灯关闭	
    	
    while(1)
    {
    		/************** 状态 1:东西红灯 (30s), 南北绿灯 (25s)************/ 
    		/**************** 状态 2:东西红灯 (30s), 南北黄灯 (5s)***************/
    			while(1) 
    			{ 
    				init(); // 初始化计时器 
    		
    				NS_G=ON; // 南北方向的绿灯打开 
    				EW_R=ON; // 东西方向的红灯打开
    				while(EWF!=0) 
    				{ 
    					display1(EWF/10,EWF%10);// 东西方向红灯 (25s) 
    					display2(NSF/10,NSF%10);// 南北方向绿灯 (30s) 
    					while(EWF==5) 
    					{ 
    						while(X!=0) 
    						{ 
    						display1(EWF/10,EWF%10);// 东西方向红灯 (5s) 
    						display2(X/10,X%10);// 南北方向黄灯 (5s) 
    						NS_G=OFF; // 南北方向的绿灯关闭 
    						NS_Y=ON; // 南北方向的黄灯打开 
    						} 
    					} 
    				 }	 
    			EW_R=OFF; // 东西方向的红灯关闭 
    			NS_G=OFF; // 南北方向的绿灯关闭 
    			NS_Y=OFF; // 南北方向的黄灯打开 		
    		   EWF=30,NSF=25,X=30,Y=25,Z=30,SHU=30;// 重新赋值
    /**************** 状态 3:东西绿灯 (25s), 南北红灯 (30s)**************/ 
    /*************** 状态 4:东西黄灯 (5s) , 南北红灯 (30s)****************/ 
    			while(1)
    			{
    				init(); // 初始化计时器 
    		
    			   NS_R=ON;// 南北方向的红灯打开 
    				EW_G=ON;// 东西方向的绿灯打开
    				while(Z!=0) 
    				{ 
    					display2(Z/10,Z%10);// 南北方向红灯 (25s) 
    					display1(Y/10,Y%10);// 东西方向绿灯 (30s) 
    					while(Z==5) 
    					{ 
    						while(SHU!=0) 
    						{ 
    						display1(Z/10,Z%10);// 东西红灯 (5s) 
    						display2(SHU/10,SHU%10);// 南北绿灯 (5s) 
    						EW_G=OFF; // 东西方向的绿灯关闭 
    						EW_Y=ON; // 东西方向的黄灯打开
    						} 
    					} 
    				 }
    			NS_R=OFF; // 南北方向的红灯关闭 
    			EW_G=OFF; // 东西方向的绿灯关闭 
    			EW_Y=OFF; // 东西方向的黄灯关闭
    			EWF=30,NSF=25,X=30,Y=25,Z=30,SHU=30;// 重新赋值
    			break;
    			}
    		}	
    	 }
    }
    

    个人小结:
    这次是我认为最有意义的一次课程设计,从原理图设计到软件仿真,我从中收获
    了许多。刚开始设计时,我就在校门口仔细观察交通灯的转换,经过研究思考最终得
    到了上述的交通灯状态转换表。
    对于交通灯这个题目,由于刚学了 PLC实现交通信号灯的控制实验,所以就想通
    过不同的核心器件来实现同样的功能,来加深自己在这个题目上的深入研究,在确定
    题目之后,查阅了大量的资料,初步完成了电路设计方案。
    在程序编写上,我选择了用 KEIL C 语言进行编程,。在整个程序的编写过程中,采用模块化,编一个子程序仿真一个, 通过 Keil 和 proteus 两个软件来实现的。Keil帮助检查程序是否存在语法错误之类的问题,同时可以生成 hex 文件,供 proteus 软件仿真使用。通过一周的课程设计,使我更深入的学习了 AT89C52单片机,尤其是在中断程序的编写上学到了好多。

    参考文献: [1] 张毅坤 . 单片微型计算机原理及应用,西安电子科技大学出版社 1998 [2] 夏继强 . 单片机实验与实践教程
    . 北京:北京航空航天大学出版社 , 2001 [3] 彭伟. 单片机 C语言程序设计 100 例. 北京:电子工业出版社 , 2009
    [5] 雷丽文 . 微机原理与接口技术 . 北京:电子工业出版社 , 2001 [6] 于永. 51单片机 C语言常用模块与综合系统设计
    . 北京:电子工业出版社 , 2007 14 [7] 谭浩强 . C 语言程序设计 . 北京:清华大学出版社 , 2005 [8]
    于永. 51单片机 C语言常用模块与综合系统设计 . 北京:电子工业出版社 , 2007

    展开全文
  • 51单片机模拟交通灯

    千次阅读 多人点赞 2016-09-17 22:40:01
    利用51单片机的控制二极管及数码管的显示来模拟交通灯,系统晶振为11.0592MHZ,东西方向红灯设置为30秒,南北方向红灯设置为20 秒,P1.3接一个应急按钮,按下第一次放开,南北方向绿灯一直亮,东西方向红灯一直亮...
  • 基于51单片机交通灯控制设计

    万次阅读 多人点赞 2019-07-16 20:16:13
    题目 交通灯控制设计 课程设计目标与任务、计划与进度安排: 实践教学要求与任务: 1、了解交通灯的基本工作原理; 2、用Proteus模拟实现交通灯控制; 3、用Keil C51编程实现上述功能; 4、用Keil与Proteus联调。 工作...
  • 基于51单片机交通灯,在基本的十字路口交通灯的基础下,加了一些功能
  • 交通信号灯程序

    2020-07-30 23:33:30
    关于交通灯的c语言编程, 得到的hex, 可以直接用在单片机
  • 51单片机 交通灯实验及报告

    千次阅读 2020-05-26 19:13:37
    单片机端口作输出口,控制四个方向共12个发光二极管亮灭,模拟交通灯管理。功能描述如下:初始态为四个路口的红灯全亮之后,东西路口的绿灯亮,南北路口的红灯亮,东西路口方向通车,延时一段时间后东西路口的绿灯
  • 基于51单片机交通灯C语言程序设计

    万次阅读 多人点赞 2016-01-25 11:27:10
    十字交叉路口的交通灯控制器,是很常见的课程设计题目。做而论道以前写过一个,功能十分简单。最近,综合了一些百度知道中的题目要求,写出了一个稍稍复杂一点设计方案,使用了大家比较喜欢的C语言编写程序。基本...
  • 基于51单片机交通灯原理图加代码

    万次阅读 多人点赞 2019-07-21 18:04:35
    花了一个星期制作的交通灯仿真程序+原理图,通过数码管显示路口的时间,通过led显示红绿灯。@TOC ![#include<reg51.H>      // 对单片机的口进行了定义 #define uint unsigned int #...
  • 一个简易模拟十字路口交通灯的程序,首先a道方向绿灯亮,b到方向红灯亮,同时开始计时60s,在段数码管上显示时间60秒倒数。当时间少于10s倒计时A道方向切换黄灯,B道依然为红灯。当60s倒计时结束后,A道方向黄灯开始...
  • 十字路口交通信号灯控制系统主要任务开发平台设计思路 主要任务 设计一个用于十字路口的交通灯控制器,能显示十字路口东西、南北两个方向的红、黄、绿的指示状态; 具有倒计时的功能,用两组数码管作为东西和南北...
  • 内含完整程序,仿真电路,打开即可用,AVR单片机技术,Keil软件编程
  • 本此课程设计交通灯系统利用单片机AT89C51作为核心元件,实现了通过信号灯对路面状况的智能控制。系统具有结构简单、可靠性高、成本低、实时性好、安装维护方便等优点,有广泛的应用前景。 交通灯控制器设计主要功能...
  • 从零开始--单片机十字路口交通灯控制实验

    万次阅读 多人点赞 2019-10-31 07:42:07
    3. 十字路口交通灯实验题目的分析与构思 4. 各部分代码的实现 5. 代码实现的难点解析 1. 准备工作(理论知识的学习+源代码编辑软件keil+仿真软件proteus) 理论知识的学习(推荐爱课程的...
  • 一、设计任务描述 1.1设计目的 通过课程设计使学生更进一步掌握微机原理及应用课程的有关知识,提高应用微机解决问题的能力,加深... 控制LED,按照十字路口红绿灯的原理亮灭显示: (1) 东西方向车辆放行x秒...
  • 51 汇编编程:倒计时交通灯

    千次阅读 2016-01-25 11:27:10
    一个51单片机汇编语言的程序,要求就是红灯25秒,绿灯20秒,黄灯闪烁5秒。题目链接:http://zhidao.baidu.com/question/560272874很简单的要求,用下图电路即可实现:图片链接:...
  • 文件形式 单片机仿真红绿灯成品 只能用proteus打开仿真 和keil编程 红绿黄三色 还有倒计时显示 做设计可以参考或者直接应用 自行修改即可
  • 交通信号灯的出现是人类历史上的一次重大改革,使人类的聚居生活,产生了深远的影响。使交通得以有效管制,对于疏导交通流量,提高道路通行能力,减少交通事故有明显效果。如何采用合适的控制...
1 2 3 4 5 ... 17
收藏数 338
精华内容 135
关键字:

单片机交通信号灯编程