一、蓝桥杯开发板数码管完整硬件原理图

整套数码管电路分为三大部分:段选锁存电路、位选锁存电路、地址译码片选电路、8 位共阳数码管

二、硬件模块逐部分拆解讲解


2.1 U7(74HC573)段选锁存器
输入:单片机 P0 口 D0~D7 8 位数据
输出:A'~G'、DP',串联 1k 限流电阻后连接数码管 a~g 段、小数点引脚
片选控制信号:Y7C(地址 0xA000)
核心作用:锁存段码数据,控制数码管显示什么数字


2.2 U8(74HC573)位选锁存器
输入:单片机 P0 口 D0~D7 8 位数据
输出:COM1~COM8,分别对应 8 个数码管公共阳极
片选控制信号:Y6C(地址 0xC000)
核心作用:锁存位选数据,控制哪一个数码管被点亮


2.3 74HC138 译码器 + U25 或门片选逻辑
地址输入:单片机 A0、A1、A2 地址线,译码输出 Y4/Y5/Y6/Y7
段选锁存器地址:0xA000 对应 Y7C
位选锁存器地址:0xC000 对应 Y6C


2.4 DS1、DS2 共阳极数码管
类型:共阳极数码管,COM 公共端高电平熄灭、低电平点亮
引脚对应:COM1~COM8 依次对应第 1~8 位数码管;A'~G' 控制笔画、DP' 控制小数点
硬件特性:笔画引脚串联限流电阻,防止电流过大烧毁数码管

三、数码管动态扫描核心原理

3.1 为什么采用动态扫描?

单片机 IO 口资源有限,8 个数码管静态驱动至少需要 16 路 IO,硬件成本高、占用资源多。蓝桥杯方案通过两片 74HC573 分时复用 P0 总线,利用人眼视觉暂留效应(1/24s 内刷新无闪烁),快速轮流点亮每一位数码管,视觉上实现 8 位同时点亮。

3.2 单次动态扫描标准流程(8 位循环)

  1. 消隐操作:向位选地址写入 0xFF,关闭所有数码管,消除残影拖影(必做步骤)
  2. 输出位码:向位选地址 0xC000 写入仅点亮当前位的掩码
  3. 输出段码:向段选地址 0xA000 写入当前数字对应的段码
  4. 延时维持:1ms 延时,保证肉眼清晰看到数字
  5. 循环切换下一位数码管,重复 1~4 步骤,持续循环刷新

3.3 蓝桥杯标准共阳数码管段码表

共阳极数码管,低电平点亮笔画,0xFF 代表数码管完全熄灭:

显示数字0123456789熄灭
段码值0xC00xF90xA40xB00x990x920x820xF80x800x900xFF
#include <STC15F2K60S2.H>
#include <intrins.h>


// 数码管段码 0-9 全灭
unsigned char tab[] = {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90, 0xFF};
unsigned char dspbuf[8] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; 
unsigned char dspcom = 0;       // 位选

// 比赛通用毫秒延时函数(适配11.0592MHz晶振)
void Delay_ms(unsigned int t)
{
    unsigned int i,j;
    for(i = t; i > 0; i--)
        for(j = 110; j > 0; j--);
}
// 锁存器选择函数
void SelectHC573(unsigned char channel) 
{
    switch(channel)
    {
        case 4: P2=(P2&0x1f)|0x80; break; // LED
        case 5: P2=(P2&0x1f)|0xa0; break; // 蜂鸣器、继电器
        case 6: P2=(P2&0x1f)|0xc0; break; // 数码管位选
        case 7: P2=(P2&0x1f)|0xe0; break; // 数码管段选
    }
}
// 数码管显示扫描
void display(void)
{
    SelectHC573(7); // 段消影
    P0 = 0xff;
    P2 &= 0x1f;
    
    SelectHC573(6); // 位选
    P0 = (1 << dspcom);    
    P2 &= 0x1f;

    SelectHC573(7); // 段选
    P0 = dspbuf[dspcom];
    P2 &= 0x1f;

    if(++dspcom == 8) dspcom = 0;
    Delay_ms(1);   
}



void main(void)
{
    while(1)
    {
        display(); // 循环持续刷新数码管
    }
}

当前使用循环刷新的方式,后续在定时器章节 使用定时刷新方式

更多推荐