早在我將舊型電話按鍵盤改做數字鍵盤之前,就覺得直接驅動 3x4 數字鍵盤至少需要用到 7 條 GPIO 接線,這樣太過佔用 GPIO 腳位了,便有了該將之改造成 I²C (Inter-Integrated Circuit) 介面的想法。
尋找到的 MCP23008 是一個具有將串列介面擴充成 8 位元輸入/輸出的 IC,查看了它的 data sheet,直覺應該可以達成目的,便先買了兩顆來試試。
在 Raspberry Pi 的測試
若不能確認 Raspbian 是否已啟用 I²C,可參考 Using the I2C Interface 的說明,該文也列出了稍後即將使用到的 SMBus Functions。
再來要在麵包板上接線-將 Raspberry Pi 與 MCP23008 的 I²C 信號腳位連接,MCP23008 的 GPIO 與數字鍵盤的接腳連接,如以下所示。
RPi MCP23008 3x4 Keypad
--- -------- ----------
SCL <---> SCL
SDA <---> SDA
3V3 <---> VDD
GND <---> VSS
GP0 ----> C1
GP1 ----> C2
GP2 ----> C3
GP3 <---- R1
GP4 <---- R2
GP5 <---- R3
GP6 <---- R4
MCP23008 有三個接腳 (A0, A1, A2) 是用來設定從屬裝置在 I²C bus 上的位址 (address),將其皆接在 GND 可得位址為 0x20,事後可用 i2cdetect 指令確認位址是否如預期。另外還有 i2cget 與 i2cset 兩個指令可用來對從屬裝置做讀取與寫入。
pi@raspberrypi ~ $ sudo i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: 20 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
MCP23008 內部有 11 個暫存器做設定與控制用的,以下稱 CCR (Configuration and Control Registers),程式將對這些 CCR 進行讀取或寫入以達成與所連接的裝置通信或控制的目的。
我將這些基本功能編寫成一個 MCP23008 類別以方便讀取或寫入 CCR,基於此再編寫了一個 MyNumPad 類別,使應用程式輕易讀取數字鍵盤的輸入。程式範例如下:
#!/usr/bin/python
from mcp23008 import MCP23008
import time
class MyNumPad:
keys= [['1','2','3'],['4','5','6'],['7','8','9'],['*','0','#']]
def __init__(self, address):
self.mcp= MCP23008(address)
def read(self):
self.mcp.writeByte('IODIR', 0b11111000)
self.mcp.writeByte('GPIO', 0)
self.mcp.writeByte('GPPU', 0b11111111)
for i in range(3):
self.mcp.writeByte('GPIO', (1 << i) ^ 0b11111111)
time.sleep(0.05)
v= (self.mcp.readByte('GPIO') | 0b00000111) ^ 0b11111111
for j in range(4):
if (v & (0b00001000 << j)) != 0:
time.sleep(0.1)
return self.keys[j][i]
return 0
# test read input from MyNumPad
try:
npad= MyNumPad(0x20)
while True:
ch= npad.read()
if ch != 0:
print ch
except KeyboardInterrupt:
pass
使用 MCP23008 的小提示
各 GPIO 接腳僅可做內部 PULL-UP 的控制,不像直接使用 Raspberry Pi 的 GPIO 可以控制做 PULL-UP 或 PULL-DOWN,所以程式在掃瞄鍵盤按下時是要判斷電位為 LOW。
另外,RESET 與三個位址接腳不要空接,否則 MC23008 可能會處在不穩定的狀態。
下次,來試試接 16x2 LCD 顯示器模組。


沒有留言:
張貼留言