ESP32 SPIでIOエキスパンダする

  • 2021.10.01
  • SPI
ESP32 SPIでIOエキスパンダする

今回はESP32ペリフェラルのSPIを使ってIOエキスパンダでLチカしてみます。

この記事は JTAG でデバッグすることを前提にして書いています。
環境構築については こちら をご覧になってください。

投稿時の開発環境を記しておきます。

PC:
Windows10 OS

開発ボード :
ESP32-DevKitCーVE
(Soc : ESP32-D0WD-V3)

デバッガー(H/W):
FT2232D

デバッガー (S/W) :
Visual Studio Code + PlatformIO + ESP-IDF Framework

IOエキスパンダとは

IOポートを拡張するためのデバイスです。
IOエキスパンダと呼ばれるデバイスでいくつかの半導体メーカーでつくられています。

SPIやI2Cのインターフェースでマイコンと接続し、IOポートを拡張することができます。

今回は秋月電子で販売している こちら を使ってみることにしました。

MCP23S17はSPIのインターフェースで16ビットのIOポートを拡張することができ、16ビットそれぞれに対して入出力の選択が可能です。

回路図

デバッグ環境の回路構成に対して以下の回路を追加します。
ESP32の番号はGPIOの番号です。

MCP23S17はSPIのデバイスですが、アドレス選択用のピンが3本あります。
SPIデバイスでも、このようなピンがあるのですね。。

これにより、ひとつのCS(チップセレクト)信号に対して最大 16 × 8 ビットのGPIOを拡張することができます。

データシートからは読み取れなかったのですが、デバイスの14番ピン(SO)の信号はオープンドレイン出力と想定しています。
一般に SO の信号はプルアップしておくのが賢明だと思います。
一般にワイヤードオア(アンド)して使う信号であるからです。
ここでは4.7kΩでプルアップしました。

割り込み動作を試してみたのですが、うまく動かなかったので割り込みは使っていません。

(コードに少々、割り込み処理のなごりが残っています)

RESET端子は回路を簡略化するために3.3Vにつなぎました。

プロジェクトをつくる

VSCodeで使っていたプロジェクトを開いていたら、File – Close Folder して閉じておきます。

その後にVSCodeからPlatformIOをOpenします。

以下の内容でプロジェクトを新規に作成します。

Name : ESP32E-spi-master
Board : Espressif ESP32 Dev Module
Framework : Espressif IoT Development Framework

Name : ESP32E の “E” は Framework (Espressif IoT Development Framework)の頭文字を示しています。

(後から見てわかるように、ESP-IDFを使うことを明示しています)

次にplatformio.ini に以下の3行を追加して、 Ctrl + s で保存しておきます。

COM[4]の4の部分はデバイスマネージャーのポート(COMとLPT)で Silicon Labs CP210x から始まるCOMの番号を記述します。

debug_tool = minimodule
upload_port = COM[4]
monitor_speed = 115200

SPIマスターのAPIリファレンスとサンプル

SPIマスターのAPIは こちら を参照してください。

サンプルプログラムは こちら を参考にしました。

サンプルプログラムは EEPROM のものに変更を加えました。

PlatformIOで Eresspsif IoT Development Framework を選択したことにより、以下のローカルフォルダからも参照可能なはずです。

C:\Users\xxxxx\.platformio\packages\framework-espidf\examples\peripherals\spi_master\hd_eeprom

(xxxxxは皆さまのユーザー名)

動作概要

SPI

ESP32にはSPIモジュールが4つありますが、そのうちの2つ(SPI0, 1)はフラッシュメモリ用でユーザーは別の用途に使うことができません。

使うことができるのは SPI2, 3 のいずれかになります。

SPIをIO_MUXダイレクトで使う場合、高速動作が可能ですが使用可能なピンが制限されます。

SPI2、SPI3ではそれぞれ以下のピンが割り当てられています。

信号名 SPI2 SPI3
CS 15 5
SCK 14 18
MISO 12 19
MOSI 13 23

上記のGPIOがすでに使われている場合には、他のGPIOを使いGPIOマトリクス経由でSPIを使うことができるようです。

表に記したGPIOは元々の回路で使われているため今回は以下のようにGPIOを割り当ててみました。
(数値はGPIOの番号)

CS=5
SCLK=18
MISO=19
MOSI=21

IO_MUXからのダイレクトI/OではなくGPIO_Matrixを使うことになるわけですが、MCP23S17は最高でも10MHz動作なので全く問題ありません。

このへん に書かれているように、

IO_MUX : max. 80MHz
GPIO_Matrix : max. 40MHz

ということになります。

SPIの挙動としては、

(1)ハードウェアアドレス+レジスタアドレス+書き込みデータ
(2)ハードウェアアドレス+レジスタアドレス+読み込みデータ

の2パターンのみが動きます。

このデバイスでは、これで充分なのでそれ以外の動作は確認していません。

(例えば連続した複数データの読み書き等)

IOエキスパンダ MCP23S17

詳細については こちら を参照してください。

16ビットのIOポートを入力または出力ポートに設定して使うことができます。

GPIOAは全てのビットを出力に設定します。
GPIOBはD7ビットだけを入力にして、それ以外は出力に設定します。
MCP23S17にコマンドを書き込むことで内部でプルアップするのでGPIOBのD7ビットに外付けの抵抗は不要です。
(MCP23S17の内部プルアップは100kΩなのでノイズには弱いかも知れませんが・・・)

GPIOA0につながっているLED(D2) はタイマーでLチカします。
GPIOB0につながっているLED(D1) は GPIOB7 をGNDにつなぐと点灯します。

ソースコードを github spi-master-mcp23s17 におきました。

( 環境: VSCode + PlatformIO , Espressif IoT Development Framework )

ESP-IDE環境で SPI MCP23S17 を試してみたい方は参考になさってください。

参考というほど、できの良いものではありませんけれど (^_^)

SPIカテゴリの最新記事