- #include <reg51.h>
- #define uchar unsigned char
- #define uint unsigned int
- /*****定义控制位**********************/
- sbit K4=P3^2; //恢复正常
- sbit K3=P3^3; //紧急(全部红灯)
- sbit K2=P3^4; //东西通行
- sbit K1=P3^5; //南北通行
- sbit EW_LED2=P2^3; //EW_LED2控制位
- sbit EW_LED1=P2^2; //EW_LED1控制位
- sbit SN_LED2=P2^1; //SN_LED2控制位
- sbit SN_LED1=P2^0; //SN_LED1控制位
- sbit SN_Yellow=P1^6; //SN黄灯
- sbit SN_Red=P1^7; //SN红灯
- sbit SN_Green=P1^5; //SN绿灯
- sbit EW_Yellow=P1^2; //EW黄灯
- sbit EW_Red=P1^3; //EW红灯
- sbit EW_Green=P1^1; //EW绿灯
- bit Restore_flag=0; //恢复正常标志位
- bit Flag_SN_Yellow; //SN黄灯标志位
- bit Flag_EW_Yellow; //EW黄灯标志位
- char Time_EW; //东西方向倒计时单元
- char Time_SN; //南北方向倒计时单元
- uchar EW=25,SN=30; //程序初始化赋值
- uchar EW1=30,SN1=25; //用于存放修改值的变量
- uchar KeyNumber=0;
- uchar code table[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//0~~~~9段选码
- uchar code S[9]={0X28,0X48,0X18,0X48,0X82,0X84,0X81,0X84,0x88};//交通信号灯控制代码
- /**********************延时子程序************************/
- void delay_ms(uint x) //延时ms
- {
- uint i,j;
- for(i=x;i>0;i--)
- for(j=110;j>0;j--);
- }
- /*****************显示函数**************************/
- void Display(void)
- {
- char h,l;
- h=Time_EW/10;
- l=Time_EW%10;
- P0=table[l];EW_LED2=1;delay_ms(1);EW_LED2=0;
- P0=table[h];EW_LED1=1;delay_ms(1);EW_LED1=0; //东西方向数码管显示
-
- h=Time_SN/10;
- l=Time_SN%10;
- P0=table[l];SN_LED2=1;delay_ms(1);SN_LED2=0;
- P0=table[h];SN_LED1=1;delay_ms(1);SN_LED1=0; //南北方向数码管显示
- }
- /**********************INT0中断服务程序(按键扫描)*****************/
- void int0_FXR() interrupt 0
- {
- uchar FXR=P2;
- FXR=FXR&0Xf0;
- switch(FXR)
- {
- case 0x70 : KeyNumber = 1; break;
- case 0xb0 : KeyNumber = 2; break;
- case 0xd0 : KeyNumber = 3; break;
- case 0xe0 : KeyNumber = 4; break;
- default:KeyNumber = 0;
- }
- }
- /**********************T0中断服务程序*******************/
- void timer0() interrupt 1
- {
- static uchar count; //count为静态变量初值为0
- TL0 = 0xB0; //重赋定时初值50ms
- TH0 = 0x3C; //重赋定时初值50ms
- count++; //计数
- if(count==10) //加快闪烁速度
- {
- if(Flag_SN_Yellow==1) //测试南北黄灯标志位
- {SN_Yellow=~SN_Yellow;}//南北黄灯闪烁
- if(Flag_EW_Yellow==1) //测试东西黄灯标志位
- {EW_Yellow=~EW_Yellow;}//东西黄灯闪烁
- }
- if(count==20) //20*50=1000ms=1S
- {
- Time_EW--; //东西方向倒计时
- Time_SN--; //南北方向倒计时
- if(Flag_SN_Yellow==1) //测试南北黄灯标志位
- {SN_Yellow=~SN_Yellow;} //南北黄灯闪烁
- if(Flag_EW_Yellow==1) //测试东西黄灯标志位
- {EW_Yellow=~EW_Yellow;} //东西黄灯闪烁
- count=0;
- }
- }
- void keyboard()
- {
- while(KeyNumber)
- {
- if(KeyNumber)
- {
- if(KeyNumber==1)
- {
- TR0=0;
- Time_EW=0; //东西数码管赋值0s
- Time_SN=0; //南北数码管赋值0s
- while(KeyNumber==1)
- {
- Flag_EW_Yellow=0; //东西关黄灯显示信号
- P1=S[0]; //南北通行,东西红灯
- Display(); //调用显示函数
- }
- }
- if(KeyNumber==2)
- {
- TR0=0;
- Time_EW=0; //东西数码管赋值0s
- Time_SN=0; //南北数码管赋值0s
- while(KeyNumber==2)
- {
- Flag_SN_Yellow=0; //东西关黄灯显示信号
- P1=S[4]; //东西通行,南北红灯
- Display(); //调用显示函数
- }
- }
- if(KeyNumber==3)
- {
- TR0=0;
- Time_EW=0; //东西数码管赋值0s
- Time_SN=0; //南北数码管赋值0s
- while(KeyNumber==3)
- {
- P1=S[8]; //所有路口红灯
- Display(); //调用显示函数
- }
- }
- if(KeyNumber==4)
- {
- TR0=1;
- Time_EW=25; //东西数码管赋值25s
- Time_SN=30; //南北数码管赋值30s
- Restore_flag=1;
- break;
- }
- }
- }
- }
- /*********************主程序开始**********************/
- void main(void)
- {
- /*********************中断初始化**********************/
- IT0=1; //设置外部中断0触发方式(下降沿触发)
- EX0=1; //打开外部中断0的IE寄存器中断
- EA=1; //CPU开中断总允许
- ET0=1; //开定时中断
- TMOD=0x01; //定时器工作于方式1
- TL0 = 0xB0; //设置定时初值50ms
- TH0 = 0x3C; //设置定时初值50ms
- TF0 = 0; //清除TF0标志
- TR0 = 1; //定时器0开始计时
- while(1)
- {
- keyboard();
- if(Restore_flag)
- break;
- /*******S1状态(东西直行状态)**********/
- Time_EW=EW; //东西数码管赋值25s
- Time_SN=SN; //南北数码管赋值30s
- while(Time_SN>=6) //南北方向倒计时前25s循环体
- {
- Flag_SN_Yellow=0; //东西关黄灯显示信号
- P1=S[4]; //东西通行,南北红灯
- Display(); //调用显示函数
- keyboard();
- if(Restore_flag)
- break;
- }
- /*******S2状态(东西直行黄灯闪烁状态)**********/
- P1=0x00; //所有路口红绿灯短时熄灭
- if(Time_SN==5) //当南北倒计时为5s时
- Time_EW=5; //东西重新从5s开始倒计时
- while(Time_SN>=1) //南北方向倒计时最后5s循环体
- {
- Flag_EW_Yellow=1; //东西开黄灯信号位
- SN_Red=1; //东西黄灯开始闪烁,南北红灯亮
- Display(); //调用显示函数
- keyboard();
- if(Restore_flag)
- break;
- }
- /***********赋值(东西通行变南北通行)**********/
- EW=EW1; //东西25s-->30s
- SN=SN1; //南北30s-->25s
- /*******S3状态(南北直行状态)**********/
- Time_EW=EW; //东西数码管赋值30s
- Time_SN=SN; //南北数码管赋值25s
- while(Time_EW>=6) //东西方向倒计时前25s循环体
- {
- Flag_EW_Yellow=0; //东西关黄灯显示信号
- P1=S[0]; //南北通行,东西红灯
- Display(); //调用显示函数
- keyboard();
- if(Restore_flag)
- break;
- }
- /*******S4状态(南北直行黄灯闪烁状态)**********/
- P1=0X00; //所有路口红绿灯短时熄灭
- if(Time_EW==5) //当东西倒计时为5s时
- Time_SN=5; //南北重新从5s开始倒计时
- while(Time_EW>=1) //东西方向倒计时最后5s循环体
- {
- Flag_SN_Yellow=1; //南北开黄灯信号位
- EW_Red=1; //南北黄灯开始闪烁,东西红灯亮
- Display(); //调用显示函数
- keyboard();
- if(Restore_flag)
- break;
- }
- /***********赋值(南北通行变东西通行)**********/
- EW=SN1; //东西30s-->25s
- SN=EW1; //南北25s-->30s
- }
- }
复制代码
|