深入解析:51单片机基础-动态数码管显示

news/2025/11/9 14:26:15/文章来源:https://www.cnblogs.com/yxysuanfa/p/19204237

第六章 动态数码管显示

1. 导入

在第五章中,我们学习了静态数码管显示,即每个数码管的段选线独立控制,优点是显示稳定、程序简单,但缺点是占用I/O资源多(每位需8个引脚)。当需要显示多位数字时,I/O口资源迅速耗尽。

本章将介绍动态数码管显示技术,通过“扫描方式”实现多位数码管的显示,显著减少I/O占用。其核心思想是:利用人眼视觉惰性,快速轮流点亮各个数码管,形成“同时显示”的错觉

本章目标:


2. 硬件设计

2.1 动态数码管结构

多位数码管(如4位)内部由多个7段数码管组成,其特点是:

常见封装为12脚或16脚,如4位数码管通常为12脚:8根段选线 + 4根位选线。

2.2 数码管类型

仍分为:

  • 共阴极:位选线接GND使该位导通,段选线输出高电平点亮段;
  • 共阳极:位选线接VCC使该位导通,段选线输出低电平点亮段。

本章以共阴极4位数码管为例。

2.3 电路连接

功能连接方式
段选线(a~g, dp)接P0口(P0.0 ~ P0.7)
位选线(D1~D4)接P2.0 ~ P2.3
P0口上拉电阻外接10kΩ排阻(因P0为开漏)

说明:

位选驱动增强(可选)

若I/O驱动能力不足,可在位选线使用NPN三极管(如S8550)进行电流放大:

  • P2.0 → 三极管基极(通过1kΩ电阻)
  • 发射极 → VCC
  • 集电极 → 数码管COM端

此时为高电平有效位选。


3. 软件设计

3.1 段码表定义

复用第五章的共阴极段码表:

#include <reg52.h>unsigned char code seg_code[] = {0x3F, // 00x06, // 10x5B, // 20x4F, // 30x66, // 40x6D, // 50x7D, // 60x07, // 70x7F, // 80x6F  // 9};

3.2 位选控制

定义位选控制宏(共阴极,低电平有效):

#define DIGIT1 P2 = P2 & 0xFE | 0x0E  // P2.0=0, P2.1~3=1 → 选中第1位
#define DIGIT2 P2 = P2 & 0xFD | 0x0D  // P2.1=0
#define DIGIT3 P2 = P2 & 0xFB | 0x0B  // P2.2=0
#define DIGIT4 P2 = P2 & 0xF7 | 0x07  // P2.3=0

更简洁方式:直接赋值

void select_digit(unsigned char n) {
switch(n) {
case 1: P2 = (P2 & 0xF0) | 0x0E; break;
case 2: P2 = (P2 & 0xF0) | 0x0D; break;
case 3: P2 = (P2 & 0xF0) | 0x0B; break;
case 4: P2 = (P2 & 0xF0) | 0x07; break;
default: break;
}
}

实际常用:P2.03 控制位选,P2.47 保留,故先清低4位再设置。


3.3 基本显示流程

动态扫描步骤:

  1. 关闭所有位选(可选);
  2. 输出当前位的段码;
  3. 选中该位;
  4. 延时1~5ms;
  5. 关闭该位;
  6. 切换到下一位,循环。
void display(unsigned char *num, unsigned char len) {
unsigned char i;
for (i = 0; i < len; i++) {
P0 = 0x00;                    // 消隐,防止重影
P2 = (P2 & 0xF0) | 0x0F;      // 关闭所有位选(P2.0~3=1)
P0 = seg_code[num[i]];        // 输出第i位的段码
P2 = (P2 & 0xF0) | (0x0F & ~(1 << i)); // 选中第i位(低电平)
delay_ms(1);                  // 显示1ms
}
}

说明:~(1 << i) 生成第i位为0,其余为1。


3.4 显示多位数字(示例:显示1234)

