[英]Rotating 1 bit bitmap for lcd screen
我在微控制器(Arduino Mega)的陣列中存儲了一些Hitachi HD44780 LCD控制器的自定義字符。 字符基本上是位圖,其顏色深度為一位,寬度為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個字節的數組中,可能需要大量的可執行代碼來完成。
我建議表示數據的另一種方法是支持一種游程長度編碼。 可以將輸出字符視為單個位字符串,由0 / 1s的流組成,然后由其他0 / 1s的流組成,直到填充64位為止。
實際上,您正在編碼狀態更改,而不是實際的位模式。 數據將為1位寬,表示0或1,長度為3位寬,表示長度1..8。
因此與
-----#-- 0x04
----#--- 0x08
-------- 0x00
---##### 0x1F
編碼將是
這是3.5個字節,而不是4個字節進行編碼。
主題的一種變化是不對每個字節的前3位進行編碼。 當可執行代碼出現時,它會自動將三個0放入其中。 這將使上面的小示例的編碼成本下降到約2.5個字節,而這會花費一些額外的可執行代碼。
我認為這樣做的好處是,您每次都從一個字節的半字節中精確地提取一些位,然后將它們放入單個字節的位中。 IMNSHO將獲得最大的收益。
有沒有更好的方法來實現這一目標?
與其以旋轉方式保存字符位圖,不如將其打包為5個字節。
要在編譯時打包:
創建32個常量(或eunm
)
#define L_____ 0 #define L____X 1 #define L___X_ 2 ... #define LXXXX_ 30 #define LXXXXX 31
制作宏
#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))))
制作字符位圖。 這樣做的好處是源代碼看起來像字符位圖。
unsigned char letter[5] = { CHBM( \\ L__X__, \\ L_X___, \\ L_____, \\ LXXXXX, \\ LX____, \\ LXXXX_, \\ LX____, \\ LXXXXX) };
在運行時打開包裝-可能有多種方法。 下面是一個簡單的想法。
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;
}
另一個想法是使用更多的代碼,但使用32位變量。 這是OP可以配置不同代碼的位置。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.