跳轉到內容

Hempl/LCD

來自華夏公益教科書
Mizar32 I2C LCD 字元顯示模組

Mizar32 LCD 顯示屏是一個附加硬體模組,可以插入 Mizar32 主機板的六個匯流排聯結器中的任何一個。它有一個 16 列 2 行的液晶顯示屏,每個位置可以顯示一系列字元中的一個,它有六個按鈕:左、右、上、下、選擇和重置。

紅色重置按鈕會重置控制顯示屏的板載 PIC 微控制器,而五個按鈕可以透過 I2C 匯流排由主處理器讀取。

硬體檢視

[編輯 | 編輯原始碼]

LCD 顯示屏由一個 PIC 16F84 微控制器執行,這是一個低功耗處理器,執行一個由 Simplemachines 編寫的程式,該程式與 Ampire 162B LCD 面板對話,檢測按鈕按下並透過 I2C 匯流排與主 AVR32 處理器通訊。

LCD 面板本身託管另一個微處理器,SED 1278,它接收來自 PIC 的命令,為 LCD 面板生成字元,並保持顯示屏重新整理。它有一個 40 個字元 2 行的內部字元記憶體,其中 16x2 在任何時候都顯示在 LCD 螢幕上。SED 1278 的程式在 ROM 中,無法更改。

I2C 匯流排速度

[編輯 | 編輯原始碼]

透過 I2C 與 LCD 顯示屏通訊時,Mizar32 的 I2C 匯流排速度必須設定為不快於 50kHz。如果 Mizar32 以高達 100kHz 的速度與其他 I2C 裝置通訊,這不會混淆 LCD 顯示屏:它能夠以高達 100kHz 的速度識別自己的地址(並拒絕所有其他地址),但只能以最高 50kHz 的速度處理資料包。

Mizar32 LCD 模組 USB 電源破解

電源供應

[編輯 | 編輯原始碼]

LCD 顯示屏模組需要 Mizar32 從其 7.2 伏直流電源插座供電。如果你希望從 Mizar32 的 USB 電源供電,你可以在 LCD 板的下方焊接一根電線,從 BUS5 聯結器的引腳 1(靠近板邊緣的中心)到 LCD1 聯結器的引腳 2(靠近“左”按鈕)。

I2C 命令集

[編輯 | 編輯原始碼]

該板響應 8 位 I2C 命令位元組 0x7C 到 0x7F(7 位從機地址 62 和 63)

命令 功能
0x7C 向 LCD 傳送命令
0x7D 讀取 LCD RAM 地址
0x7E 向 LCD 傳送資料位元組
0x7F 讀取按鈕開關

I2C 命令 7C:傳送 LCD 命令

[編輯 | 編輯原始碼]

從物理上來說,LCD 顯示屏有 2 行 16 個字元,但從內部來說,它有一個字元記憶體,它每行儲存 40 個字元,而 16x2 可見顯示屏只顯示內部字元記憶體的一部分。

列印超出第一行字元記憶體的第 40 個字元會自動傳遞到第二行的開頭,而超出第二行的第 40 個字元會從第一行的開頭繼續。類似地,當游標從任何一行的第一個字元向左移動時,會將其移動到另一行的第 40 個位置。

清除顯示並返回首頁

[編輯 | 編輯原始碼]

命令位元組 0:重置 LCD 模組

[編輯 | 編輯原始碼]

對於 SED1278,命令位元組 0 是一個無操作命令。在這裡,相反,PIC 將其識別為一個特殊情況,並重置 SED

  • 清除螢幕
  • 無游標顯示器
  • 兩行字元
  • 8x5 畫素字元字型
  • 傳送字元資料時游標向右移動;顯示屏不移動

你可以使用以下函式來完成此操作

(mizar32-lcd-reset)

命令位元組 1:清除顯示

[編輯 | 編輯原始碼]

命令位元組 1 將空格寫入字元記憶體的每個位置,將游標移動到字元記憶體的第一行第一列,並重置顯示屏移動,以便內部字元記憶體的每一行的第一個字元與物理顯示屏的第一個字元對齊。

(mizar32-lcd-clear)

命令位元組 2:返回首頁

