51单片机-流水灯

发布者:草木知秋最新更新时间:2021-08-16 来源: eefocus关键字:51单片机  流水灯  LED 手机看文章 扫描二维码
随时随地手机看文章

本讲讲解用P0的8个IO端口控制8盏LED实现流水灯。


本教程所用开发板的硬件连接简化如下

3.png

1.数字模拟点灯


我们用八位的二进制数表示八盏灯,对应的位为0灯就亮,为1灯就灭。


流水灯的实现如下所示


11111110   //对应十六进制=0xFE,P0.0输出0,其余输出1


11111101   //对应十六进制=0xFD,P0.1输出0,其余输出1


11111011   //对应十六进制=0xFB,P0.2输出0,其余输出1


11110111   //对应十六进制=0xF7,P0.3输出0,其余输出1


11101111   //对应十六进制=0xEF,P0.4输出0,其余输出1


11011111   //对应十六进制=0xDF,P0.5输出0,其余输出1


10111111   //对应十六进制=0xBF,P0.6输出0,其余输出1


01111111   //对应十六进制=0xF7,P0.7输出0,其余输出1


11111110


11111101


......


2.流水灯代码


这里一次性控制8个IO端口就不需要sbit去定义单个IO端口了(请前去复习本章第二讲),有了之前章节的基础,代码的实现就不难了


#include  

//sbit LED2  = P0^0;  本节代码中用不到这条语句了

sbit ADDR2 = P1^2;

sbit ADDR1 = P1^1;

sbit ADDR0 = P1^0;

sbit ENLED = P1^4;

sbit ADDR3 = P1^3;

 

void delay_ms(unsigned int x)

{

    unsigned int i,j;

    if(x==1000)

    {

        for(i=0;i<19601;i++)//延时1s

        {

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

        }

    }

    else while(x--)for(j=115;j>0;j--);

}

 

void main()

{  

    ADDR3 = 1;//使能三八译码器

    ENLED = 0;// 

   

    ADDR2 = 1;//**************************

    ADDR1 = 1;//让三八译码器的IO6输出低电平

    ADDR0 = 0;//**************************

   

    while(1)

    {

        P0 = 0xFE; 

        delay_ms(100);// 大概延时一段时间 

        P0 = 0xFD; 

        delay_ms(100);

        P0 = 0xFB; 

        delay_ms(100);   

        P0 = 0xF7; 

        delay_ms(100);

        P0 = 0xEF; 

        delay_ms(100);   

        P0 = 0xDF; 

        delay_ms(100);

        P0 = 0xBF; 

        delay_ms(100);   

        P0 = 0x7F; 

        delay_ms(100);

    }

}

 

3.代码优化


为了让大家第一次了解switch语句在单片机程序中的运用(《手把手教你学51单片机》文档6.3节有介绍语句用法),我们用switch语句让代码显得整齐一些,且不需要重复书写“delay_ms(100);”,实现了书写上的优化,避免占据过多版面,修改主函数如下


void main()

{  

    unsigned char i=1;//定义新的变量用来轮流调用不同的case语句

    ADDR3 = 1;//使能三八译码器

    ENLED = 0;// 

   

    ADDR2 = 1;//**************************

    ADDR1 = 1;//让三八译码器的IO6输出低电平

    ADDR0 = 0;//**************************

   

    while(1)

    {

        switch(i)

        {   

            case 1: P0 = 0xFE; break;

            case 2: P0 = 0xFD; break;

            case 3: P0 = 0xFB; break;   

            case 4: P0 = 0xF7; break;

            case 5: P0 = 0xEF; break;   

            case 6: P0 = 0xDF; break;

            case 7: P0 = 0xBF; break;  

            case 8: P0 = 0x7F; i=0; break;//i归0使语句又从case 1执行

        } 

        i++;//i从1变到8使switch语句轮流调用“P0 = xxxx;”

        delay_ms(100);

    }

}


4.提醒


这里提及一下,在“delay_ms();”函数里有变量名i,主函数中也有同样的变量名i,但这两个相同名字的变量都是局部变量(文档7.1节有简单讲解),两个相同名字的变量各自占有独立的内存,不受各自的值变化而影响到另一个值,C语言基础知识普及。


在主函数中我们定义i为unsigned char类型是为了节约RAM内存,毕竟主函数里的i我们只需要它在1~8之间变化,不用超过255(文档4.2节有普及数据类型)。还有大家别忘了case语句结尾记得加“break;”防止程序一次性从“case 1”执行到“case 8”都没有去实现延时那部分,大家可尝试把8个“break;”都去掉,然后编译下载进开发板看会有什么现象?

关键字:51单片机  流水灯  LED 引用地址:51单片机-流水灯

上一篇:51单片机-函数传参调用
下一篇:51单片机-数组与移位

小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved