交通灯C程序
- 格式:docx
- 大小:15.45 KB
- 文档页数:6
交通灯程序/*********************************************************** 十字路口交通灯控制 C 程序***********************************************************/#include <reg51.h>#define uchar unsigned char#define uint unsigned int/*****定义控制位*******************************************/sbit Time_Show_LED2=P2^5; //Time_Show_LED2(直行时间显示)控制位sbit Time_Show_LED1=P2^4; //Time_Show_LED1(直行时间显示)控制位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 EW_Yellow=P1^2; //EW黄灯sbit EW_ManGreen=P3^0; //EW人行道绿灯sbit SN_ManGreen=P3^1; //SN人行道绿灯sbit Special_LED=P2^6; //交通特殊指示灯sbit Busy_LED=P2^7; //交通繁忙指示灯sbit Nomor_Button=P3^5; //交通正常按键sbit Busy_Btton=P3^6; //交通繁忙按键sbit Special_Btton=P3^7; //交通特殊按键sbit EW_ManRed=P3^3; //EW人行道红灯sbit SN_ManRed=P3^4; //SN人行道红灯bit Flag_SN_Yellow; //SN黄灯标志位bit Flag_EW_Yellow; //EW黄灯标志位char Time_EW; //东西方向倒计时单元char Time_SN; //南北方向倒计时单元uchar EW=60,SN=40,EWL=19,SNL=19; //程序初始化赋值,正常模式uchar EW1=60,SN1=40,EWL1=19,SNL1=19; //用于存放修改值的变量uchar codetable[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F}; //0-9段选码uchar code S[8]={0x28,0x48,0x18,0x48,0x82,0x84,0x81,0x84};//交通信号灯控制代码/**********************延时子程序**************************/void Delay(uchar a){uchar i;i=a;while(i--){;}}/*****************显示子函数******************************/ void Display(void){uchar h,l;h=Time_EW/10;l=Time_EW%10;P0=table[l];EW_LED2=1; //点亮EW_LED2Delay(2);EW_LED2=0; //熄灭EW_LED2P0=table[h];EW_LED1=1; //点亮EW_LED1Delay(2);EW_LED1=0;h=Time_SN/10;l=Time_SN%10;P0=table[l];SN_LED2=1; //点亮SN_LED2Delay(2);SN_LED2=0;P0=table[h];SN_LED1=1; //点亮SN_LED1Delay(2);SN_LED1=0;h= EW1/10;l= EW1%10;P0=table[l];Time_Show_LED1=1; //点亮Time_Show_LED1Delay(2);Time_Show_LED1=0;P0=table[h];Time_Show_LED2=1; //点亮Time_Show_LED2Delay(2);Time_Show_LED2=0;}/**********************外部0中断服务程序******************/void INT0_srv(void)interrupt 0 using 1{EX0=0; //关中断if(Nomor_Button==0) //测试按键是否按下,按下为正常状态 {EW1=60;SN1=40;EWL1=19;SNL1=19;Busy_LED=0; //关繁忙信号灯Special_LED =0; //关特殊信号灯}if(Busy_Btton==0) //测试按键是否按下,按下为繁忙状态 {EW1=45;SN1=30;EWL1=14;SNL1=14;Special_LED=0; //关特殊信号灯Busy_LED=1; //开繁忙信号灯}if(Special_Btton==0)//测试按键是否按下,按下为特殊状态 {EW1=75;SN1=55;EWL1=19;SNL1=19;Busy_LED=0; //关繁忙信号灯Special_LED =1;//开特殊信号灯}EX0=1; //开中断}/**********************T0中断服务程序*******************/ void timer0(void)interrupt 1 using 1{static uchar count;TH0=(65536-50000)/256;TL0=(65536-50000)%256;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){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 main(void){Busy_LED=0;Special_LED=0;IT0=1; //INT0负跳变触发TMOD=0x01; //定时器工作于方式1TH0=(65536-50000)/256; //定时器赋初值TL0=(65536-50000)%256;EA=1; //CPU开中断总允许ET0=1; //开定时中断EX0=1; //开外部INTO中断TR0=1; //启动定时while(1){/*******S0状态**********/SN_ManRed=0;SN_ManGreen=1; //SN人行道通行EW_ManRed=1; //EW人行道禁止EW_ManGreen=0;Flag_EW_Yellow=0; //EW关黄灯显示信号Time_EW=EW;Time_SN=SN;while(Time_SN>=5){P1=S[0]; //SN绿灯,EW红灯Display();}/*******S1状态**********/P1=0x00;while(Time_SN>=0){Flag_SN_Yellow=1; //SN开黄灯信号位P1=P1|0x08; //保持EW红灯Display();}/*******S2状态**********/SN_ManRed=1; //SN人行道禁止SN_ManGreen=0;EW_ManRed=1; //EW人行道禁止EW_ManGreen=0;Flag_SN_Yellow=0; //SN关黄灯显示信号Time_SN=SNL;while(Time_SN>=5){P1=S[2]; //SN左拐绿灯亮,EW红灯Display();}/*******S3状态**********/P1=0x00;while(Time_SN>=0){Flag_SN_Yellow=1; //SN开黄灯信号位P1=P1|0x08; //保持EW红灯Display();}/***********赋值*********/EW=EW1;SN=SN1;EWL=EWL1;SNL=SNL1;/*******S4状态**********/SN_ManRed=1; //SN人行道禁止SN_ManGreen=0;EW_ManRed=0;EW_ManGreen=1; //EW人行道通行Flag_SN_Yellow=0; //SN关黄灯显示信号Time_EW=SN;Time_SN=EW;while(Time_EW>=5){P1=S[4]; //EW通行,SN红灯Display();}/*******S5状态**********/P1=0X00;while(Time_EW>=0){Flag_EW_Yellow=1;//EW开黄灯信号位P1=P1|0x80; //保持SN红灯Display();}/*******S6状态**********/SN_ManRed=1; //SN人行道禁止SN_ManGreen=0;EW_ManRed=1; //EW人行道禁止EW_ManGreen=0;Flag_EW_Yellow=0;//EW关黄灯显示信号Time_EW=EWL;while(Time_EW>=5){P1=S[6]; //EW左拐绿灯亮,SN红灯Display();}/*******S7状态**********/P1=0X00;while(Time_EW>=0){Flag_EW_Yellow=1; //EN开黄灯信号位P1=P1|0x80; //保持SN红灯Display();}/***********赋值********/EW=EW1;SN=SN1;EWL=EWL1;SNL=SNL1;}}。
uchar duanma[10]={0xc0,0xf9,0xa4, 0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //段码unchar weima [4]={0x01,0x02,0x04,0x08}; //位码unchar nanbei [3]={40,35,4}; //南北方向三组倒记时对应红,绿,黄灯unchar dongxi [3]={35,4,40}; //东西方向三组倒计时对应绿,黄,红灯unchar nbdeng [3]={0x01,0x04,0x02}; //南北方向三组灯的状态红绿黄unchar dxdeng [3]={0x8x,0x40,0x20} //东西方向三组灯的状态绿黄红unchar jishu1,jishu2,dxjishu,nbjishu,dxmiao,nbmiao,nbmiao; //定义变量unchar xianshi [4]={0,0,0,0}; //显示缓存器void yanshi10ms (void) //延时10ms函数{Unchar i,j;for (i=20;i>0;i--)for (j=250;j.0;j--);}Void chushihua (void) //初始化函数{TMOD=0x01; //定时器T0方式1THO=(65536-10000)/256 //10ms 定时高八位初值TLO=(65536-10000)%256; //10ms 定时低八位初值EA=1;ETO=1;EXO=1;ITO=1TRO=1;//CPU,T0,INTO允许中断,外部中断下降沿触发,启动定时器}void main(void) //主函数{dxmiao=dongxi [0] //东西倒计时赋初值nbmiao=nanbei [0] //南北倒计时赋初值chushihua (); //调试初始化函数while (1); //无限循环,踏步}Void anjian (void) interrupt 0 //外部中断 INTO 中断服务函数{yanshi10ms (); //延时去抖动if (INTO==0); //二次判断{If ((dxmiao<=50) && (nbmiao<=50)); //东西,南北当前显示值不大于50 {dxmiao+=10; //东西显示值+10nbmiao+=10 //南北显示着+10}//******************************************************************* }}void daojishi (void) interrupt 1 //定时器T0中断服务函数{THO=(65536-10000)/256; //高八位初值重装TLO=(65536-10000)/256; //低八位初值重装xiaoshi[0]=duanma [nbmiao/10]; //分离南北方向秒的十位xiaoshi[1]=duanma [nbmiao%10]; //分离南北方向秒的个位xiaoshi[2]=duanma [nbmiao/10]; //分离东西方向秒的十位xiaoshi[3]=duanma [nbmiao/10]; //分离东西方向秒的个位//**********************动态扫描*********************************** jishu1 ++; //指向扫描的下一位if (jishu1==4) jishu1=0; //完成四位扫描后计数归0P0=weima [jishu1]; //送位码P1=xiaoshi [jishu1]; //送段码//********************控制灯的状态********************************* P2=dxdeng [dxjishu] | nbdeng [nbjishu]; //送灯的状态码//东西方向状态和南北方向状态组合输出//********************产生1秒记时及处理程序*********************** jishu2++; //10ms 计数if (jishu2==100) //计够100次为1秒{jishu2=0; //计够1秒后,计数归0dxmiao --; nbmiao --; //东西,南北秒各减1,实现倒计时if (dxmiao==0xff) //东西方向是否减到0{dxjishu ++ ; //是,指东西方向交通灯的下一个状态if (dxjishu==3) dxjishu==0; //完成三个状态后再重新开始dxmiao=dongxi [dxjishu]; //送东西方向数码显示的初值}if (nanbei==0xff) //南北方向是否减到0}nbjishu++; //是,指向南北方向交通灯的下一个状态if (nbjishu==3) nbjishu=0; //完成三个状态后再重新开始nbmiao==nanbei[nbjishu]; //送南北方向数码显示的初值 }}}。
Proteus仿真原理图:Keil C源程序:#include<reg51.h>#define uchar unsigned char#define uint unsigned intsbit RED_DONGXI = P1^0;//南北方向红灯亮sbit YELLOW_DONGXI = P1^1;//南北方向黄灯亮sbit RED_NANBEI = P1^3;//东西方向红灯亮sbit GREEN_DONGXI = P1^2;//南北方向绿灯亮sbit YELLOW_NANBEI = P1^4;//东西方向黄灯亮sbit GREEN_NANBEI = P1^5;//东西方向绿灯亮sbit DXweixuan1 = P1^6;//南北方向数码管位选1sbit DXweixuan2 = P1^7;//南北方向数码管位选2sbit NBweixuan1 = P3^0;//东西方向数码管位选1sbit NBweixuan2 = P3^1;//东西方向数码管位选2sbit L1=P3^5;sbit L2=P3^6;sbit L3=P3^7;uint aa, bai,shi,ge,bb;uint shi1,ge1,shi2,ge2;uint code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; uint code table1[]={0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xfe,0xf6};void delay(uint z);void init(uint a);void display(uint shi1,uint ge1,uint shi2,uint ge2);void xtimer0();void init1();void init2();void init3();void init4();void init5();void xint1();void xint0();void LED_ON();void LED_OFF();void main(){P0=0xFF;P1=0xFF;P2=0x00;P3=0xFF;EA=1;EX0=1;IT0=0;init1();while(1){init2();//第2个状态init3(); //第3个状态init4(); //第4个状态init5();//第5个状态}}void init1()//第一个状态:东西、南北方向均亮红灯5S {uint temp;temp=5;TMOD=0x01;TH0=(65535-50000)/256;TL0=(65535-50000)%256;EA=1;ET0=1;TR0=1;while(1){RED_DONGXI=0; //第一个状态东西、南北均亮红灯5SRED_NANBEI=0;GREEN_DONGXI=1;GREEN_NANBEI=1;YELLOW_DONGXI=1;YELLOW_NANBEI=1;if(aa==20)//定时20*50MS=1S{aa=0;temp--;}shi1=shi2=temp/10;ge1=ge2=temp%10;if(temp==0){temp=5;break;}display(ge1,shi1,ge2,shi2);}}void init2()//第二个状态:东西亮红灯30S~5S、南北亮绿灯25~0S;{uint temp;temp=26;TMOD=0x01;TH0=(65535-50000)/256;TL0=(65535-50000)%256;EA=1;ET0=1;TR0=1;while(1){RED_DONGXI=1;RED_NANBEI=0;GREEN_DONGXI=0;GREEN_NANBEI=1;YELLOW_DONGXI=1;//第二个状态:东西亮绿灯25S、南北亮红灯YELLOW_NANBEI=1;if(aa==20)//定时20*50MS=1S{aa=0;temp--;shi1=(temp+5)/10;ge1=(temp+5)%10;shi2=temp/10;ge2=temp%10;if(temp==0){temp=26;break;}}display(ge1,shi1,ge2,shi2);}}void init3() //第三个状态:东西绿灯变为黄灯闪5次、南北亮红灯5S {uint temp;temp=6;TMOD=0x01;TH0=(65535-50000)/256;TL0=(65535-50000)%256;EA=1;ET0=1;TR0=1;while(1){RED_NANBEI=0;GREEN_DONGXI=1;if(aa==20)//定时20*50MS=1S{aa=0;temp--;YELLOW_DONGXI=~YELLOW_DONGXI;shi1=temp/10;shi2=shi1;ge1=temp%10;ge2=ge1;}if(temp==0){temp=6;break;}display(ge1,shi1,ge2,shi2);}}void init4()//第四个状态:东西亮绿灯25~0S,南北方向亮红灯30~5S;{uint temp;temp=26;TMOD=0x01;TH0=(65535-50000)/256;TL0=(65535-50000)%256;EA=1;ET0=1;TR0=1;while(1){RED_DONGXI=0;RED_NANBEI=1;YELLOW_DONGXI=1;//第一个状态东西、南北均亮红灯5SGREEN_NANBEI=0;if(aa==20){aa=0;temp--;shi1=temp/10;shi2=(temp+5)/10;ge1=temp%10;ge2=(temp+5)%10;if(temp==0){temp=26;break;}}display(ge1,shi1,ge2,shi2);}}void init5()//第五个状态:东西亮红灯、南北绿灯闪5次转亮黄灯5S {uint temp;temp=6;TMOD=0x01;TH0=(65535-50000)/256;TL0=(65535-50000)%256;EA=1;ET0=1;TR0=1;while(1){RED_NANBEI=1;RED_DONGXI=0;GREEN_DONGXI=1;GREEN_NANBEI=1;if(aa==20){aa=0;temp--;YELLOW_NANBEI=~YELLOW_NANBEI;shi1=temp/10;shi2=shi2;ge1=temp%10;ge2=ge1;if(temp==0){temp=6;break;}}display(ge1,shi1,ge2,shi2);}}void display(uint shi1,uint ge1,uint shi2,uint ge2) {DXweixuan1=0;DXweixuan2=1;NBweixuan1=1;NBweixuan2=1;P0=table[ge1];delay(5);DXweixuan1=1;DXweixuan2=0;NBweixuan1=1;NBweixuan2=1;P0=table[shi1];delay(5);DXweixuan1=1;DXweixuan2=1;NBweixuan1=0;NBweixuan2=1;P0=table[ge2];delay(5);DXweixuan1=1;DXweixuan2=1;NBweixuan1=1;NBweixuan2=0;P0=table[shi2];delay(5);}void xint0() interrupt 0 {RED_NANBEI=0;RED_DONGXI=0;GREEN_NANBEI=1;GREEN_DONGXI=1;YELLOW_NANBEI=1;YELLOW_DONGXI=1;P0=0x00;NBweixuan1=0;NBweixuan2=0;DXweixuan1=0;DXweixuan2=0;delay(2);return ;}void xint1() interrupt 2 {RED_NANBEI=1;RED_DONGXI=1;GREEN_NANBEI=0;GREEN_DONGXI=0;YELLOW_NANBEI=1;YELLOW_DONGXI=1;P0=0x00;NBweixuan1=0;NBweixuan2=0;DXweixuan1=0;DXweixuan2=0;delay(2);return ;}void xtimer0() interrupt 1 {TH0=(65535-50000)/256;TL0=(65535-50000)%256;aa++;}void delay(uint z){uint x,y;for(x=0;x<z;x++)for(y=0;y<110;y++); }。
#include<reg52.h>#define uchar unsigned char#define uint unsigned intsbit led1=P2^0;sbit led2=P2^1;uchar gc10ms,gcCount10ms,Sec;void disp(uchar nsecondsleft);delay(uchar t){uchar i=0;for(i=0;i<142;i++);}void main(void){uchar flicker=0;IE=0x82;TMOD=0x01;TL0=0x78;TH0=0xec;TR0=1;while(1){/********状态1******/Sec=10; //倒计时30SP3=0x7e; //东西绿灯亮,南北红灯亮while(Sec>0); //3S倒计时结束标志/*******状态2*****/P3=0xbe; // 东西黄灯亮,南北红灯闪烁Sec=5; //倒计时5Swhile(Sec>0); //5S倒计时结束标志for(flicker=0;flicker<5;flicker++){gcCount10ms=0;while(gcCount10ms<50);// WR=~WR;RXD=~RXD; //红灯闪烁}/*******状态3*******/P3=0xcf; //东西红灯亮,南北绿灯亮Sec=20; //倒计时20Swhile(Sec>0); //20S倒计时结束标志/********状态4******/P3=0xdd; //东西红灯闪烁,南北黄灯亮Sec=5; //倒计时5Swhile(Sec>0); //5S倒计时结束标志for(flicker=0;flicker<5;flicker++){gcCount10ms=0;while(gcCount10ms<50);// TXD=~TXD;T1=~T1; //红灯闪烁}}}void Timer_0(void) interrupt 1 using 1{uchar uctemp;TL0=0x78;TH0=0xec;if(INT0!=0){gcCount10ms++;gc10ms++;if(gc10ms>=100){gc10ms=0;Sec--;}disp(Sec);return;}TR0=0; //紧急按键按下uctemp=P3;P3=0xde;while(INT1==1){disp(88);}P3=uctemp;TR0=1;}void disp(uchar nsecondsleft){const uchar asegcodetable[]={0xc0,0xf9,0xa4, 0xb0,0x99,0x92,0x82,0xf8,0x80, 0x90,0x88 //共阳数码管编码// 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00 //共阴数码管};uint i=0;P1=asegcodetable[nsecondsleft/10];led1=1;delay();led1=0;P1=asegcodetable[nsecondsleft%10];led2=1;delay();led2=0;}。
交通灯C程序及PROTUES仿真#include<reg51.h>//头文件#include<intrins.h>//头文件#define uchar unsigned char//宏定义#define uint unsigned int//宏定义sbit RED_ZHU = P0^0;sbit YELLOW_ZHU = P0^2;sbit GREEN_ZHU = P0^1;sbit RED_ZHI = P0^3;sbit YELLOW_ZHI = P0^5;sbit GREEN_ZHI = P0^4;uint aa, bai,shi,ge,bb; //定义变量/*数码管显示0-9*/uint code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; /*子函数声明*/void delay(uint z);void delay0(uint z);//void init(uint a);void display(uint ge,uint shi);void xtimer0();void init1();void init2();void init3();void init4();void init5();void xint1();void xint0();void LED_ON();void LED_OFF();/**********************主函数************************/void main(){P0=0X00;P1=0x00;P2=0x00;EA=1;//打开外部中断EX1=1;//允许外部中断1中断IT1=0;//INT0为沿触发方式init1();while(1){init2();//第2个状态init3(); //第3个状态init4(); //第4个状态init5();//第5个状态}}void init1()//第一个状态:主干道、支干道均亮红灯5S{uint temp;temp=6;//变量赋初值TMOD=0x01;//定时器0工作于方式1TH0=0x4c;TL0=0x00;//定时器赋初值EA=1;//开外部中断ET0=1;//开定时中断TR0=1;//开定时器0while(1){RED_ZHU=1; //第一个状态主干道、支干道均亮红灯5SRED_ZHI=0;GREEN_ZHU=1;GREEN_ZHI=1;YELLOW_ZHI=1;if(aa==20)//定时20*50MS=1S{aa=0;//定时完成一次后清0temp--;//变量自增YELLOW_ZHU=~YELLOW_ZHU;//delay(10);if(temp>250)//定时100mS{temp=6;//变量清0break;}shi=temp%100/10;//显示十位ge=temp%10;//显示个位}display(ge,shi);}}void init2()//第二个状态:主干道亮绿灯30S、支干道亮红灯{uint temp;temp=26;//变量赋初值TMOD=0x01;//定时器0工作于方式1TH0=0x4c;TL0=0x00;//定时器赋初值EA=1;//开外部中断ET0=1;//开定时中断TR0=1;//开定时器0while(1){RED_ZHU=1;RED_ZHI=0;GREEN_ZHU=0;GREEN_ZHI=1;YELLOW_ZHU=1;//第二个状态:主干道亮绿灯30S、支干道亮红灯YELLOW_ZHI=1;if(aa==20)//定时20*50MS=1S{aa=0;//定时完成一次后清0temp--;//变量自增if(temp==5)//定时100S{temp=30;//变量清0break;}shi=temp%100/10;//显示十位ge=temp%10;//显示个位}display(ge,shi);}}void init3() //第三个状态:{uint temp;temp=6;//变量赋初值TMOD=0x01;//定时器0工作于方式1TH0=0x4c;TL0=0x00;//定时器赋初值EA=1;//开外部中断ET0=1;//开定时中断TR0=1;//开定时器0while(1){RED_ZHI=0;GREEN_ZHU=1;if(aa==20)//定时20*50MS=1S{aa=0;//定时完成一次后清0temp--;//变量自增YELLOW_ZHU=~YELLOW_ZHU;if(temp>200)//定时100S{temp=6;//变量清0break;}shi=temp%100/10;//显示十位ge=temp%10;//显示个位}display(ge,shi);;}}void init4()//第四个状态:主干道亮红灯、支干道亮绿灯25S {uint temp;temp=26;//变量赋初值TMOD=0x01;//定时器0工作于方式1TH0=0x4c;TL0=0x00;//定时器赋初值EA=1;//开外部中断ET0=1;//开定时中断TR0=1;//开定时器0while(1){RED_ZHU=0;RED_ZHI=1;YELLOW_ZHU=1;YELLOW_ZHI=1;GREEN_ZHU=1;GREEN_ZHI=0;if(aa==20)//定时20*50MS=1S{aa=0;//定时完成一次后清0temp--;//变量自增if(temp==5)//定时100S{temp=25;//变量清0break;}shi=temp%100/10;//显示十位ge=temp%10;//显示个位}display(ge,shi);}}void init5()//第五个状态:{uint temp;temp=6;//变量赋初值TMOD=0x01;//定时器0工作于方式1TH0=0x4c;TL0=0x00;//定时器赋初值EA=1;//开外部中断ET0=1;//开定时中断TR0=1;//开定时器0while(1){RED_ZHI=1;RED_ZHU=0;GREEN_ZHU=1;GREEN_ZHI=1;if(aa==20)//定时20*50MS=1S{aa=0;//定时完成一次后清0temp--;//变量自增YELLOW_ZHI=~YELLOW_ZHI;if(temp>250)//定时100S{temp=6;//变量清0break;}shi=temp%100/10;//显示十位ge=temp%10;//显示个位}display(ge,shi);}}/*显示子函数*/void display(uint ge,uint shi){P2=0x02;P1=table[shi];//显示十位delay0(5);P2=0x01;P1=table[ge];//显示个位delay0(5);}void xint0() interrupt 2 //外部中断1,这里用2是INT1的优先级为0 {LED_ON();}void LED_ON()//外部中断0显示子程序{RED_ZHI=0;RED_ZHU=0;GREEN_ZHI=1;GREEN_ZHU=1;YELLOW_ZHI=1;YELLOW_ZHU=1;delay0(1000);return ;}/*定时中断子函数*/void xtimer0() interrupt 1{TH0=0x4c;TL0=0x00;aa++;}/*延时子函数*/void delay0(uint z){uint i,j;for(i=0;i<z;i++)for(j=0;j<110;j++);}/******** 500ms延时函数晶振:12MHz *******/void delay( uint j){uint k;uint i;while(j){i=1250; while(i){k=180;while(k){k--;};i--;}j--;}}。
#include <reg51.h>#define uchar unsigned char#define uint unsigned intuchar data buf[4];uchar data sec_dx=20; //东西数默认uchar data sec_nb=30; //南北默认值uchar data set_timedx=20; //设置东西方向的时间uchar data set_timenb=30; //设置南北方向的时间int n;uchar data countt0;//定时器0中断次数//定义5组开关sbit k4=P3^7; //切换方向sbit k1=P3^5; //时间加sbit k2=P3^6; //时间减sbit k3=P3^4; //确认sbit k5=P3^1; //禁止// P3^2 //只允许东西方向通行,中断0// P3^3 //只允许南北方向通行,中断1sbit Red_nb=P2^6; //南北红灯标志sbit Yellow_nb=P2^5; //南北黄灯标志sbit Green_nb=P2^4; //南北绿灯标志sbit Red_dx=P2^3; //东西红灯标志sbit Yellow_dx=P2^2; //东西黄灯标志sbit Green_dx=P2^1; //东西绿灯标志sbit Buzz=P3^0;bit Buzzer_Indicate;bit set=0; //调时方向切换键标志=1时,南北,=0时,东西bit dx_nb=0; //东西南北控制位bit shanruo=0;uchar code table[11]={ //共阴极字型码0x3f, //--00x06, //--10x5b, //--20x4f, //--30x66, //--40x6d, //--50x7d, //--60x07, //--70x7f, //--80x6f, //--90x00 //--NULL};//函数的声明部分void delay(int ms); //延时子程序void key(); //按键扫描子程序void key_to1(); //键处理子程序void key_to2();void key_to3();void display(); //显示子程序void logo(); //开机LOGOvoid Buzzer();//主程序void main(){TMOD=0X11; //定时器设置TH0=0X3C; //定时器0置初值0.05STL0=0XB0;EA=1; //开总中断ET0=1; //定时器0中断开启TR0=1; //启动定时0EX0=1; //开外部中断0EX1=1; //开外部中断1logo();P2=0Xc3; // 开始默认状态,东西绿灯,南北黄灯sec_nb=sec_dx+5; //默认南北通行时间比东西多5秒while(1){key(); //调用按键扫描程序display(); //调用显示程序Buzzer();}}//函数的定义部分void key(void) //按键扫描子程序{if(k1!=1) //当K1(时间加)按下时{display(); //调用显示,用于延时消抖if(k1!=1){TR0=0; //关定时器shanruo=0;P2=0x00;if(set==0)set_timedx++; //南北加1Selseset_timenb++; //东西加1Sif(set_timenb==100)set_timenb=1;if( set_timedx==100)set_timedx=1; //加到100置1sec_nb=set_timenb ; //设置的数值赋给东西南北sec_dx=set_timedx; //do{display();}while(k1!=1);}}if(k2!=1) //当K2(时间减)按键按下时{display(); //调用显示,用于延时消抖if(k2!=1){TR0=0; //关定时器shanruo=0;P2=0x00;if(set==0)set_timedx--; //南北减1Selseset_timenb--; //东西减1Sif(set_timenb==0)set_timenb=99;if( set_timedx==0 )set_timedx=99; //减到1重置99sec_nb=set_timenb ; //设置的数值赋给东西南北sec_dx=set_timedx;do{display(); //调用显示,用于延时}while(k2!=1);}}if(k3!=1) //当K3(确认)键按下时{display(); //调用显示,用于延时消抖if(k3!=1){TR0=1; //启动定时器Buzzer_Indicate=0;sec_nb=set_timenb; //从中断回复,仍显示设置过的数值sec_dx=set_timedx; //显示设置过的时间if(set==0) //时间倒时到0时{P2=0X00; //东西绿灯,南北红灯Green_dx=1;Red_nb=1;sec_nb=sec_dx+5; //回到初值}else{P2=0x00; //南北绿灯,东西红灯Green_nb=1;Red_dx=1;sec_dx=sec_nb+5;}}}if(k4!=1) //当K4(切换)键按下{display(); //调用显示,用于延时消抖if(k4!=1){TR0=0;set=!set; //取反set标志位,以切换调节方向dx_nb=set;do{display();}while(k4!=1);}}if(k5!=1) //当K5(禁止)键按下时{display(); //调用显示,用于延时消抖if(k5!=1){TR0=0; //关定时器P2=0x00;Red_dx=1;Red_nb=1; //全部置红灯sec_dx=00; //四个方向的时间都为00sec_nb=00;Buzzer_Indicate=1;do{display();}while(k5!=1);}}}void display(void) //显示子程序{buf[1]=sec_nb/10; //第1位东西秒十位buf[2]=sec_nb%10; //第2位东西秒个位buf[3]=sec_dx/10; //第3位南北秒十位buf[0]=sec_dx%10; //第4位南北秒个位P1=0xff; // 初始灯为灭的P0=0x00;P1=0xfe; //片选LED1P0=table[buf[1]]; //送东西时间十位的数码管编码delay(1); //延时P1=0xff; //关显示P0=0x00;P1=0xfd; //片选LED2P0=table[buf[2]];delay(1);P1=0xff;P0=0x00;P1=0Xfb; //片选LED3P0=table[buf[3]];delay(1);P1=0xff;P0=0x00;P1=0Xf7;P0=table[buf[0]]; //片选LED4delay(1);}void time0(void) interrupt 1 using 1 //定时中断子程序{TH0=0X3C; //重赋初值TL0=0XB0;TR0=1; //重新启动定时器countt0++; //软件计数加1if(countt0==10){if((sec_nb<=5)&&(dx_nb==0)&&(shanruo==1)) //东西黄灯闪{Green_dx=0;Yellow_dx=0;}if((sec_dx<=5)&&(dx_nb==1)&&(shanruo==1)) //南北黄灯闪{Green_nb=0;Yellow_nb=0;}}if(countt0==20) // 定时器中断次数=20时(即1秒时){ countt0=0; //清零计数器sec_dx--; //东西时间减1sec_nb--; //南北时间减1if((sec_nb<=5)&&(dx_nb==0)&&(shanruo==1)) //东西黄灯闪{Green_dx=0;Yellow_dx=1;}if((sec_dx<=5)&&(dx_nb==1)&&(shanruo==1)) //南北黄灯闪{Green_nb=0;Yellow_nb=1;}if(sec_dx==0&&sec_nb==5) //当东西倒计时到0时,重置5秒,用于黄灯闪烁时间{sec_dx=5;shanruo=1;}if(sec_nb==0&&sec_dx==5) //当南北倒计时到0时,重置5秒,用于黄灯闪烁时间{sec_nb=5;shanruo=1;}if(dx_nb==0&&sec_nb==0) //当黄灯闪烁时间倒计时到0时,{P2=0x00; //重置东西南背方向的红绿灯Green_nb=1;Red_dx=1;dx_nb=!dx_nb;shanruo=0;sec_nb=set_timenb; //重赋南北方向的起始值sec_dx=set_timenb+5; //重赋东西方向的起始值}if(dx_nb==1&&sec_dx==0) //当黄灯闪烁时间到{P2=0X00; //重置东西南北的红绿灯状态Green_dx=1;Red_nb=1;dx_nb=!dx_nb;shanruo=0;sec_dx=set_timedx; //重赋东西方向的起始值sec_nb=set_timedx+5; //重赋南北方向的起始值}}}//外部中断0void int0(void) interrupt 0 using 1 //只允许东西通行{TR0=0; //关定时器P2=0x00;Green_dx=1; //东西方向置绿灯Red_nb=1; //南北方向为红灯Buzzer_Indicate=0;sec_dx=00; //四个方向的时间都为00sec_nb=00;}//外部中断1void int1(void) interrupt 2 using 1 //只允许南北通行{TR0=0; //关定时器P2=0x00;Green_nb=1; //置南北方向为绿灯Red_dx=1; //东西方向为红灯Buzzer_Indicate=0;sec_nb=00; //四个方向的时间都为00 sec_dx=00;}void logo()//开机的Logo "- - - -"{for(n=0;n<50;n++){P0=0x40;P1=0xfe;delay(1);P1=0xfd;delay(1);P1=0Xfb;delay(1);P1=0Xf7;delay(1);P1 = 0xff;}}void Buzzer(){if(Buzzer_Indicate==1)Buzz=!Buzz;else Buzz=1;}void delay(int ms) //延时子程序{uint j,k;for(j=0;j<ms;j++) //延时msfor(k=0;k<124;k++); //大约1毫秒的延时}。
/****************************************************************************** ** 实验名: 动态显示数码管实验* 使用的IO :* 实验效果: 数码管显示76543210。
* 注意:当位选用P1口的时候注意可能会有一位不亮,那么调整J21******************************************************************************* /#include<reg51.h>//--定义使用的IO口--//#define GPIO_DIG P0#define GPIO_PLACE P1#define GPIO_TRAFFIC P2sbit RED10 = P2^0; //上人行道红灯sbit GREEN10 = P2^1; //上人行道绿灯sbit RED11 = P2^2;sbit YELLOW11= P2^3;sbit GREEN11 = P2^4;sbit RED00 = P3^0; //右人行道红灯sbit GREEN00 = P3^1; //右人行道绿灯sbit RED01 = P2^5;sbit YELLOW01= P2^6;sbit GREEN01 = P2^7;//--定义全局变量--//unsigned char code DIG_PLACE[8] = {0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//位选控制查表的方法控制unsigned char code DIG_CODE[17] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//0、1、2、3、4、5、6、7、8、9、A、b、C、d、E、F的显示码unsigned char DisplayData[8];//用来存放要显示的8位数的值unsigned char Time, Second; //用来存放定时时间//--声明全局函数--//void DigDisplay(); //动态显示函数void Timer0Cofig(void);/****************************************************************************** ** 函数名: main* 函数功能: 主函数* 输入: 无* 输出: 无******************************************************************************* /void main(void){Second = 1;Timer0Cofig();while(1){if(Second == 70){Second = 1;}//--宝田路通行,30秒--//if(Second < 31){DisplayData[0] = 0x00;DisplayData[1] = 0x00;DisplayData[2] = DIG_CODE[(30 - Second) % 100 / 10];DisplayData[3] = DIG_CODE[(30 - Second) %10];DisplayData[4] = 0x00;DisplayData[5] = 0x00;DisplayData[6] = DisplayData[2];DisplayData[7] = DisplayData[3];DigDisplay();//--宝田路通行--//GPIO_TRAFFIC = 0xFF; //将所有的灯熄灭RED00 = 1;GREEN00 = 1;GREEN11 = 0; //宝田路绿灯亮GREEN10 = 0; //宝田路人行道绿灯亮RED01 = 0; //前进路红灯亮RED00 = 0; //前进路人行道红灯亮}//--黄灯等待切换状态,5秒--//else if(Second < 36){DisplayData[0] = 0x00;DisplayData[1] = 0x00;DisplayData[2] = DIG_CODE[(35 - Second) % 100 / 10];DisplayData[3] = DIG_CODE[(35 - Second) %10];DisplayData[4] = 0x00;DisplayData[5] = 0x00;DisplayData[6] = DisplayData[2];DisplayData[7] = DisplayData[3];DigDisplay();//--黄灯阶段--//GPIO_TRAFFIC = 0xFF; //将所有的灯熄灭RED00 = 1;GREEN00 = 1;YELLOW11 = 0; //宝田路黄灯亮RED10 = 0; //宝田路人行道红灯亮YELLOW01 = 0; //前进路红灯亮RED00 = 0; //前进路人行道红灯亮}//--前进路通行--//else if(Second < 66){DisplayData[0] = 0x00;DisplayData[1] = 0x00;DisplayData[2] = DIG_CODE[(65 - Second) % 100 / 10];DisplayData[3] = DIG_CODE[(65 - Second) %10];DisplayData[4] = 0x00;DisplayData[5] = 0x00;DisplayData[6] = DisplayData[2];DisplayData[7] = DisplayData[3];DigDisplay();//--黄灯阶段--//GPIO_TRAFFIC = 0xFF; //将所有的灯熄灭RED00 = 1;GREEN00 = 1;RED11 = 0; //宝田路红灯亮RED10 = 0; //宝田路人行道红灯亮GREEN01 = 0; //前进路绿灯亮GREEN00 = 0; //前进路人行道绿灯亮}//--黄灯等待切换状态,5秒--//else{DisplayData[0] = 0x00;DisplayData[1] = 0x00;DisplayData[2] = DIG_CODE[(70 - Second) % 100 / 10];DisplayData[3] = DIG_CODE[(70 - Second) %10];DisplayData[4] = 0x00;DisplayData[5] = 0x00;DisplayData[6] = DisplayData[2];DisplayData[7] = DisplayData[3];DigDisplay();//--黄灯阶段--//GPIO_TRAFFIC = 0xFF; //将所有的灯熄灭RED00 = 1;GREEN00 = 1;YELLOW11 = 0; //宝田路黄灯亮RED10 = 0; //宝田路人行道红灯亮YELLOW01 = 0; //前进路红灯亮RED00 = 0; //前进路人行道红灯亮}}}/****************************************************************************** ** 函数名: DigDisplay* 输入: 无* 输出: 无******************************************************************************* /void DigDisplay(){unsigned char i;unsigned int j;for(i=0; i<8; i++){GPIO_PLACE = DIG_PLACE[i]; //发送位选GPIO_DIG = DisplayData[i]; //发送段码j = 10; //扫描间隔时间设定while(j--);GPIO_DIG = 0x00; //消隐}}/****************************************************************************** ** 函数名: Timer0Cofig* 函数功能: 配置定时器* 输入: 无* 输出: 无******************************************************************************* /void Timer0Cofig(void){TMOD = 0x01; //定时器0选择工作方式1TH0 = 0x3C; //设置初始值,定时50MSTL0 = 0xB0;EA = 1; //打开总中断ET0 = 1; //打开定时器0中断TR0 = 1; //启动定时器0}/****************************************************************************** ** 函数名: Timer0* 输入: 无* 输出: 无******************************************************************************* /void Timer0() interrupt 1{TH0 = 0x3C; //设置初始值TL0 = 0xB0;Time++;if(Time == 20){Second ++;Time = 0;}}。