2013/12/21

Raspberry Pi:使用MCP23008擴充數位腳位

這篇要示範使用MCP23008這顆晶片擴充數位腳位,將會以其中一個腳位作為輸出,點亮LED,另一個腳位作為輸入,讀取開關的狀態。

MCP23008的傳輸介面是I2C,支援8個擴充腳位,每個腳位可驅動20~25mA電流,不過全部可驅動的電流則是125mA(流出去)或150mA(流進來)。

MCP23008與Raspberry Pi的接線如下:
MCP23008的SCL接rpi的SCL(針腳5)。
MCP23008的SDA接rpi的SCL(針腳3)。
MCP23008的A2、A1、A0,都接地。
MCP23008的RESET(逆向邏輯)接3.3V,不重置。
MCP23008的Vss,接GND。
MCP23008的Vdd,接3.3V。
MCP23008的GP0,接LED。
MCP23008的GP1,接開關。

I2C屬於匯流排架構,同一線路上可裝設254個I2C裝置,每個裝置須擁有獨一無二的位址。MCP23008的A0、A1、A2便是可以設定位址的腳位。

電子線路完成後,首先要開啟Raspbian支援I2C的部份。因預設不載入I2C的驅動程式,請修改/etc/modprobe.d/raspi-blacklist.conf,加上註解,如下:
# blacklist spi and i2c by default (many users don't need them)

#blacklist spi-bcm2708
#blacklist i2c-bcm2708

若想開機後就載入I2C模組,可修改/etc/modules,加入底下這兩行:
i2c-bcm2708
i2c-dev

也可以自己手動以底下指令載入:

$ sudo modprobe i2c-bcm2708
$ sudo modprobe i2c-dev

若成功載入I2C模組,下指令lsmod便可看到i2c_dev與i2c_bcm2708的身影。
$ lsmod
Module                  Size  Used by
i2c_dev                 5594  0
cpufreq_stats           2797  0
snd_bcm2835            16432  0
snd_pcm                77728  1 snd_bcm2835
snd_seq                53482  0
snd_timer              20110  2 snd_pcm,snd_seq
snd_seq_device          6462  1 snd_seq
snd                    58744  5 snd_bcm2835,snd_timer,snd_pcm,snd_seq,snd_seq_device
snd_page_alloc          5169  1 snd_pcm
spidev                  5248  0
leds_gpio               2243  0
led_class               3570  1 leds_gpio
i2c_bcm2708             3947  0
spi_bcm2708             4841  0

然後更新一下軟體套件,安裝I2C的工具程式:

$ sudo apt-get update
$ sudo apt-get dist-upgrade -y
$ sudo apt-get install python-smbus i2c-tools

安裝後,執行底下指令可查出MCP23008的I2C位址。Rev 1板子的參數是0、Rev 2板子的參數是1。
$ 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: -- -- -- -- -- -- -- --

由此可知位址是0x20,因為之前把A0、A1、A2都接地。

接下來安裝C介面的程式庫WiringPi

$ git clone git://git.drogon.net/wiringPi
$ cd wiringPi
$ ./build

安裝後,便可開始寫程式了:

#include <stdio.h>
#include <wiringPi.h>
#include <mcp23008.h>

#define PIN_BASE 65 // 任何大於64的數字
#define ADDRESS 0x20
int main(int argc, char *argv[])
{
  int i;
  int s;
  wiringPiSetup();
  mcp23008Setup(PIN_BASE, ADDRESS);

  pinMode(PIN_BASE + 0, OUTPUT); // 輸出,LED
  pinMode(PIN_BASE + 1, INPUT); // 輸入,開關

  while(1){
    s = digitalRead(PIN_BASE + 1); // 讀取開關狀態
    printf("switch is %d\n", s);

    digitalWrite(PIN_BASE + 0, 1); // 閃爍LED
    delay(1000);
    digitalWrite(PIN_BASE + 0, 0);
    delay(1000);
  }

  return 0;
}

編譯指令是:
$ gcc -lwiringPi mcp3008.c

執行./a.out後,便可看到LED閃爍,畫面上也會顯示開關的狀態。

若想要更多的擴充腳位,可加入更多個MCP23008(最多8個),但要以A0、A1、A2指定不同的位址,或可改用16個擴充腳位的MCP23017。而MCP23S08與MCP23S17的功能也是一樣,但傳輸介面是SPI。


參考資料:
  1. Adafruit Learning System的MCP230xx GPIO Expander on the Raspberry Pi
  2. Raspberry Pi: MCP23008 Port Expander,使用Quick2Wire I2C程式庫,Python介面。
  3. IO Port Expander (MCP23017 and MCP23008),使用Adafruit的MCP3008程式庫,有Python與C介面。
  4. Extend your GPIOs on Raspberry Pi with MCP23017 & MCP23008,相當詳盡,還試著控制文字型LCD。

No comments:

Post a Comment