【蓝桥杯单片机】:零基础吃透数码管动态扫描
一、蓝桥杯开发板数码管完整硬件原理图
整套数码管电路分为三大部分:段选锁存电路、位选锁存电路、地址译码片选电路、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 位循环)
- 消隐操作:向位选地址写入 0xFF,关闭所有数码管,消除残影拖影(必做步骤)
- 输出位码:向位选地址 0xC000 写入仅点亮当前位的掩码
- 输出段码:向段选地址 0xA000 写入当前数字对应的段码
- 延时维持:1ms 延时,保证肉眼清晰看到数字
- 循环切换下一位数码管,重复 1~4 步骤,持续循环刷新
3.3 蓝桥杯标准共阳数码管段码表
共阳极数码管,低电平点亮笔画,0xFF 代表数码管完全熄灭:
| 显示数字 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 熄灭 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 段码值 | 0xC0 | 0xF9 | 0xA4 | 0xB0 | 0x99 | 0x92 | 0x82 | 0xF8 | 0x80 | 0x90 | 0xFF |
#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(); // 循环持续刷新数码管
}
}
当前使用循环刷新的方式,后续在定时器章节 使用定时刷新方式
更多推荐

所有评论(0)