第4讲 交通信号灯

一、 实验说明

实验原理图如下:

第4讲 交通信号灯_第1张图片

器件:7SEG-MPX2-CC-BLUE两位八段共阴数码管,显示为蓝色。还有红黄绿三个LED灯。

其中,P2口的前七位接数码管的7个段选,P3口的前两位接两个位选,P1口的前三位接三个LED灯。

实验的目的是数码管从10开始减到00,然后下一个小灯亮。这里我们不用精确的1秒计时,而是用语句进行一个延时。

二、 编写程序

 检测器件

首先检测一下所有器件是否能正常运行,先这样写源程序:

#include

#define uchar unsigned char //宏定义,用uchar代替unsigned char

#define uint unsigned int

uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};

sbit wei1 = P3^0; //位定义

sbit wei2 = P3^1;

sbit red = P1^0;

sbit yellow = P1^1;

sbit green = P1^2;

void delay();

void main()

{

red = 0; //点亮LED灯

yellow = 0;

green = 0;

while(1)

{

P2 = table[1]; //让数码管动态显示‘10’

wei1 = 0;

delay();

wei1 = 1;

P2 = table[0];

wei2 = 0;

delay();

wei2 = 1;

}

}

void delay()

{

uint i,j;

for(i=5;i>0;i--)

for(j=1;j>0;j--);

}

运行效果如下:

第4讲 交通信号灯_第2张图片

可以看到所有的器件都能正常运行。下面我们就可以开始一点一点写程序了。

 先写倒计时程序。

主函数可改为:

void main()

{

uchar shi,ge; //shi代表第一个数码管显示的字符,ge代表第二个数码管显示的字符

uint time; //用time变量进行延时

shi = 1; //第一个数码管刚开始显示‘1’

ge = 0; //第二个数码管刚开始显示‘0’

time = 5000; //time初始化为5000

red = 0; //刚开始红灯亮

while(1)

{

time--; //time自减

if(time==0) //当time减到0时,说明已经过了大约1秒,数码管应该变化了

{

time = 5000; //time重新赋值,以便再次计时

shi = 0; //第一个数码管显示‘0’

ge = 9; //第二个数码管显示‘9’

}

P2 = table[shi]; //让数码管进行动态显示

wei1 = 0;

delay();

wei1 = 1;

P2 = table[ge];

wei2 = 0;

delay();

wei2 = 1;

}

}

可以看到,我们是用自减语句加if条件判断来实现延时的,因为动态显示要在很短的时间内重复执行那几条语句,所以while(1){}中如果有一个很长时间的延时,那么动态显示的效果就出不来了。

到这里数码管已经能从‘10’变为‘09’了,那怎样才能循环变化呢,我们只需加入几个if判断语句即可。主函数改为如下:

void main()

{

uchar shi,ge;

uint time;

shi = 1;

ge = 0;

time = 5000;

red = 0; //先点亮红灯

while(1)

{

time--;

if(time==0)

{

time = 5000;

if(shi==1) //当第一个数码管为‘1’时,才变化第一个数码管

{

shi = 0;

ge = 9;

}

else ge--; //当第一个数码管不为‘1’时,只让第二个数码管自减

if(ge==0) //当第二个数码管为0时,数码管重新显示‘10’

{

shi = 1;

ge = 0;

}

}

P2 = table[shi];

wei1 = 0;

delay();

wei1 = 1;

P2 = table[ge];

wei2 = 0;

delay();

wei2 = 1;

}

}

这样倒计时程序就写好了。

加入小灯控制语句

倒计时程序写好后,只需要在适当的位置加入小灯控制语句即可。完整的源程序如下:

#include

#define uchar unsigned char

#define uint unsigned int

uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};

sbit wei1 = P3^0;

sbit wei2 = P3^1;

sbit red = P1^0;

sbit yellow = P1^1;

sbit green = P1^2;

void delay();

void main()

{

uchar shi,ge,temp; //加入变量temp,它用来记录哪个灯亮着

uint time;

shi = 1;

ge = 0;

temp=0; //开始temp为0,表示红灯亮着

time = 5000;

red = 0; //先点亮红灯

while(1)

{

time--;

if(time==0)

{

time = 5000;

if(shi==1)

{

shi = 0;

ge = 9;

}

else ge--;

if(ge==0)

{

shi = 1;

ge = 0;

temp++; //每过10秒下一个小灯点亮

if(temp==3) //当temp为3时,让它重新变为0

temp = 0;

}

}

switch(temp) //对temp的不同值进行小灯的亮灭设置

{

case 0: green = 1;red = 0;break; //0表示红灯应该亮,将其前面的绿灯关闭。

case 1: red = 1;yellow = 0;break; //1表示黄灯应该亮,将其前面的红灯关闭。

case 2: yellow = 1;green = 0;break; //2表示绿灯应该亮,将其前面的黄灯关闭。

}

P2 = table[shi];

wei1 = 0;

delay();

wei1 = 1;

P2 = table[ge];

wei2 = 0;

delay();

wei2 = 1;

}

}

void delay()

{

uint i,j;

for(i=5;i>0;i--)

for(j=1;j>0;j--);

}

需要说明的是,因为端口位定义的red,yellow,green不能像其他变量一样进行if条件判断,所以我们加入了变量temp,它起的是标志的作用,用来标记哪个灯亮着。这样就能根据它来控制小灯了。标志的用途很多,在一个大程序里可能要用到很多标志,但标志会影响程序的可读性,要慎重使用。

最终效果如下:

第4讲 交通信号灯_第3张图片

你可能感兴趣的:(单片机仿真实验系列教程)