1.4 数码管显示实验
学习目标:掌握数码管段码与位码原理、静态显示与动态扫描技术,实现数字 0~9 的显示。
实验原理
数码管结构
七段数码管(7-Segment)由 a~g 七段 LED 加小数点 dp 组成,共 8 个 LED 段。按公共端接法分为:
- 共阴极:所有 LED 阴极接公共端(接地),段选端接高电平点亮
- 共阳极:所有 LED 阳极接公共端(接 VCC),段选端接低电平点亮(51 常用)
a
┌─────┐
f │ │ b
│ g │
├─────┤
e │ │ c
│ │
└─────┘
d · dp段码表(共阳极)
| 数字 | a | b | c | d | e | f | g | 段码(共阳) |
|---|---|---|---|---|---|---|---|---|
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0xC0 |
| 1 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 0xF9 |
| 2 | 0 | 0 | 1 | 0 | 0 | 1 | 0 | 0xA4 |
| 3 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 0xB0 |
| 4 | 1 | 0 | 0 | 1 | 1 | 0 | 0 | 0x99 |
| 5 | 0 | 1 | 0 | 0 | 1 | 0 | 0 | 0x92 |
| 6 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0x82 |
| 7 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 0xF8 |
| 8 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0x80 |
| 9 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0x90 |
段码 = 二进制位 b7b6b5b4b3b2b1b0 对应 dp g f e d c b a,共阳时点亮段为 0。
静态显示实验(1 位数码管)
电路
1 位共阳数码管接 P1 口(a~dp 依次接 P1.0~P1.7),公共端接 VCC:
AT89C51 共阳数码管
┌──────┐
│ P1.0 ├──a─────────┐
│ P1.1 ├──b │
│ P1.2 ├──c │ 段选
│ P1.3 ├──d │
│ P1.4 ├──e │
│ P1.5 ├──f │
│ P1.6 ├──g │
│ P1.7 ├──dp │
│ │ │
│ │ 公共端 ─── VCC
└──────┘程序
c
/****************************************************
* 实验名称:静态显示——1位共阳数码管
****************************************************/
#include <reg51.h>
// 共阳极 0~9 段码表
code unsigned char seg_code[] = {
0xC0, 0xF9, 0xA4, 0xB0, 0x99,
0x92, 0x82, 0xF8, 0x80, 0x90
};
void delay(unsigned int ms)
{
unsigned int i, j;
for (i = ms; i > 0; i--)
for (j = 120; j > 0; j--);
}
void main(void)
{
unsigned char i;
while (1)
{
for (i = 0; i < 10; i++)
{
P1 = seg_code[i]; // 输出数字 i 的段码
delay(1000); // 显示 1 秒
}
}
}动态扫描实验(4 位数码管)
原理:视觉暂留
多位数码管若每位独立占 8 个 I/O,将占用大量引脚。动态扫描利用人眼视觉暂留效应(约 20ms 内保持影像),逐位快速轮流点亮:
- 某一位显示 1~2ms
- 切换到下一位显示
- 循环扫描,人眼看到的是"同时显示"的效果
电路
4 位共阳数码管:段选 a~dp 共接 P1 口(P1.0~P1.7),位选 P2.0~P2.3 控制每一位公共端:
AT89C51 4位共阳数码管
┌──────┐
│ P1.0~│──段选a~dp───(所有位共用)
│ P1.7 │
│ P2.0 ├──位选1(千位)
│ P2.1 ├──位选2(百位)
│ P2.2 ├──位选3(十位)
│ P2.3 ├──位选4(个位)
└──────┘程序
c
/****************************************************
* 实验名称:动态扫描——4位共阳数码管
* 显示 "1234"
****************************************************/
#include <reg51.h>
code unsigned char seg_code[] = {
0xC0, 0xF9, 0xA4, 0xB0, 0x99,
0x92, 0x82, 0xF8, 0x80, 0x90
};
// 位选控制字:选中第0~3位(共阳,低电平选中需取反,此处用 P2 直接输出)
void delay(unsigned int ms)
{
unsigned int i, j;
for (i = ms; i > 0; i--)
for (j = 120; j > 0; j--);
}
void main(void)
{
unsigned char num[4] = {1, 2, 3, 4}; // 待显示数字
unsigned char i;
while (1)
{
for (i = 0; i < 4; i++)
{
P2 = ~(0x01 << i); // 位选:选中第 i 位(低电平有效)
P1 = seg_code[num[i]]; // 输出该位数字段码
delay(2); // 停留 2ms
}
}
}关键知识点
| 知识点 | 说明 |
|---|---|
| 段码(Seg Code) | 控制 a~dp 各段亮灭,决定显示字形 |
| 位选(Bit Select) | 控制多位数码管的哪一位显示 |
| 静态显示 | 每位独立驱动,占 I/O 多、亮度高 |
| 动态扫描 | 分时复用段选线,占 I/O 少、需刷新 |
| 视觉暂留 | 扫描周期 < 20ms,人眼不察觉闪烁 |
常见问题
Q1:数码管显示乱码?
- 检查段码表是否与共阳/共阴匹配
- 检查段选线连接顺序是否正确
Q2:动态扫描有闪烁?
- 缩短每位停留时间(1~2ms)
- 检查扫描总周期是否 < 20ms
Q3:共阳和共阴搞混?
- 共阳段码用 0 点亮段,共阴段码用 1 点亮段
- 两者段码互补(取反)
实验任务
- 1 位数码管循环显示 0~9
- 4 位数码管动态显示自己的学号后四位
- 扩展:做一个 0~99 循环计数器
考核点 / 验收标准
| 考核项 | 验收标准 | 分值 |
|---|---|---|
| 段码表 | 能正确写出 0~9 共阳段码并理解编码规则 | 25 |
| 静态显示 | 1 位数码管正确显示 0~9 | 25 |
| 动态扫描 | 4 位数码管动态显示无闪烁 | 30 |
| 原理理解 | 能解释视觉暂留与动态扫描原理 | 20 |
实操要求:现场实现 4 位数码管显示指定数字(如学号后四位)。