51单片机交通灯

交通灯

一、 系统功能分析

  • 交通灯由AT89C52单片机、13个LED灯,4个7SEG—COM数码管,2个按键构成。一组红绿灯由一个数码管和红黄绿的led灯构成,有东西南北四组。

  • 北方和南方的数码管接P2口,西方和东方的数码管接P0口,P3口主要接LED灯。即北方和南方控制显示相同,东方和西方控制相同。

  • 规则指定:红灯亮15秒,黄灯亮3秒,绿灯亮12秒,按下紧急停止按键时,所有的交通灯熄灭,紧急灯(红灯)亮。当按下恢复的按钮时,交通灯开始恢复:开始状态,南北方向绿灯12秒,西北方向红灯15秒。

二、 系统方案设计(功能框图)

img

电路图

image-20220114204434475

简要说明

  • 按下紧急停止按键时,所有的交通灯熄灭,紧急灯(红灯)亮。当按下恢复的按钮时,交通灯开始恢复:开始状态,南北方向绿灯12秒,西北方向红灯15秒。
  • 在实现操作的时候感觉,交通灯有点卡,可能是代码问题,可能还需要进一步的优化吧。

源代码

红绿灯转换过程主要是标志量来转换

#include<reg52.h>
//定义数码管位选择
#define LSE_choice P1

//急停与恢复
sbit Key_stop=P3^2;
sbit Key_continue=P3^3;

//红绿灯
sbit Led1_g=P3^0;//上下绿灯
sbit Led1_y=P3^1;//上下黄灯
sbit Led1_r=P3^6;//上下红灯
sbit Led2_g=P3^7;//左右绿灯
sbit Led2_y=P3^4;//黄灯
sbit Led2_r=P3^5;//红灯

sbit RED_LED=P1^7;//警告灯

//定义按键
sbit Key_0=P3^2;//
sbit Key_1=P3^3;
typedef unsigned char u8;//8指8位,1个字节
typedef unsigned int u16;//定义关键字;16指16位,2字节
sbit L0=P1^0;
sbit L1=P1^1;
u8 second0=15;//上下起始秒
u8 second1=12;//左右起始秒

u8 key=0;//键值

//全局标志量
u8 sign0=0;//上下全局标志
u8 sign1=2;//左右

u8 sign_0=2;//上下:2表示绿到红,1表示红到绿
u8 sign_1=1;//左右
u8 timer0=0;//中断0次数
u8 timer1=0;//中断1次数


u8 code smgduan[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};

void delay(u16 i)//延时函数
{
    while(i--);
}

void Statu()//停止和是否继续判断
{
    if(Key_stop==0)//停止判断
        key=1;
    if(Key_continue==0)//继续
        key=2;
}

void Get(u8 led11,u8 led12)//数码管显示
{
    TR0=1;//定时器0开启
    LSE_choice=0xf5;//位选
    led11=0;//上下led
    led12=0;//左右
    P0=smgduan[second1/10];//上下十位数
    P2=smgduan[second0/10];//左右
    delay(100);
    LSE_choice=0xfa;
    P0=smgduan[second1%10];//上下个位数
    P2=smgduan[second0%10];
    delay(100);
}

void Choice_sign()//标志
{
    if(second0==0 && sign0==0)//判断上下绿灯时间是否为0
    {
        TR0=0;
        sign0=1;//黄灯
        second0=3;//转黄灯3S
    }
    if(second1==0 && sign1==0)//判断左右时间绿灯时间
    {
        sign1=1;
        second1=3;
    }
    if(second0==0 && sign0==1)//判断上下黄灯
    {
        if(sign_0==2)//判断黄到红
        {
            TR0=0;
            sign0=2;
            second0=15;//红灯15S
            sign_0=1;
        }
        else//等价sign_0=1;判断黄到绿
        {
            TR0=0;
            sign0=0;
            second0=12;//绿灯12S
            sign_0=2;
        }
    }
    if(second1==0 && sign1==1)//判断左右黄灯
    {
        if(sign_1==2)//判断黄到红
        {
            sign1=2;
            second1=15;//红灯15S
            sign_1=1;
        }
        else//等价sign_1=1;判断黄到绿
        {
            sign1=0;
            second1=12;//绿灯12S
            sign_1=2;
        }
    }
    if(second0==0 && sign0==2)//判断上下红灯
    {
        TR0=0;
        sign0=1;//黄灯
        second0=3;//转黄灯3S
    }
    if(second1==0 && sign1==2)//判断左右红灯
    {
        sign1=1;//黄灯
        second1=3;//转黄灯3S
    }
}

void Display()//显示函数
{
    if(sign0==0 && sign1==0)//上下绿,左右绿
    {
        Led1_g=0;Led2_g=0;
        Get(Led1_g,Led2_g);
        Led1_g=1;Led2_g=1;
    }
    if(sign0==0 && sign1==1)//上下绿,左右黄
    {
        Led1_g=0;Led2_y=0;
        Get(Led1_g,Led2_y);
        Led1_g=1;Led2_y=1;
    }
    if(sign0==0 && sign1==2)//上下绿,左右红
    {
        Led1_g=0;Led2_r=0;
        Get(Led1_g,Led2_r);
        Led1_g=1;Led2_r=1;
    }
    if(sign0==1 && sign1==0)//上下黄,左右绿
    {
        Led1_y=0;Led2_g=0;
        Get(Led1_y,Led2_g);
        Led1_y=1;Led2_g=1;
    }
    if(sign0==1 && sign1==1)//上下黄,左右黄
    {
        Led1_y=0;Led2_y=0;
        Get(Led1_y,Led2_y);
        Led1_y=1;Led2_y=1;
    }
    if(sign0==1 && sign1==2)//上下黄,左右红
    {
        Led1_y=0;Led2_r=0;
        Get(Led1_y,Led2_r);
        Led1_y=1;Led2_r=1;
    }
    if(sign0==2 && sign1==0)//上下红,左右绿
    {
        Led1_r=0;Led2_g=0;
        Get(Led1_r,Led2_g);
        Led1_r=1;Led2_g=1;
    }

    if(sign0==2 && sign1==1)//上下红,左右黄
    {
        Led1_r=0;Led2_y=0;
        Get(Led1_r,Led2_y);
        Led1_r=1;Led2_y=1;
    }
    if(sign0==2 && sign1==2)//上下红,左右红
    {
        Led1_r=0;Led2_r=0;
        Get(Led1_r,Led2_r);
        Led1_r=1;Led2_r=1;
    }
    Choice_sign();
    Statu();
}


void main()
{
    TMOD=0x01;
    EA=1;
    ET0=1;
    TH0=0xee;//一次5ms
    TL0=0x00;
    TR0=1;
    while(1)
    {
        switch(key)
        {
            case 0:Display();break;
            case 1://全面停止
            {
                Statu();
                RED_LED=0;
                TR0=0;
                LSE_choice=0x7f;
                break;
            }
            case 2:
            {
                ET0=1;
                TH0=0xee;
                TL0=0x00;
                TR0=1;
                second0=15;//上下起始秒
                second1=12;//左右起始秒
                sign0=0;//上下全局标志
                sign1=2;//左右
                sign_0=2;
                sign_1=1;//左右
                key=0;
                break;
            }
        }
    }
}

void Int_T0() interrupt 1
{
    timer0++;
    if(timer0==200)//判断一秒
    {
        timer0=0;
        second0--;
        second1--;
    }
    TH0=0xee;//一次5ms
    TL0=0x00;
}

资源电路图和代码下载

  • 10
    点赞
  • 97
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值