今回はESP32ペリフェラルのI2Cを使って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ポートを拡張することができます。
今回は秋月電子で販売している こちら を使ってみることにしました。
MCP23017はI2Cのインターフェースで16ビットのIOポートを拡張することができ、16ビットそれぞれに対して入出力の選択が可能です。
回路図
デバッグ環境の回路構成に対して以下の回路を追加します。
ESP32の番号はGPIOの番号です。
MCP23017はI2Cのデバイスで、アドレス選択用のピンが3本あります。
これにより、ワンペアのI2C信号で最大 16 × 8 ビットのGPIOを拡張することができます。
I2CのSCLK, SDAの信号はプルアップして使います。ここでは4.7kΩでプルアップしました。
割り込みは使っていません。
RESET端子は回路を簡略化するために3.3Vにつなぎました。
プロジェクトをつくる
VSCodeで使っていたプロジェクトを開いていたら、File – Close Folder して閉じておきます。
その後にVSCodeからPlatformIOをOpenします。
以下の内容でプロジェクトを新規に作成します。
Name : ESP32E-i2c-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
I2CマスターのAPIリファレンスとサンプル
I2CのAPIは こちら を参照してください。
サンプルプログラムは こちら を参考にしました。
PlatformIOで Eresspsif IoT Development Framework を選択したことにより、以下のローカルフォルダからも参照可能なはずです。
C:\Users\xxxxx\.platformio\packages\framework-espidf\examples\peripherals\i2c\i2c_self_test
(xxxxxは皆さまのユーザー名)
動作概要
I2C
I2CはSPIに比べると低速です。
テクニカルリファレンスマニュアルの4.IO_MUXの項目を見ると、DirectI/O(first signal)の部分にI2Cはありません。
ということでIO_MUXは気にせずに、GPIOを適当に選んで使いました。(回路図を参照)
まぁI2Cは遅いですからね、全く問題ナシ。。
SPIのGPIO Matrix and IO_MUX によると、
IO_MUX : max. 80MHz
GPIO Matrix : max. 40MHz
だそうです。
クロックはI2Cとしては速からず遅からずの400kHzで動かしてみることにしました。
概要からは見つけられなかったのですが、I2Cは0と1の2つが存在するようです。
(レジスタの説明に 0 と 1 の記述がある)
今回は0を使ってみます。そして以下のようにGPIOを割り当ててみました。
(数値はGPIOの番号)
SDA=2
SCLK=0
I2Cの挙動としては、
(1)ハードウェアアドレス+レジスタアドレス+書き込みデータ
(2)ハードウェアアドレス+レジスタアドレス+読み込みデータ(リスタートを含む)
の2パターンのみが動きます。
このデバイスでは、これで充分なのでそれ以外の動作は確認していません。
(例えば連続した複数データの読み書き等)
実際には 400KHz 出ていませんでした。360kHz程度でしょうか。。
観測した波形を貼っておきます。
(1)GPIOAへの書き込みの後、GPIOBを読み、GPIOBへの書き込み
(2)GPIOAへの書き込み(詳細)
(3)クロック波形の確認用
IOエキスパンダ MCP23017
詳細については こちら を参照してください。
16ビットのIOポートを入力または出力ポートに設定して使うことができます。
やることはSPIの時と同じでインターフェースがかわるだけです。
GPIOAは全てのビットを出力に設定します。
GPIOBはD7ビットだけを入力にして、それ以外は出力に設定します。
MCP23017にコマンドを書き込むことで内部でプルアップするのでGPIOBのD7ビットに外付けの抵抗は不要です。
(MCP23017の内部プルアップは100kΩなのでノイズには弱いかも知れませんが・・・)
GPIOA0につながっているLED(D2) はタイマーでLチカします。
GPIOB0につながっているLED(D1) は GPIOB7 をGNDにつなぐと点灯します。
ソースコードを github esp32e-i2c-master-mcp23017 におきました。
( 環境: VSCode + PlatformIO , Espressif IoT Development Framework )
ESP-IDE環境で SPI MCP23017 を試してみたい方は参考になさってください。
参考というほど、できの良いものではありませんけれど (^_^)