[edit | edit source]

命令位元組 2 將游標移動到字元儲存區的首行首列,並重置顯示屏滾動。它等同於“清除顯示屏”,但不會清除字元儲存區的內容。

(mizar32-lcd-home)

資料輸入模式

[edit | edit source]

命令位元組 4:列印時,游標向右移動

[edit | edit source]

傳送命令位元組 4 後,在 LCD 顯示屏上列印字元會使游標向右移動一個位置:如果游標移出物理顯示屏的右邊緣,它將繼續寫入內部字元儲存區,但游標以及這些字元不會顯示在物理顯示屏上。

命令位元組 5:列印時,顯示屏向右滾動

[edit | edit source]

這是另一種反向列印文字的方式,這次保持游標在顯示屏上的相同位置,並在每次列印字元時將文字向右滾動一個位置。如果您處於這種模式,游標位於 (1,1),並列印“Hello”,最終將在第一行的第五個位置得到 H,並在第二行的前四個位置得到“olle”,因為從 40 列字元儲存區的任何一端移出都會在另一行的另一端繼續。

命令位元組 6:列印時,游標向左移動

[edit | edit source]

傳送命令位元組 6 後,列印字元會使游標向左移動一個位置,因此如果您列印“Hello”,寫入的內容將在顯示屏上反向顯示為“olleH”,游標停留在最後一個字元的左側。要看到這一點,您首先需要將游標移動到顯示屏的右側,否則它會立即移出顯示屏的左邊緣,只留下一個可見的“H”,並在第二行的末尾列印“olle”(超出螢幕)。

命令位元組 7:列印時,顯示屏向左滾動

[edit | edit source]

傳送命令位元組 7 後,每次將字元傳送到顯示屏時,游標都將停留在相同的物理位置,所有顯示的字元都將向左移動一個位置。另一種理解方式是 16x2 的物理顯示屏在虛擬顯示屏上向右移動一個位置,例如,如果它顯示的是 1-16 列,那麼它將顯示 2-17 列。要看到列印的文字,您首先需要將游標移動到顯示屏的右側,否則您顯示的所有內容都將立即從顯示屏的左邊緣移出,並且只有在列印了另外 24 個字元(24 個是因為虛擬顯示屏有 40 個字元寬,而物理顯示屏有 16 個字元寬)之後才會在右邊緣重新出現。

在 Hempl 中,可以使用以下函式選擇這四種選項:

功能 函式域
(mizar32-lcd-setup display-shift right-to-left) {T, NIL}

預設情況下,顯示屏不滾動,字元從左到右列印。

游標模式

[edit | edit source]

同時開啟或關閉顯示屏,並指定想要顯示的游標型別。

命令位元組 8:關閉顯示屏

[edit | edit source]

這將關閉顯示屏,顯示一個空白麵板。但是,它會記住 40x2 字元儲存區中的資料、使用者定義的字元、游標位置以及在物理顯示屏上顯示的字元儲存區的哪一部分。

命令位元組 12:開啟顯示屏,但不顯示游標

[edit | edit source]

如果顯示屏已關閉,則將其重新開啟,但不會顯示游標。

命令位元組 13:開啟顯示屏並顯示閃爍的塊狀游標

[edit | edit source]

如果顯示屏已關閉,則將其重新開啟,並在游標位置顯示一個閃爍的黑塊。

命令位元組 14:開啟顯示屏並顯示下劃線游標

[edit | edit source]

如果顯示屏已關閉,則將其重新開啟,並在游標位置顯示字元單元的底線全黑。

命令位元組 15:開啟顯示屏,並顯示下劃線和閃爍的塊狀游標

[edit | edit source]

在這種情況下,您將獲得恆定的下劃線和閃爍的塊狀游標。我不確定您為什麼要這樣做...

在 Hempl 中,可以使用以下函式選擇游標型別:

