1.控制要求
(1) 东西南北双向红绿灯显示,红灯30s,绿灯27s,黄灯闪烁3s。
(2)夜间模式:黄灯闪烁
(3)禁行模式:一侧红灯,一侧绿灯
(4)时间调节:改变红绿灯时间
2.仿真
(1)工具:proteus
3.程序
(1)keil c51
4.程序
#include// 头文件 #define uchar unsigned char // 宏定义 #define uint unsigned int // 宏定义 uchar led_code[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//共阴数码管字符 sbit w1=P1^0; //南北方向数码管第一位的选择标志 sbit w2=P1^1; //南北方向数码管第二位的选择标志 sbit w3=P1^2; //东西方向数码管第二位的选择标志 sbit w4=P1^3; //东西方向数码管第二位的选择标志 sbit green1=P2^4; //南北绿灯标志 sbit yellow1=P2^5; //南北黄灯标志 sbit red1=P2^6; //南北红灯标志 sbit green2=P2^1; //东西绿灯标志 sbit yellow2=P2^2; //东西黄灯标志 sbit red2=P2^3; //东西红灯标志 sbit k1=P3^5; //夜间模式 sbit k2=P3^6; //禁行 sbit k3=P3^4; //方向切换 sbit k4=P3^7; //加时间 sbit k5=P3^1; //减时间 sbit k6=P1^5; //确认 char number1=30; //南北红灯时间 char number2=27; //南北绿灯时间 char number3=3; //南北黄灯时间 char number4=27; //东西绿灯时间 char number5=3; //南北黄灯时间 char number6=30; //东西红灯时间 uchar number_ns=0; //南北方向时间 uchar number_we=0; //东西方向时间 uchar time1=60; //南北方向时间标志 uchar time2=60; //东西方向时间标志 uchar i; //定时器T0溢出计数 bit set=0; //方向切换标志 void num_display(void); //数字显示函数声明 void delay(unsigned char t1); //声明延时函数 void led_display(void); //LED灯显示函数声明 void key(void); //按键函数声明 void main() //主程序 { number_ns=number1; number_we=number4; //初始赋值 TMOD=0x01; //定时器T0的模式1 TH0=0x3c; //定时器T0初值设置,实现50ms定时 TL0=0xb0; EA=1; //打开总中断 ET0=1; //允许定时器T1中断 TR0=1; //启动定时器T0 while(1) //循环执行程序 { num_display(); led_display(); key(); } } void num_display(void) { P0=led_code[number_ns/10]; //南北方向数码管数字十位显示 w1=0; //南北位选:为0时送数据,为一时关闭, delay(5); w1=1; P0=led_code[number_ns%10]; //南北方向数码管显示各位 w2=0; delay(5); w2=1; P0=led_code[number_we/10]; //东西方向数码管显示个位 w3=0; //东西方向位选 delay(5); w3=1; P0=led_code[number_we%10]; //东西方向数码管数字个位显示 w4=0; delay(5); w4=1; } void led_display(void) { if(time1>(60-number1)) // 南北红灯阶段 { yellow1=0; green1=0; red1=1; } if((time1<(60-number1)||time1==(60-number1))&&(time1>3)) //南北绿灯阶段 { red1=0; yellow1=0; green1=1; } if(time1<3||time1==3) //南北方向黄灯阶段 { green1=0; if(i==5||i==15) yellow1=1; if(i==10||i==20) yellow1=0; } if(time2>(60-number4)) //东西方向绿灯阶段 { yellow2=0; green2=1; red2=0; } if((time2<(60-number4)||time2==(60-number4))&&(time2>number6)) //东西方向黄灯阶段 { green2=0; if(i==5||i==15) yellow2=1; if(i==10||i==20) yellow2=0; } if(time2<(number6)||time2==number6) //东西方向红灯阶段 { red2=1; yellow2=0; green2=0; } } void times() interrupt 1 { TH0=0x3c; //定时器T0初值设置,实现50ms定时 TL0=0xb0; i++; if(i==20) //定时1S完成 { i=0; //清空标志 number_ns--; //南北数字减一 number_we--; //东西数字减一 time1--; time2--; //转换标志同步自减 if(time1==(60-number1)) //南北红灯时间结束 number_ns=number2; //赋绿灯时间 if(time1==3) number_ns=number3; //绿灯时间赋黄灯时间 if(time1==60) number_ns=number1; //初始赋红灯时间 if(time1==0) //循环结束重新赋值 { time1=60; number_ns=number1; } if(time2==(60-number4)) //东西绿灯时间结束 number_we=number5; //赋黄灯时间 if(time2==57-number4) //黄灯时间结束赋绿灯时间 number_we=number6; if(time2==60) //初始赋绿灯时间 number_we=number4; if(time2==0) //重新赋值 { time2=60; number_we=number4; } } } void key(void) { if(k1==0) //当夜间模式按键按下 delay(100); //消抖 if(k1==0) { while(k1==1); //松手检测 while(1) //循环执行黄灯闪烁与数码管置0 { red1=0; red2=0; green1=0; green2=0; if(i==5||i==15) // 黄灯闪烁 { yellow2=1; yellow1=1; } if(i==10||i==20) { yellow2=0; yellow1=0; } P0=led_code[0]; //数码管显示0 w1=0; delay(5); w1=1; P0=led_code[0]; w2=0; delay(5); w2=1; P0=led_code[0]; w3=0; delay(5); w3=1; P0=led_code[0]; w4=0; delay(5); w4=1; } } if(k2==0); // 当单向禁行按键被按下 delay(100); // 消抖 if(k2==0) { while(k2==1); //松手检测 while(1) { P0=led_code[0]; //数码管显示0 w1=0; delay(5); w1=1; P0=led_code[0]; w2=0; delay(5); w2=1; P0=led_code[0]; w3=0; delay(5); w3=1; P0=led_code[0]; w4=0; delay(5); w4=1; if(k3==0) //切换按键按下 delay(100); if(k3==0) { while(k3==0); set=~set; //切换标志取反,方向切换 } if(set==0) //切换标志为0时,南北禁行 { red1=1; red2=0; green1=0; green2=1; yellow1=0; yellow2=0; } if(set==1) //切换标志为1时,东西禁行 { red1=0; red2=1; green1=1; green2=0; yellow1=0; yellow2=0; } } } if(k4==0) //时间加按键按下 delay(100); //消抖 if(k4==0) { TR0=0; number1++; //南北红灯加 number2--; //南北绿灯减 number4++; //东西绿灯加 number6--; //东西绿灯减 number_ns=number1; //赋入改变后的值 number_we=number4; while(k4==1); //松手监测 while(1) { P0=led_code[number1/10]; //显示南北调节的数字 w1=0; delay(5); w1=1; P0=led_code[number1%10]; w2=0; delay(5); w2=1; P0=led_code[number4/10]; //显示东西调节的数字 w3=0; delay(5); w3=1; P0=led_code[number4%10]; w4=0; delay(5); w4=1; if(k4==1) break; } } if(k5==0) // 当减时间按键按下 delay(100); // 消抖 if(k5==0) { TR0=0; number1--; // 南北红灯时间减 number2++; // 南北绿灯时间加 number4--; // 东西绿灯时间减 number6++; // 东西红灯时间加 number_ns=number1; // 赋入改变后的值 number_we=number4; while(k5==1); //松手检测 while(1) { P0=led_code[number1/10]; // 显示南北方向调节中的值 w1=0; delay(5); w1=1; P0=led_code[number1%10]; w2=0; delay(5); w2=1; P0=led_code[number4/10]; // 显示东西方向调节中的值 w3=0; delay(5); w3=1; P0=led_code[number4%10]; w4=0; delay(5); w4=1; if(k5==1) break; //跳出死循环 } } if(k6==0) //确认键被按下 delay(100); //消抖 if(k6==0) { while(k6==1); //松手检测 TR0=1; //开定时器 number_ns=number1; //赋改变后的值 number_we=number4; } } void delay(uchar t1) //延时函数,约1ms延时 { uchar i,j; for(i=5;i>t1;i--) for(j=200;j>0;j--); }
5.仿真图