unsigned char show[] = {1, 2, 3, 4}; // 显示内容
void main() {
while(1) {
display(show, 4);
}
}

注意:display函数需在主循环中持续调用,扫描频率建议 ≥ 50Hz,避免闪烁。


3.5 消除重影(Ghosting)

重影原因:前一位未完全关闭时,后一位已开启,导致两位列同时亮。

解决方法:

  1. 消隐法:在切换位前,先将段选线清零;
  2. 快速扫描:提高扫描频率;
  3. 关闭位选:切换时短暂关闭所有位选。

改进版扫描函数:

void display(unsigned char *num, unsigned char len) {
unsigned char i;
for (i = 0; i < len; i++) {
P0 = 0x00;                    // 消隐
P2 = (P2 & 0xF0) | 0x0F;      // 关闭所有位选
P0 = seg_code[num[i]];        // 设置段码
P2 = (P2 & 0xF0) | (0x0F & ~(1 << i)); // 选中第i位
delay_ms(1);
}
}

3.6 显示小数点

若需在第2位显示小数点(如12.34),则:

P0 = seg_code[num[i]] | 0x80;  // 仅在第2位加小数点

可在display函数中判断位数:

if (i == 1) {  // 第2位(索引1)
P0 = seg_code[num[i]] | 0x80;
} else {
P0 = seg_code[num[i]];
}

3.7 使用定时器中断扫描(预告)

当前方法在主循环中扫描,若主程序有复杂逻辑,可能导致显示不稳定。后续可使用定时器中断

  • 定时器每1ms中断一次;
  • 在中断中切换数码管位;
  • 实现非阻塞、高稳定性显示。

留待“定时器”章节深入。


3.8 编译与下载

若显示错乱:


4. 小结

本章通过实现动态数码管显示,掌握了多位数字显示的核心技术,主要内容包括:

  • 硬件连接:理解段选与位选结构,正确连接共阴极数码管;
  • 扫描原理:利用视觉惰性实现“多路复用”;
  • 软件实现:编写扫描函数,支持多位显示、小数点控制;
  • 问题解决:掌握消隐、防重影、亮度均衡等技巧;
  • 扩展能力:为实现计时器、频率计等应用奠定基础。

4.1 常见问题与解决

问题原因解决方法
显示闪烁扫描频率太低增加扫描次数或减少延时
重影未消隐或切换太快加入消隐步骤,短暂关闭所有位
某位不亮位选线未导通检查P2口输出与三极管驱动
亮度不均各位显示时间不同保证每位延时一致
显示乱码段码表错误确认数码管类型并重新编码

4.2 下一步学习建议

  • 使用定时器中断实现动态扫描,解放主程序;
  • 实现电子钟功能,显示时分秒;
  • 引入按键调节时间;
  • 学习矩阵键盘,扩展输入方式。

本章标志着你已掌握高效的多位显示技术,下一章将进入定时器/计数器模块的学习,实现精准时间控制与非阻塞操作。


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/960494.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Ubuntu 22.04 的镜像源列表

Ubuntu 22.04 的镜像源列表#清华 deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy main restricted universe multiversedeb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy main restricted unive…

关于梅特勒-托利多 称重传感器检查

模拟传感器检查: 测量方式:万用表:红色->传感器:+SIG 白色 万用表:黑色->传感器:-SIG 红色判断依据: 正常值在:2-5mV 若其中一只超出范围或差距过大,则判断损坏

Window 11 安装wsl

安装WSL 这个参考链接,参考了部分内容,记录亲测的安装步骤,注意使用代理,不然在执行powershell中执行wsl --install时会报错,提示没有服务。 1、开发指定服务 设置-控制面板-程序和功能-启用或关闭Windows功能,启…

深入解析:达梦数据库TDE透明加密解决方案:构建高安全数据存储体系

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

现代Web API应用与优化建议

