Youtubeも元気に更新中!!

Youtubeのチャンネルで動画公開中。
動画のほうがわかりやすい項目について解説しています!

チャンネル登録

RaspberryPiでMCP23S17を使うときのアドレスについて解説

raspberrypi-mcp23s17-slave-address-eyecatchRaspberryPi(ラズパイ)

以前の記事で、MCP23S17をRaspberryPi400で制御する方法を紹介しました。

その際、MCP23S17のアドレスを決定づける、
A0~A3すべてをGNDにつないでアドレスを0x20にしていました。

ただ、そのA0~A3を3.3Vにつないでも実は
所望の動きになるという話でした。

MCP23017ではもちろんそんなことしたら、
RaspberryPiから制御はできなかったわけですが、
MCP23S17は少し事情が異なるんですね。

そのことについて詳しく解説していこうと思います。

自己紹介

東証一部上場企業でサラリーマンしてます。

主に工場(生産現場)で使用する検査装置のアプリケーション開発してます。

ヒトの作業を自動化して簡略化するアプリケーションを日々開発中。

転職に成功して現在は超大手企業でシステム系の開発をしています。

Youtubeチャンネルにさまざまな動画を上げています

↓↓↓こちらからYoutubeチャンネルにアクセス!! ↓↓↓

MCP23S17をRaspberryPiで制御したときの記事はこちら↓

ここに今回につながる内容が満載なので、まずはご覧いただいたほうが良いです。

そもそもMCP23S17のアドレスの決め方は?

さて、MCP23S17のアドレスの決め方について復習していきましょう。

まずはデータシートが重要な手掛かりになります。
こちらはデータシートから抜粋した内容です。↓↓

MCP23S17-SPIControlformat
MCP23S17のデータシートより抜粋

このように、A2,A1,A0のピンがHIGHかLOWによって
SlaveAddressつまり、接続したMCP23S17のアドレスが決定されます。

例えば、MCP23S17の物理ピンのA0のみ3.3Vをつないで、
他のA2,A1はGNDにつないだ場合、

0100001となります。
これは、0x21となります。

さらに、このSlaveAddressの後にR/Wつまり、
WriteなのかReadなのかの1byteが入ってControl Byteとなるわけです。

さて、ここまでで、A2~A0のピンをどうつなげるかで
アドレスが変えられるということになるはずです。

しかし、ここからが重要なところです。
データシートのここをご覧下さい。

mcp23s17-data-sheet-spi-device
MCP23S17のデータシートより抜粋。SPIのアドレスについての記載。

読み飛ばしてしまいそうな内容ですが、
とても重要な内容なので詳しく解説していきますね。

SPIデバイス(MCP23S17)のアドレス指定について

ここに書いてあるのは、スレーブアドレスがA2,A1,A0の各ピンで
アドレスが決まりますよ。


ただし、IOCON.HAENを有効にしたときね。

と言っています。

見逃してしまいますよね…
また、このIOCON.HAENですが、
デフォルトで無効になっています。

無効になっている場合の処遇についても記載があります。

それが、「無効時はA2=A1=A0と解釈されます。」
という一文です。

つまり、デフォルトでIOCON.HAENが無効になっていたので、
A2だけ3.3Vにつなげようが、A2~A0すべてを3.3Vにつなげようと、
アドレスとしては0x20で通ってしまうということです。

【I2C通信版】MCP23017との違いは?

ここまででI2C通信版のMCP23017との差がわかっていただけたと思います。
MCP23017では特にIOCON.HAENなどは登場しませんでした。

SPI通信版のMCP23S17の特徴と言えると思います。

I2C版のほうは、接続後、RaspberryPiで接続中のSlaveAddressをターミナルで
確認できるので、アドレス違いで接続できないというのはあまりないと思いますが、
SPI通信に関してはそんな便利なものはないので、
アドレス違いが発見しにくいと思います。

さらに、IOCON.HAENはデフォルト状態で無効となっており、
IOCON.HAENをいじらないと、実質A2~A0がどこにつながっていても
0x20で接続できてしまうので、気づきにくいです。

いいんだか、わるいんだか….

アドレスを変えて複数のMCP23S17をつなげたかったらどうすればいい?

さてご興味があるのは恐らくここでしょう。
A2~A0の配線がどうでもよくなってしまっているということは….

アドレスを指定して複数のMCP23S17が接続できない。

ということになります。
そりゃそうですよね。2個、3個とつなげても同じ0x20というアドレスになってしまいますから。

複数のMCP23S17を接続するため、
ひいては自分の決めたアドレスで接続するための方法についてご紹介いたします。

SlaveAddressを思い通りに変えるには

ここまで解説してきた通り、
ポイントとなるのは、IOCON.HAENがデフォルトで無効となっていることです。

そうです。
初めにIOCON.HAENを有効にして、
SlaveAddressを変更できるようにすればいいのです。

というわけで具体的には、データシートのこちらをご覧ください。

MCP23S17のデータシートより。IOCONのbit3にHAENが割り当てられているのが確認できる。

レジスタアドレス0x0Aのbit3に1を立てたらIOCON.HAENが有効になるという
流れになります。IODIRAなど、以前にも紹介したレジスタの表ですので、
見方は理解できるかと思います。

さて、データシートには、HAENの正式名称は、
ハードウェア アドレス イネーブル
の略記として変数の名前としているようです。

最後にIOCON.HAENを有効にする具体的な記述方法についてご紹介して
終わりとします。
使うのはPythonです。

こんな感じで記述してあげれば、
A2~A0の配線通りのアドレスとなり、
複数台のMCP23S17が思い通りに制御できることになります。

import spidev
import time

#初期設定
spi = spidev.SpiDev()
spi.open(0,0)
spi.mode = 0
spi.max_speed_hz = 1000000

Control_Byte = 0x40
REG_IODIRA = 0x00 #入出力設定レジスタ
REG_GPIOA = 0x12 # 出力レジスタ
REG_IOCON = 0x0A # iocon ←ここでIOCONのレジスタアドレスを定義
# 
spi.xfer2([Control_Byte,REG_IODIRA,0x00]) 

spi.xfer2([Control_Byte,REG_IOCON,0x08]) # ここで3bit目を立てているのでHAENがONになる。
def destroy():
    print("end")
try:
    while True:
        spi.xfer2([Control_Byte,REG_GPIOA,0x03]) #ON
        time.sleep(1)
        spi.xfer2([Control_Byte,REG_GPIOA,0x00]) #OFF
except KeyboardInterrupt:
        destroy()

今回のまとめ

今回は、SPI通信Ver.のMCP23S17のアドレスについて解説しました。
実は初めてMCP23S17をいじった時に違和感を感じたんですね。

A2~A0の配線を少し変更しても、
そのまま動いちゃうぞ….?と。

MCP23017の時では絶対にありえない現象だったので、
データシートを詳しく確認したところビンゴ。

複数のMCP23S17を使う人がどれくらいいるかは不明ですが、
アドレスについて困っている方の手助けになれば幸いです。

コメント

タイトルとURLをコピーしました