MCP23S17 16-Bit I/O Expander with SPI

1.關於MCP23S17

MCP23S17 IO擴充IC使用SPI介面控制,與74HC166及74HC4094的差異是,MCP23S17可規劃I/O腳的方向,也就是可以定義成輸入/輸出作為使用,而控制上採用SPI也與一般的串列I/O使用時序控制而有所不同,基本上如果使用時序控制的話,只要能夠了解動作時序,使用程式將時序刻出來就可以進行控制,而使用MCP23S17這樣的擴充IO時就必須先具備理解暫存器的概念,透過SPI的Read/Write來讀取及控制其相關暫存器。

比起一般串列串列IO來說MCP23S17更像是一般MCU通用型的I/O擴充,他提供了以下特徵的功能:

a.提供PortA,B兩組8Bit共16bit的I/O

b.可獨立規劃每1bit I/O方向(輸入/輸出)

c.提供PortA,B兩組狀態變化中斷輸出(INTA,INTB)

d.sink/source current達25mA

e.提供Address定址功能可節省SPI chip select 腳位(A2,A1,A0)

f.超寬的工作電壓1.8V~5.5V

 2.MCP23S17 I/O相關暫存器

2.1 IODIR I/O方向控制暫存器

用來設定PortA及PortB方向性,可以針對某1bit I/O進行方向設置。

1 = Input輸入, 0 = Output輸出

2.2 IOPL I/O邏輯反向控制暫存器

用來設定反應I/O暫存器狀態是否反向用。

1 = 反向I/O暫存器狀態

0=I/O狀態輸入不變

如果啟用該功能I/O腳上如果輸入是正邏輯(1)則讀取時會得到負邏輯(0)。

2.3 GPINTEN I/O狀態變化中斷暫存器

MCP23S17支援I/O產生變化時,由INTA或INTB腳位輸出中斷訊號,而變化比較的方式與條件須透過INTCON以及DEFVAL做設定,可以設定I/O腳與前次的值做比較,也就是只要狀態改變時,就產生中斷,或者是與DEFVAL做比較,當I/O腳狀態值與DEFVAL不相同時,則產生中斷。

如此一來便可以設定I/O變化時產生中斷,或者是特定條件發生時才產生中斷的應用。

1 = 致能I/O中斷功能

0 = 禁止I/O中斷功能

2.4 DEFVAL 預設值暫存器

如2.3所說,設定GPINTEN時可設定該暫存器進行I/O狀態比較,當狀態不符時,則會產生中斷訊號。

2.5 INTCON 中斷條件控制

這邊即是2.3節所說的,MCP23S17可以有兩種觸發條件的選擇,其一是可設定I/O腳狀態與DEFVAL暫存器比較,當位元狀態相異時則產生中斷,另外一個則是,與I/O本身前次狀態比較,也就是當狀態改變的時候,則產生中斷。

1 = 設定I/O狀態與DEFVAL比較

0 = 設定I/O與前次狀態比較

3.MCP23S17 Configuration Register

MCP23S17提供數個控制設定用的暫存器,其中包含一些通用的設定,中斷旗標以及I/O狀態的讀取等等。

3.1 IOCON I/O擴充配置暫存器

這個暫存器內包含整個IC的通用設定。

a.BANK 控制器暫存器配置方式

1 = 將A、B兩個Port的暫存器切開,變成兩塊獨立區域,此時透過SPI一次僅能「寫」入1byte資料(8bit mode)。

0 = A、B兩Port的暫存器會連續擺放,此投透過SPI一次可「寫」入2byte資料(16bit mode)。

在Spec中有提及8bit mode與16bit mode其差異在於暫存器擺放位置是否連續,以及使用SPI操作時可同時操作位址長度

b.MIRROR INT腳位鏡像設定

1 = 致能鏡像

0 = 取消鏡像

鏡像設定啟用的時候IC內部會將INTA與INTB使用OR閘拉再一起,也就是當其中一個人有中斷觸發產生的時候,INTA與INTB同時都會產生中斷訊號。

c.SEQOP 地址指標自動遞增(順序操作)

1 = 致能地址指標自動遞增

0 = 取消地址指標自動遞增

在SPI操作模式下如要「連續」寫入暫存器時,可透過致能該功能使IC自動在寫完一個暫存器的時候,自動把指標遞增指向下一個位址進行寫入。

 d.DISSLW SDA輸出斜率控制

