
秋月電子通商で2026年現在販売されている 128×64 ドットディスプレイ、価格が 580 円ととてもお求めやすい価格でうれしく、大きさも基板が縦横およそ1インチと小さいので楽器に埋め込むのにも重宝しそうです。使い方を覚えるべく購入して、いつも使っているマイクロコントローラ STM32C092KCT6 から動かしてみました。やり方をすぐ忘れてしまいそうなので記事にしておこうと思います。
ディスプレイの概要
秋月電子通商の商品説明はこちら。
https://akizukidenshi.com/catalog/g/g112031
いつかリンクが切れてしまうかもしれませんけれども。大事なことは、制御チップに SSD1306 が使われているということです。このサイズの OLED は大抵そうらしく作例や解説などの資料が多数 見つけられます。
SSD1306 のデータシートは秋月から配布されています。こちらがなくなっても検索すればあちこちから見つけられるようです。
https://akizukidenshi.com/goodsaffix/ssd1306.pdf
このチップ向けの既存のライブラリは豊富なので、今回はサボってデータシートをろくに見ずにつなげてしまいます。
インタフェースは I2C で、ピンは電源と I2C 接続のための4本です。

裏面を見ると “IIC Address Select” という部分があってここが何気に重要です。I2C で SSD1306 を制御する場合、デバイスのアドレスは “0111100” または “0111101” が使えるようです。I2C ではアドレスを指定する際1ビット左シフトするので 0x78 または 0x7A で、この切り替えが基板上の抵抗の付け替えでできるようです。デュアルディスプレイなんかやりたい場合には使うわけですね。

配線
いつも使っているコントローラ STM32C092KCT を今回も使います。このコントローラは I2C を二回線持っていますがブレッドボード上の配線を楽にするため 2番目のものを選びました。配線は単純で以下の通りです。プログラマもつながないといけませんがこの記事では省略しています。

マイクロコントローラの設定
IDE には STM32CubeIDE を使いました。
クロックは特に気にしなくても大丈夫だと思いますが念のため RC クロックで 48 MHz に設定

I2C の設定は、I2C2 を有効にしたときに最初に指定されたピンをそのまま使うのでかなり単純です。I2C2を有効にしてスピードを Fast Mode にします。割り込みや DMA は今回使うライブラリでは使わないので設定不要ですがライブラリを改造したりする場合必要になるかもしれません。I2Cスピードは 1 MHz の Fast Mode Plus でも動作するようです。データシートを確認しましたがクロック速度については記述がなく、設計上想定されているスピードなのかどうかは不明です。

GPIO のプルアップはしなくても動作しましたが念のためプルアップしておきます。そしてこれも念のため Output Speed を Fast にしておきます

SWD の設定も明示しなくても良いはずですけれども後で間違って重複させないように設定をしておきます。

コントローラの設定は以上。ここでプロジェクトをセーブして IDE に必要なファイルを生成してもらいます。
STM32 向けの SSD1306 ライブラリを準備する
SSD1306 のライブラリは Aleksander Alekseev さんが書いた以下のものを使いました。ドキュメントはありませんがソースコードが単純にきれいに書かれていて読みやすいので一旦動き出したら使い方を理解するのはそれほど困らないと思います。
https://github.com/afiskon/stm32-ssd1306
こちらをプロジェクトの下にチェックアウトしてきます。
$ git clone https://github.com/afiskon/stm32-ssd1306.git
$ ls -1F
Core/
Drivers/
STM32C092KCTX_FLASH.ld
hello-ssd1306.ioc
stm32-ssd1306/
$ tree -d stm32-ssd1306
stm32-ssd1306
├── examples
│ ├── custom-fonts
│ └── oled-tester
│ ├── firmware
│ │ ├── i2c
│ │ │ ├── Inc
│ │ │ ├── Src
│ │ │ └── ssd1306
│ │ └── spi
│ │ ├── Inc
│ │ ├── Src
│ │ └── ssd1306
│ ├── hardware
│ └── images
└── ssd1306
16 directoriesBash最低限必要なのは stm32-ssd1306/ssd1306 ディレクトリの下にあるソースコードです。
ls -1 stm32-ssd1306/ssd1306
ssd1306.c
ssd1306.h
ssd1306_conf_template.h
ssd1306_fonts.c
ssd1306_fonts.h
ssd1306_tests.c
ssd1306_tests.hBashこれをプロジェクトに取り込みます。メニューから Project -> Properties さらに C/C++ General -> Paths and Symbols の Includes タブと Source Location タブを呼び出して上記のディレクトリを追加します。

