C51单片机 简单的交通红绿灯设计一

各位读者朋友们你们好,感谢你们能点开这篇文章,作为一个非硬件专业的学生,我没有扎实的硬件基础,很担心自己所写内容没有理论基础或者存有漏洞,如果有不对的地方,期待您能指正,一起学习。交通红绿灯的设计算是51的小入门。涉及仅有数码管,LED交通灯,Delay函数延时的使用。

总览:一:数码管用来显示数字。

二:LED交通灯本质上就是二极管,含有红绿黄,作为交通灯。

三:Delay函数,用以计时。(在还未学习计时器的情况下,用Delay函数计时,虽有误差,但能接受)

我的板子是清翔的A4板,静态数码管原理图如下:

一个静态数码管其实是由八个小的二极管组成,如上图,你可以看到,如果想让数码管显示数字1,就是点亮b,c两个二极管,其他不点亮。(原理图中每个二极管分别用字母a~Dp代替,下文同上)

我们再设计接线,做过入门的点亮第一个LED灯的都知道,点亮LED就是给电平置低,我设计的接线是引脚P0^0~P0^7接J8的A~Dp。

这样我们就可以写出每个数字所需点亮的二极管以及对应的引脚了:

数字0:a,b,c,d,e,f 对应引脚:P00 P01 P02 P03 P04 P05

数字1: b,c 对应引脚:P01 P02

数字2:a,b,d,e,g 对应引脚: P00 P02 P03 P06

数字3:。。。。。。。

我们写一个函数,将0-10的数字包含进去:

void NiXie(unsigned char Number)
{
        switch(Number)
    {
        case 0:P0_0=P0_1=P0_2=P0_3=P0_4=P0_5=0;break;
        case 1:P0_1=P0_2=0;break;
        case 2:P0_0=P0_1=P0_3=P0_4=P0_6=0;break;
        case 3:P0_0=P0_1=P0_2=P0_3=P0_6=0;break;
        case 4:P0_1=P0_2=P0_5=P0_6=0;break;
        case 5:P0_0=P0_2=P0_3=P0_5=P0_6=0;break;
        case 6:P0_0=P0_2=P0_3=P0_4=P0_5=P0_6=0;break;
        case 7:P0_0=P0_1=P0_2=0;break;
        case 8:P0_0=P0_1=P0_2=P0_3=P0_4=P0_5=P0_6=0;break;
        case 9:P0_0=P0_1=P0_2=P0_3=P0_5=P0_6=0;break;
        case 10:P0_6=0;break;
    }
}

数字10我用中间那个杠,也就是g编码的二极管代替了(对应P0^6),毕竟这个例程只有一个数码管…

这样利用switch的好处是很明显的,当我们输入一个Number,对应的case就会自动对应这个数,比如Number=5,对应case 5:对应的数码管被点亮,实现显示数字5的效果。

注:数字之间的切换

比如数字1过后想亮数字2,需要把数字1亮过的二极管全部置高后再行动,若没有置高,实际上就是数字之间发生重叠,为统一起见,每亮(显示)一个数字后,将所有引脚置高,全部关灯,即:

P0_0=P0_1=P0_2=P0_3=P0_4=P0_5=P0_6=P0_7=1;//return

(提示:如果你用模块化编程,会使main函数看起来更简洁)

数字显示做好后,我们来看红绿灯:在我这块板子上,红黄绿灯,我接的是:

P2^2——绿灯

P2^3——黄灯

P2^4——红灯

延时函数Delay:如果你看到这篇文章的话,应该还没由接触到吧,Delay函数是可以在生成器中自动生成的,看下图:

系统频率也就是晶振,结合自己的板子,有的是12.0000KHZ的,我的是11.0592KHZ的,定时长度可设计最小为微秒的计时单位,在本实验中毫秒更适用,指令集选择STC-Y1对应STC89C型号的板子,都勾选好后,就可以把生成的代码复制来用了,在主函数中,直接调用这个函数,就可以起到延时的效果了。

