#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;
}
}
|