花了一个星期制作的交通灯仿真程序+原理图,通过数码管显示路口的时间,通过led显示红绿灯。@[TOC]
#include<reg51.H> // 对单片机的口进行了定义
#define uint unsigned int
#define uchar unsigned char
uchar code a[10]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};//段码组合,共阳极
uchar code b[4]={0x01,0x02,0x04,0x08}; //位码组合
uchar code c[4]={0xcc,0xd4,0x78,0xb8};/P1 绿红、黄红、红绿、红黄/
//12MHz
//*************************************************************************************
uchar NB=25,DX=30,NBG=25,DXG=15,H=5; /数码管显示值设置/
uchar i,k=0,cnt=0,j=0;
sbit K0=P3^4; /支干道通行/
sbit K1=P3^5; /主干道通行/
sbit K4=P3^6; /返回/
sbit K3=P3^2; /设置时间/
sbit K2=P3^3; /紧急刹车/
void delay(uchar t); /定义延时程序/
void key(); /定义键盘程序/
void display(); /定义显示程序/
void settime(); /定义时间设置显示程序/
//程序初始********************
void init(void)
{
TMOD=0x01; /使用定时器0模式一/
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=0xd8; /红灯全亮/
for(;?
{
settime();if(K1==0) /*P3^6=0设置主干道通行时间*/{ delay(40);if(K1==0){while(!K1){settime();}DXG++; /*主干道通行时间加1*/if(DXG==100)DXG=0; }}if(K0==0) /*P3^5=0设置支干道通行时间*/{ delay(40);if(K0==0){while(!K0){settime();}NBG++; /*支干道通行时间加1*/if(NBG==100)NBG=0; }}if(K4==0) /*P3^7=0返回*/ { delay(40); if(K4==0){while(!K4){}k=0;P1=c[k];NB=NBG,DX=NBG+H; display(); EA=1;break;} }}
}
//***************中断1处理程序
void int1(void) interrupt 2 //紧急情况
{
/*东西南北红灯亮*/
EA=0;
TR0=!TR0; /停止计数/
for(;? /主支干道显示全为0/
{
P1=0xd8,
P0=a[0];
P2=b[0];delay(20);P2=b[1];delay(20);P2=b[2];delay(20);P2=b[3];delay(20);if(K4==0) /*返回*/
{
delay(20);
EA=1;
P1=c[k]; /返回紧急前状态开始计数/
TR0=!TR0; /重启计数/
break;
}
}
}
void time1(void) interrupt 1 /交通灯控制程序/
{
TH0=0x3c; /定时50ms/
TL0=0xb0;
cnt++;
if(cnt>=20) /每2050ms=1s自减一*/
{
NB–;
DX–;
cnt=0;
if(NB0||DX0)
{
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=b[0],P0=a[(NBG+H)%10]; /*显示主干道通行时间 */delay(20); P2=b[1],P0=a[(NBG+H)/10]; delay(20); P2=b[2],P0=a[(DXG+H)%10]; /*显示支干道通行时间*/delay(20); P2=b[3],P0=a[(DXG+H)/10]; delay(20);
}
void key() //键盘程序用KO K1模拟一道有车一道无车
{
if(K1==0) /*主干道有车支干道无车*/{ delay(40);if(K1==0) { while(!K1){ display();}k=0,P1=c[k];cnt=0;NB=NBG, DX=NBG+H;display();}}if(K0==0) /*支干道有车主干道无车*/{ delay(40);if(K0==0){while(!K0){display(); }k=2,P1=c[k];cnt=0;NB=DXG+H,DX=DXG;display(); }
}
}
void display() //显示程序
{
P2=b[0],P0=a[NB%10]; /由k的不同值进入确定显示数值/
delay(20);
P2=b[1],P0=a[NB/10];
delay(20);
P2=b[2],P0=a[DX%10];
delay(20);
P2=b[3],P0=a[DX/10];
delay(20);
}
void main(void)
{ //主程序
init();
for(;?
{
display();
key();
//黄灯闪烁程序
while(j==1) /主干道黄灯闪烁/
{ P1=0xdc; /*给黄灯一高电平黄灯灭*/ for(i=83;i>0;i--){display();} /*执行for循环延时*/ P1=c[k]; /*再给黄灯一低电平黄灯亮*/for(i=83;i>0;i--){display();}
}
while(j==2)
{ /*支干道黄灯闪烁*/P1=0xf8;for(i=83;i>0;i--){display();}P1=c[k];for(i=83;i>0;i--){display();}
}
}
}