3. 数码管静态显示:共阴/共阳数码管原理、段码表计算、单个数码管显示数字0-9
好,咱们今天来聊聊数码管。这东西在嵌入式开发里太常见了,电梯楼层计数器、电子钟、温度显示器……到处都有它的身影。我个人觉得,数码管是入门嵌入式显示最好的起点——它简单、直观,而且能让你真正理解“显示”这件事的本质。
3.1 共阴与共阳:两种“脾气”的数码管
先说说数码管的结构。一个数码管,说白了就是8个LED灯排成“8”字形,外加一个小数点。这8个LED的阳极或阴极被连在一起,就分出了两种类型。
共阴极数码管:所有LED的阴极连在一起,接GND。你要点亮哪一段,就给对应的阳极送高电平。说白了,就是“高电平点亮”。
共阳极数码管:所有LED的阳极连在一起,接VCC。你要点亮哪一段,就给对应的阴极送低电平。也就是“低电平点亮”。
嗯,这里要注意:千万别搞混了。我在项目中遇到过一位同事,把共阳的段码表用在共阴的数码管上,结果显示出来的数字全是乱的,排查了半天才发现是极性搞反了。你想想看,这多耽误事。
3.2 段码表计算:从“画图”到“编码”
段码表,说白了就是数字和LED段之间的对应关系。咱们先给数码管的8段编个号:从a到g,再加上小数点dp。通常的排列顺序是:a在上横,b在右上,c在右下,d在下横,e在左下,f在左上,g在中间横,dp在右下角。
怎么算段码?我教你一个笨办法——画图。拿张纸,画个“8”,然后对着数字0到9,把要亮的段涂黑,不亮的留白。然后按顺序写出二进制位,再转成十六进制。
举个例子,显示数字“0”:需要点亮a、b、c、d、e、f这6段,g和dp不亮。假设我们用的共阴极,高电平点亮。那么二进制就是:dp g f e d c b a = 0 0 1 1 1 1 1 1 = 0x3F。
如果是共阳极,那就反过来:低电平点亮,所以二进制是:1 1 0 0 0 0 0 0 = 0xC0。
你看,其实就是一个取反的关系。我个人习惯把共阴和共阳的段码表都算好,存成两个数组,用的时候直接查表,省得每次现算。
共阴段码 = 点亮段对应位写1,不亮写0,然后转十六进制。
共阳段码 = 对共阴段码按位取反。
3.3 0-9的段码表:直接拿来用
下面是我常用的段码表,共阴和共阳都有。你直接复制到代码里就行。
| 数字 | 共阴段码 (十六进制) | 共阳段码 (十六进制) | 点亮段 |
|---|---|---|---|
| 0 | 0x3F | 0xC0 | a,b,c,d,e,f |
| 1 | 0x06 | 0xF9 | b,c |
| 2 | 0x5B | 0xA4 | a,b,d,e,g |
| 3 | 0x4F | 0xB0 | a,b,c,d,g |
| 4 | 0x66 | 0x99 | b,c,f,g |
| 5 | 0x6D | 0x92 | a,c,d,f,g |
| 6 | 0x7D | 0x82 | a,c,d,e,f,g |
| 7 | 0x07 | 0xF8 | a,b,c |
| 8 | 0x7F | 0x80 | a,b,c,d,e,f,g |
| 9 | 0x6F | 0x90 | a,b,c,d,f,g |
3.4 单个数码管显示:代码实战
理论说完了,咱们来点实际的。下面是一个用51单片机控制共阴数码管显示0-9的例子。硬件连接很简单:数码管的a-g和dp分别接P0口的P0.0到P0.7,公共端接GND。
#include <reg51.h>
// 共阴数码管段码表
unsigned char code segCode[] = {
0x3F, // 0
0x06, // 1
0x5B, // 2
0x4F, // 3
0x66, // 4
0x6D, // 5
0x7D, // 6
0x07, // 7
0x7F, // 8
0x6F // 9
};
void delay(unsigned int ms) {
unsigned int i, j;
for(i = 0; i < ms; i++)
for(j = 0; j < 120; j++);
}
void main() {
unsigned char i;
while(1) {
for(i = 0; i < 10; i++) {
P0 = segCode[i]; // 输出段码
delay(1000); // 延时1秒
}
}
}
这段代码很简单:循环0到9,每次把对应的段码送到P0口,数码管就显示对应的数字了。延时1秒,方便你观察。
如果是共阳数码管,只需要把段码表换成共阳的那一套,然后注意公共端接VCC就行。代码逻辑完全一样。
3.5 避坑指南:我踩过的几个雷
做这个实验,有几个地方容易出问题。我把自己踩过的坑列出来,你注意避开。
- 段码顺序搞反: 我刚开始做的时候,把a和dp的位置搞反了,结果显示的数字全是镜像的。后来我养成了一个习惯:画个图,标好每个引脚对应的段,再写代码。
- 共阴共阳搞混: 这个前面说过了,买回来先测一下,别偷懒。
- 限流电阻忘加: 数码管每个段都需要串一个电阻,一般220Ω到470Ω。不加的话,LED电流太大,要么烧数码管,要么烧IO口。我见过有人直接接,结果数码管冒烟了……
- 小数点处理: 段码表里一般把dp位放在最高位。如果你不需要小数点,记得把dp位置0,否则会多一个亮点。
好了,这一节的内容就到这儿。你先把单个数码管调通,能显示0到9,后面咱们再讲多位数码管的动态扫描。记住,基础打牢了,后面才走得稳。