基于LPC2138控制的双向交通信号灯(ARM裸机编程)(最后3s绿灯闪烁)

/****************************************************************************
* File:Main.C
* 功能:计数器,通过两个按键来控制加减计数器,并输出数码管显示.。
****************************************************************************/
#include  "config.h"
#include  "Math.h"
#define CON 0x00ffffff    //控制P0.0~P0.23作为输出引脚
#define SW1 (1<<30)
#define SW2 0x80000000

/****************************************************************************
* 名称:DelayNS()
* 功能:长软件延时
* 入口参数:dly        延时参数,值越大,延时越久
* 出口参数:无
****************************************************************************/

void  delay(uint32  dly)

   uint32  i;

   for(; dly>0; dly--)
      for(i=0; i<250; i++);
}

void clear_All()//将两个方向的信号灯熄灭,数码管清零
{
    IO0CLR = CON;
    //直到开关SW2恢复高电平,再重新开始工作
    while(1)
    {
        if((IO0PIN & SW2) == SW2)//如果P0.31 = 1
        {
            break;
        }
    }
}

void yellow_Light()//夜间模式
{
    PINSEL0 = 0;//P0.0-15为GPIO
    PINSEL1 = 0;//P0.16-31为GPIO
    IO0DIR = CON;
    IO0CLR = CON;
    while(1)
    {
        if((IO0PIN & SW1) == SW1)//如果P0.30 = 1
        {
            break;
        }
        else if((IO0PIN & SW1) == 0)//如果P0.30 = 0
        {
            //开关SW2监测点
            if((IO0PIN & SW2) == 0)//如果P0.31 = 0,关闭信号系统
            {
                clear_All();
            }
            //P0.17, P0.20 高低电平变化
            IO0SET = 0x120000;
            delay(1000);
            IO0CLR = 0x120000;
            delay(1000);
        }
    }
}

int  main()
{
    int temp1;
    int flag;//区分第一个灯是红灯还是绿灯,1代表红灯,2代表绿灯
    int judge;//若另一个信号灯黄灯亮,judge=1,否则为0
    //开关SW1监测点
    if((IO0PIN & SW1) == 0)//如果P0.30 = 0,进入夜间模式
    {
        yellow_Light();
    }
    //开关SW2监测点
    if((IO0PIN & SW2) == 0)//如果P0.31 = 0,关闭信号系统
    {
        clear_All();
        goto Start;
    }
Start:
    temp1 = 15;
    flag = 1;
    judge = 0;
    PINSEL0 = 0;//P0.0-15为GPIO
    PINSEL1 = 0;//P0.16-31为GPIO
    IO0DIR = CON;
    IO0CLR = CON;
    //开始时红灯亮,置P0.16 = 1
    //另一方向绿灯亮,置P0.21 = 1
    IO0SET = 0x210000;
    while(1)
    {    
        IO0CLR = 0xffff;
        IO0SET = 16*(temp1/10) + temp1%10;
        if(flag == 1 && judge == 0)//红灯周期,另一信号为绿灯周期 
        {
            IO0SET = (16*((temp1 - 3)/10) + (temp1 - 3) %10) * pow(16,2);
        }
        else if(flag == 2)//绿灯周期,另一信号为红灯周期
        {
            IO0SET = (16*((temp1 + 3)/10) + (temp1 + 3) %10) * pow(16,2);
        }
        if(temp1 < 3 && flag == 1)//红灯最后3秒
        {
            //另一方向黄灯亮 P0.20 = 1    + 绿灯灭 P0.21 = 0
            judge = 1;
            IO0SET = 0x100000;//另一方向黄灯亮 P0.20 = 1
            IO0CLR = 0x200000;//另一方向绿灯灭 P0.21 = 0
            IO0SET = (16*(temp1/10) +temp1%10) * pow(16,2);//另一方向黄灯倒计时
        }
        temp1--;
        delay(500);
        if(temp1 < 2 && flag == 2)//绿灯 02 01 00s闪烁
        {
            IO0CLR = 0x40000; //绿灯灭,P0.18 = 0
        }
        if(temp1 < 5 && flag == 1 && judge == 0)//另一信号绿灯最后3秒
        {
            IO0CLR = 0x200000;//另一方向绿灯灭,P0.21 = 0
        }
        delay(500);
        if(temp1 < 2 && flag == 2)//绿灯 02 01 00闪烁
        {
            IO0SET = 0x40000;//绿灯亮,P0.18 = 1
        }
        if(temp1 < 5 && flag == 1 && judge == 0)//另一信号绿灯最后3秒
        {
            IO0SET = 0x200000;//另一方向绿灯亮,P0.21 = 1
        }

        //开关SW1监测点
        if((IO0PIN & SW1) == 0)//如果P0.30 = 0,进入夜间模式
        {
            yellow_Light();
            goto Start;//待开关SW1抬起,夜间模式结束,重新进入白天模式
        }
        //开关SW2监测点
        if((IO0PIN & SW2) == 0)//如果P0.31 = 0,关闭信号系统
        {
            clear_All();
            goto Start;
        }
        if(temp1 == -1)
        {
            if(flag == 1)//红灯周期结束
            {
                flag = 2;//标识即将进入绿灯周期
                IO0CLR =0x110000;//红灯灭,P0.16 = 0    另一方向黄灯灭 P0.20 = 0
                IO0SET = 0xC0000;//信号灯变绿灯,P0.18 = 1    另一方向变红灯 P0.19 = 1
                judge = 0;//另一方向黄灯周期结束
                temp1 = 11;//绿灯11s
            }
            else if(flag == 2)//绿灯周期结束
            {
                flag = 1;//标识即将进入红灯周期
                IO0CLR = 0x40000;//绿灯灭,P0.18 = 0

                temp1 =2;//黄灯周期2s
                IO0SET = 0x20000;//黄灯亮,P0.17 = 1
                while(temp1 >= 0)//黄灯周期
                {
                    //开关SW1监测点
                    if((IO0PIN & SW1) == 0)//如果P0.30 = 0,进入夜间模式
                    {
                        yellow_Light();
                        goto Start;//待开关SW1抬起,夜间模式结束,重新进入白天模式
                    }
                    //开关SW2监测点
                    if((IO0PIN & SW2) == 0)//如果P0.31 = 0,关闭信号系统
                    {
                        clear_All();
                        goto Start;
                    }
                    IO0CLR = 0xffff;//清空数码管
                    IO0SET = 16*(temp1/10) + temp1%10;//黄灯周期数码管显示 
                    IO0SET = (16*(temp1/10) + temp1%10) * pow(16,2);//另一信号红灯周期02 01 00数码管显示
                    delay(1000);
                    temp1 --;
                }
                IO0CLR = 0x20000;//黄灯灭,P0.17 = 0

                IO0SET = 0x210000;//信号灯变红灯,P0.16 = 1  另一方向变绿灯 P0.21 = 1
                IO0CLR = 0x80000;//红灯灭 P0.19 = 0
                temp1 = 15;//红灯15s
            }
        }
    }
}
 

 

 

猜你喜欢

转载自blog.csdn.net/weixin_42048463/article/details/94714921
今日推荐