|
单片机源程序如下:
- #include<reg51.h>
- #define uchar unsigned char
- #define uint unsigned int
- uchar data a[4];
- uchar data time_dx=37;//东西数默认
- uchar data time_nb=37;//南北默认值
- uchar data set_timedx=37;//存放设置的数值
- uchar data set_timenb=37;
- int n; uchar data b;//定时器中断次数
- sbit k5=P3^4;//时间加按键
- sbit k6=P3^5;//时间减按键
- sbit k7=P3^6;//确认/恢复按键
- sbit k1=P3^0;//切换方向按键
- sbit k2=P3^1;//紧急按键(都不通行60s)
- sbit k3=P3^2;//东西通行60s (使用外部中断T0)
- sbit k4=P3^3;//南北通行60s (使用外部中断T1)
- sbit Green_nbzx=P2^7; //往南北转向绿灯
- sbit Green_dxzx=P2^0;//往东西转向绿灯
- sbit Yellow_nb=P2^5; //南北黄灯
- sbit Yellow_dx=P2^2; //东西黄灯
- sbit Green_nb=P2^4; //南北绿灯
- sbit Green_dx=P2^1;//东西绿灯
- sbit Red_nb=P2^6;//南北红灯
- sbit Red_dx=P2^3;//东西红灯
- bit time=0;//灯状态循环标志,实现灯自动切换
- bit set=1;//调时方向切换键标志
- uchar code table[11]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,
- 0x7d,0x07,0x7f,0x6f,0x00}; //共阴数码管编码
- void key();//按键扫描子程序
- void key_t1();//键处理子程序//加
- void key_t2();//减
- void key_t3(); //紧急
- void display();//显示子程序
- void logo(); //开机 LOGO
- void delay(int ms);//延时子程序
- void main()
- {
- TMOD=0X01;//使用定时器T0的模式1
- TH0=0XD8; //定时器T0的高8位赋初值
- TL0=0XF0;// 定时器T0的低8位赋初值
- EA=1; //开总中断
- ET0=1;//定时器T0中断允许
- TR0=1;//开定时器
- EX0=1;//开外部中断0
- EX1=1;//开外部中断1
- P1=0X00;
- logo();//调用logo子程序,显示开机logo
- P2=0XBD;// 开始默认状态,东西绿灯,南北红灯,转向灯不亮
- time_nb=time_dx+23; //南北比东西大5s //改过(5-23)
- while(1)
- {
- key(); //调用按键扫描程序
- display(); //调用显示程序
- }
- }
- void key() //按键扫描子程序
- {
- if(k1!=1) //k1切换方向
- { TR0=0;
- delay(5);
- if(k1!=1)
- {while(k1!=1); set=!set;}//如果检测到k1按下,则改变方向标志位set
- }
- if(k2!=1) //k2紧急按键,都不通行
- {
- delay(5);
- if(k2!=1)
- {
- while(k2!=1)//如果检测到k2按下,则调用key_to3子程序
- key_t3();
- }
- }
- if(k5!=1) //k5时间加
- {
- delay(10);
- if(k5!=1)
- {
- while(k5!=1) //如果检测到k5按下,则调用key_to1子程序
- {
- key_t1();
- for(n=0;n<60;n++)//用一个循环,延时,以达到消抖,使每按一次按钮只加一个数
- { display();}
- }
- }
- }
- if(k6!=1) //k6时间减
- {
- delay(10);
- if(k6!=1)
- {
- while(k6!=1) //如果检测到k6按下,则调用key_to2子程序
- {
- key_t2();
- for(n=0;n<60;n++)//用一个循环,延时,以达到消抖,使每按一次按键只减一个数
- { display();}
- }
- }
- }
- if(k7!=1)//k7确认/恢复
- {
- TR0=1; //启动定时器
- time_nb=set_timenb; //从中断回复,显示设置的数值
- time_dx=set_timedx;
- if(time==0) //检测灯循环标志位,若time=0,则东西绿灯,南北红灯,并南北时间比东西大23s
- { P2=0xBD;time_nb=time_dx+23; } //(18-99,5-23)
- else { P2=0XE7;time_dx=time_nb+23; }//否则南北绿灯,东西红灯,并东西时间比南北大23s
- }
- }
- void key_t1() // 加时间
- {
- TR0=0; //关定时器
- if(set==0)
- set_timenb++; //南北加 1S
- else
- set_timedx++; //东西加 1S
- if(set_timenb==100)//加到 100时置 1
- set_timenb=1;
- if(set_timedx==100)
- set_timedx=1;
- time_nb=set_timenb; //设置的数值赋给南北
- time_dx=set_timedx;//设置的数值赋给东西
- }
- void key_t2() //减时间
- {
- TR0=0; //关定时器
- if(set==0)
- set_timenb--; //南北减 1S
- else
- set_timedx--; //东西减 1S
- if(set_timenb==0)
- set_timenb=99;
- if(set_timedx==0)
- set_timedx=99; //减到 1 时重置 99
- time_nb=set_timenb ; //设置的数值赋给南北
- time_dx=set_timedx;//设置的数值赋给东西
- }
- void key_t3() //紧急(都不通行)
- {
- TR0=1; //打开定时器
- P2=0XB7;
- time_dx=60;
- time_nb=60;
- }
- void display() //显示子程序
- {
- a[0]=time_dx/10; //东西十位
- a[1]=time_dx%10; //东西个位
- a[2]=time_nb/10; //南北十位
- a[3]=time_nb%10; //南北个位
-
- P0=0x00;
- P1=0Xf4; //片选东西十位
- P0=table[a[0]];
- delay(1);
-
- P0=0x00;
- P1=0Xf5; //片选东西个位
- P0=table[a[1]];
- delay(1);
-
- P0=0x00;
- P1=0xf0; //片选南北十位
- P0=table[a[2]];
- delay(1);
-
- P0=0x00;
- P1=0xf1; //片选南北个位
- P0=table[a[3]];
- delay(1);
-
- }
- void time0(void) interrupt 1 using 1 //定时中断子程序
- {
- b++;
- if(b==15) // 定时器中断次数
- {
- b=0;
- time_dx--;
- time_nb--;
- if(time_nb<=26&&time_nb>23&&time==0) //东西直行最后3s绿闪
- {
- Green_dx=!Green_dx;
- }
- if(time_dx<=26&&time_dx>23&&time==1) // 南北直行最后3s绿闪
- {
- Green_nb=!Green_nb;
- }
- if(time_nb<=23&&time_nb>20&&time==0) //东西直行-黄闪
- {
- Green_dx=1;Yellow_dx=!Yellow_dx;
- }
- if(time_dx<=23&&time_dx>20&&time==1) // 南北直行-黄闪
- {
- Green_nb=1;Yellow_nb=!Yellow_nb;
- }
- if(time_dx==0&&time_nb==23) //东西黄闪数码管重新赋值
- time_dx=3;
- if(time_nb==0&&time_dx==23) //南北黄闪数码管重新赋值
- time_nb=3;
- if(time_nb<=20&&time_nb>6&&time==0) //东西直行-黄闪-往东西转向
- {
- Green_dx=1;Yellow_dx=1;Green_dxzx=0;
- }
- if(time_dx<=20&&time_dx>6&&time==1) // 南北直行-黄闪-往南北转向
- {
- Green_nb=1;Yellow_nb=1;Green_nbzx=0;
- }
- if(time_dx==0&&time_nb==20) //东西转向绿数码管重新赋值
- time_dx=17;
- if(time_nb==0&&time_dx==20) //东西转向绿数码管重新赋值
- time_nb=17;
- if(time_nb<=6&&time_nb>3&&time==0) //东西转向最后3s绿闪
- {
- Green_dxzx=!Green_dxzx;
- }
- if(time_dx<=6&&time_dx>3&&time==1) // 南北转向最后3s绿闪
- {
- Green_nbzx=!Green_nbzx;
- }
-
- if(time_nb<=3&&time==0) //东西黄灯闪
- { Green_dx=1;Green_dxzx=1;Yellow_dx=!Yellow_dx;}
- if(time_dx<=3&&time==1) //南北黄灯闪
- { Green_nb=1;Green_nbzx=1;Yellow_nb=!Yellow_nb;}
- if(time_dx==0&&time_nb==3) // 东西黄闪数码管重新赋值
- time_dx=3;
- if(time_nb==0&&time_dx==3) //南北黄闪数码管重新赋值
- time_nb=3;
- if(time==0&&time_nb==0) //灯置状态循环标志且南北红灯时间到,变绿灯
- {
- P2=0xE7;
- time=!time;
- time_nb=set_timenb;
- time_dx=set_timenb+23;
- }
- if(time==1&&time_dx==0)//灯置状态循环标志且东西红灯时间到,变绿灯
- {
- P2=0XBD;
- time=!time;
- time_dx=set_timedx;
- time_nb=set_timedx+23;
- }
- }
- }
- void int0(void) interrupt 0 using 1 //使用外部中断控制,东西通行,南北不通行
- {
- if(k3!=1) //k3东西通行按键
- {
- delay(5);
- if(k3!=1)
- {
- while(k3!=1)//如果检测到k3按下
- { TR0=1;//打开定时器
- P2=0XBD;//东西绿灯,南北红灯
- time_dx=60;
- time_nb=60;}
- }
- }
-
- }
- void int1(void) interrupt 2 using 1 //使用外部中断控制,南北通行,东西不通行
- {
- if(k4!=1) //k4南北通行按键,都不通行
- {
- delay(5);
- if(k4!=1)
- {
- while(k4!=1)//如果检测到k4按下
- { TR0=1; //打开定时器
- P2=0XE7;//南北绿灯,东西红灯
- time_nb=60;
- time_dx=60; }
- }
- }
-
- }
- void logo()//开机显示"- -"
- {
- for(n=0;n<100;n++)
- {
- P0=0x40;
- P1=0xf0;
- delay(1);
- P1=0xf1;
- delay(1);
- P1=0Xf4;
- delay(1);
- P1=0Xf5;
- delay(1);
-
- }
- }
- void delay(int ms) //延时子程序
- {
- uint j,k;
- for(j=0;j<ms;j++)
- for(k=0;k<124;k++);
- }
复制代码
代码经过本人实践可使用
|
-
整体系统仿真
-
按钮对应要求
-
系统要求
-
零件表
-
主程序流程图
-
外部中断
-
-
红绿灯交通灯.zip
118.24 KB, 下载次数: 21, 下载积分: 黑币 -5
c语言编程及仿真 2个文件下载
评分
-
查看全部评分
|