void Delay1ms()        //@11.0592MHz
{
    unsigned char i, j;

    _nop_();
    i = 2;
    j = 199;
    do
    {
        while (--j);
    } while (--i);
}

看此函数,结合我们的需求我们可以稍作改动,1000毫秒为一秒,我们想要1000毫秒来实现交通灯,这里只有1毫秒,我们只需要加个while函数循环我们想要的秒数的次数,就可以实现了

修改的代码如下:

void Delay(unsigned int xms)        //@11.0592MHz
{
    unsigned char i, j;
    while(xms)
    {
        _nop_();
        i = 2;
        j = 199;
        do
        {
            while (--j);
        } while (--i);
        xms--;
    }   
}

我们写一个参数,自己输入你想延时多少毫秒,比如xms=1000,while循环里每循环一次xms–;就可以实现循环xms次一毫秒的循环了。1000次就是一秒钟了。(我在这里将函数名改为了Delay())

说了这么多,是时候上代码了:

#include <REGX51.H>
#include<INTRINS.H>
void NiXie(unsigned char Number)
{
        switch(Number)
    {
        case 0:P0_0=P0_1=P0_2=P0_3=P0_4=P0_5=0;break;
        case 1:P0_1=P0_2=0;break;
        case 2:P0_0=P0_1=P0_3=P0_4=P0_6=0;break;
        case 3:P0_0=P0_1=P0_2=P0_3=P0_6=0;break;
        case 4:P0_1=P0_2=P0_5=P0_6=0;break;
        case 5:P0_0=P0_2=P0_3=P0_5=P0_6=0;break;
        case 6:P0_0=P0_2=P0_3=P0_4=P0_5=P0_6=0;break;
        case 7:P0_0=P0_1=P0_2=0;break;
        case 8:P0_0=P0_1=P0_2=P0_3=P0_4=P0_5=P0_6=0;break;
        case 9:P0_0=P0_1=P0_2=P0_3=P0_5=P0_6=0;break;
        case 10:P0_6=0;break;
    }
}

void Delay(unsigned int xms)        //@11.0592MHz
{
    unsigned char i, j;
    while(xms)
    {
        _nop_();
        i = 2;
        j = 199;
        do
        {
            while (--j);
        } while (--i);
        xms--;
    }   
}
void main()
{

    while(1)
    {
            unsigned int i=10,j=3,k=10;
            for(i;i>0;i--)
            {
                P2_2=0;//Grenn light
                NiXie(i);
                Delay(1000);
                P0_0=P0_1=P0_2=P0_3=P0_4=P0_5=P0_6=P0_7=1;//return
                
            }
                P2_2=1;//off the green light 
                
                for(j;j>0;j--)
            {
                    P2_3=0;//Yellow light 
                    NiXie(j);
                    Delay(500);    
                    P2_3=1;
                    Delay(500);//实现闪烁
                    P0_0=P0_1=P0_2=P0_3=P0_4=P0_5=P0_6=P0_7=1;//return
            }
                P2_3=1;
                for(k;k>0;k--)
            {
                P2_4=0;//Red light
                NiXie(k);
                Delay(1000);
                P0_0=P0_1=P0_2=P0_3=P0_4=P0_5=P0_6=P0_7=1;//return
            }
                P2_4=1;
    }
}

在黄灯部分,我设计黄灯闪烁,更像交通灯了哈哈哈哈。(接下来准备写交通红绿灯设计二,用定时器减小误差,另,一个数码管确实有些可怜了,准备加个LCD1602或者用两个数码管)。

实验现象:

如有不懂的地方,欢迎您的私信。

如有写的不对的地方,非常期待能收到您的指正。

物联沃分享整理
物联沃-IOTWORD物联网 » C51单片机 简单的交通红绿灯设计一

发表评论