基于51单片机十字路口红绿灯控制器软件程序源码

#include <reg52.h>

#define uchar unsigned char    
#define uint  unsigned int      


sbit wela = P2^7;          // 数码管位选
sbit dula = P2^6;        // 数码管段选

// 下面是八个交通灯对应的位定义
sbit     LED1_blue   = P1^0;
sbit     LED1_red    = P1^1;
sbit     LED1_green  = P1^2;
sbit     LED1_yellow = P1^3;
sbit     LED2_blue   = P1^4;
sbit     LED2_red    = P1^5;
sbit     LED2_green  = P1^6;
sbit     LED2_yellow = P1^7;

// 按键位定义
sbit    key_auto     = P3^0;    // 自动
sbit    key_step     = P3^1;    // 手动
sbit    key_emerg     = P3^2;    // 紧急情况 110/120通过
sbit    key_night   = P3^6;// 夜间模式


uint cnt = 0;    // 记录定时器定时了多少毫秒
uint sec = 0;    // 记录定时器计时了多少秒

uchar light_num = 0;

// 四位八段共阴极数码管数字显示编码
uchar code table[]={
//"0" "1"  "2"  "3"
0x3f,0x06,0x5b,0x4f,
//"4" "5"  "6"  "7"
0x66,0x6d,0x7d,0x07,
//"8" "9"  "A"  "B"
0x7f,0x6f,0x77,0x7c,
//"C" "D"  "E"  "F"
0x39,0x5e,0x79,0x71
};


uchar code light[]={
// 主G辅R      主G辅R    主Y辅R
    0xdb,       0xde,     0xd7,
// 主R辅G      主R辅B    主R辅R
    0xbd,       0xed,     0x7d,
    0xdf,       0xee,     0xdd
};

/*************函数声明********************/
void delay_ms(uint);
void system_Init();
void Display_R_time(uchar);
void Display_C_time(uchar);
void key_scan();

void main()
{
    system_Init();

    while(1)
    {
        key_scan();
    }
}


// 毫秒级延时
void delay_ms(uint z)
{
    uint x,y;
    for(x=z;x>0;x--)
        for(y=123;y>0;y--);

}

// 系统初始化
void system_Init()
{
    wela=0;        // 关闭位选
    dula=0;        // 关闭段选
    TMOD=0x01;  // 定时器0方式1 16位
    TH0=0x4c;     // 定时器装初值 50ms(11.05926MHz  TH0=0x4c TL0=0x00)
    TL0=0x00;    // (12MHz 的初值是 TH0=0x3c TL0=0xb0)
    EA=1;        // 开总中断
    ET0=1;        // 开定时器0中断
    TR0=1;        // 允许中断溢出
}

// 显示横向的(即辅干道)倒计时
void Display_R_time(uchar time)
{
    uchar time_tens, time_ones;

    time_tens = time / 10;    // 提取倒计时时间的十位数
    time_ones = time % 10;    // 提取倒计时时间的个位数


    // 下面对两位数倒计时时间进行显示(数码管)
    P0=0xff;
    wela=1;
    P0=0xbf;    
    wela=0;
    dula=1;
    P0=table[time_tens];
    dula=0;
    delay_ms(1);             
    
    P0=0xff;
    wela=1;
    P0=0x7f;    
    wela=0;    
    dula=1;
    P0=table[time_ones];
    dula=0;
    delay_ms(1);
}


// 显示竖向的(即主干道)倒计时
void Display_C_time(uchar time)
{
    uchar time_tens, time_ones;  

    time_tens = time / 10;
    time_ones = time % 10;
    
    P0=0xff;
    wela=1;
    P0=0xfb;       
    wela=0;    
    dula=1;
    P0=table[time_tens];
    dula=0;
    delay_ms(1);  

    P0=0xff;
    wela=1;
    P0=0xf7;     
    wela=0;    
    dula=1;
    P0=table[time_ones];
    dula=0;
    delay_ms(1);
}


void key_scan()
{
    if(key_auto == 0)
    {
        delay_ms(5);
        if(key_auto == 0)                // 自动按钮按下
        {
            // 主干道通过 辅干道红灯
            if(sec <= 15)
            {
                Display_C_time(15-sec);    // 倒计时显示
                Display_R_time(30-sec);
                P1 = light[0];          // 主道绿灯亮  辅道红灯亮
            }
            else if(sec > 15 && sec <= 24)
            {
                Display_C_time(24-sec);    // 倒计时显示
                Display_R_time(30-sec);
                P1 = light[1];            // 主道蓝灯亮 单独左转  辅道红灯亮
            }
            else if(sec > 24 && sec <= 30)
            {
                Display_C_time(30-sec);    // 倒计时显示
                Display_R_time(30-sec);
                P1 = light[2];            // 主道黄灯亮  辅道红灯亮
            }
    
            // 下面换道
            else if(sec > 30 && sec <= 35)
            {
                Display_R_time(35-sec);    // 倒计时显示
                Display_C_time(50-sec);
                P1 = light[3];            // 主道红灯亮  辅道绿灯亮
            }
            else if(sec > 35 && sec <= 44)
            {
                Display_R_time(44-sec);    // 倒计时显示
                Display_C_time(50-sec);
                P1 = light[4];            // 主道红灯亮  辅道蓝灯亮 单独左转信号
            }
            else if(sec > 44 && sec <= 50)
            {
                Display_R_time(50-sec);    // 倒计时显示
                Display_C_time(50-sec);
                P1 = light[5];            // 主道红灯亮  辅道黄灯亮    
            }
    
            else
            {
                sec = 0;// 秒数清零,继续循环上述代码
            }
        }
        
    }

    // 手动步进按钮按下,按一次,交通灯的状态改变一次
    if(key_step == 0)
    {
        delay_ms(5);
        if(key_step == 0)
        {
            if(light_num == 6)
            {
                light_num = 0;
            }
            P1 = light[light_num];
            light_num++;
            while(!key_step);  // 松手检测
        }
    }

    // 紧急情况 emergency
    if(key_emerg == 0) 
    {
        delay_ms(5);
        if(key_emerg == 0)
        {
            P1 = 0xdd;  // 主干道辅干道都是红灯
            while(!key_emerg);
        }
    }
    // 夜间模式 
    if (key_night == 0)
    {
        delay_ms(5);
        if (key_night == 0)
        {
            P1 = 0x77;  // 主干道辅干道都是黄灯
            while (!key_night);
        }
    }
}


// 定时器0中断服务函数
void timer0() interrupt 1
{
    TH0=0x4c;        // 定时器装初值 50ms(11.05926MHz  TH0=0x4c TL0=0x00) 
    TL0=0x00;        // (12MHz 的初值是 TH0=0x3c TL0=0xb0)
    cnt++;
    if(cnt == 20)
    {
        cnt = 0;
        sec++;      // 记录1秒
    }

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SKCQTGZX

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值