/****************************************************************************
* 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
}
}
}
}