1 = 取消控制

0 = 致能控制

其實我不知道這個用意是什麼?為什麼只有針對SDA?跟EMI有關係?且在MCP23S17中SPI模式下並無SDA Pin,從Spec中也看不出所以然。

e.HAEN 啟用硬體定址功能

1 = 致能硬體定址(硬體A2、A1、A0透過外部偏壓設定)

0 = 取消硬體定址(A2=A1=A0=0)

這功能只有MCP23"S"17才有,在4線式SPI工作時需要有CS、SCL、SDO、SDI四隻腳,其中SCL是Clock訊號,SDO與SDI是Data輸出輸入訊號,CS腳則是chip select控制腳,也就是說如果今天當要併接多顆MCP23S17時,就需要有多支CS腳才能切換不同顆的MCP23S17,但硬體定址功能解決了這個問題,使所有MCP23S17可以共用SPI的所有腳位。

在併接多顆的情況底下,初始化時,必須先致能HAEN才能使MCP23S17啟用定址功能,而這個啟用方式有點類似廣播的方式,因為既然是併接,所以單向的將控制訊號丟出去時,大家都會同時收到,之後就可以使用定址的address進行SPI通訊。

f.ODR 中斷INTA,INTB 設定為Open Drain模式

1 = 致能open drain模式(覆蓋INTPOL設定)

0 = 取消open drain模式(INTPOL設定有效)

這個設定主要要配合外部硬體的設計。

g.INTPOL INTA、INTB中斷輸出電位

1 = 預設Low電位,中斷觸發為High

0 = 預設High電位,中斷觸發為Low

這個設定主要要配合外部硬體的設計。

3.2 GPPU Pullup電阻設定

1 = 致能Pullup電阻

0 = 取消Pullup電阻

現在大多MCU都有提供類似這樣的功能,相信應該不陌生,這個設定可以減少外部一些Pullup電阻的配置。

3.3 INTF中斷旗標狀態暫存器

當中斷狀態發生時該暫暫存器用以表示是由哪支I/O發生中斷。

3.4 INTCAP 中斷狀態捕捉暫存器

當中斷發生時,該暫存器會捕捉I/O準位信號。

3.4 GPIO 通用I/O控制暫存器

在Input模式底下透過GPIOA、GPIOB讀取I/O腳上的狀態,而在Output模式底下亦可透過該暫存器改變輸出狀態。

3.5 OLAT  OUTPUT LATCH REGISTER(中文我不知道怎麼解釋)

這個暫存器目的與其設計結構有關係,簡單說,當I/O設定為輸出模式時,可以使用GPIO暫存器進行輸出狀態改變,也可以透過OLAT暫存器進行改變。

其原因可參考 Read-Modify-Write(轉)

4.控制範例

這次又很大才小用的做了一個很無趣的範例,我使用了兩顆MCP23S17作為I/O擴充使用,突然面對這麼多I/O我也不知道要怎麼用它,後來想到一個很牛B的範例,既然我有四組8bit的I/O我乾脆拿1組當輸入3組當輸出去驅動七段顯示器,而七段顯示器的值對應第一組輸入值,所以我使用了8個push開關,以及三個七段顯示器做結果的顯示。

我的構想是當8個按鈕分配給8個bit時,則對應結果可以產生0~255的狀再由另外3組8bit I/O驅動三顆七段顯示器顯示0~255的結果。

4.1配置圖

許久不見的麵包板再度重出江湖。

20141114_211356

4.2 運作結果

4.3程式及相關資料下載

a.Use polling function source code

  MCP23S17_polling_test (691.3 KiB, 241 次下載)

b.Use interrupt function source code

  MCP23S17_interrupt_test (700.5 KiB, 200 次下載)

c.MCP23S17 test circuit

  MCP23S17 Test Circuit (22.1 KiB, 339 次下載)

d.英文版Datasheet

e.中文版Datasheet

8 thoughts on “MCP23S17 16-Bit I/O Expander with SPI

  1. Hi QQ,
    抱歉,電路圖中RESET 220R是畫錯的,原本是想要放跟下面一樣1K,通常Reset我們會給定一個明確的電壓不會去浮接,故因MCP23S17的Reset是Low動作,所以Normal就用電阻Pullhigh,通常Reset需求的電流都很小,所以用1K足矣。

發表迴響