1. ResizeObserver:像素级「监听」元素尺寸 痛点:window.resize 只能监听视口,图表容器被 flex 布局偷偷撑开你却拿不到回调。 一行代码: new ResizeObserver(entries => myChart.resize()).observe(document.q…

Linux 云计算核心技术:原理、组件与 K8s 实战部署 - 详解

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

局域网---传输文件资料信息

我们在进行文件传输的过程中,通常都是使用微信传输,但是微信传输会被自动压缩,特别是在传输视频的时候。而且微信传输文件,如果不注意清理,就会导致存储的文件越来越多,内存占据越来越多。 推荐一个局域网的传输…

ICPC2023南京个人题解

I. Counter 题意:给定一个初始值为零的计数器,每次操作可以使值+1或者变为0,再给定 \(m\) 个特定时间 \(a_i\) 的对应计数器的值 \(b_i\) ,问有没有可能的长度为 \(n\) 的操作序列满足所有条件。 限制条件:\(1\le…

从C++到wasm,并在JavaScript中调用

我将为你提供一个完整的从 C++ 编译到 WebAssembly 并在 JavaScript 中调用的指南。 环境准备 1. 安装 Emscripten # 克隆 emsdk 仓库 git clone https://github.com/emscripten-core/emsdk.git cd emsdk# 安装最新版本…

图书馆管理系统初步设计

图书馆管理系统开发记录 1. 我使用了什么AI工具辅助选题 在项目初期,我使用了deepseek和豆包等AI工具辅助选题。通过与这些工具交流,了解了当前常见的Java课程设计选题方向,分析了不同选题的可行性和复杂度,最终结…

Delphi 修改单元名称后,编译报错找不到修改前的单元

原因是: 被修改的单元的名称,没有同步到早前引用了该单元的单元中. 做个比喻就是 张三改名为李四,以后大家也都叫他李四,但是在他没改名之前,注册在某单元里面的名字还是叫张三. 解决方案是: 菜单 - 搜索 - 在文件中查…

详细介绍:计算某字符出现次数

详细介绍:计算某字符出现次数pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco"…

3dgs Scene详解 - 详解

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

英语_阅读_30 years ago_待读

It was a few years ago. 那是几年前的事了。 A friend had sent me a restaurant gift card for Christmas and I had picked a sunny Sunday afternoon to use it. 一个朋友送了我一张餐厅礼品卡做圣诞礼物,我选了一…

2026 NOI 做题记录(九)

推荐阅读:A、F、G、I、PContest Link \(\text{By DaiRuiChen007}\)*A. [P11984] 占卜 3 (8.5) Problem Link 首先朴素的想法就是用 \(a\) 个 \(0\) 和 \(b\) 个 \(1\) 表示 \(\binom{a}{a+b}\) 级别的信息。 有几个问…

英语_阅读_When youre bored_待读

When youre bored, what will you do first? 当你感到无聊时,你会先做什么? If youre like many, the answer is quite simple: You reach for your phone. 如果你和许多人一样,答案很简单:你会拿起手机。 Five m…

教学视频(1)

一、剪辑元素 剪辑需要的部分,加上音乐、文字、元素、台词、镜头图片 二、录播软件 直播伴侣(自带美颜) obs studio obs 多平台操作,操作步骤复杂点 ev录屏 部分功能受限 芦笋软件 手机 x recorder 手机录…

实用指南:C++STL---静态数组array

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

设置linux时间

# 设置时区 sudo timedatectl set-timezone Asia/Shanghai # 开启设置时间 timedatectl set-ntp no # 具体设置时间 timedatectl set-time "2025-06-11 19:05:55" # 重启 reboot # 立即关机 sudo shutdow…

MCP神器!一键部署连接任何MCP服务器

Hello, 大家好,我是程序员海军, 全栈开发 |AI爱好者 | 独立开发。最近一直在研究MCP方面的事情,使用的技术栈是Python + FastAPi + FastMCP,开发了多个MCP-Server,本地化访问没啥问题,准备部署试着玩一下,调研…