找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1734|回复: 0
收起左侧

单片机红绿显示屏切换交通灯仿真程序

[复制链接]
ID:825397 发表于 2022-6-16 14:51 | 显示全部楼层 |阅读模式
本交通灯程序贴合实际,除了可以显示时间外,还可以切换红绿显示。原理图利用595控制数码管位,减少IO口的占用。如果想减少595,也可以将双向同色显示屏的位接在一起。注意:仿真必须用proteus8.12版本才能打开!!!
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
2.jpg 3.jpg

单片机源程序如下:
#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int

sbit duanla=P2^6;
sbit weila =P2^7;

/******控制红绿灯切换******/
sbit SH_CP=P2^0;
sbit DS=P2^1;
sbit ST_CP=P2^2;

/******控制红绿显示屏切换******/
sbit SH_CP1=P2^3;
sbit DS1=P2^4;
sbit ST_CP1=P2^5;
sbit OE=P3^0;

sbit key1=P2^6;//紧急按钮
sbit key2=P2^7;//回复运行按钮

uchar count,time;//中断次数,时间分段
uchar a,b;//显示时间变量

/******两个方向的时间设置,以1分钟为总时间******/
uchar Atime_red=30,Atime_green=25,Atime_yellow=5;
uchar Btime_red=30,Btime_green=25,Btime_yellow=5;


//uchar code duanma[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};

uchar code duanma[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//共阴数码管段码{0123456789}


void delay(uint z)//延时函数
{
        while(z--);
}


/**************** 向HC595发送一个字节函数,控制红绿黄灯 ******************/
void send_595(uint dat)
{               
        uchar i;
        for(i=0;i<16;i++)
        {
                dat <<= 1;
                DS  = CY; //溢出位赋值数据输出端
                SH_CP = 1; //移位时钟
                SH_CP = 0;
        }
}

/**************** 向HC595发送一个字节函数,控制红绿显示屏 ******************/
void send_595W(uint dat)
{               
        uchar i;
        for(i=0;i<16;i++)
        {
                dat <<= 1;
                DS1  = CY; //溢出位赋值数据输出端
                SH_CP1 = 1; //移位时钟
                SH_CP1 = 0;
        }
}


void init()
{
        TH0=(65536-50000)/256;
        TL0=(65536-50000)%256;
        TMOD=0X01;
        EA=1;
        ET0=1;
        TR0=1;
        SH_CP=0;
        ST_CP=0;
        SH_CP1=0;
        ST_CP1=0;
        OE=0;
        
}


void display_SN_R_EW_G()//南北红灯-东西绿灯
{
        send_595W(0xffbe);
        ST_CP1=1;
        ST_CP1=0;
        P0=duanma[a/10];
        delay(500);
        send_595W(0xff7d);
        ST_CP1=1;
        ST_CP1=0;
        P0=duanma[a%10];
        delay(500);
        
        send_595W(0xebff);
        ST_CP1=1;
        ST_CP1=0;
        P0=duanma[b/10];
        delay(500);
        send_595W(0xd7ff);
        ST_CP1=1;
        ST_CP1=0;
        P0=duanma[b%10];
        delay(500);
}

void display_SN_R_EW_Y()//南北红—东西黄灯
{
        send_595W(0xffbe);
        ST_CP1=1;
        ST_CP1=0;
        P0=duanma[a/10];
        delay(500);
        send_595W(0xff7d);
        ST_CP1=1;
        ST_CP1=0;
        P0=duanma[a%10];
        delay(500);
        
        send_595W(0xffeb);
        ST_CP1=1;
        ST_CP1=0;
        P0=duanma[b/10];
        delay(500);
        send_595W(0xffd7);
        ST_CP1=1;
        ST_CP1=0;
        P0=duanma[b%10];
        delay(500);
}

void display_SN_G_EW_R()//南北绿灯——东西红
{
        send_595W(0xbeff);
        ST_CP1=1;
        ST_CP1=0;
        P0=duanma[a/10];
        delay(500);
        send_595W(0x7dff);
        ST_CP1=1;
        ST_CP1=0;
        P0=duanma[a%10];
        delay(500);
        
        send_595W(0xffeb);
        ST_CP1=1;
        ST_CP1=0;
        P0=duanma[b/10];
        delay(500);
        send_595W(0xffd7);
        ST_CP1=1;
        ST_CP1=0;
        P0=duanma[b%10];
        delay(500);
}

void display_SN_Y_EW_R()//南北黄灯——东西红
{
        send_595W(0xffbe);
        ST_CP1=1;
        ST_CP1=0;
        P0=duanma[a/10];
        delay(500);
        send_595W(0xff7d);
        ST_CP1=1;
        ST_CP1=0;
        P0=duanma[a%10];
        delay(500);
        
        send_595W(0xffeb);
        ST_CP1=1;
        ST_CP1=0;
        P0=duanma[b/10];
        delay(500);
        send_595W(0xffd7);
        ST_CP1=1;
        ST_CP1=0;
        P0=duanma[b%10];
        delay(500);
}



void main()
{
        init();
        while(1)
        {
                if(time>=0&&time<25)display_SN_R_EW_G();
                else if(time>=25&&time<30)display_SN_R_EW_Y();
                else if(time>=30&&time<55)display_SN_G_EW_R();
                else if(time>=55&&time<60)display_SN_Y_EW_R();
                else
                {
                }
                if(key1==0)
                {
                        delay(20);
                        if(key1==0)
                        {
                                OE=1;//关闭显示屏
                                send_595(0xfff0);//双方向红灯
                                ST_CP=1;
                                ST_CP=0;
                                TR0=0;//关闭定时器
                        }
                        while(!key1);//按键释放
                }
                if(key2==0)
                {
                        delay(20);
                        if(key2==0)
                        {
                                TR0=1;//开启定时器,重新开始
                                return;
                        }
                        while(!key2);
                }
        }
}


void timer0() interrupt 1
{
        TH0=(65536-50000)/256;
        TL0=(65536-50000)%256;        
        count++;
        if(count==20)
        {
                time++;
                if(time>=0&&time<25)
                {                                       
                        send_595(0xff5a);
                        ST_CP=1;
                        ST_CP=0;
                                                               
                        a=Atime_red--;
                        b=Btime_green--;

                }                        
                else if(time>=25&&time<30)
                {
                        send_595(0xf5fa);
                        ST_CP=1;
                        ST_CP=0;
                        Btime_green=25;
                        a=Atime_red--;
                        b=Btime_yellow--;

                }
                else if(time>=30&&time<55)
                {
                        send_595(0xffa5);
                        ST_CP=1;
                        ST_CP=0;        
                        Atime_red=30;
                        Btime_yellow=5;
                        a=Atime_green--;
                        b=Btime_red--;

                }
                else if(time>=55&&time<60)
                {               
                        send_595(0xfaf5);
                        ST_CP=1;
                        ST_CP=0;
                        Atime_green=25;
                        a=Atime_yellow--;
                        b=Btime_red--;

                }
                else
                {
                        time=0;
                        Atime_yellow=5;
                        Btime_red=30;
                }
                count=0;
        }
        
}

1.jpg
Keil代码与Proteus仿真下载:
注意:仿真必须用proteus8.12版本才能打开,如果没有8.12的话就不要下载了
交通灯51单片机.7z (247.58 KB, 下载次数: 36)

评分

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

查看全部评分

回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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