コンパイルを通すには、ssd1306_conf.h というファイルが必要なので ssd1306_conf_template.h からコピーして作成します。

この ssd1306_conf.h ファイルを開いて設定を若干修正します。設定のデフォルトではターゲットが STM32F0 に設定されていますから、STM32C0 に変更します。
// Choose a microcontroller family
//#define STM32F0
//#define STM32F1
//#define STM32F4
//#define STM32L0
//#define STM32L1
//#define STM32L4
//#define STM32F3
//#define STM32H7
//#define STM32F7
//#define STM32G0
#define STM32C0
//#define STM32U5CI2C のチャネルは I2C1 が設定されていますが、I2C2 を使うのでそこも変更します。
// I2C Configuration
#define SSD1306_I2C_PORT hi2c2 // デフォルトは hi2c1
#define SSD1306_I2C_ADDR (0x3C << 1) // 基板を修正して 0x7A アドレスを使う場合 (0x3D << 1) に変更するCSSD1306 は SPI でも制御できて SPI 用のコードもライブラリに用意されていますが、秋月のディスプレイは I2C のみ対応なので不要です。
この変更が完了するとプロジェクトはビルドができるようになります。
描画コードを加える
必要な描画コードを加えて描画します。まずは、Hello World から。ライブラリのファイルをインクルードして
/* USER CODE BEGIN Includes */
#include "ssd1306.h"
#include "ssd1306_fonts.h"
#include "ssd1306_tests.h" // optional
/* USER CODE END Includes */
C以下をメインプログラムのループする前に入れます
/* USER CODE BEGIN 2 */
ssd1306_Init();
ssd1306_Fill(Black);
ssd1306_SetCursor(10, 10);
ssd1306_WriteString("HELLO", Font_11x18, White);
ssd1306_SetCursor(10, 30);
ssd1306_WriteString("WORLD", Font_11x18, White);
ssd1306_UpdateScreen();
/* USER CODE END 2 */
Cさてこれをビルドしてデバイスに書き込みます。

無事描画できました!
ライブラリの使い方は、テストプログラムを参考にすると良いと思います。
/* USER CODE BEGIN 2 */
ssd1306_Init();
ssd1306_TestAll();
/* USER CODE END 2 */
Cこういうディスプレイを手にしたらアニメーションをやってみたくなるのが人情ですが、テストプログラムには入っていません。ControllersTech というサイトのチュートリアルに馬のアニメーションの作り方が出ていて素敵だったのでライブラリが別ですが移植してみました。
// Download the bitmap from ControllersTech: https://controllerstech.com/oled-display-using-i2c-stm32/
#include "horse_anim.h"
// in the main program...
const unsigned char* horse_bitmaps[8] = {
horse1, horse2, horse3, horse4, horse5, horse6, horse7, horse8
};
unsigned int frame = 0;
while (1)
{
ssd1306_Fill(Black);
ssd1306_DrawBitmap(0, 0, horse_bitmaps[++frame % 8], 128, 64, White);
ssd1306_UpdateScreen();
}Cできました!
Controllers Tech のチュートリアルも懇切丁寧でお勧めです。
https://controllerstech.com/oled-display-using-i2c-stm32
このプロジェクトは Github で公開しました。よければご参考にどうぞ

