51单片机基础02 动态数码管显示-并串转换

目录

一、原理图

二、字段关系

三、基本代码介绍

1、延时

2、段选与位选

3、高级思路


一、原理图

可以看到所有数码管的段选全都连接在一起(内部),而片选经过了3-8译码器,原因是,如果每一个数码管都单独接一个位选信号,那么8个数码管就需要8个IO,而是用了译码器,可以实现3个IO控制8个的亮灭。

优点:省引脚IO

缺点:降低了刷新速率。

二、字段关系

共阴极连接:对应端口输出高电平则点亮该字段,否则熄灭。

共阳极连接:对应端口输出低电平则点亮该字段,否则熄灭。

|------|------|------|------|------|------|------|------|-------|------|
| P0.7 | P0.6 | P0.5 | P0.4 | P0.3 | P0.2 | P0.1 | P0.0 | 数字段码 | 显示字符 |
| h | g | f | e | d | c | b | a | | |
| 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 0x3F | 0 |
| 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 0x06 | 1 |
| 0 | 1 | 0 | 1 | 1 | 0 | 1 | 1 | 0x5B | 2 |
| 0 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 0x4F | 3 |
| 0 | 1 | 1 | 0 | 0 | 1 | 1 | 0 | 0x66 | 4 |
| 0 | 1 | 1 | 0 | 1 | 1 | 0 | 1 | 0x6D | 5 |
| 0 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 0x7D | 6 |
| 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 0x07 | 7 |
| 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0x7F | 8 |
| 0 | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 0x6F | 9 |
| 0 | 1 | 1 | 1 | 0 | 1 | 1 | 1 | 0x77 | A |
| 0 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0x7C | b |
| 0 | 0 | 1 | 1 | 1 | 0 | 0 | 1 | 0x39 | C |
| 0 | 1 | 0 | 1 | 1 | 1 | 1 | 0 | 0x5E | d |
| 0 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | 0x079 | E |
| 0 | 1 | 1 | 1 | 0 | 0 | 0 | 1 | 0x71 | F |

动态显示就是通过字段引脚向数码管输出所要显示字符的段码。每一时刻,只有1位数码管的位选线有效,其他各位位选线都是无效的。逐位地每隔一定时间轮流点亮各位数码管(扫描方式),由于LED数码管的余辉和人眼的**"视觉暂留"**作用,只要控制好每位显示的时间和间隔,则可以造成"多位同时亮"的假象,达到同时显示的效果。一般LED数码管的显示时间间隔(扫描间隔)大约在1~10ms之间即可。

三、基本代码介绍

cpp 复制代码
#include <AT89X52.h>       //调用51单片机的头文件

//---------------------------------------
//数码管字形表,供显示时查询
unsigned char code LED[10]=
{                          //定义表格一定要使用code,这样会做到程序存储区中
    0x3F,                  //"0"的字形表,0B00111111
    0x06,                  //"1"的字形表,0B00000110
    0x5B,                  //"2"的字形表,0B01011011
    0x4F,                  //"3"的字形表,0B01001111
    0x66,                  //"4"的字形表,0B01100110
    0x6D,                  //"5"的字形表,0B01101101
    0x7D,                  //"6"的字形表,0B01111101
    0x07,                  //"7"的字形表,0B00000111
    0x7F,                  //"8"的字形表,0B01111111
    0x6F,                  //"9"的字形表,0B01101111
};

//---------------------------------------
//4位数码管相关I/O设置
//P1.0-P1.2为3-8译码器U16的3个输入,编码选通输出Y0-Y3中的一位,即四个数码管中的一个进行显示。
sbit U165A0=P1^0;           //U165(74HC138)的A0脚接在P1.0口上,定义U165A0为P1.0,即P1端口的最低位
sbit U165A1=P1^1;           //U165(74HC138)的A1脚接在P1.1口上,同上,U165A1定义为P1.1
sbit U165A2=P1^2;           //U165(74HC138)的A2脚接在P1.2口上,165A2定义为P1.2
//---------------------------------------


