c++ - 液晶屏旋转1位位图

标签 c++ c arrays arduino atmega

我正在我的微 Controller (Arduino Mega) 上的一个数组中存储 Hitachi HD44780 LCD Controller 的一些自定义字符。一个字符基本上是一个位图,颜色深度为一位,宽 5 像素,高 8 像素。

为了尽可能多地节省宝贵的内存,我决定旋转存储数据。否则我会每行浪费三位。因此,例如,一个 É 将像这样存储:

---#####   0x1F
-#-#-#-#   0x55
#--#-#-#   0x95
---#-#-#   0x15
---#---#   0x11

输出应该是这样的:

-----#--   0x04
----#---   0x08
--------   0x00
---#####   0x1F
---#----   0x10
---####-   0x1E
---#----   0x10
---#####   0x1F

我的问题是,将其转回 É 的最有效方法是什么。我们在这里谈论的是一个只有 8 KB RAM 的 16 MHz 处理器,因此保持它尽可能快和尽可能小是关键。编程语言为C(++)。

我个人的想法是创建所需的 8 字节数组并从左到右扫描行,用一些位掩码设置位。这就是为什么我还镜像了这些字母,这样我就可以轻松地将位掩码右移并将其用于两个数组。

基本上扫描第一个输入字节,相应地设置输出数组的第 3 位,扫描第二行,设置输出数组的第 4 位,依此类推。

但是有没有更好的方法来实现这一点?

最佳答案

首先,谢谢。这是我几个月来看到的最有趣的问题。

所以空间是制约因素。正如我所见,主要问题是位提取和插入的成本会很快耗尽代码内存。从一个 5 字节的数组中提取一个位,然后插入到一个 8 字节的数组中的循环可能需要一大块可执行代码才能做到这一点。

我建议表示数据的一种不同方式是支持一种 run-length encoding.输出字符可以被认为是一个单比特串,由一个 0/​​1 流组成,然后是其他 0/1 流,直到填满 64 位。

实际上,您是在编码状态变化,而不是实际的位模式。 数据将是 1 位宽,表示 0 或 1,长度为 3 位宽,表示长度 1 .. 8。

因此与

-----#--   0x04
----#---   0x08
--------   0x00
---#####   0x1F

编码为

  • 0101-0位,共6位位置,编码为6-1(-----)
  • 1000-1位,共1位位置,编码为1-1(#)
  • 0101-0位,共6位位置,编码为6-1(-----)
  • 1000-1位,共1位位置,编码为1-1(#)
  • 0111-0位,共8位位置,编码为8-1(--------)
  • 0101-0位,共6位位置,编码为6-1(-----)
  • 1100 - 1 bit,共5个bit位置,编码为5 - 1 (#####)

这是 3.5 个字节而不是 4 个字节来编码。


主题的一个变体是不对每个字节的前 3 位进行编码。当可执行代码到达那里时,它会自动将三个 0 放入其中。这将以一些额外的可执行代码为代价,将上面这个小例子的编码成本降低到大约 2.5 个字节。

我认为这里的好处是您每次都从一个字节的一个半字节中精确地提取位,并将它们放入单个字节的位中。恕我直言,这将获得最大的性价比。

关于c++ - 液晶屏旋转1位位图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45537419/

相关文章:

C++ | DLL/EXE - 如何从导出类中调用另一个类方法?

c - 使用环境变量执行不同的文件

c - 如何知道(3 个数字中)第二大的数字是多少? (C)

javascript - 根据元素的数字顺序合并两个数组

c++ - 构造函数的快捷方式

c++ - GetVolumePathName() 失败,错误 158 : ERROR_NOT_LOCKED

c++ - 如何在 CLion 中设置 -v 编译器选项并查看相应结果

c - 'switch' 比 'if' 快吗?

python - N点与numpy/scipy中的引用之间的有效距离计算

python - Numpy:多个外积