跳转至

汉字点阵显示

本次实验中,我们将介绍如何在 Logisim 中进行汉字的显示。

Image title


1.1.1 显示原理

Lab3 中我们提到,普通的 LED 灯包括亮起和熄灭两个状态,如果输入的信号为低电平,则 LED 等保持熄灭;如果输入的信号为高电平,则 LED 保持亮起。七段数码管可以视作由 7 个条形 LED 灯组成,根据其亮起 / 熄灭的状态不同显示不同的字符。

LED 显示屏采用了类似的原理:一块显示屏上有 \(r\times c\) 个 LED 灯,以矩形的方式排列。根据不同位置上 LED 灯的亮起与熄灭不同,我们可以显示不同的图案,其中就包括了汉字。

为了规范汉字显示时的字形,我们采用字形码作为显示方案。字形码是点阵代码的一种。为了将汉字在显示器或打印机上输出,我们把汉字视作一个个图形符号,并将其设计成点阵图,就得到了相应的点阵代码(字形码)。无论汉字的笔画有多少,我们都可以将其写在同样大小的方块中。

Image title

上图为「大」字的字形点阵及编码,你可以自行验证:对于点阵的每一行,右侧的 4 位十六进制数即对应着左侧的 16 位「二进制数」(有点为 1,无点为 0)。

Image title

我们在 Logisim 中可以使用 LED Matrix 组件,设置其大小为 \(16\times16\),以同样的方式显示中文字符。

提醒

由于 Logisim 中复制电路时,输入引脚的状态会被清空,故我们建议大家使用常量(Constant,在 Wiring 目录中)而不是输入端口对 LED 点阵进行赋值。

那么,如何得到汉字的字形码呢?你可以访问这个网站获取一定的帮助。

1.1.2 滚动显示

实际生活中,我们见到的 LED 显示屏往往具有滚动显示的功能,用较少的 LED 屏幕显示一段较长的文本。现在,我们也可以在 Logisim 中实现类似的功能。

现在,每个 LED 屏幕上显示的内容是动态的,因此我们不能使用常量作为数据的输入,而是选择使用只读存储器 ROM 的数据端口作为输入。这样,我们只需要给出确定的地址 address,ROM 便会给出对应的数据 data 显示在 LED 屏幕上了。

滚动显示的原理也十分直观:穷举每一时刻应当显示的字符即可。假定我们只在水平方向上进行移动操作,对于 LED 显示屏的某一行,某时刻其显示的数值为 0x3001。如果向左移动,则下一时刻显示的数值就是 0x6002,再下一时刻显示的数值就是 0xc004。因此,我们可以用一个计数器存储地址,并在 ROM 中写入如下的内容:

address     data
000         3001
001         6002
002         c004
...         ...

每个时钟周期,如果 address 增加,则 LED 显示屏会呈现向左移动的效果;如果 address 减小,则 LED 显示屏会呈现向右移动的效果。如果我们调整 address 变化的频率,则 LED 显示屏移动的速度也会发生变化。

上面展示了显示屏的某一行由 ROM 控制的流程。你可以使用 16 个 ROM 控制显示屏的每一行。

Tips:简单的实现

一种比较简单的实现方案是:让数据输入的方向与移动的方向垂直。例如,如果我们选择水平滚动显示,则可以将 LED Matrix 设置成以列为单位进行数据输入。这样,每一列对应的 ROM 存储的数据是一致的,仅存在地址上的偏移。例如:某时刻的显示情况如下:

col[0]: 0x0001
col[1]: 0x0002
col[2]: 0x0003
col[3]: 0xfffc

下一帧的显示情况则变为:

col[0]: 0x2345
col[1]: 0x0001
col[2]: 0x0002
col[3]: 0x0003

因此,假定 col[0] 对应的存储器为 ROM0,col[1] 对应的存储器为 ROM1,则只需要让存储的数据满足关系 ROM0[i] = ROM1[i+1],即可在地址为 address 时正确显示此时的数据(col[0] = ROM0[address],col[1] = ROM1[address])。

ROM 组件位于 Memory 目录下,可定制的内容包括存储单元数目、存储单元位宽以及内部存储的数值。你可以直接点击对应的存储单元,在键盘上输入该单元存储的数值;也可以使用特定的文件进行批量导入。文件开头必须为 v2.0 raw,后面的十六进制字形码可写作任意行,顺序正确即可。

Image title Image title

例子:滚动显示

下面是助教实现的对于「科」字的向上滚动显示。你可以参考其实现的思路完成自己的设计。

Image title Image title Image title

那么,如何实现循环显示呢?只需要让存储单元「循环」存储即可。

题目 1-2:汉字点阵显示

请结合以上内容,完成本项练习


最后更新: November 29, 2023

评论

Authors: wintermelon008