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)里,而且延时是非常不精确的,后续如果增加类似定时功能、外置按钮控制数码管增减,就需要考虑定时器、外部中断等操作了,后续会进行相关介绍。

相关推荐
嵌入式小站3 小时前
STM32 零基础可移植教程 17:USART + DMA + IDLE,串口不定长接收怎么做
stm32·单片机·嵌入式硬件
史蒂芬_丁3 小时前
Cortex-M内核中断保护机制详解:PRIMASK寄存器的正确使用方法
单片机·嵌入式硬件
榴莲llll3 小时前
LED高亮数码管显示驱动芯片数显屏驱动器最大支持13×3的按键VK16K33A
单片机
崇山峻岭之间4 小时前
单片机传感器实验
单片机·嵌入式硬件
鼎讯信通6 小时前
协议深析 + 工业耐用 + 数据赋能HM-M155 守护能源通信链路全生命周期
能源·信息与通信·通信
芯岭技术7 小时前
PY32F030国产32位MCU,应用场景广泛,宽工作电压、丰富外设
单片机·嵌入式硬件·物联网
星恒讯工业路由器7 小时前
星恒讯便携移动路由器的好处
网络·5g·智能路由器·信息与通信·wifi6·便携
智者知已应修善业11 小时前
【51单片机数码管驱动2位显示0-99按键3短按+1长按+10按键4短按-1长按清零,按键不影响数码管显示】2023-8-16
c++·经验分享·笔记·算法·51单片机
FreakStudio11 小时前
大话电容传感器和电容SOC芯片,看这一篇就够了
python·单片机·嵌入式·面向对象·并行计算·电子diy·电子计算机
信看11 小时前
常见通信接口
单片机·嵌入式硬件