GPIO 與 UART
除了 I2C,腳本還能操作 GPIO 腳位,以及跟 UART 面板互動。GPIO 在模擬後端
(mock)就能跑;UART 需要真的接上會回話的硬體,模擬後端沒有對應的模擬。
gpio.write/gpio.read/gpio.release
gpio.write(0, true) -- 把腳位 0 設成輸出,寫入高電位
local v = gpio.read(0) -- 讀回目前電位:1(高)或 0(低)
gpio.write(0, false) -- 寫入低電位;也可以直接寫數字 gpio.write(0, 0)
gpio.release(0) -- 交還腳位,讓其他人可以使用gpio.write(腳位, 電位):把腳位設為輸出並寫入電位。電位可以寫true/false, 也可以直接寫數字(非0是高、0是低)。gpio.read(腳位):讀回目前腳位的電位,回傳1或0。腳位如果之前已經被同一支 腳本gpio.write()設成輸出,gpio.read()讀的就是目前輸出的鎖存值,不用先切回 輸入。gpio.release(腳位):提早把腳位交還,讓其他使用者(其他面板、下一次手動操作) 可以接手。就算不呼叫,腳本結束時(不論通過、失敗、出錯或被中止)程式都會自動 收回這支腳本佔用的全部腳位——gpio.release()只是給你一個提早釋放的手段,不是 唯一的收尾方式。
⚠ 模擬後端只模擬腳位 0~3:mock 只會回應這四支腳位的讀寫,其餘腳位編號在
mock 上會失敗;真實硬體支援的腳位數依接的裝置而定。
範例:腳位 0~3 輪流輸出高/低並讀回確認
-- GPIO 腳位 0~3 的寫入/讀回/釋放;hal_mock 只模擬這四支腳位。
for pin = 0, 3 do
gpio.write(pin, true)
check(gpio.read(pin) == 1, "pin " .. pin .. " reads back high")
gpio.write(pin, false)
check(gpio.read(pin) == 0, "pin " .. pin .. " reads back low")
gpio.release(pin)
end
log("info", "gpio_toggle done")預期輸出
CHECK OK: pin 0 reads back high
CHECK OK: pin 0 reads back low
CHECK OK: pin 1 reads back high
CHECK OK: pin 1 reads back low
CHECK OK: pin 2 reads back high
CHECK OK: pin 2 reads back low
CHECK OK: pin 3 reads back high
CHECK OK: pin 3 reads back low
gpio_toggle doneuart.write/uart.read/uart.expect:需要真實硬體
uart.write("PING\n") -- 把字串原樣送出
local line = uart.read(2000) -- 等最多 2000ms,等到一行就回傳字串,逾時回傳 nil
local line2, num = uart.expect("^PONG (%d+)", 2000) -- 等到就回傳整行+括號比對到的內容,逾時回傳 niluart.write(字串 [, panel]):原樣送出字串,不會自動加換行。uart.read(逾時毫秒 [, panel]):在時限內等待下一行收到的資料;逾時就回傳nil,不會讓腳本出錯。uart.expect(樣式, 逾時毫秒 [, panel]):跟uart.read一樣等待,但只在等到 「符合樣式」的一行才算數(樣式是string.find用的 Lua pattern);等到符合的 行時,第一個回傳值是整行內容,接著是樣式裡每一組括號(...)各自比對到的 子字串(沒有括號就只回傳整行),逾時一樣回傳nil。panel都是可省略的最後一個參數:目前的分頁如果剛好只開了一個 UART 面板, 省略就是指那一個;開了不只一個(或一個都沒開)就必須自己指定,不然會出錯。- ⚠
uart.read/uart.expect只看得到這支腳本本次執行、第一次呼叫任何一個uart.*之後才到達的資料,執行前就已經在面板上的舊資料不算「已經到的」; 該看的資料如果在腳本讀到之前就被覆寫掉,兩者都會出錯提醒你(而不是靜默漏看)。
⚠ uart.* 沒辦法在模擬後端上真的跑:mock 不會模擬任何 UART 裝置的回話,
下面這支範例只用來示範語法,實際執行需要接上一個會回應 PING/PONG 這類約定
的真實裝置。
-- 需要真實 UART 硬體才能執行:等待裝置回覆符合特定樣式的一行。
-- (hal_mock 沒有 UART 模擬,本檔只在建置期做語法檢查,不會被實際執行。)
uart.write("PING\n")
local line = uart.expect("^PONG", 2000)
if line == nil then
fail("no PONG reply within 2000ms")
end
log("info", "uart_expect got: " .. line)⚠ 這支範例需要實體硬體才能真的執行,模擬後端(mock)沒有對應的裝置可以回應。
接下來
下一頁介紹 dump/dump_all/file.append/timestamp:怎麼把暫存器內容或
自己的訊息留下記錄。