|
1.用单片机扩展一片8255,用4个交通灯模拟一个十字交叉路口的红、绿、黄灯,并设置二个单方向行按键,和一个紧急按键;
2.正常行驶时,东西或南北方向的灯按绿灯亮27秒,黄灯闪烁3秒,红灯亮30秒控制;
3.当两个单方向通行按键某一个按下时,则南北(东西)方向一直是绿灯,东西(南北)方向一直是红灯;或者紧急按键按下时,两方向均为红灯禁止通行,而只要有按键按下时8个数码管均显示8,且停止计时,按键松开后恢复到之前的状态。 本设计选用的51单片机内部晶振为12MHz,12分频所得时钟周期为1μs,选用定时器0,选用方式1,T0定时最长时间约为65ms,选用T0产生50ms的定时,再通过计时20次产生1S标志。设定时初值为X,则有(65536-X)*1μs=50ms,得X=3CB0H, 即 TH0=3CH, TL0=B0H
源程序: - #include<reg51.h>
- #include<absacc.h>
- #define uchar unsigned char
- #define uint unsigned int
- #define PA XBYTE[0x0000] //8255 A口地址
- #define PB XBYTE[0x0001] //8255 B口地址
- #define PC XBYTE[0x0002] //8255 C口地址
- #define PS XBYTE[0x0003] //8255 控制口地址
- sbit button1=P3^3; //K0 接外部中断1,紧急车辆通过指示开关
- sbit button2=P1^0; //K1 支道状态开关
- sbit button3=P1^1; //K2 主道状态开关
- sbit button4=P3^2; //K3 接外部中断0,调整红绿时长
- sbit button5=P0^4;
- sbit wei1=P1^4;
- sbit wei2=P1^5;
- sbit wei3=P1^6;
- sbit wei4=P1^7;
- sbit wei5=P1^2;
- sbit wei6=P1^3;
- sbit wei7=P3^0;
- sbit wei8=P3^1;
- uint num0=0,num1=0;
- uint k;
- uchar dp1,dp2,dp3,dp4;
- uchar code table[]= //共阴七段码
- {
- 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f
- };
- void time0_int() //计时器初始化
- {
- TMOD=0x11; //设置定时器0位方式1
- TH0=0x3C; //定时50毫秒,初值为15536=3CB0
- TL0=0xB0;
- EA=1; //开全局中断
- EX1=1; //开外部中断1
- EX0=1;
- IT0=0;
- IT1=0; //中断1为低电平触发
- ET0=1; //开计时器0中断
- TR0=1; //启动计时器0
-
- }
- void delay(unsigned int z) //延时程序
- {
- uint x,y;
- for(x=z;x>0;x--)
- for(y=110;y>0;y--);
- }
- void ini() //两路灯初始状态
- {
- P3=0xff;
- P1=0xff;
- P2=0xff;
- PA=0x21;
- PB=0x0C;
- }
-
- void display0(uchar unit,uchar decade) //南北方向倒计时显示
- {
- wei1=0; //显示低位
- P2=table[unit];
- delay(2);
- wei1=1;
- wei2=0; //高位显示
- P2=table[decade];
- delay(2);
- wei2=1;
- wei5=0;
- P2=table[unit];
- delay(2);
- wei5=1;
- wei6=0;
- P2=table[decade];
- delay(2);
- wei6=1;
- }
- void display1(uchar unit,uchar decade) //东西方向倒计时
- {
- wei3=0; //显示低位
- P2=table[unit];
- delay(10);
- wei3=1;
- wei4=0; //显示高位
- P2=table[decade];
- delay(10);
- wei4=1;
- wei7=0;
- P2=table[unit];
- delay(10);
- wei7=1;
- wei8=0;
- P2=table[decade];
- delay(10);
- wei8=1;
- }
- void main()
- {
- PS=0x80; //8255控制字写入,A B C口均为输出,均为方式0
- time0_int();
- ini();
- while(1)
- {
- while((button1!=0)&&(button2!=0)&&(button3!=0))
- {
- if((button1!=0)&&(button2!=0)&&(button3!=0)) //南北方向
- {
- if(num0>0&&num0<540)
- {
- PA=0x0C; //绿灯亮27秒
- dp1=(27-(num0-0)/20)%10;
- dp2=(27-(num0-0)/20)/10;
- display0(dp1,dp2); //倒计时显示
- }
-
- if(num0>=540&&num0<600) //黄灯连续闪烁3秒
- {
- PA=0x12;
- delay(200);
- PA=0x00;
- dp1=(3-(num0-540)/20)%10;
- dp2=(3-(num0-540)/20)/10;
- display0(dp1,dp2); //倒计时显示
- }
-
- if(num0>=600&&num0<1200) //红灯亮30秒
- {
- PA=0x21;
- dp1=(30-(num0-600)/20)%10;
- dp2=(30-(num0-600)/20)/10;
- display0(dp1,dp2); //倒计时显示
- }
- if(num0>=1200)num0=0;
- }
-
- if((button1!=0)&&(button2!=0)&&(button3!=0)) //东西方向
- {
- if(num1>0&&num1<600) //红灯亮30秒
- {
- PB=0x0C;
- dp3=(30-num1/20)%10;
- dp4=(30-num1/20)/10;
- display1(dp3,dp4); //倒计时显示
- }
- if(num1>=600&&num1<1140) //绿灯亮27秒
- {
- PB=0x21;
- dp3=(27-(num1-600)/20)%10;
- dp4=(27-(num1-600)/20)/10;
- display1(dp3,dp4); //倒计时显示
- }
-
- if(num1>=1140&&num1<1200) //黄灯连续闪3秒
- {
- PB=0x12;
- delay(200);
- PB=0x00;
- dp3=3-(num1-1140)/20;
- dp4=0;
- display1(dp3,dp4); //倒计时显示
- }
- if(num1>1200)num1=0;
- }
- }
- }
- }
- void time0() interrupt 1 //定时中断响应
- {
- TH0=0x3C; //定时1ms初值
- TL0=0xB0;
- num0++;
- num1++;
- }
- void thing1() interrupt 0 //某一方向放行
- {
- display0(0,0);
- display1(0,0);
- while((button1!=0)&&(button2!=0)&&(button3==0)) //南北禁行,东西放行
- {
- PA=0x21;
- PB=0x21;
- dp1=8;
- dp2=8;
- display0(8,8);
- display1(8,8);
- }
-
- while((button1!=0)&&(button2==0)&&(button3!=0)) //南北放行,东西禁行
- {
- PA=0x0C;
- PB=0x0C;
- dp1=8;
- dp2=8;
- display0(8,8);
- display1(8,8);
- }
- }
- void thing2() interrupt 2 //外部中断器1响应_紧急情况_两道禁止通行
- {
- PA=0x21;
- PB=0x0C;
-
- display0(8,8);
- display1(8,8);
- }
复制代码
|
评分
-
查看全部评分
|