2018年1月7日日曜日

[SSD1331]SPIライブラリを使わないで描画してみた

ライブラリを用いてた箇所をベタなArduinoのコードに置き換えてみました。

使用するのは、今までと同じく
の二つで、接続も以下のようになっています。

Arduino UNO R3との配線
Arduino UNO R3 Pin Pmod OLEDrgb Pin
SCK-13
- 4:SCK
MISO-12

MOSI-11
- 2:MOSI
SS-10 - 1:CS
9 - 8:RES
8
- 7:D/C
6:VCC or 12:VCC
9:VCCEN and 10:PMODEN

3.3V -

5V


GND - 5:GND or 11:GND

基本的には無駄な部分が大半ですが、ライブラリでの処理の原型を保ちつつシンプルにした結果であり、動作の検証と実験用なので、実用的ではありません。

#define cs  10
#define rst 9
#define dc  8

#define  GREEN           0x07E0

#include <SPI.h>

int16_t width = 96;
int16_t height = 64;

void setup()   {
  pinMode(dc, OUTPUT);
  pinMode(cs, OUTPUT);

  SPI.begin();
  SPI.setDataMode(SPI_MODE3);

// 初期化処理
  // SSD1331_CMD_DISPLAYOFF
  digitalWrite(dc, LOW);
  digitalWrite(cs, LOW);
  SPI.transfer(0xAE);
  digitalWrite(cs, HIGH);

  // SSD1331_CMD_SETREMAP
  digitalWrite(dc, LOW);
  digitalWrite(cs, LOW);
  SPI.transfer(0xA0);
  digitalWrite(cs, HIGH);

  digitalWrite(dc, LOW);
  digitalWrite(cs, LOW);
  SPI.transfer(0x72);
  digitalWrite(cs, HIGH);

  // SSD1331_CMD_STARTLINE
  digitalWrite(dc, LOW);
  digitalWrite(cs, LOW);
  SPI.transfer(0xA1);
  digitalWrite(cs, HIGH);

  digitalWrite(dc, LOW);
  digitalWrite(cs, LOW);
  SPI.transfer(0x0);
  digitalWrite(cs, HIGH);

  // SSD1331_CMD_DISPLAYOFFSET
  digitalWrite(dc, LOW);
  digitalWrite(cs, LOW);
  SPI.transfer(0xA2);
  digitalWrite(cs, HIGH);

  digitalWrite(dc, LOW);
  digitalWrite(cs, LOW);
  SPI.transfer(0x0);
  digitalWrite(cs, HIGH);

  // SSD1331_CMD_NORMALDISPLAY
  digitalWrite(dc, LOW);
  digitalWrite(cs, LOW);
  SPI.transfer(0xA4);
  digitalWrite(cs, HIGH);

  // SSD1331_CMD_SETMULTIPLEX
  digitalWrite(dc, LOW);
  digitalWrite(cs, LOW);
  SPI.transfer(0xA8);
  digitalWrite(cs, HIGH);

  digitalWrite(dc, LOW);
  digitalWrite(cs, LOW);
  SPI.transfer(0x3F);
  digitalWrite(cs, HIGH);

  // SSD1331_CMD_SETMASTER
  digitalWrite(dc, LOW);
  digitalWrite(cs, LOW);
  SPI.transfer(0xAD);
  digitalWrite(cs, HIGH);

  digitalWrite(dc, LOW);
  digitalWrite(cs, LOW);
  SPI.transfer(0x8E);
  digitalWrite(cs, HIGH);

  // SSD1331_CMD_POWERMODE
  digitalWrite(dc, LOW);
  digitalWrite(cs, LOW);
  SPI.transfer(0xB0);
  digitalWrite(cs, HIGH);

  digitalWrite(dc, LOW);
  digitalWrite(cs, LOW);
  SPI.transfer(0x0B);
  digitalWrite(cs, HIGH);

  // SSD1331_CMD_PRECHARGE
  digitalWrite(dc, LOW);
  digitalWrite(cs, LOW);
  SPI.transfer(0xB1);
  digitalWrite(cs, HIGH);

  digitalWrite(dc, LOW);
  digitalWrite(cs, LOW);
  SPI.transfer(0x31);
  digitalWrite(cs, HIGH);

  // SSD1331_CMD_CLOCKDIV
  digitalWrite(dc, LOW);
  digitalWrite(cs, LOW);
  SPI.transfer(0xB3);
  digitalWrite(cs, HIGH);

  digitalWrite(dc, LOW);
  digitalWrite(cs, LOW);
  SPI.transfer(0xF0);
  digitalWrite(cs, HIGH);

  // SSD1331_CMD_PRECHARGEA
  digitalWrite(dc, LOW);
  digitalWrite(cs, LOW);
  SPI.transfer(0x8A);
  digitalWrite(cs, HIGH);

  digitalWrite(dc, LOW);
  digitalWrite(cs, LOW);
  SPI.transfer(0x64);
  digitalWrite(cs, HIGH);

  // SSD1331_CMD_PRECHARGEB
  digitalWrite(dc, LOW);
  digitalWrite(cs, LOW);
  SPI.transfer(0x8B);
  digitalWrite(cs, HIGH);

  digitalWrite(dc, LOW);
  digitalWrite(cs, LOW);
  SPI.transfer(0x78);
  digitalWrite(cs, HIGH);

  // SSD1331_CMD_PRECHARGEC
  digitalWrite(dc, LOW);
  digitalWrite(cs, LOW);
  SPI.transfer(0x8C);
  digitalWrite(cs, HIGH);

  digitalWrite(dc, LOW);
  digitalWrite(cs, LOW);
  SPI.transfer(0x64);
  digitalWrite(cs, HIGH);

  // SSD1331_CMD_PRECHARGELEVEL
  digitalWrite(dc, LOW);
  digitalWrite(cs, LOW);
  SPI.transfer(0xBB);
  digitalWrite(cs, HIGH);

  digitalWrite(dc, LOW);
  digitalWrite(cs, LOW);
  SPI.transfer(0x3A);
  digitalWrite(cs, HIGH);

  // SSD1331_CMD_VCOMH
  digitalWrite(dc, LOW);
  digitalWrite(cs, LOW);
  SPI.transfer(0xBE);
  digitalWrite(cs, HIGH);

  digitalWrite(dc, LOW);
  digitalWrite(cs, LOW);
  SPI.transfer(0x3E);
  digitalWrite(cs, HIGH);

  // SSD1331_CMD_MASTERCURRENT
  digitalWrite(dc, LOW);
  digitalWrite(cs, LOW);
  SPI.transfer(0x87);
  digitalWrite(cs, HIGH);

  digitalWrite(dc, LOW);
  digitalWrite(cs, LOW);
  SPI.transfer(0x06);
  digitalWrite(cs, HIGH);

  // SSD1331_CMD_VCOMH
  digitalWrite(dc, LOW);
  digitalWrite(cs, LOW);
  SPI.transfer(0xBE);
  digitalWrite(cs, HIGH);

  digitalWrite(dc, LOW);
  digitalWrite(cs, LOW);
  SPI.transfer(0x3E);
  digitalWrite(cs, HIGH);

  // SSD1331_CMD_CONTRASTA
  digitalWrite(dc, LOW);
  digitalWrite(cs, LOW);
  SPI.transfer(0x81);
  digitalWrite(cs, HIGH);

  digitalWrite(dc, LOW);
  digitalWrite(cs, LOW);
  SPI.transfer(0x91);
  digitalWrite(cs, HIGH);

  // SSD1331_CMD_CONTRASTB
  digitalWrite(dc, LOW);
  digitalWrite(cs, LOW);
  SPI.transfer(0x82);
  digitalWrite(cs, HIGH);

  digitalWrite(dc, LOW);
  digitalWrite(cs, LOW);
  SPI.transfer(0x50);
  digitalWrite(cs, HIGH);

  // SSD1331_CMD_CONTRASTC
  digitalWrite(dc, LOW);
  digitalWrite(cs, LOW);
  SPI.transfer(0x83);
  digitalWrite(cs, HIGH);

  digitalWrite(dc, LOW);
  digitalWrite(cs, LOW);
  SPI.transfer(0x7D);
  digitalWrite(cs, HIGH);

  // SSD1331_CMD_DISPLAYON
  digitalWrite(dc, LOW);
  digitalWrite(cs, LOW);
  SPI.transfer(0xAF);
  digitalWrite(cs, HIGH);

// 画面描画(画面の塗潰し)
  for (int16_t x = 0; x < width; x++) {
    for (int16_t y = 0; y < height; y++) {
      // SSD1331_CMD_SETCOLUMN
      digitalWrite(dc, LOW);
      digitalWrite(cs, LOW);
      SPI.transfer(0x15);
      digitalWrite(cs, HIGH);

      digitalWrite(dc, LOW);
      digitalWrite(cs, LOW);
      SPI.transfer(x);
      digitalWrite(cs, HIGH);

      digitalWrite(dc, LOW);
      digitalWrite(cs, LOW);
      SPI.transfer(width - 1);
      digitalWrite(cs, HIGH);

      // SSD1331_CMD_SETROW
      digitalWrite(dc, LOW);
      digitalWrite(cs, LOW);
      SPI.transfer(0x75);
      digitalWrite(cs, HIGH);

      digitalWrite(dc, LOW);
      digitalWrite(cs, LOW);
      SPI.transfer(y);
      digitalWrite(cs, HIGH);

      digitalWrite(dc, LOW);
      digitalWrite(cs, LOW);
      SPI.transfer(height - 1);
      digitalWrite(cs, HIGH);

      // データの設定
      digitalWrite(dc, HIGH);
      digitalWrite(cs, LOW);

      SPI.transfer(GREEN >> 8);
      SPI.transfer(GREEN);

      digitalWrite(cs, HIGH);
    }
  }
}

void loop() {
}

処理としては、"初期化処理"と"画面描画(画面の塗潰し)"の二つに別れています。
"初期化処理"の部分については、ライブラリでの設定がほぼほぼ初期値と変わらないので設定しなくとも動きます。
"cs"、"dc"のHIGH、LOWの設定箇所は元のコードの方が高速に動作しますが、塗りつぶし程度では大きな差はありません。

ここから先は、グラフィックスアクセラレーションコマンドセットなどを検証していくと面白そうです。

0 件のコメント:

コメントを投稿