#include <reg52.h>
#define uint8 unsigned char
#define unused8 0xFF
#define ON 0
#define OFF 1
#define EWTime_Count 30 //东西红灯60s
#define NSTime_Count 60 //南北红灯57s
#define YELTime_Count 5 //黄灯 5s
/*---------------------------------IO对应关系定义---------------------*/
#define EW_RED_ON() do { EW_RED=ON;EW_GRE=OFF;EW_YEL=OFF; } while (0)
#define EW_YEL_ON() do { EW_RED=OFF;EW_GRE=OFF;EW_YEL=ON; } while (0)
#define EW_GRE_ON() do { EW_RED=OFF;EW_GRE=ON;EW_YEL=OFF; } while (0)
#define NS_RED_ON() do { NS_RED=ON;NS_GRE=OFF;NS_YEL=OFF; } while (0)
#define NS_YEL_ON() do { NS_RED=OFF;NS_GRE=OFF;NS_YEL=ON; } while (0)
#define NS_GRE_ON() do { NS_RED=OFF;NS_GRE=ON;NS_YEL=OFF; } while (0)
sbit LED_D1 = P3^1;
sbit LED_C1 = P3^0;
sbit LED_B1 = P3^1;
sbit LED_A1 = P3^0;
sbit Key = P3^2;
sbit NS_GRE = P2^5;
sbit NS_YEL = P2^4;
sbit NS_RED = P2^3;
sbit EW_GRE = P2^2;
sbit EW_YEL = P2^1;
sbit EW_RED = P2^0;
//uint8 table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
// bc abged abcdg bcfg afgcd acdefg
uint8 table[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};
uint8 EW_Timer = unused8; //东西方向红灯定时器
uint8 NS_Timer = unused8; //南北方向红灯定时器
uint8 YEL_Timer = unused8; //黄灯 5s定时器
uint8 Flag_Key = 0; //按键是否按下标识
uint8 EW_Timer; //东西方向红灯定时器
uint8 NS_Timer; //南北方向红灯定时器
uint8 YEL_Timer; //黄灯 5s定时器
uint8 Timer = 20; //定时器 1s
void Delay10uS(uint8 z);
void display1(uint8 num1,uint8 num2);
void display2(uint8 num3,uint8 num4);
void INT0_Init(void);
void Timer_Init(void);
uint8 Flag_Key; //按键是否按下标识
int main(void)
{
Timer_Init(); //定时器初始化
INT0_Init(); //外部中断初始化
EA=1; //打开全局中断
NS_GRE = OFF; //所有的灯都灭
NS_YEL = OFF;
NS_RED = OFF;
EW_GRE = OFF;
EW_YEL = OFF;
EW_RED = OFF;
P3 = 0xFF; //所有显示灭
//先让东西方向红灯亮 南北方向通行
EW_Timer = EWTime_Count;//东西方向开始计时
while(1)
{
if((EW_Timer != unused8) && (EW_Timer != 0)){ //东西方向做红灯倒计时
display1(EW_Timer/10, EW_Timer%10); //东西方向显示时间 南北方向不显示
EW_RED_ON(); //东西方向保持红灯
NS_GRE_ON(); //南北方向保持绿灯
}
else if((EW_Timer != unused8) && (EW_Timer == 0) && (YEL_Timer == unused8)){//东西方向红灯计时到 东西方向保持红灯 南北方向变黄灯 开始黄灯5s计时
EW_RED_ON(); //东西方向红灯
NS_YEL_ON(); //南北方向黄灯
YEL_Timer = YELTime_Count; //5s计时
}
if((EW_Timer != unused8) && (YEL_Timer != unused8) && (YEL_Timer != 0)){
display1(YEL_Timer/10, YEL_Timer%10); //东西方向显示时间 南北方向不显示
}
if((EW_Timer != unused8) && (YEL_Timer == 0)){ //东西方向红-南北方向黄灯5s计时到 东西红灯定时器关 黄灯定时器关 南北红灯 东西绿灯 南北计时器开
EW_Timer = unused8; //东西红灯定时器关
YEL_Timer = unused8; //黄灯定时器关
NS_RED_ON(); //南北变红灯
EW_GRE_ON(); //东西变绿灯
NS_Timer = NSTime_Count; //南北红灯定时器开
}
if((NS_Timer != unused8) && (NS_Timer != 0)){ //南北红灯定时器正在计时
display2(NS_Timer/10, NS_Timer%10); //南北方向显示时间 东西方向不显示
EW_GRE_ON(); //东西保持绿灯
NS_RED_ON(); //南北保持红灯
}
else if((NS_Timer != unused8) && (NS_Timer == 0) && (YEL_Timer == unused8)){ //南北方向红灯计时到 南北方向保持红灯 东西方向变黄灯 开始黄灯5s计时
NS_RED_ON(); //南北方向保持红灯
EW_YEL_ON(); //东西方向变黄灯
YEL_Timer = YELTime_Count; //5s计时
}
if((NS_Timer != unused8) && (YEL_Timer != unused8) && (YEL_Timer != 0)){
display2(YEL_Timer/10, YEL_Timer%10); //南北方向显示时间 东西方向不显示
}
if((NS_Timer != unused8) && (YEL_Timer == 0)){ //南北方向红-东西方向黄灯5s计时到 南北方向定时器关 黄灯定时器关 东西方向变红灯 南北方向变绿灯 东西方向红灯计时器开始计时
NS_Timer = unused8;
YEL_Timer = unused8;
EW_RED_ON(); //东西方向变红灯
NS_GRE_ON(); //南北方向变绿灯
EW_Timer = EWTime_Count; //东西方向开始计时
}
if(Flag_Key == 1){ //如果急停按键按下 则全红灯 显示灭
P3 = 0xFF; //所有显示灭
EW_RED_ON(); //东西方向红灯
NS_RED_ON(); //南北方向红灯
EW_Timer = unused8; //关闭所有定时器
NS_Timer = unused8;
YEL_Timer = unused8;
}
}
}
/**********************************
延时程序
**********************************/
void Delay10uS(uint8 z)
{
uint8 i,a,b;
for(i=0;i<z;i++){
for(b=1;b>0;b--)
for(a=2;a>0;a--);
}
}
/***************************************************
* 定时器初始化
* 12M晶体 1us 计数一次
****************************************************/
void Timer_Init(void)
{
TMOD=0x01; //定时器工作方式
TH0=(65536-50000)/256; //定时器初值 50ms中断一次
TL0=(65536-50000)%256;
ET0=1; //使能定时器中断
TR0=1; //启动定时器0
}
/***************************************************
* 定时器中断函数
*装入初值
*计时变量递减
****************************************************/
void timer1(void) interrupt 1
{
TH0=(65536-50000)/256; //重新装入初值
TL0=(65536-50000)%256;
if(Timer > 0){
Timer--;
if(Timer == 0){ //1s 定时时间到
Timer = 20;
//添加其他定时器
if((EW_Timer != unused8) && (EW_Timer > 0)){ //东西红灯定时器
EW_Timer--;
}
if((NS_Timer != unused8) && (NS_Timer >0)){ //南北红灯定时器
NS_Timer--;
}
if((YEL_Timer != unused8) && (YEL_Timer >0)){ //黄灯计时
YEL_Timer--;
}
}
}
}
/***************************************************
* EW显示函数
*num1 要显示数值的十位 num2 要显示数值的各位
***************************************************/
void display1(uint8 num1,uint8 num2)
{
P3=0XFF;
P0=0XFF;
P0=table[num1];
LED_A1=ON;
Delay10uS(5);
LED_A1=OFF;
P0=0XFF;
P0=table[num2];
LED_B1=ON;
Delay10uS(5);
LED_B1=OFF;
P0=0XFF;
}
/***************************************************
* NS显示函数
*num1 要显示数值的十位 num2 要显示数值的各位
***************************************************/
void display2(uint8 num3,uint8 num4)
{
P0=0XFF;
P3=0XFF;
P0=table[num3];
LED_C1=ON;
Delay10uS(1);
LED_C1=OFF;
P0=0XFF;
P0=table[num4];
LED_D1=ON;
Delay10uS(1);
LED_D1=OFF;
P0=0XFF;
}
/****************************************
*外部中断初始化
*INT0 下降沿触发
*****************************************/
void INT0_Init(void)
{
EX0 = 1; //INT0 使能
IT0 = 1; //下降沿触发
}
void Key_Stop(void) interrupt 0
{
Delay10uS(200);
if(Key == 0) //确认按键按下
{
Flag_Key = 1;
}
}
|