软件的设计
首先我们先把C语言头文件引入,然后定义常量uchar,uint:
#include<reg51.h>
#define uchar unsigned char
#define uint unsigned int
完了以后我们把数码管段选号定义好:
uchar shuzi[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //共阳无小数点
我们把单片机各个引脚位定义:
/**************************P1控制LED灯是否亮************************/
sbit ew_red=P1^2; //东西红灯,低电平亮
sbit ew_yellow=P1^3;
sbit ew_green=P1^4;
sbit sn_red=P1^5;
sbit sn_yellow=P1^6;
sbit sn_green=P1^7;
/*****************************p0口控制段码****************************/
sbit P0_0=P0^0;
sbit P0_1=P0^1;
sbit P0_2=P0^2;
sbit P0_3=P0^3;
sbit P0_4=P0^4;
sbit P0_5=P0^5;
sbit P0_6=P0^6;
/*****************************控制数码管位码*****************************/
sbit P2_0=P2^0; //p2_0,p2_1控制东西灯位码
sbit P2_1=P2^1;
sbit P2_2=P2^2; //p2_2,p2_3控制南北灯位码
sbit P2_3=P2^3;
/*********************************按键******************************/
sbit P3_2=P3^2; //东西通行按键
sbit P3_3=P3^3; //南北通行按键
sbit P3_4=P3^4; //全部禁止按键
sbit sn_reduce=P3^5;
sbit ew_reduce=P3^6;
后续代码我们用到一些变量先定义好:
int ewadd=0;
int ewreduce=0;
int snadd=0;
int snreduce=0;
int s=0,n=0;
中断函数,产生1秒
void time(void) interrupt 1 //中断,产生1s
{
TH0=(65536-50000)/256; //0.05s=50ms
TL0=(65536-50000)%256;
n++;
if(n==20)
{n=0;
s++;}
if(s==50)
s=0;
}
东西方向通过(绿灯)南北方向等待(红灯)
void ew_allow() //东西绿灯南北红灯
{
ew_yellow=1;
ew_green=0; //低电平亮
sn_red=0;
sn_yellow=1;
sn_green=1;
}
东西方向等待(绿灯)南北方向通过(红灯)
void sn_allow() //东西红灯南北绿灯
{
ew_yellow=1;
ew_green=1;
sn_red=1;
sn_yellow=1;
sn_green=0;
}
东西黄灯南北红灯
void ew_wait() //东西黄灯南北红灯
{
ew_yellow=~ew_yellow;
ew_green=1;
sn_red=0;
sn_yellow=1;
sn_green=1;
}
东西红灯南北黄灯
void sn_wait() //东西红灯南北黄灯
{
ew_yellow=1;
ew_green=1;
sn_red=1;
sn_yellow=~sn_yellow;
sn_green=1;
}
延时函数
void delay()
{ int i;
int j;
for(i=0;i<100;i++)
for(j=0;j<10;j++);
}
P2初始化
void chushi() //P2初始化
{
P2_0=0;
P2_1=0;
P2_2=0;
P2_3=0;
}
禁止通行
void jinzhi() //按下禁止按钮后四个方向都禁止(都为红灯) 且时间显示为99
{
chushi();
P0=shuzi[9]; //段码
P2_1=1;
P2_3=1;
delay();
chushi();
P2_2=1;
P2_0=1;
ew_red=0;
ew_yellow=1;
ew_green=1;
sn_red=0;
sn_yellow=1;
sn_green=1;
delay();
}
LED显示函数
void display_led() //led灯显示
{
if(s<=20)
ew_allow(); //东西绿灯南北红灯
else if(s<=25) //5s
ew_wait(); //东西黄灯南北红灯
else if(s<=45)
sn_allow(); //东西红灯南北绿灯
else if(s<=50)
sn_wait();
else
jinzhi();
}
绿灯黄灯的倒计时显示
void display_shuzi1() //绿灯以及黄灯的倒计时显示
{
if(s<=20)
{
chushi();
P0=shuzi[(20-s)/10]; //每100t=5s 十位(0-2)
P2_1=0;
P2_0=1;
delay();
chushi();
P0=shuzi[(20-s)%10]; //个位(0-9) 2次
P2_1=1; //个位
P2_0=0; //十位
delay();
}
else if(s<=25)
{
chushi();
P0=shuzi[(25-s)/10];
P2_1=0;
P2_0=1;
delay();
chushi();
P0=shuzi[(25-s)%10];
P2_1=1;
P2_0=0;
delay();
}
else if(s<=45)
{
chushi();
P0=shuzi[(45-s)/10];
P2_3=0;
P2_2=1;
delay();
chushi();
P0=shuzi[(45-s)%10];
P2_3=1;
P2_2=0;
delay();
}
else if(s<=50)
{
chushi();
P0=shuzi[(50-s)/10];
P2_3=0;
P2_2=1;
delay();
chushi();
P0=shuzi[(50-s)%10];
P2_3=1;
P2_2=0;
delay();
}
else
jinzhi();
}
红灯的倒计时显示
void display_shuzi2() //红灯的倒计时显示
{
if(s<=25)
{
chushi();
P0=shuzi[(25-s)/10];
P2_3=0; //个位
P2_2=1; //南北数码管十位
delay();
chushi();
P0=shuzi[(25-s)%10];
P2_3=1;
P2_2=0;
delay();
}
else if(s<=50)
{
chushi();
P0=shuzi[(50-s)/10];
P2_1=0;
P2_0=1;
delay();
chushi();
P0=shuzi[(50-s)%10];
P2_1=1;
P2_0=0;
delay();
}
else
jinzhi();
}
按键判断函数
void panduan() //按键的判断
{
if(P3_2==0) //按下时切换到东西绿灯刚亮起的时间段
s=1;
if(P3_3==0) //按下时切换到南北绿灯刚亮起的时间段
s=26;
if(P3_4==0) //按下时切换到循环之外的时间段 实现全部禁止(恢复通行需要按下南北通行或东西通行)
s=51;
if(sn_reduce==0)
snreduce=1;
if(sn_reduce==1&&snreduce==1) //按下并弹起减少南北红灯时间3s(东西通行时无效)
{
if(s>=0&&s<20)
s=s+3;
if(s>=20&&s<25)
s=25;
snreduce=0;
}
if(ew_reduce==0)
ewreduce=1;
if(ew_reduce==1&&ewreduce==1) //按下并弹起减少东西通行时间5s(南北通行时无效)
{
if(s>=25&&s<45)
s=s+3;
if(s>=45&&s<50)
s=50;
ewreduce=0;
}
}
最后是主函数
void main()
{
TMOD=0x01;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
EA=1;
ET0=1;
TR0=1;
while(1)
{
display_led();
display_shuzi1();
display_shuzi2();
panduan();
}
}