51单片机 交通灯,有仿真效果 程序带注释
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
单片机源程序如下:
- #include<reg52.h> // 对单片机的口进行了定义
- #define uint unsigned int
- #define uchar unsigned char
- uchar code a[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //段码组合,共阴极数码管
- uchar code c[4]={0x30,0x28,0x84,0x44}; /*P1 绿红、黄红、红绿、红黄*/
-
- //12MHz
- //*************************************************************************************
- uchar NB=25,DX=30,NBG=25,DXG=15,H=5; /*数码管显示值设置*/
- uchar i,k=0,cnt=0,j=0;
- sbit K0=P3^0; /*主干道通行*/
- sbit K1=P3^1; /*次干道通行*/
- sbit K2=P3^2; /*中断设置时间加减*/
- sbit K3=P3^3; /*紧急情况控制*/
- sbit K4=P3^5; /*南北时间加*/
- sbit K5=P3^6; /*东西时间加*/
- sbit K6=P3^7; /*设置完成,返回*/
- void delay(uchar t); /*定义延时程序*/
- void key(); /*定义键盘程序*/
- void display(); /*定义显示程序*/
- void settime(); /*定义时间设置显示程序*/
- //*************************程序初始*********************************************
- void init(void)
- {
- TMOD=0x01; /*使用定时器0模式1*/
- TH0=0x3c; /*(65536-5000)/256*/
- TL0=0xb0; /*(65536-5000)%256*/
- IT0=1; //开中断
- ET0=1;
- TR0=1;
- EA=1;
- EX0=1;
- EX1=1;
- P1=c[k]; //开启交通灯
- }
- //*************************外部中断0处理程序***************************************
- void int0(void) interrupt 0 // 通行时间设置
- {
- EA=0;
- P1=0x90; /*红灯全亮*/
-
- while(1)
- {
- settime();
- if(K4==0) /*P3^6=0设置主干道通行时间*/
- {
- delay(40);
- if(K4==0)
- {
- while(!K4)
- {
- settime();
- }
- NBG++; /*主干道通行时间加1*/
- if(NBG==100)
- NBG=0;
- }
- }
-
- if(K5==0) /*P3^5=0设置支干道通行时间*/
- {
- delay(40);
- if(K5==0)
- {
- while(!K5)
- {
- settime();
- }
- DXG++; /*支干道通行时间加1*/
- if(DXG==100)
- DXG=0;
- }
- }
-
- if(K6==0) /*P3^7=0返回*/
- {
- delay(40);
- if(K6==0)
- {
- while(!K6)
- {
- }
- k=0;P1=c[k];
- NB=NBG,DX=NBG+H;
- display();
- EA=1;
- break;
- }
- }
- }
- }
-
- /***********************************中断1处理程序********************/
- void int1(void) interrupt 2 //紧急情况
- {
- /*东西南北红灯亮*/
- EA=0;
- TR0=!TR0; /*停止计数*/
- while(1) /*主支干道显示全为0*/
- {
- P1=0x90,P0=a[0];
- P2=0xfe;
- delay(20);
-
- P2=0xfd;
- delay(20);
- P2=0xfb;
- delay(20);
- P2=0xf7;
- delay(20);
-
- if(K6==0) /*P3^7=0返回*/
- {
- delay(40);
- if(K6==0)
- {
- while(!K6)
- {
- }
-
- EA=1;
- P1=c[k]; /*返回紧急前状态开始计数*/
- TR0=!TR0; /*重启计数*/
- break;
- }
- }
- }
- }
- void time1(void) interrupt 1 /*交通灯控制程序*/
- {
- TH0=0x3c; /*定时50ms*/
- TL0=0xb0;
- cnt++;
-
- if(cnt==20) /*每20*50ms=1s自减一*/
- {
- NB--;
- DX--;
- cnt=0;
- if(NB==0||DX==0)
- {
- k++;
- if(k>3) /*k取0,1,2,3*/
- k=0;
- switch(k)
- {
- case 0:NB=NBG,DX=NBG+H;j=0;P1=c[k];break; /*主干道通行显示绿红*/
- case 1:NB=H;j=1;P1=c[k];break; /*主干道黄灯闪烁*/
- case 2:NB=DXG+H,DX=DXG;j=0;P1=c[k];break; /*支干道通行显示红绿*/
- case 3:DX=H;j=2;P1=c[k];break; /*支干道黄灯闪烁*/
- }
- }
- }
- }
- void delay(uchar t) //延时程序延时0.1*nms
- {
- uchar i;
- do
- {
- for(i=0;i<20;i++);;;
- }
- while(t--);
- }
-
- void settime()
- {
- P2=0xfe,P0=a[(NBG+H)/10]; /*显示主干道通行时间 */
- delay(20);
-
- P2=0xfd,P0=a[(NBG+H)%10];
- delay(20);
-
- P2=0xfb,P0=a[(DXG+H)/10]; /*显示支干道通行时间*/
- delay(20);
-
- P2=0xf7,P0=a[(DXG+H)%10];
- delay(20);
- }
- void key() //键盘程序用KO K1模拟一道有车一道无车
- {
- if(K0==0) /*主干道有车支干道无车*/
- {
- delay(40);
- if(K0==0)
- {
- while(!K0)
- {
- display();
- }
- k=0,P1=c[k];cnt=0;
- NB=NBG, DX=NBG+H;
- display();
- }
- }
- if(K1==0) /*支干道有车主干道无车*/
- {
- delay(40);
- if(K1==0)
- {
- while(!K1)
- {
- display();
- }
- k=2,P1=c[k];cnt=0;
- NB=DXG+H,DX=DXG;
- display();
- }
- }
- }
- void display() //显示程序
- {
- P2=0xfe,P0=a[NB/10]; /*由k的不同值进入确定显示数值*/
- delay(20);
-
- P2=0xfd,P0=a[NB%10];
- delay(20);
-
- P2=0xfb,P0=a[DX/10];
- delay(20);
-
- P2=0xf7,P0=a[DX%10];
- delay(20);
- }
- void main(void)
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
交通灯【参考程序】.rar
(72.64 KB, 下载次数: 100)
|