DSP

交通灯实验

2019-07-13 14:44发布

一、 实验说明 实验原理图如下:
原理图   器件:7SEG-MPX2-CC-BLUE两位八段共阴数码管,显示为蓝 {MOD}。还有红黄绿三个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--); } 运行效果如下: clip_image004   可以看到所有的器件都能正常运行。下面我们就可以开始一点一点写程序了。  先写倒计时程序。 主函数可改为: 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,它起的是标志的作用,用来标记哪个灯亮着。这样就能根据它来控制小灯了。标志的用途很多,在一个大程序里可能要用到很多标志,但标志会影响程序的可读性,要慎重使用。 最终效果如下: clip_image005   本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/yafeilinux/archive/2009/10/31/4751702.aspx