背景
七段数码管是由 7+1 个 LED 构成的数字显示器件,其中前面七个 LED 各自显示数字的一段,最后的一个LED显示小数点。它有十二个引脚,其中八个引脚用于控制七段数码管显示什么图案,四个引脚分别作为四位七段数码管的使能信号,即分别控制四位七段数码管是否显示该图案。
笔者使用的 Arduino 板的 LED 是 共阳极的,因此低电平才能点亮,即当信号为 0 时亮起,为 1 时熄灭。为了节约管脚,它们都使用了同一组输入信号,因此同一时间四个七段数码管都会显示相同的内容。如下图:
本次我们要使用七段数码管实现十六进制译码器 (Hex 7-Segment Decoder Display),并且实现数码管显示功能。
真值表与电路设计
七段数码管可以将十六进制数字以下图的形式显示:
因此我们可以设计出如下的真值表:
$X_b$ | $X_h$ | $a$ | $b$ | $c$ | $d$ | $e$ | $f$ | $g$ |
---|---|---|---|---|---|---|---|---|
0000 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
0001 | 1 | 1 | 0 | 0 | 1 | 1 | 1 | 1 |
0010 | 2 | 0 | 0 | 1 | 0 | 0 | 1 | 0 |
0011 | 3 | 0 | 0 | 0 | 0 | 1 | 1 | 0 |
0100 | 4 | 1 | 0 | 0 | 1 | 1 | 0 | 0 |
0101 | 5 | 0 | 1 | 0 | 0 | 1 | 0 | 0 |
0110 | 6 | 0 | 1 | 0 | 0 | 0 | 0 | 0 |
0111 | 7 | 0 | 0 | 0 | 1 | 1 | 1 | 1 |
1000 | 8 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
1001 | 9 | 0 | 0 | 0 | 0 | 1 | 0 | 0 |
1010 | A | 0 | 0 | 0 | 1 | 0 | 0 | 0 |
1011 | B | 1 | 1 | 0 | 0 | 0 | 0 | 0 |
1100 | C | 0 | 1 | 1 | 0 | 0 | 0 | 1 |
1101 | D | 1 | 0 | 0 | 0 | 0 | 1 | 0 |
1110 | E | 0 | 1 | 1 | 0 | 0 | 0 | 0 |
1111 | F | 0 | 1 | 1 | 1 | 0 | 0 | 0 |
如果我们设四位输入信号(16位译码器是 4-16 的) 为 $I_0,I_1,I_2,I_3$ ,那么输出到七个引脚 $a,b,c,d,e,f,g,h$ 的信号可看作是七个关于这四位输入信号的布尔函数。对每个布尔函数我们都可以画出相应的电路图,但是感觉有些复杂,为什么我们不能进行化简呢?正好输入信号就是四位,可以使用 K-map 优化,事情就这样成了,比如 $a,b,e$ 这三个引脚的优化:
根据卡诺图我们可以得到:
同理其它引脚的表达式也如下:
$$ \begin{aligned} c &= \overline{I_3} \cdot \overline{I_2} \cdot I_1 \cdot \overline{I_0} +I_3 \cdot I_2 \cdot \overline{I_0} +I_3 \cdot I_2 \cdot I_1\\ d &= \overline{I_3} \cdot \overline{I_2} \cdot \overline{I_1} \cdot I_0+ \overline{I_3} \cdot I_2 \cdot \overline{I_1} \cdot \overline{I_0} +I_2 \cdot I_1 \cdot I_0+I_3 \cdot \overline{I_2} \cdot I_1 \cdot \overline{I_0} \\ f &= \overline{I_3} \cdot \overline{I_2} \cdot I_0+ \overline{I_3} \cdot \overline{I_2} \cdot I_1+ \overline{I_3} \cdot I_1 \cdot I_0+I_3 \cdot I_2 \cdot \overline{I_1} \cdot I_0\\ g &= \overline{I_3} \cdot \overline{I_2} \cdot \overline{I_1} + \overline{I_3} \cdot I_2 \cdot I_1 \cdot I_0+I_3 \cdot I_2 \cdot \overline{I_1} \cdot \overline{I_0} \\ \end{aligned} $$
根据简化后的表达式,我们可以画出如下的电路图:
在 Logisim 上模拟运行的结果如下
仿真激励与上板验证
我们将画好图的模块导出为 verilog 文件 MyMC14495.v
,并且为其编写激励模块:
|
|
在 Vivado 上运行仿真激励得到如下结果:
使用 Verilog 进行接线,编写引脚约束文件。上板验证,但是有盒我就不放图图了。
使四个七段数码管同时显示四个数字?
可以利用视觉残留效应:当物体在快速运动时, 人眼所看到的影像消失后,人眼仍能继续保留其影像 $\frac{1}{24}$ 秒左右的图像,因此我们可以用时钟作为选择器,以一定的(足够高的)频率输出四位的信号控制四个数码管的使能端,使得每次只亮起一个数码管,这个数码管显示的是其对应的数字(类似于显示器的扫描线)。这样的话,在第二个数字亮起的同时,上一个数字的像还没有从人眼中消失,在视觉上便得到了同时显示四个数字的效果:
Time | $E_3E_2E_1E_0$ | $O$ |
---|---|---|
0 | 1110 | N_0 |
1 | 1101 | N_1 |
2 | 1011 | N_2 |
3 | 0111 | N_3 |
4 | 1110 | N_0 |
… | … | … |
因为是四个数码管,因此这四段数码管应该在 $\frac{1}{24}$ 秒内完成一次扫描循环,单个数码管亮起熄灭的时间则是 $\frac{1}{24}\cdot\frac{1}{4}=\frac{1}{96}$ 秒。 这是我下周将要实现的内容。下播。