- #include<reg51.h>
- #include<at89x51.h>
- #define uchar unsigned char/*定义字符串类型为无符号型*/
- uchar code a[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
- uchar code b[4]={0x0D,0x0E,0x07,0x0B};/****P2口,低有效*/
- uchar code c[4]={0xDE,0xDD,0xF3,0xEB};/****P1口,低有效*/
- char SN=25,WE=30;
- char SN_G=25,WE_G=15,Y=5;
- uchar i,k=0,count=0;
- void delay(uchar t);/*定义函数*/
- void?light();/*定义函数*/
- void?led();/*定义函数*/
- sbit K0=P3^7;/*开关K0接P3^7管脚*/
- sbit K1=P3^6;/*开关K1接P3^6管脚*/
- sbit K2=P3^3;/*开关K2接P3^3管脚*/
- sbit K3=P3^5;/*开关K3接P3^5管脚*/
- sbit K4=P3^2;/*开关K4接P3^2管脚*/
- /*程序初始化*/
- void init(void)
- {
- /*12MHz*/
- TMOD=0x01;/**计数器用模式1,为16位计数器*****/
- TH1=(65536-50000)/256;/*0x3C*/
- TL1=(65536-50000)%256;/*0xB0*//*计50000个数,用时50ms*/
- IT0=1;/*外部中断0为边沿触发方式*/
- ET0=1;/*允许T0中断*/
- TR0=1;/*启动计数器*/
- EA=1;/*CPU开放总中断*/
- EX0=1;/*允许外部中断0中断,即允许响应端口P3^2(K4)中断*/
- EX1=1;/*允许外部中断1中断,即允许响应端口P3^3(K2)中断*/
- }
- /*中断0处理程序*/
- void int0(void) interrupt0
- {
- EA=0;/*CPU禁止响应一切中断*/
- P1=0xDB,P0=a[0];/*东西南北方向均红灯亮,P0口输出0*/
- for(;;)/*无条件循环*/
- {
- P2=b[0],P0=a[(SN_G+Y)%10];/*南北方向数码管显示可通行时间的个位*/
- delay(5);/*延时*/
- P2=b[1],P0=a[(SN_G+Y)/10];/*南北方向数码管显示可通行时间的十位*/
- delay(5);/*延时*/
- P2=b[2],P0=a[(WE_G+Y)%10];/*东西方向数码管显示可通行时间的个位*/
- delay(5);/*延时*/
- P2=b[3],P0=a[(WE_G+Y)/10];/*东西方向数码管显示可通行时间的十位*/
- delay(5);/*延时*/
-
- /*设置南北方向通行时间*/
- if(K0==0)/*P3^7=0*/
- {
- delay(10);/*延时,把抖动的时间抛掉*/
- if(K0==0)
- {
- while(!K0)/*当松开K0开关时,跳出空循环,执行后面的程序*/
- {
- }
- SN_G++;/*南北方向绿灯时间+1*/
- if(SN_G==100)
- SN_G=0;/*由于使用的是两位数码管,当南北方向绿灯时间加到100后清零*/
- }
- }
- /*设置南北方向通行时间*/
- if(K0==0)/*P3^7=0*/
- {
- delay(10);/*延时,把抖动的时间抛掉*/
- if(K0==0)
- {
- while(!K0)/*当松开K0开关时,跳出空循环,执行后面的程序*/
- {
- }
- SN_G++;/*南北方向绿灯时间+1*/
- if(SN_G==100)
- SN_G=0;/*由于使用的是两位数码管,当南北方向绿灯时间加到100后清零*/
- }
- }
- /*设置东西方向通行时间*/
- if(K1==0)/*P3^6=0*/
- {
- delay(10);/*延时,把抖动的时间抛掉*/
- if(K1==0)
- {
- while(!K1)/*当松开K1开关时,跳出空循环,执行后面的程序*/
- {
- }
- WE_G++;/*东西方向绿灯时间+1*/
- if(WE_G==100)
- WE_G=0;/*由于使用的是两位数码管,当东西方向绿灯时间加到100后清零*/
- }
- }
- /*返回*/
- if(K3==0)
- {
- while(!K3)/*当松开K3开关时,跳出空循环,执行后面的程序*/
- {
- }
- count=0;/*清零*/
- k=0;/*南北方向通车,东西方向不通车*/
- SN=SN_G,WE=SN_G+Y;/*南北方向显示时间为南北方向绿灯通行时间,东西方向显示时间为南北方向绿灯通行时间加黄灯闪亮时间*/
- light();/*调用交通灯函数*/
- led();/*调用数码管函数*/
- EA=1;/*CPU开放总中断*/
- break;/*跳出*/
- }
- }
- }
- }
- /*中断1处理程序*/
- void int1(void) interrupt2
- {
- P1=0xDB,P0=a[0];/*东西南北方向均红灯亮,P0口输出0*/
- EA=0;/*CPU禁止响应一切中断*/
- TR0=!TR0;/*计数器停止工作*/
- for(;;)/*无条件循环*/
- {
- /*数码管扫描程序*/
- P2=b[0];/*显示南北方向个位*/
- delay(5);/*延时*/
- P2=b[1];/*显示南北方向十位*/
- delay(5);/*延时*/
- P2=b[2];/*显示东西方向个位*/
- delay(5);/*延时*/
- P2=b[3];/*显示东西方向十位*/
- delay(5);/*延时*/
- /*返回*/
- if(K3==0) /*P3^5=0*/
- {
- delay(10);/*延时,把抖动的时间抛掉*/
- if(K3==0)
- {
- while(!K3)/*当松开K3开关时,跳出空循环,执行后面的程序*/
- {
- }
- EA=1;/*CPU开放总中断*/
- TR0=!TR0;/*启动计数器*/
- break;/*跳出*/
- }
- }
- }
- }
- /*键盘程序*/
- void key()
- {
- /*南北有车而东西无车*/
- if(K0==0) /*K0=0*/
- {
- delay(10);/*延时,把抖动的时间抛掉*/
- if(K0==0)
- {
- while(!K0)/*当松开K0开关时,跳出循环,执行后面的程序*/
- {
- light();/*调用交通灯函数*/
- led();/*调用数码管函数*/
- }
- count=0;/*清零*/
- k=0;/*南北方向通车,东西方向不通车*/
- SN=SN_G,WE=SN_G+Y;/*南北方向显示时间为南北方向绿灯通行时间,东西方向显示时间为南北方向绿灯通行时间加黄灯闪亮时间*/
- light();/*调用交通灯函数*/
- led();/*调用数码管函数*/
- }
- }
- /*南北无车而东西有车*/
- if(K1==0) /*K1=0*/
- {
- delay(10);/*延时,把抖动的时间抛掉*/
- if(K1==0)
- {
- while(!K1)/*当松开K1开关时,跳出循环,执行后面的程序*/
- {
- light();/*调用交通灯函数*/
- led();/*调用数码管函数*/
- }
- count=0;/*清零*/
- k=2;/*南北方向不通车,东西方向通车*/
- SN=WE_G+Y,WE=WE_G;/*南北方向显示时间为东西方向绿灯通行时间加黄灯闪亮时间,东西方向显示时间为东西方向绿灯通行时间*/
- light();/*调用交通灯函数*/
- led();/*调用数码管函数*/
- }
- }
- }
- /*定时函数*/
- void time 1(void) interrupt 1
- {
- TH0=0x3c;
- TL0=0xb0;/*计50000个数,用时50ms*/count++;
- /*自增运算*/
- if(count>=20)/*当count大于或等于20时,历时1s,执行程序*/
- {
- SN--;/*自减运算*/
- WE--;/*自减运算*/
- count=0;/*清零*/
- if(SN==0||WE==0)/*当SN=0或者WE=0时,执行程序*/
- {
- k++;/*自增运算*/
- if(k>3)/*当k>3时,执行程序*/
- k=0;/*清零*/
- switch(k)/*switch语句*/
- {
- case 0:SN=SN_G,WE=SN_G+Y;break;/*南北方向显示时间为南北方向绿灯通行时间,东西方向显示时间为南北方向绿灯通行时间加黄灯闪亮时间*/
- case 1:SN=Y,WE=Y;break;/*东西南北方向显示时间均为黄灯闪亮时间*/
- case 2:SN=WE_G+Y,WE=WE_G;break;/*南北方向显示时间为东西方向绿灯通行时间加黄灯闪亮时间,东西方向显示时间为东西方向绿灯通行时间*/
- case 3:SN=Y,WE=Y;break;/*东西南北方向显示时间均为黄灯闪亮时间*/
- }
- }
- }
- }
- /*延时t毫秒*/
- void delay(uchar t)
- {
- uchari;
- for(t;t>0;t--)
- {
- for(i=2000;i>0;i--)
- {}
- }
- }
- /*交通灯函数*/
- void light()
- {
- P1=c[k];/*交通灯对应着k的值变化*/
- if(P1==c[1]&&count==0)/*当南北方向亮黄灯且count=0时,执行程序*/
- {
- TH1=(65536-50000)/256;
- TL1=(65536-50000)%256;/*延时50ms*/
- P1=0xDF;/*南北方向黄灯熄灭,东西方向亮红灯*/
- }
- else
- if(P1==c[3]&&count==0)/*当东西方向亮黄灯且count=0时,执行程序*/
- {
- TH1=(65536-300000)/256;
- TL1=(65536-300000)%256;/*延时50ms*/
- P1=0xFB;/*南北方向亮红灯,东西方向黄灯熄灭*/
- }
- }
- /*数码管函数*/
- void led()
- {
- P2=b[0],P0=a[SN%10];/*显示南北方向个位*/
- delay(5);/*延时*/
- P2=b[1],P0=a[SN/10];/*显示南北方向十位*/
- delay(5);/*延时*/
- P2=b[2],P0=a[WE%10];/*显示东西方向个位*/
- delay(5);/*延时*/
- P2=b[3],P0=a[WE/10];/*显示东西方向十位*/
- delay(5);/*延时*/
- }
- /*主函数*/
- void main(void)
- {
- init();/*调用程序初始化函数*/
- for(;;)/*无条件循环*/
- {
- key();/*调用键盘程序*/
- light();/*
- 调用交通灯函数*/
复制代码 |