多个数码管显示

点击打开在线编译器,边学边练

1.余晖效应

流水灯如果在流速太快的基础上再加速,那么我们看到的则是一排灯都在亮着,这就叫人眼的余晖效应。同理,我们想让多个数码管同时亮,那么就要让三八译码器的IO0~IO5每个输出引脚轮流快速切换出低电平,需要显示什么数字再由P0的8个IO端口控制。

这里提供了一段代码供大家调试玩玩,用实验现象领悟余晖效应。

#include <reg52.h> 
sbit ADDR2 = P1^2;
sbit ADDR1 = P1^1;
sbit ADDR0 = P1^0;
sbit ENLED = P1^4;
sbit ADDR3 = P1^3;

void main()
{  
    unsigned char i=1;
    unsigned int x;
    ADDR3 = 1;//使能三八译码器
    ENLED = 0;// 
  
    P0=0xC0;  //让6个数码管都显示0
    while(1)
    {  
        switch(i)
        {
            case 1: ADDR2 = 0;ADDR1 = 0;ADDR0 = 0;break;//让IO0输出低电平
            case 2: ADDR2 = 0;ADDR1 = 0;ADDR0 = 1;break;//让IO1输出低电平
            case 3: ADDR2 = 0;ADDR1 = 1;ADDR0 = 0;break;//让IO2输出低电平
            case 4: ADDR2 = 0;ADDR1 = 1;ADDR0 = 1;break;//让IO3输出低电平
            case 5: ADDR2 = 1;ADDR1 = 0;ADDR0 = 0;break;//让IO4输出低电平
            case 6: ADDR2 = 1;ADDR1 = 0;ADDR0 = 1;i=0;break;//让IO5输出低电平
        }
        i++;
        for(x=0;x<5000;x++);//这里是延时,大家把5000不断地改小到200,中间不断地下载进开发板来领悟余晖效应,
                            //其实我们做的只是让三八译码器的不同IO输出持续时间不同而已,然后就产生了不一样的实验效果
    }              
}

 

2.题目

如果我们既要6个数码管同时亮,还要使6个数码管都同时间隔一秒地显示0~F的状态不停循环,模拟图像如下

EEEEEE     //持续一秒

FFFFFF     //持续一秒

000000    //持续一秒

……

请思考如何下手?

提示:软件调试仿真出1秒内所要执行的内容。

还有大家别傻乎乎加个“delay_ms(1000);”用来实现间隔1秒的数字自加,这样做我们怎么去实现IO0~IO5的快速切换出低电平呀。

请大家先自己思考尝试动手练练写写,实在没头绪再参考一下这些代码,其实这跟无源蜂鸣器的间隔鸣叫的编程技巧是一样的

#include <reg52.h> 
sbit ADDR2 = P1^2;
sbit ADDR1 = P1^1;
sbit ADDR0 = P1^0;
sbit ENLED = P1^4;
sbit ADDR3 = P1^3;

unsigned char code LedChar[16]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E};//数码管状态值初始化

void main()
{  
    unsigned int i,x;
    unsigned char sec;//定义一个一秒之后自增1的变量
    ADDR3 = 1;//使能三八译码器
    ENLED = 0;// 
  
    P0=0xC0;  //先让所有数码管显示0
    while(1)
    {    
        for(x=0;x<28492;x++)//软件调试得出这个循环耗时1秒
        { 
            switch(i)
            {
                case 0: ADDR2 = 0;ADDR1 = 0;ADDR0 = 0;i++;break;//让IO0输出低电平
                case 1: ADDR2 = 0;ADDR1 = 0;ADDR0 = 1;i++;break;//让IO1输出低电平
                case 2: ADDR2 = 0;ADDR1 = 1;ADDR0 = 0;i++;break;//让IO2输出低电平
                case 3: ADDR2 = 0;ADDR1 = 1;ADDR0 = 1;i++;break;//让IO3输出低电平
                case 4: ADDR2 = 1;ADDR1 = 0;ADDR0 = 0;i++;break;//让IO4输出低电平
                case 5: ADDR2 = 1;ADDR1 = 0;ADDR0 = 1;i=0;break;//让IO5输出低电平
            }   
        } 
        sec++;//一秒之后变量自加1
        if(sec>=16)sec=0;
        P0=LedChar[sec];//取数组元素中标号为0~15的元素  
    }
}

我们把i放到了前面的case语句中自加,这样阅读起来更加快速明白switch语句是每条都要按顺序轮流去执行的意思(参考了宋老师的代码)。还有大家别把i定义成unsigned char型,不然无论怎么修改x的值都调试不出for循环持续1秒。

学到这里需要大家进一步学会自己分析整体代码的系统结构了。


本文固定URL:https://www.dotcpp.com/course/194

上一课:数码管&LED 下一课:同时显示不同的数字
第一章 单片机入门
第二章 LED
第三章 蜂鸣器
第四章 数码管
第五章 独立按键
第六章 多文件编程
第七章 外部中断
第八章 定时器
第九章 舵机与超声波模块
第十章 串口通信
第十一章 1602液晶屏
第十二章 IIC通信
第十三章 红外遥控与温度传感器
第十四章 AD与DA
第十五章 混合例程
第十六章 完结
Dotcpp在线编译      (登录可减少运行等待时间)