void main(void)            //主函数,单片机开机后就是从这个函数开始运行
{

    unsigned char c=0;     //定义一个char型变量,做延时用
    unsigned char d=0;     //定义一个char型变量,控制显示位置
    unsigned char e=0;     //定义一个char型变量,做延时用
    unsigned int  f=0;     //定义一个int型变量,显示内容用,显示内容0-9999

    while(1)               //死循环,单片机初始化后,将一直运行这个死循环
    {

        for(c=0;c<250;c++);//做一个0-250的循环,不执行其他操作,只为延时
        if(++e>200)        //做一个延时,时间到将显示内容加1
        {
            e=0;           //清零,为下一次延时做准备
            if(++f>9999) f=0;//显示内容加1,因为只有4位显示,超过9999后归零
        }
        P2=0;              //关一次显示,以免显示出鬼影
        if(++d>3) d=0;     //先将d加1,然后判断是否大于3,大于3归零
        if(d==0)           //如果d=0,显示千位
        {
            P1=0x03;       //U165A0=1,U165A1=1,U165A2=0选通数码管的千位进行显示
            P2=LED[f/1000];          //将要显示的f的千位提取出来查表后送显示,P1和P2的定义在"AT89X52"
        }
        else if(d==1)      //如果d=1,显示百位
        {
            P1=0x02;       //U165A0=0,U165A1=1,U165A2=0选通数码管的百位进行显示
            P2=LED[(f%1000)/100];    //将要显示的f的百位提取出来查表后送显示
        }
        else if(d==2)      //如果d=2,显示十位
        {
            P1=0x01;       //U165A0=1,U165A1=0,U165A2=0选通数码管的十位进行显示
            P2=LED[(f%100)/10];      //将要显示的f的十位提取出来查表后送显示
        }
        else               //如果d=3,显示个位
        {
            P1=0x00;       //U165A0=0,U165A1=0,U165A2=0选通数码管的个位进行显示
            P2=LED[f%10];            //将要显示的f的个位提取出来查表后送显示
        }
    }
}

程序主要是实现了每次增加f值,其在0-9999递增,而数码管显示出来4位的数字

1、延时

如果没有延时,递增的速度会非常快,肉眼几乎无法分辨。

2、段选与位选

先设定位选再设定段选。

3、高级思路

实际上以上的代码非常low,因为所有的刷新都放在了while(1)里,而且延时是非常不精确的,后续如果增加类似定时功能、外置按钮控制数码管增减,就需要考虑定时器、外部中断等操作了,后续会进行相关介绍。

相关推荐
无人装备硬件开发爱好者18 小时前
STM32G474 + 1.32 寸 OLED(128×96)俄罗斯方块游戏实现指南
stm32·嵌入式硬件·游戏
三佛科技-1341638421219 小时前
SM2850P无电感离线稳压器 5V输出 典型应用电路分析(管脚、关键设计要点)
单片机·嵌入式硬件·物联网·智能家居·pcb工艺
潜创微科技20 小时前
IT6636+USB 协同芯片 3 进 1 出 HDMI2.1 KVM 切换器一体化方案
嵌入式硬件·音视频
dqsh0620 小时前
关于STM32G474芯片有规律的自动重启的问题
stm32·单片机·嵌入式硬件·系统重启·原因解析
时空自由民.20 小时前
BLDC无刷直流电机作为发电机的波形图
单片机
JSMSEMI1121 小时前
JSM63006 5A 28V三相无刷电机驱动电路
单片机·嵌入式硬件
国产芯片设计21 小时前
【LCD驱动实战】单颗YL1621脚位不足?双芯片联动驱动方案详解
stm32·单片机·mcu·51单片机·硬件工程
不怕犯错,就怕不做21 小时前
RK3562的CPU如何降频及关闭硬件编解码
linux·驱动开发·嵌入式硬件
yuanyuan2o221 小时前
从最小项目开始的 CMake 教程
c语言·开发语言·arm开发·c++·makefile·make·cmake
Hical_W1 天前
Hical 踩坑实录五部曲(二):MSVC / GCC / Clang 三平台 C++20 编译差异
linux·windows·经验分享·嵌入式硬件·macos·开源·c++20