功能 函式域
(mizar32-lcd-cursor 'what) what = {none, line, block}

您還可以使用以下程式碼開啟或關閉 LCD 顯示屏:

功能 函式域
(mizar32-lcd-display 'what) what = {on, off}

當您重新開啟顯示屏時,Alcor6L 會記住游標型別並將其恢復。這適用於所有 Alcor6L 語言。

游標或顯示屏滾動

[edit | edit source]

還有一種方法可以左右滾動 40 列儲存區的可見部分,並將游標左右移動一個位置。

命令位元組 16:將游標向左移動一個位置

[edit | edit source]

這將游標在儲存區和顯示屏上同時向左移動一個字元位置。如果它移出顯示屏的可見部分,游標將不可見,如果它從第 1 列向左移動,它將移動到另一行的第 40 列。

命令位元組 20:將游標向右移動一個位置

[edit | edit source]

這將游標在儲存區和顯示屏上同時向右移動一個字元位置。如果它移出顯示屏的可見部分,游標將不可見,如果它從第 40 列向右移動,它將移動到另一行的第 1 列。

在 Hempl 中,可以使用以下程式碼執行這些操作:

功能 函式域
(mizar32-lcd-cursor 'dir) dir = {left, right}

命令位元組 24:將顯示屏向左滾動一個位置

[edit | edit source]

這將改變虛擬顯示屏的哪一部分在物理顯示屏上可見。它將所有可見的字元向左滾動一個位置,並在右邊緣顯示來自虛擬顯示屏的一列新字元。

當移動顯示屏時,游標在內部字元記憶體中的位置保持不變,因此在物理顯示屏上也看到它向左移動了一位。

命令位元組 28:將顯示屏向右移動一位

[編輯 | 編輯原始碼]

使用命令 28 可以獲得相反的效果,它將顯示的字元和游標向右移動一位,並在左側顯示兩個新字元。同樣,游標始終停留在之前所在的字元上。

在 Hempl 中,可以使用以下命令:

功能 函式域
(mizar32-lcd-display 'dir) dir = {left, right}

設定顯示屏操作模式

[編輯 | 編輯原始碼]

命令位元組 32-63

[編輯 | 編輯原始碼]

這些命令的位 4、8 和 16 設定顯示屏的操作模式

含義
0 1
4 顯示字型型別 5x8 5x11
8 顯示行數 1 行 2 行
16 介面資料長度 4 位 8 位

對於 Mizar32 顯示模組,您需要 5x8、2 行、4 位,這是上電時的預設設定。

設定 RAM 地址

[編輯 | 編輯原始碼]

命令位元組 64-127:設定 CG RAM 地址

[編輯 | 編輯原始碼]

命令位元組 64 到 127 將游標從顯示屏移動到字元生成器 RAM。以下資料位元組不會在螢幕上顯示任何內容,而是說明 8 個使用者定義字元(程式碼 0 到 7(以及 8 到 15))中哪些點是透明的,哪些是黑色的。

第一個使用者定義字元的定義位於位置 64 到 71,第二個位於 72 到 79,依此類推。每個位元組定義一個字元行,從上到下工作,其中 5 個最低有效位定義每行的 5 個畫素,按從左到右的順序 16、8、4、2、1。 "1" 位顯示為黑色。

例如,要將字元 0 和 1 定義為指向左邊的黑色三角形和指向右邊的黑色三角形

1
6
8 4 2 1 總計 1
6
8 4 2 1 總計
* 1 * 16
* * 3 = 2 + 1 * * 24 = 16 + 8
* * * 7 = 4 + 2 + 1 * * * 28 = 16 + 8 + 4
* * * * 15 = 8 + 4 + 2 + 1 * * * * 30 = 16 + 8 + 4 + 2
* * * 7 = 4 + 2 + 1 * * * 28 = 16 + 8 + 4
* * 3 = 2 + 1 * * 24 = 16 + 8
* 1 * 16
0 0

您需要傳送命令位元組 64,後跟 1、3、7、15、7、3、1、0、16、24、28、30、28、24、16、0,要返回到常規字元寫入模式以顯示它們,您需要發出 "設定 DD RAM 地址" 命令位元組(參見下一條目)。如果字元已顯示在螢幕上,則在重新定義時,其形狀會立即更改。在 Alcor6L 中,您可以使用以下函式呼叫完成所有這些操作

對於指向左邊的三角形,

(mizar32-lcd-definechar 0 (1 3 7 15 7 3 1) )

對於指向右邊的三角形,

(mizar32-lcd-definechar 1 (16 24 28 30 28 24 16) )

與命令位元組介面不同,Hempl 的 definechar 函式用於 LCD 會將您切換回正常字元寫入模式,並將文字游標保留在其所在的位置。

命令位元組 128-255:設定 DD RAM 地址

[編輯 | 編輯原始碼]

如果命令位元組的最高位被設定,則較低的 7 位設定游標在資料記憶體中的位置,資料記憶體是下一個字元將在顯示屏的字元記憶體中儲存的位置(以及在顯示屏移動時顯示該部分字元記憶體時顯示在螢幕上)。

程式碼 游標將移動到的位置
128-167 第一行 40 個字元
192-231 第二行 40 個字元

我不知道如果設定 DD RAM 地址為 168-191 或 232-255 會發生什麼。

在 Hempl 中,您可以使用以下命令:

功能 函式域
(mizar32-lcd-goto row column) row = {1, 2}, column = {1, 2, .., 40}

I2C 命令 7D:讀取地址計數器

[編輯 | 編輯原始碼]

I2C 命令 0x7D 讀取游標在字元記憶體中的當前位置,並將其透過 I2C 匯流排傳送回。

這是在您傳送資料位元組時下一個字元將儲存的內部記憶體地址。返回的位元組是從 0 到 127 的值,對應於上述 "設定 DD RAM 地址" 命令中使用的程式碼的較低的 7 位。在 PicoLisp 中,以下函式將返回一個列表,其 car 為 1 或 2,其 cadr 為 1 到 40 之間的值。

(setq pos-tab (mizar32-lcd-getpos) )
(setq
   row (car pos-tab)      # Row number
   col (cadr pos-tab) )   # Column number

I2C 命令 7E:傳送 LCD 資料位元組

[編輯 | 編輯原始碼]

I2C 命令 0x7E 將資料傳送到 LCD 顯示屏。

您傳送的每個資料位元組通常都會在 LCD 顯示屏上顯示一個字元,並將游標向右移動一個位置。

程式碼 它們顯示的內容
0-7 8 個使用者定義字元
8-15 相同的 8 個使用者定義字元
16-31 空白
32-126 標準 ASCII 字元
127
128-159 空白
160-255 漢字和特殊符號

唯一的例外是當您剛剛傳送了命令位元組 64-127 之一,這將使以下資料位元組設定使用者定義字元的畫素(參見上面的 "設定 CG RAM 地址")。

在 Hempl 中,您可以使用以下命令:

(mizar32-lcd-prinl data)

其中 data 是一個或多個字串和數字的列表,以逗號分隔。字串是顯示 ASCII 文字訊息的正常方式,而數值資料應具有 0 到 255 之間的值,並顯示上述表格中的單個字元。相反,要以十進位制形式列印一個整數,您需要先對其進行格式化。例如,如果變數 gen 包含一個適合 3 個字元(0-999)的整數,則可以使用

(mizar32-lcd-prinl (format gen) )

I2C 命令 7F:讀取按鈕

[編輯 | 編輯原始碼]

I2C 命令 0x7F 獲取 LCD 模組的按鈕開關的當前狀態,這是一個位元組,其中一些組合的較低的 5 位被設定為指示當前按下了哪些按鈕。

選擇
1 2 4 8 16

顯示屏可以可靠地檢測到選擇按鈕是否被按下以及其他四個按鈕中的任意兩個是否被按下。如果其他三個按鈕被按下,模組將返回一個位元組,表示所有四個按鈕都被按下(這是按鈕在電路板上連線方式的結果,使用只有四根線的五根按鈕)。

在 Hempl 中,您可以執行以下操作:

(setq lcd-buttons (mizar32-lcd-buttons) )

每個函式都返回一個字串,其中包含字元 LRUDS 的選擇,以說明當前是否按下了左、右、上、下和選擇按鈕。如果未按下任何按鈕,則返回一個空字串。硬體允許可靠地檢測到選擇按鈕以及其他四個按鈕中的最多兩個,但如果按下左、右、上和下中的三個按鈕,則返回所有四個按鈕。

軟體檢視

[編輯 | 編輯原始碼]

如果您敢於嘗試,可以使用上述程式碼和 eLua 的 i2c 平臺模組基元與 LCD 顯示模組進行通訊。例如,要顯示 "Hello",您可以說

(de mizar32-lcd-write-i2c (x)
   (i2c-setup 0 50000)
   (i2c-start 0)
   (if (not (= 0 (i2c-address 0 63 *i2c-transmitter*)))
      (i2c-write 0 x) )
   (i2c-stop 0) )

(mizar32-lcd-write-i2c 'Hello)

您也可以從我們的 github 頁面下載上述示例的 程式碼

SimpleMachines 在 Hempl 中添加了一個平臺模組(Mizar32 的 LCD 模組),如上文所述,它為您完成了所有 I2C 幻術和特殊計時。使用此模組來實現上述功能,您只需說

(mizar32-lcd-prinl 'Hello)

它提供以下函式。

LCD 重置

[編輯 | 編輯原始碼]
(mizar32-lcd-reset)

初始化顯示器,將所有內容重置為初始狀態:清除螢幕,無游標,顯示 40 列記憶體中的第 1-16 列,準備在 (1,1) 位置列印,從左到右寫入文字,並在每個字元後將游標向右移動一個位置。您不必在程式開始時呼叫重置,但這樣做可以確保即使顯示器因先前執行而處於奇怪狀態,您的程式仍然可以正常工作。

LCD 設定

[編輯 | 編輯原始碼]
(mizar32-lcd-setup display-shift right-to-left)

這可以用於設定 LCD 顯示器的一些奇怪的操作模式。兩個引數都是可選的,如果您省略它們,它們預設值為 false,這將設定合理的模式。

display_shift:如果為 true,則在您隨後列印的每個字元中,游標將像往常一樣在字元記憶體中移動一個位置,但顯示器的內容也會在水平方向上向相反方向移動一個位置,以便游標保持在物理顯示器的同一列。這可用於實現“滾動文字”效果。但是請注意,當游標從第 40 列移至第 1 列或反之亦然時,它會翻轉到另一行。

right_to_left:如果為 true,則文字將從右到左列印:游標將在字元記憶體中向左移動一個位置,並且如果也啟用了顯示器移動,則顯示器的內容將向右移動,以便游標保持在螢幕上的同一列。

LCD 清除

[編輯 | 編輯原始碼]
(mizar32-lcd-clear)

清除顯示器,將游標移動到左上角(位置 1,1)並重置顯示器移動以顯示第 1 到第 16 列。

LCD 主頁

[編輯 | 編輯原始碼]
(mizar32-lcd-home)

將游標移動到左上角(位置 1,1)並重置顯示器移動。

LCD 游標移動到

[編輯 | 編輯原始碼]
(mizar32-lcd-goto row column)

將游標移動到指定的行和列。

  • row:一個數字(1 或 2),表示您要移動到的行。
  • column:一個數字(1 到 40),表示該行中字元記憶體中的位置。

LCD 游標位置

[編輯 | 編輯原始碼]
示例 返回值
(setq lcd-pos (mizar32-lcd-getpos) ) (car lcd-pos), (cadr lcd-pos)

返回當前游標位置。

符號 含義
row 一個數字(1 或 2),表示當前行。
column 一個數字(1 到 40),表示字元記憶體中當前列。

LCD 列印

[編輯 | 編輯原始碼]
(mizar32-lcd-prinl [data1] [data2] ... [datan])

從當前游標位置開始寫入 LCD 字元記憶體。游標將為每個列印的字元前進一個位置。當它超過第 40 列時,它會移動到另一行的第 1 列(反之亦然,當從右到左列印時)。

每個資料項可以是字串或整數。字串是顯示 ASCII 文字訊息的正常方式。整數引數應具有從 0 到 255 的值以顯示單個字元,該字元可以是使用者定義的字元 0-7、常規 ASCII 字元 32-125 以及 126 和 127(分別用於向右和向左箭頭)以及具有程式碼 160-255 的中文、希臘語和數學符號。

LCD 游標設定

[編輯 | 編輯原始碼]
(mizar32-lcd-cursor what)

設定在游標位置顯示的游標型別或將游標向左或向右移動。

what 是一個字串,用於說明應該執行的操作。

  • "none"、"line" 或 "block" 將分別在游標位置顯示無可見游標、恆定下劃線或閃爍的實心方塊。
  • "left" 或 "right" 將游標在字元記憶體和顯示器上向左或向右移動一個位置,而不會改變底層字元。在這種情況下,顯示器永遠不會移動,並且像往常一樣,游標會在一行的第 40 列和另一行的第 1 列之間包裹。

LCD 顯示器設定

[編輯 | 編輯原始碼]
(mizar32-lcd-display what)

開啟或關閉物理顯示器,或將顯示的字元向左或向右移動。

what 是一個字串,用於說明應該執行的操作。

  • "off" 和 "on" 分別關閉和開啟物理顯示器。當顯示器關閉時,它看起來是空白的,但字元記憶體的內容、游標的位置和型別、使用者定義的字元和設定模式都會被記住,並且您可以在顯示器關閉時寫入字元記憶體並執行所有其他操作。這使您能夠更新顯示器,而不會讓觀眾看到太多閃爍。
  • "left" 或 "right" 將顯示的字元向左或向右移動一個位置。例如,如果它顯示的是通常的第 1-16 列,並且您說 mizar32.lcd.display("left")(或其他語言中的等效程式碼),那麼它將顯示第 2-17 列:可見字元向左移動,但字元記憶體上的視窗向右移動。

使用者定義的字元

[編輯 | 編輯原始碼]
(mizar32-lcd-definechar code glyph)

對八個使用者可定義字元中的一個進行程式設計,這些字元的程式碼為 0 到 7。定義後,可以使用 mizar32.lcd.print(n) 顯示字元,其中 n 是從 0 到 7 的數字。如果正在顯示的字元是正在顯示的字元,則其可見形式將在顯示器上立即發生更改。在開機時,8 個字元被定義為隨機垃圾。

  • code:一個數字(0 到 7),表示您要重新定義的字元。
  • glyph:一個最多包含八個數字的表,表示字元的八行的位模式,從上到下按順序排列。這些數字中的每一個都是一個從 0 到 31 的值,用於定義該行中哪個 5 位應該是黑色的。畫素從左到右的值分別為 16、8、4、2 和 1。例如,{1, 3, 7, 15, 31, 15, 7, 3, 1, 0} 將在上面的 7 行中定義一個左指的實心三角形。額外的行將被忽略,缺少的行將被空白。

若要使用 PicoLisp 以法語列印,您可以嘗試以下操作

# A PicoLisp program to demonstrate
# user defined characters.
(de print-msg ()
   # clear screen first
   (mizar32-lcd-clear)

   # define the French accent character `é'.
   (mizar32-lcd-definechar 0 (1 2 14 17 31 16 14 0))

   # print "Liberté, égalité".
   (mizar32-lcd-prinl 'Libert 0 ",")
   (mizar32-lcd-prinl 0 'galit 0 ",")

   # print fraternité in the next line·
   (mizar32-lcd-goto 2 1)
   (mizar32-lcd-prinl 'fraternit 0) )

(print-msg)

請注意:您還可以從我們在 github 上的示例儲存庫中下載上述程式碼 french.l

LCD 按鈕

[編輯 | 編輯原始碼]
(setq buttons (mizar32-lcd-buttons) )

說明當前按下五個使用者按鈕中的哪一個。

  • buttons 是一個字串(在 PicoLisp 中,buttons 是一個列表),包含最多五個字元 L、R、U、D 和 S,表示當前是否按下左、右、上、下和選擇按鈕。如果沒有按下,則返回空字串。硬體允許可靠地檢測選擇以及其他四個按鈕中的最多兩個:如果按下左、右、上和下中的三個,則返回所有四個按鈕。

例如,在遊戲中使用的程式碼片段可以是(在 PicoLisp 中)

(setq buttons (mizar32-lcd-buttons))
(if (member "S" (chop buttons))
   (do-select) )

進一步閱讀

[編輯 | 編輯原始碼]
華夏公益教科書