Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ lcd屏幕旋转1位位图_C++_C_Arrays_Arduino_Atmega - Fatal编程技术网

C++ lcd屏幕旋转1位位图

C++ lcd屏幕旋转1位位图,c++,c,arrays,arduino,atmega,C++,C,Arrays,Arduino,Atmega,我正在我的微控制器(Arduino Mega)上的阵列中存储日立HD44780 LCD控制器的一些自定义字符。字符基本上是一个颜色深度为一位的位图,宽5像素,高8像素 为了尽可能节省宝贵的内存,我决定存储数据。否则,我将浪费每行三位。例如,一个É的存储方式如下: ---##### 0x1F -#-#-#-# 0x55 #--#-#-# 0x95 ---#-#-# 0x15 ---#---# 0x11 -----#-- 0x04 ----#--- 0x08 -----

我正在我的微控制器(Arduino Mega)上的阵列中存储日立HD44780 LCD控制器的一些自定义字符。字符基本上是一个颜色深度为一位的位图,宽5像素,高8像素

为了尽可能节省宝贵的内存,我决定存储数据。否则,我将浪费每行三位。例如,一个É的存储方式如下:

---#####   0x1F
-#-#-#-#   0x55
#--#-#-#   0x95
---#-#-#   0x15
---#---#   0x11
-----#--   0x04
----#---   0x08
--------   0x00
---#####   0x1F
---#----   0x10
---####-   0x1E
---#----   0x10
---#####   0x1F
输出应如下所示:

---#####   0x1F
-#-#-#-#   0x55
#--#-#-#   0x95
---#-#-#   0x15
---#---#   0x11
-----#--   0x04
----#---   0x08
--------   0x00
---#####   0x1F
---#----   0x10
---####-   0x1E
---#----   0x10
---#####   0x1F
我的问题是,怎样才能最有效地将这一切变回现实。我们这里说的是一个只有8KB内存的16MHz处理器,所以保持它尽可能快和小是关键。编程语言是C++

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

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


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

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

因此,空间是制约因素。在我看来,主要的问题是位提取和插入的成本会很快消耗代码内存。一个循环从一个5字节的数组中提取一个位,然后插入到一个8字节的数组中,这可能需要大量的可执行代码来完成

我建议另一种表示数据的方法是支持一种输出字符,这种输出字符可以被认为是一个单位字符串,由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位,共5位位置,编码为5-1
这是3.5字节,而不是4字节的编码


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


我认为这样做的好处是,每次从字节的一个半字节中精确地提取位,然后将它们放入单个字节的位中。我想这将是一个最划算的价格。

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

因此,空间是制约因素。在我看来,主要的问题是位提取和插入的成本会很快消耗代码内存。一个循环从一个5字节的数组中提取一个位,然后插入到一个8字节的数组中,这可能需要大量的可执行代码来完成

我建议另一种表示数据的方法是支持一种输出字符,这种输出字符可以被认为是一个单位字符串,由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位,共5位位置,编码为5-1
这是3.5字节,而不是4字节的编码


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

我认为这样做的好处是,每次从字节的一个半字节中精确地提取位,然后将它们放入单个字节的位中。这将是最大的规模爆炸为美元

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

与其以旋转的方式保存字符位图,不如将其压缩为5个字节

要在编译时打包,请执行以下操作:

  • 创建32个常量(或
    eunm

  • 制作宏

    #define PACK8_5(a,b,c,d,e,f,g,h) \
      ((((((uint64_t)(a) << 5) + (b)) << 5) + (c)) << 5) + (d) ...
    #define UNPACK40_5(a) \
      ((a) >> 32) & 31, ((a) >> 24) & 31, ((a) >> 16) & 31, ((a) >> 8) & 31, (a) & 31 
    #define CHBM(a,b,c,d,e,f,g,h) (UNPACK40_5(PACK8_5((a),(b),(c),(d),(e),(f),(g),(h))))
    
  • 要在运行时解包,可以使用多种方法。下面是一个简单的想法

    void unpack5to8(unsigned char dest[8], const unsigned char src[5]) {
      uint64_t pack = src[0];
      for (unsigned i=1; i<5; i++) {
        pack <<= 8;
        pack += src[i];
      }
      for (unsigned i=8; i>0; ) {
        i--;
        dest[i] = pack & 31;
        pack >>= 5;
      }
    
    void unpack5to8(unsigned char dest[8],const unsigned char src[5]){
    uint64_t pack=src[0];
    对于(无符号i=1;i=5;
    }
    
    另一个想法是使用更多的代码,但使用32位变量。这是OP可以分析不同代码的地方

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

    与其以旋转的方式保存字符位图,不如将其压缩为5个字节

    要在编译时打包,请执行以下操作:

  • 创建32个常量(或
    eunm