使用するのは、
- Arduino UNO R3 ( 3.3v動作 )
- Pmod OLEDrgb
- Adafruit-SSD1331-OLED-Driver-Library-for-Arduino
Pmod OLEDrgbは、名前のままでPmodポート用のものです。
機能は下記
- 96×64 pixel RGB OLED screen
- 0.8“ x 0.5” グラフィックディスプレイ
- 16ビットカラー解像度
- 2つの低電力ディスプレイシャットダウンモード
- SPIインタフェース付き12ピンPmodコネクタ
- ロジックレベル 3.3v
ロジックレベル3.3v動作なので、Arduino UNO R3の場合ロジックレベルコンバータなどを使用する必要があるかもです。私が使っているUNOは5v、3.3vのレベル変換スイッチが付いてるので、3.3vに切り替えて使用しています。
Pmod OLEDrgbのピン配置
1 CS |
2 MOSI |
3 NC |
4 SCK |
5 GND |
6 VCC |
---|---|---|---|---|---|
7 D/C |
8 RES |
9 VCCEN |
10 PMODEN |
11 GND |
12 VCC |
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 |
※ 9: VCCENを3.3V、10: PMODENをGNDに接続すると消費電力を約200nAに減らすことができるそうです。ただし、描画が停止する度に省電力で画面が薄暗くなります。
以上で物理的な接続は完了です。
準備が整ったら、いよいよライブラリを調べてみましょう!
ライブラリは下図の手順で開いてください。
他にもArduino IDEにインストールしておけば、ローカル環境で呼び出せてサンプルの実行も可能となるので上記の環境が整っていればそちらをお勧めします。
↓
”examples”を開く
↓
"test"を開く
↓
"test.pde"をエディタで開く
まずは、冒頭部分から見て行きます。
// 任意の(4または)5ピンを使用できます | |
#define sclk | 13 |
#define mosi | 11 |
#define cs | 10 |
#define rst | 9 |
#define dc | 8 |
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1331.h>
#include <SPI.h>
// Option 1: 任意のピンを使用すると若干遅くなります
Adafruit_SSD1331 display = Adafruit_SSD1331(cs, dc, mosi, sclk, rst);
// Option 2: ハードウェアSPIピンを使用する必要があります
// (UNOの場合はsclk = 13、sid = 11)、ピン10は出力でなければなりません。
//これははるかに高速です - microSDカードを使用する場合にも必要です(画像の描画例を参照)
//Adafruit_SSD1331 display = Adafruit_SSD1331(cs, dc, rst);
ArduinoのSPI対応PINの宣言、ライブラリの読み込み、
"display"を"Adafruit_SSD1331"クラスを"display"の名称でオブジェクト化しています。
この際、任意のPINを使用してSPI通信を行うソフトウェアSPIと、マイコン内蔵のSPIモジュールを使用したハドウェアSPIの選択が行えます。
コードは、そのままだとソフトウェアSPIが有効になっていますが、UNO R3ではハードウェアSPIに対応しているので、
// Option 1: 任意のピンを使用すると若干遅くなります
// Adafruit_SSD1331 display = Adafruit_SSD1331(cs, dc, mosi, sclk, rst);
// Option 2: ハードウェアSPIピンを使用する必要があります
// (UNOの場合はsclk = 13、sid = 11)、ピン10は出力でなければなりません。
//これははるかに高速です - microSDカードを使用する場合にも必要です(画像の描画例を参照)
Adafruit_SSD1331 display = Adafruit_SSD1331(cs, dc, rst);
// Adafruit_SSD1331 display = Adafruit_SSD1331(cs, dc, mosi, sclk, rst);
// Option 2: ハードウェアSPIピンを使用する必要があります
// (UNOの場合はsclk = 13、sid = 11)、ピン10は出力でなければなりません。
//これははるかに高速です - microSDカードを使用する場合にも必要です(画像の描画例を参照)
Adafruit_SSD1331 display = Adafruit_SSD1331(cs, dc, rst);
ソフトウェアSPIをコメントアウト、ハードウェアSPIをアンコメントした状態で以降のコードを追います。
"Adafruit_SSD1331(cs, dc, rst)"は、"Adafruit_SSD1331.cpp"の中に記載されているので見てみましょう。
ちなみに、ハードウェアSPIはソフトウェアSPIに比べて目視できるレベルで圧倒的に早いですし、SDカードを接続するなどスレーブが複数になった場合にも有効です。
ここで引数として代入されている値、"TFTWIDTH"、"TFTHEIGHT"の二つは、"Adafruit_SSD1331.h"で以下のように宣言されています。
さて、ここまでで、以下の設定が行われています。
全てが必要であるかは不明ですが、コードを調べて行く上では必要となる事もあるかと思うので、ここに記載しておきました。
/********************************* 低レベル・ピンの初期化 */
Adafruit_SSD1331::Adafruit_SSD1331(uint8_t cs, uint8_t rs, uint8_t rst):Adafruit_GFX(TFTWIDTH, TFTHEIGHT) {
_cs = cs;
_rs = rs;
_sid = 0;
_sclk = 0;
_rst = rst;
}
Adafruit_SSD1331::Adafruit_SSD1331(uint8_t cs, uint8_t rs, uint8_t rst):Adafruit_GFX(TFTWIDTH, TFTHEIGHT) {
_cs = cs;
_rs = rs;
_sid = 0;
_sclk = 0;
_rst = rst;
}
uint8_t cs | 1 バイトの符号なし整数 cd | 10(cs) |
uint8_t rs | 1 バイトの符号なし整数 rs | 8 (dc) |
uint8_t rst | 1 バイトの符号なし整数 rst | 9(rst) |
ちなみに、ハードウェアSPIはソフトウェアSPIに比べて目視できるレベルで圧倒的に早いですし、SDカードを接続するなどスレーブが複数になった場合にも有効です。
ここで引数として代入されている値、"TFTWIDTH"、"TFTHEIGHT"の二つは、"Adafruit_SSD1331.h"で以下のように宣言されています。
static const int16_t TFTWIDTH = 96;
static const int16_t TFTHEIGHT = 64;
static const int16_t TFTHEIGHT = 64;
続いて"Adafruit_GFX(TFTWIDTH, TFTHEIGHT)"を確認してみます。
こちらは、"Adafruit_GFX.cpp"に見つけることが出来ました。
各変数の初期値を設定しているようですね。
WIDTH、HEIGHTは、"Adafruit_GFX.h"で宣言されています。
const int16_t
WIDTH, HEIGHT; // これは'raw'ディスプレイのw / hです - 決して変化しません
ただし、こちらに直接値を入れている箇所や、"WIDTH()"、"HEIGHT()"について設定している場所が見当たらないので未解決です。
こちらは、"Adafruit_GFX.cpp"に見つけることが出来ました。
各変数の初期値を設定しているようですね。
Adafruit_GFX::Adafruit_GFX(int16_t w, int16_t h):
WIDTH(w), HEIGHT(h)
{
_width = WIDTH;
_height = HEIGHT;
rotation = 0;
cursor_y = cursor_x = 0;
textsize = 1;
textcolor = textbgcolor = 0xFFFF;
wrap = true;
_cp437 = false;
gfxFont = NULL;
}
WIDTH(w), HEIGHT(h)
{
_width = WIDTH;
_height = HEIGHT;
rotation = 0;
cursor_y = cursor_x = 0;
textsize = 1;
textcolor = textbgcolor = 0xFFFF;
wrap = true;
_cp437 = false;
gfxFont = NULL;
}
uint16_t w | 2 バイトの符号なし整数 x | TFTWIDTH(96) |
uint16_t y | 2 バイトの符号なし整数 y | TFTHEIGHT(64) |
WIDTH、HEIGHTは、"Adafruit_GFX.h"で宣言されています。
WIDTH, HEIGHT; // これは'raw'ディスプレイのw / hです - 決して変化しません
ただし、こちらに直接値を入れている箇所や、"WIDTH()"、"HEIGHT()"について設定している場所が見当たらないので未解決です。
さて、ここまでで、以下の設定が行われています。
uint8_t _cs | 10(cs) |
uint8_t _rs | 8 (dc) |
uint8_t _sid | 0 |
uint8_t _sclk | 0 |
uint8_t _rst | 9(rst) |
int16_t _width | 96(WIDTH) |
int16_t _height | 64(HEIGHT) |
uint8_t rotation | 0 |
int16_t cursor_y | 0 |
int16_t cursor_x | 0 |
uint8_t textsize | 1 |
uint16_t textcolor | 0xFFFF |
uint16_t textbgcolor | 0xFFFF |
boolean wrap | true |
boolean _cp437 | false |
gfxFont | NULL |
全てが必要であるかは不明ですが、コードを調べて行く上では必要となる事もあるかと思うので、ここに記載しておきました。
本来のコードからは大幅に端折って、ハードウェアSPI設定のみに絞ってありますが、ここからSSD1331の初期化から画面を黒で塗りつぶす処理までのコードを追って見ます。
// 色の定義
#define BLACK0x0000
void setup(void) {
display.begin();
display.fillScreen(BLACK);
}
void loop() {
}
#define BLACK0x0000
void setup(void) {
display.begin();
display.fillScreen(BLACK);
}
void loop() {
}
"BLACK"の色定義、display(Adafruit_SSD1331)のbegin()の実行、fillScreen()までの流れとなっていますが、まずはbegin()を調べて見ます。
この関数は、"Adafruit_SSD1331.cpp"にあります。
void Adafruit_SSD1331::begin(void) {
// ピンの方向を設定する
pinMode(_rs, OUTPUT);
// ハードウェアSPIを使用します
SPI.begin();
SPI.setDataMode(SPI_MODE3);
// リセットするにはRSTをローに切り替えます; CSがlowであれば指示の受け入れが可能です
pinMode(_cs, OUTPUT);
digitalWrite(_cs, LOW);
cspin = digitalPinToBitMask(_cs);
csportreg = portOutputRegister(digitalPinToPort(_cs));
rspin = digitalPinToBitMask(_rs);
rsportreg = portOutputRegister(digitalPinToPort(_rs));
// I初期化シーケンス
writeCommand(SSD1331_CMD_DISPLAYOFF); // 0xAE
writeCommand(SSD1331_CMD_SETREMAP); // 0xA0
writeCommand(0x72); // RGB Color
writeCommand(SSD1331_CMD_STARTLINE); // 0xA1
writeCommand(0x0);
writeCommand(SSD1331_CMD_DISPLAYOFFSET); // 0xA2
writeCommand(0x0);
writeCommand(SSD1331_CMD_NORMALDISPLAY); // 0xA4
writeCommand(SSD1331_CMD_SETMULTIPLEX); // 0xA8
writeCommand(0x3F); // 0x3F 1/64 duty
writeCommand(SSD1331_CMD_SETMASTER); // 0xAD
writeCommand(0x8E);
writeCommand(SSD1331_CMD_POWERMODE); // 0xB0
writeCommand(0x0B);
writeCommand(SSD1331_CMD_PRECHARGE); // 0xB1
writeCommand(0x31);
writeCommand(SSD1331_CMD_CLOCKDIV); // 0xB3
writeCommand(0xF0); // 7:4 = Oscillator Frequency, 3:0 = CLK Div Ratio (A[3:0]+1 = 1..16)
writeCommand(SSD1331_CMD_PRECHARGEA); // 0x8A
writeCommand(0x64);
writeCommand(SSD1331_CMD_PRECHARGEB); // 0x8B
writeCommand(0x78);
writeCommand(SSD1331_CMD_PRECHARGEA); // 0x8C
writeCommand(0x64);
writeCommand(SSD1331_CMD_PRECHARGELEVEL); // 0xBB
writeCommand(0x3A);
writeCommand(SSD1331_CMD_VCOMH); // 0xBE
writeCommand(0x3E);
writeCommand(SSD1331_CMD_MASTERCURRENT); // 0x87
writeCommand(0x06);
writeCommand(SSD1331_CMD_CONTRASTA); // 0x81
writeCommand(0x91);
writeCommand(SSD1331_CMD_CONTRASTB); // 0x82
writeCommand(0x50);
writeCommand(SSD1331_CMD_CONTRASTC); // 0x83
writeCommand(0x7D);
writeCommand(SSD1331_CMD_DISPLAYON); //--turn on oled panel
}
// ピンの方向を設定する
pinMode(_rs, OUTPUT);
// ハードウェアSPIを使用します
SPI.begin();
SPI.setDataMode(SPI_MODE3);
// リセットするにはRSTをローに切り替えます; CSがlowであれば指示の受け入れが可能です
pinMode(_cs, OUTPUT);
digitalWrite(_cs, LOW);
cspin = digitalPinToBitMask(_cs);
csportreg = portOutputRegister(digitalPinToPort(_cs));
rspin = digitalPinToBitMask(_rs);
rsportreg = portOutputRegister(digitalPinToPort(_rs));
// I初期化シーケンス
writeCommand(SSD1331_CMD_DISPLAYOFF); // 0xAE
writeCommand(SSD1331_CMD_SETREMAP); // 0xA0
writeCommand(0x72); // RGB Color
writeCommand(SSD1331_CMD_STARTLINE); // 0xA1
writeCommand(0x0);
writeCommand(SSD1331_CMD_DISPLAYOFFSET); // 0xA2
writeCommand(0x0);
writeCommand(SSD1331_CMD_NORMALDISPLAY); // 0xA4
writeCommand(SSD1331_CMD_SETMULTIPLEX); // 0xA8
writeCommand(0x3F); // 0x3F 1/64 duty
writeCommand(SSD1331_CMD_SETMASTER); // 0xAD
writeCommand(0x8E);
writeCommand(SSD1331_CMD_POWERMODE); // 0xB0
writeCommand(0x0B);
writeCommand(SSD1331_CMD_PRECHARGE); // 0xB1
writeCommand(0x31);
writeCommand(SSD1331_CMD_CLOCKDIV); // 0xB3
writeCommand(0xF0); // 7:4 = Oscillator Frequency, 3:0 = CLK Div Ratio (A[3:0]+1 = 1..16)
writeCommand(SSD1331_CMD_PRECHARGEA); // 0x8A
writeCommand(0x64);
writeCommand(SSD1331_CMD_PRECHARGEB); // 0x8B
writeCommand(0x78);
writeCommand(SSD1331_CMD_PRECHARGEA); // 0x8C
writeCommand(0x64);
writeCommand(SSD1331_CMD_PRECHARGELEVEL); // 0xBB
writeCommand(0x3A);
writeCommand(SSD1331_CMD_VCOMH); // 0xBE
writeCommand(0x3E);
writeCommand(SSD1331_CMD_MASTERCURRENT); // 0x87
writeCommand(0x06);
writeCommand(SSD1331_CMD_CONTRASTA); // 0x81
writeCommand(0x91);
writeCommand(SSD1331_CMD_CONTRASTB); // 0x82
writeCommand(0x50);
writeCommand(SSD1331_CMD_CONTRASTC); // 0x83
writeCommand(0x7D);
writeCommand(SSD1331_CMD_DISPLAYON); //--turn on oled panel
}
とりあえず簡単なところから、
// ピンの方向を設定する
pinMode(_rs, OUTPUT);
// リセットするにはRSTをローに切り替えます; CSがlowであれば指示の受け入れが可能です
pinMode(_cs, OUTPUT);
digitalWrite(_cs, LOW);
if (_rst) {
pinMode(_rst, OUTPUT);
digitalWrite(_rst, HIGH);
delay(500);
digitalWrite(_rst, LOW);
delay(500);
digitalWrite(_rst, HIGH);
delay(500);
}
pinMode(_rs, OUTPUT);
// リセットするにはRSTをローに切り替えます; CSがlowであれば指示の受け入れが可能です
pinMode(_cs, OUTPUT);
digitalWrite(_cs, LOW);
if (_rst) {
pinMode(_rst, OUTPUT);
digitalWrite(_rst, HIGH);
delay(500);
digitalWrite(_rst, LOW);
delay(500);
digitalWrite(_rst, HIGH);
delay(500);
}
"pinMode"、"digitalWrite"の詳細は下記の解説を見てもらえば良いかと思いますが、8(_rs)、10(_cs)ピンを出力に、10(_cs)ピンをLOW(0V)に設定しています。
"_rst"での条件分岐以降の部分は、9(_rst)を出力に設定した後に500ms毎にHIGH(3.3V)、LOW(0V)、HIGH(3.3V)と切り替えています。
コメントにもあるように"_rst"の設定の前に、"_cs"の設定が必要となります。
pinMode()
[Digital I/O]
説明
指定されたピンが入力または出力として動作するように設定します。 ピンの機能の詳細については(デジタルピン)の説明を参照してください。 Arduino 1.0.1以降、INPUT_PULLUPモードで内部プルアップ抵抗をイネーブルすることが可能です。 さらに、INPUTモードは、内部プルアップを明示的にdisablesにします。
構文
pinMode(pin, mode)
パラメータ
pin: the number of the pin whose mode you wish to set
mode: INPUT、OUTPUT、またはINPUT_PULLUP (機能の詳細な説明については (デジタルピン) のページを参照してください)
戻り値
Nothing
[Digital I/O]
説明
指定されたピンが入力または出力として動作するように設定します。 ピンの機能の詳細については(デジタルピン)の説明を参照してください。 Arduino 1.0.1以降、INPUT_PULLUPモードで内部プルアップ抵抗をイネーブルすることが可能です。 さらに、INPUTモードは、内部プルアップを明示的にdisablesにします。
構文
pinMode(pin, mode)
パラメータ
pin: the number of the pin whose mode you wish to set
mode: INPUT、OUTPUT、またはINPUT_PULLUP (機能の詳細な説明については (デジタルピン) のページを参照してください)
戻り値
Nothing
digitalWrite()
[Digital I/O]
説明
HIGHまたはLOW値をデジタルピンに書き込みます。
ピンがpinMode()でOUTPUTとして設定されている場合、その電圧は対応する値に設定されます。HIGHの場合は5V(または3.3Vのボードの場合は3.3V)、LOWの場合は0V(グランド)。
ピンがINPUTとして設定されている場合、digitalWrite()は入力ピンの内部プルアップをEnable(HIGH)またはDisable(LOW)にします。内部プルアップ抵抗をイネーブルにするには、pinMode()をINPUT_PULLUPに設定することを推奨します。詳細については、デジタルピンのチュートリアルを参照してください。
pinMode()をOUTPUTに設定せずにLEDをピンに接続すると、digitalWrite(HIGH)を呼び出すときにLEDが暗く見えることがあります。pinMode()を明示的に設定しなければ、digitalWrite()は内部プルアップ抵抗を有効にし、大電流制限抵抗のように動作します。
構文
digitalWrite(pin, value)
パラメータ
pin: ピン番号
mode: IHIGHまたはLOW
戻り値
Nothing
[Digital I/O]
説明
HIGHまたはLOW値をデジタルピンに書き込みます。
ピンがpinMode()でOUTPUTとして設定されている場合、その電圧は対応する値に設定されます。HIGHの場合は5V(または3.3Vのボードの場合は3.3V)、LOWの場合は0V(グランド)。
ピンがINPUTとして設定されている場合、digitalWrite()は入力ピンの内部プルアップをEnable(HIGH)またはDisable(LOW)にします。内部プルアップ抵抗をイネーブルにするには、pinMode()をINPUT_PULLUPに設定することを推奨します。詳細については、デジタルピンのチュートリアルを参照してください。
pinMode()をOUTPUTに設定せずにLEDをピンに接続すると、digitalWrite(HIGH)を呼び出すときにLEDが暗く見えることがあります。pinMode()を明示的に設定しなければ、digitalWrite()は内部プルアップ抵抗を有効にし、大電流制限抵抗のように動作します。
構文
digitalWrite(pin, value)
パラメータ
pin: ピン番号
mode: IHIGHまたはLOW
戻り値
Nothing
ハードウェアSPIの設定
// ハードウェアSPIを使用します
SPI.begin();
SPI.setDataMode(SPI_MODE3);
SPI.begin();
SPI.setDataMode(SPI_MODE3);
SPI対応のマイコンと"#include <SPI.h>"は必須。
SPI.begin()
説明
SCK、MOSI、およびSSを出力に設定し、SCKおよびMOSIをローに引き上げ、SSをハイにすることで、SPIバスを初期化します。
構文
SPI.begin()
パラメータ
None
戻り値
None
setDataMode()
説明
PIパラメータを設定するには、SPI.beginTransaction()でSPISettingsを使用します。
SPIデータモードを設定します。つまり、クロックの極性と位相です。詳細については、SPIに関するWikipediaの記事を参照してください
構文
SPI.setDataMode(mode)
パラメータ
戻り値
Nothing
説明
PIパラメータを設定するには、SPI.beginTransaction()でSPISettingsを使用します。
SPIデータモードを設定します。つまり、クロックの極性と位相です。詳細については、SPIに関するWikipediaの記事を参照してください
構文
SPI.setDataMode(mode)
パラメータ
mode: | - SPI_MODE0 : アイドル時のクロックがLow、立ち上がりでサンプリング | |
- SPI_MODE1 : アイドル時のクロックがLow、立ち下がりでサンプリング | ||
- SPI_MODE2 : アイドル時のクロックがHigh、立ち上がりでサンプリング | ||
- SPI_MODE3 : アイドル時のクロックがHigh、立ち下がりでサンプリング | ||
slaveSelectPin | slave device SS pin | (Arduino Due only) |
戻り値
Nothing
と、ここまではArduinoを触っていれば周知の範疇。
ここから先は、私も含め知らない人の方が多い気がします。
cspin = digitalPinToBitMask(_cs);
csportreg = portOutputRegister(digitalPinToPort(_cs));
rspin = digitalPinToBitMask(_rs);
rsportreg = portOutputRegister(digitalPinToPort(_rs));
csportreg = portOutputRegister(digitalPinToPort(_cs));
rspin = digitalPinToBitMask(_rs);
rsportreg = portOutputRegister(digitalPinToPort(_rs));
uint8_t cspin | 1 バイトの符号なし整数 cspin | digitalPinToBitMask() |
uint8_t *csportreg | 1 バイトの符号なし整数 csportreg | portOutputRegister() |
uint8_t rspin | 1 バイトの符号なし整数 rspin | digitalPinToBitMask() |
uint8_t *rsportreg | 1 バイトの符号なし整数 rsportreg | portOutputRegister() |
digitalPinToBitMask()
説明
指定したピンが対応するピンのビットマスクを返すマクロです。
hardware/arduino/cores/arduino/Arduino.h に定義されています。
構文
digitalPinToBitMask(P)
パラメータ
P: ピン番号
戻り値
uint8_t ビットマスク
説明
指定したピンが対応するピンのビットマスクを返すマクロです。
hardware/arduino/cores/arduino/Arduino.h に定義されています。
#define digitalPinToBitMask(P) ( pgm_read_byte( digital_pin_to_bit_mask_PGM+(P) ) )
構文
digitalPinToBitMask(P)
パラメータ
P: ピン番号
戻り値
uint8_t ビットマスク
portOutputRegister()
説明
指定したポートに対応するレジスタを返すマクロです。
hardware/arduino/cores/arduino/Arduino.h に定義されています。
構文
portOutputRegister(P)
パラメータ
P: ポート番号
戻り値
uint8_t レジスタ
説明
指定したポートに対応するレジスタを返すマクロです。
hardware/arduino/cores/arduino/Arduino.h に定義されています。
#define portOutputRegister(P) ( ( volatile uint8_t * )( pgm_read_word( port_to_output_PGM + (P) ) ) )
構文
portOutputRegister(P)
パラメータ
P: ポート番号
戻り値
uint8_t レジスタ
digitalPinToPort()
説明
指定したピンに対応するポートを返すマクロです。
hardware/arduino/cores/arduino/Arduino.h に定義されています。
構文
digitalPinToPort(P)
パラメータ
P: ピン番号
戻り値
uint8_t ポート番号
説明
指定したピンに対応するポートを返すマクロです。
hardware/arduino/cores/arduino/Arduino.h に定義されています。
#define digitalPinToPort(P) ( pgm_read_byte( digital_pin_to_port_PGM + (P) ) )
構文
digitalPinToPort(P)
パラメータ
P: ピン番号
戻り値
uint8_t ポート番号
以上3つのマクロの中には、
- pgm_read_byte(address)
- digital_pin_to_bit_mask_PGM - 配列
- pgm_read_word(address)
- port_to_output_PGM - 配列
- digital_pin_to_port_PGM - 配列
など、更に見慣れないワードが出てきます。深堀していけばフラッシュメモリ周りの知識や技術が向上しますが、ここではそれを求めている訳ではないのでビットマスクとレジスタを取得している程度の認識で留めておきます。
// I初期化シーケンス
writeCommand(SSD1331_CMD_DISPLAYOFF); // 0xAE
writeCommand(SSD1331_CMD_DISPLAYOFF); // 0xAE
"Adafruit_SSD1331.cpp"に記載されているこの関数を見て行きます。
扱われている関数は、先に出てきたものですが、"Adafruit_SSD1331.h"で、
と宣言され、新たに出てきた"PortReg"、"PortMask"も同じヘッダファイルの中で下記のように宣言されています。
まとめるとこの様になります。
では、SPIを行う前の処理を調べて見ましょう。
"&= ~"は説明にもある通りで、ポインタ"*rsportreg"や"*csportreg"に0を代入しています。これはコードのコメントにある様に、各端子を"LOW"に指定している状態です。
SPI送信が終わった後に、"|="で1(HIGH)に戻しています。
一旦0(LOW)にしているので、代入した変数の値にしからならいので"|="を用いている意味は良くわからないです。
この辺りに関しては、SSD1331 Datasheetに、
7.2 コマンドデコーダ
このモジュールは、入力をD / C#ピンの入力に基づいてデータまたはコマンドとして解釈する必要があるかどうかを決定します。D/C#ピンがHIGHの場合、データはグラフィック表示データRAM(GDDRAM)に書き込まれます。D/C#がLOWの場合、D0〜D15の入力はコマンドとして解釈され、デコードされて対応するコマンドレジスタに書き込まれます。
と、記載されています。
これらを参考に先ほどの処理内容と照らし合わせると、
CS#(*csportreg) : LOW / D/C#(*rsportreg) : LOW
なので、"Write command"に設定して、"spiwrite(c);"でコマンドの書き込みを行い、CS#(*csportreg) : HIGH に戻す事で"Write command"を解除しています。この辺りは、コマンド、データの書き込みに追いては必須となります。
void Adafruit_SSD1331::writeCommand(uint8_t c) {
*rsportreg &= ~ rspin;
//digitalWrite(_rs, LOW);
*csportreg &= ~ cspin;
//digitalWrite(_cs, LOW);
//Serial.print("C ");
spiwrite(c);
*csportreg |= cspin;
//digitalWrite(_cs, HIGH);
}
uint8_t c | 1 バイトの符号なし整数 c | SSD1331_CMD_DISPLAYOFF(0xAE) |
扱われている関数は、先に出てきたものですが、"Adafruit_SSD1331.h"で、
PortReg *csportreg, *rsportreg, *sidportreg, *sclkportreg;
PortMask cspin, rspin, sidpin, sclkpin;
と宣言され、新たに出てきた"PortReg"、"PortMask"も同じヘッダファイルの中で下記のように宣言されています。
typedef volatile uint8_t PortReg;
typedef uint8_t PortMask;
typedef uint8_t PortMask;
まとめるとこの様になります。
volatile uint8_t *csportreg | 1 バイトの符号なし整数 csportreg |
volatile uint8_t *rsportreg | 1 バイトの符号なし整数 rsportreg |
volatile uint8_t *sidportreg | 1 バイトの符号なし整数 sidportreg |
volatile uint8_t *sclkportreg | 1 バイトの符号なし整数 sclkportreg |
uint8_t cspin | 1 バイトの符号なし整数 cspin |
uint8_t rspin | 1 バイトの符号なし整数 rspin |
uint8_t sidpin | 1 バイトの符号なし整数 sidpin |
uint8_t sclkpin | 1 バイトの符号なし整数 sclkpin |
使用されているポインタアクセス演算子&複合演算子&ビット演算子
"spiwrite()"は、"Adafruit_SSD1331.cpp"に記載されている関数です。下記では、ハードウェアSPIに関する箇所以外は削除してあります。(_sid = 0なので)
これらの情報から、"spiwrite()"は、引数"c"を経由して"transfer()"でSPI通信により引き継いだ値を送信していることがわかります。
*
[Pointer Access Operators]
説明
Dereferencingは、特にポインタで使用するための機能の1つです。アスタリスク演算子*がこの目的に使用されます。pがポインタの場合、* pはpが指すアドレスに含まれる値を表します。
[Pointer Access Operators]
説明
Dereferencingは、特にポインタで使用するための機能の1つです。アスタリスク演算子*がこの目的に使用されます。pがポインタの場合、* pはpが指すアドレスに含まれる値を表します。
&=
[Compound Operators]
説明
複合AND演算子&=は、変数と定数とともに使用され、変数の特定のビットをLOW状態(0)にします。これは、プログラミングガイドで「クリア」または「リセット」ビットと呼ばれることがよくあります。
ビット単位のAND&演算子のレビュー
構文
x &= y; // x = x & y;と同じ動作です。
パラメータ
x:変数。 使用できるデータ型:char、int、long
y:変数または定数。 使用できるデータ型:char、int、long
[Compound Operators]
説明
複合AND演算子&=は、変数と定数とともに使用され、変数の特定のビットをLOW状態(0)にします。これは、プログラミングガイドで「クリア」または「リセット」ビットと呼ばれることがよくあります。
ビット単位のAND&演算子のレビュー
0011 | operand1 |
0101 | operand2 |
---------- | |
0001 | (operand1 & operand2) - 返された結果 |
構文
x &= y; // x = x & y;と同じ動作です。
パラメータ
x:変数。 使用できるデータ型:char、int、long
y:変数または定数。 使用できるデータ型:char、int、long
~
[Bitwise Operators]
説明
C++のビット単位のNOT演算子はチルダ文字~です。&や|と異なり、ビット単位のNOT演算子は、その右側の単一のオペランドに適用されます。ビット単位のNOTは各ビットをその反対の値に変更します: 0は1になり、1は0になります。
言い換えると:
[Bitwise Operators]
説明
C++のビット単位のNOT演算子はチルダ文字~です。&や|と異なり、ビット単位のNOT演算子は、その右側の単一のオペランドに適用されます。ビット単位のNOTは各ビットをその反対の値に変更します: 0は1になり、1は0になります。
言い換えると:
0 1 | operand1 |
----- | |
1 0 | ~operand1 |
|=
[Compound Operators]
説明
複合のビット単位OR演算子| =は、変数内の特定のビットを「設定」(1に設定)するために変数と定数とともに使用されることがよくあります。
ビット単位のOR | 演算子のレビュー
構文
x |= y; // x = x | y;と同じ動作です。
パラメータ
x:変数。 使用できるデータ型:char、int、long
y:変数または定数。 使用できるデータ型:char、int、long
[Compound Operators]
説明
複合のビット単位OR演算子| =は、変数内の特定のビットを「設定」(1に設定)するために変数と定数とともに使用されることがよくあります。
ビット単位のOR | 演算子のレビュー
0011 | operand1 |
0101 | operand2 |
---------- | |
0111 | (operand1 | operand2) - 返された結果 |
構文
x |= y; // x = x | y;と同じ動作です。
パラメータ
x:変数。 使用できるデータ型:char、int、long
y:変数または定数。 使用できるデータ型:char、int、long
"spiwrite()"は、"Adafruit_SSD1331.cpp"に記載されている関数です。下記では、ハードウェアSPIに関する箇所以外は削除してあります。(_sid = 0なので)
/********************************** 低レベルピンインタフェース */
inline void Adafruit_SSD1331::spiwrite(uint8_t c) {
if (!_sid) {
SPI.transfer(c);
return;
}
}
inline void Adafruit_SSD1331::spiwrite(uint8_t c) {
if (!_sid) {
SPI.transfer(c);
return;
}
}
uint8_t c | 1 バイトの符号なし整数 c | 0xAE |
uint8_t _sid | 1 バイトの符号なし整数 _sid | 0 |
SPI.transfer() / transfer16()
説明
SPI転送は、同時送受信が基本となっています: 受信したデータはreceivedVal(またはreceivedVal16)に返されます。バッファ転送の場合、受信したデータはバッファ内の現在の位置に格納されます(古いデータは受信したデータに置き換えられます)。
構文
receivedVal = SPI.transfer(val)
receivedVal16 = SPI.transfer16(val16)
SPI.transfer(buffer, size)
パラメータ
val: バスを介して送信するバイト
val16: バスを介して送出するための2バイトの変数
buffer: 転送されるデータの配列
戻り値
受信したデータ
説明
SPI転送は、同時送受信が基本となっています: 受信したデータはreceivedVal(またはreceivedVal16)に返されます。バッファ転送の場合、受信したデータはバッファ内の現在の位置に格納されます(古いデータは受信したデータに置き換えられます)。
構文
receivedVal = SPI.transfer(val)
receivedVal16 = SPI.transfer16(val16)
SPI.transfer(buffer, size)
パラメータ
val: バスを介して送信するバイト
val16: バスを介して送出するための2バイトの変数
buffer: 転送されるデータの配列
戻り値
受信したデータ
これらの情報から、"spiwrite()"は、引数"c"を経由して"transfer()"でSPI通信により引き継いだ値を送信していることがわかります。
では、SPIを行う前の処理を調べて見ましょう。
"&= ~"は説明にもある通りで、ポインタ"*rsportreg"や"*csportreg"に0を代入しています。これはコードのコメントにある様に、各端子を"LOW"に指定している状態です。
SPI送信が終わった後に、"|="で1(HIGH)に戻しています。
一旦0(LOW)にしているので、代入した変数の値にしからならいので"|="を用いている意味は良くわからないです。
この辺りに関しては、SSD1331 Datasheetに、
Table 8 - シリアルインタフェースの制御端子 | ||||
---|---|---|---|---|
Function | E | R/W# | CS# | D/C# |
Write command | Tie low | Tie low | L | L |
Write data | Tie low | Tie low | L | H |
7.2 コマンドデコーダ
このモジュールは、入力をD / C#ピンの入力に基づいてデータまたはコマンドとして解釈する必要があるかどうかを決定します。D/C#ピンがHIGHの場合、データはグラフィック表示データRAM(GDDRAM)に書き込まれます。D/C#がLOWの場合、D0〜D15の入力はコマンドとして解釈され、デコードされて対応するコマンドレジスタに書き込まれます。
と、記載されています。
これらを参考に先ほどの処理内容と照らし合わせると、
CS#(*csportreg) : LOW / D/C#(*rsportreg) : LOW
なので、"Write command"に設定して、"spiwrite(c);"でコマンドの書き込みを行い、CS#(*csportreg) : HIGH に戻す事で"Write command"を解除しています。この辺りは、コマンド、データの書き込みに追いては必須となります。
なんとなく何が行われているのか理解出来てきたので、再び初期化にあたってのコード一覧を見てみます。
// I初期化シーケンス
writeCommand(SSD1331_CMD_DISPLAYOFF); // 0xAE
writeCommand(SSD1331_CMD_SETREMAP); // 0xA0
writeCommand(0x72); // RGB Color
writeCommand(SSD1331_CMD_STARTLINE); // 0xA1
writeCommand(0x0);
writeCommand(SSD1331_CMD_DISPLAYOFFSET); // 0xA2
writeCommand(0x0);
writeCommand(SSD1331_CMD_NORMALDISPLAY); // 0xA4
writeCommand(SSD1331_CMD_SETMULTIPLEX); // 0xA8
writeCommand(0x3F); // 0x3F 1/64 duty
writeCommand(SSD1331_CMD_SETMASTER); // 0xAD
writeCommand(0x8E);
writeCommand(SSD1331_CMD_POWERMODE); // 0xB0
writeCommand(0x0B);
writeCommand(SSD1331_CMD_PRECHARGE); // 0xB1
writeCommand(0x31);
writeCommand(SSD1331_CMD_CLOCKDIV); // 0xB3
writeCommand(0xF0); // 7:4 = Oscillator Frequency, 3:0 = CLK Div Ratio (A[3:0]+1 = 1..16)
writeCommand(SSD1331_CMD_PRECHARGEA); // 0x8A
writeCommand(0x64);
writeCommand(SSD1331_CMD_PRECHARGEB); // 0x8B
writeCommand(0x78);
writeCommand(SSD1331_CMD_PRECHARGEA); // 0x8C
writeCommand(0x64);
writeCommand(SSD1331_CMD_PRECHARGELEVEL); // 0xBB
writeCommand(0x3A);
writeCommand(SSD1331_CMD_VCOMH); // 0xBE
writeCommand(0x3E);
writeCommand(SSD1331_CMD_MASTERCURRENT); // 0x87
writeCommand(0x06);
writeCommand(SSD1331_CMD_CONTRASTA); // 0x81
writeCommand(0x91);
writeCommand(SSD1331_CMD_CONTRASTB); // 0x82
writeCommand(0x50);
writeCommand(SSD1331_CMD_CONTRASTC); // 0x83
writeCommand(0x7D);
writeCommand(SSD1331_CMD_DISPLAYON); //--turn on oled panel
writeCommand(SSD1331_CMD_DISPLAYOFF); // 0xAE
writeCommand(SSD1331_CMD_SETREMAP); // 0xA0
writeCommand(0x72); // RGB Color
writeCommand(SSD1331_CMD_STARTLINE); // 0xA1
writeCommand(0x0);
writeCommand(SSD1331_CMD_DISPLAYOFFSET); // 0xA2
writeCommand(0x0);
writeCommand(SSD1331_CMD_NORMALDISPLAY); // 0xA4
writeCommand(SSD1331_CMD_SETMULTIPLEX); // 0xA8
writeCommand(0x3F); // 0x3F 1/64 duty
writeCommand(SSD1331_CMD_SETMASTER); // 0xAD
writeCommand(0x8E);
writeCommand(SSD1331_CMD_POWERMODE); // 0xB0
writeCommand(0x0B);
writeCommand(SSD1331_CMD_PRECHARGE); // 0xB1
writeCommand(0x31);
writeCommand(SSD1331_CMD_CLOCKDIV); // 0xB3
writeCommand(0xF0); // 7:4 = Oscillator Frequency, 3:0 = CLK Div Ratio (A[3:0]+1 = 1..16)
writeCommand(SSD1331_CMD_PRECHARGEA); // 0x8A
writeCommand(0x64);
writeCommand(SSD1331_CMD_PRECHARGEB); // 0x8B
writeCommand(0x78);
writeCommand(SSD1331_CMD_PRECHARGEA); // 0x8C
writeCommand(0x64);
writeCommand(SSD1331_CMD_PRECHARGELEVEL); // 0xBB
writeCommand(0x3A);
writeCommand(SSD1331_CMD_VCOMH); // 0xBE
writeCommand(0x3E);
writeCommand(SSD1331_CMD_MASTERCURRENT); // 0x87
writeCommand(0x06);
writeCommand(SSD1331_CMD_CONTRASTA); // 0x81
writeCommand(0x91);
writeCommand(SSD1331_CMD_CONTRASTB); // 0x82
writeCommand(0x50);
writeCommand(SSD1331_CMD_CONTRASTC); // 0x83
writeCommand(0x7D);
writeCommand(SSD1331_CMD_DISPLAYON); //--turn on oled panel
このコマンドの大半は、"Adafruit_SSD1331.h"で定義されています。
定義内容とそれぞれの機能をSSD1331のDatasheetを確認しながら調べて見ます。
0xAC | |||||||||||||||||||||
#define SSD1331_CMD_DISPLAYOFF | 0xAE | ||||||||||||||||||||
#define SSD1331_CMD_DISPLAYON | 0xAF | ||||||||||||||||||||
ACh = 調光モードで表示ON AEh = 表示OFF (sleep mode) Default AFh = ノーマルモードで表示ON 9.1.13 ディスプレイのON / OFFを設定する (ACh / AEh / AFh) これらの1バイトコマンドは、OLEDパネルの表示をONまたはOFFするために使用されます。表示がONのときは、マスタ構成設定コマンドで選択した回路がONになります。ディスプレイがオフのとき、これらの回路はオフになり、セグメントとコモン出力はハイインピーダンス状態になります。 これらのコマンドは、次の3つの状態のいずれかに表示を設定します: o ACh:暗いモードの表示ON o AEh:表示OFF(スリープモード) o AFh:通常の明るさ表示オン ここで、暗いモード設定はコマンドABhによって制御される。 |
#define SSD1331_CMD_SETREMAP | 0xA0 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// RGB Color | 0x72 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
ドライバのリマップと色深度を設定する A [0] = 0、水平アドレスインクリメント A [0] = 1、垂直アドレスインクリメント A [1] = 0、RAMカラム0〜95はピンセグ(SA、SB、SC)にマップ0〜95 A [1] = 1、RAMカラム0〜95はピンセグ(SA、SB、SC)にマップ95〜0 A [2] = 0、順序 SA、SB、SC(例えば、RGB) A [2] = 1、逆順 SC、SB、SA(例えば、BGR) A [3] = 0、COM上での左右スワッピングを無効にする A [3] = 1、COMに左右スワップを設定する A [4] = 0、COM0からCOM [N-1]へスキャン A [4] = 1、COM [N-1]からCOM0にスキャンする。 ここで、Nは多重比です。 A [5] = 0、COMスプリット奇数を無効にする(RESET) A [5] = 1、COMスプリット奇数を有効にする A [7:6] = 00; 256色フォーマット A [7:6] = 01; 65kカラーフォーマット A [7:6] = 10; 65kカラーフォーマット2 9/18ビットモードを選択した場合、設定に関係なく色深度は65kに固定されます。 9.1.6 リマップとデータフォーマットを設定 (A0h) このコマンドには複数の構成があり、各ビットの設定は次のように記述されています。 •アドレスインクリメントモード(A [0]) 0に設定すると、ドライバは水平アドレスインクリメントモードに設定されます。ディスプレイRAMが読み書きされた後、列アドレスポインタは自動的に1だけ増加する。列アドレスポインタが列終了アドレスに到達すると、列アドレスポインタは列開始アドレスにリセットされ、行アドレスポインタは1だけ増加される。水平アドレスインクリメントモードの行および列アドレスポイントの移動シーケンスを図23に示します。
A [0]を1に設定すると、ドライバは垂直アドレスインクリメントモードに設定されます。表示RAMが読み書きされた後、行アドレスポインタは自動的に1だけ増加する。行アドレスポインタが行終了アドレスに達すると、行アドレスポインタは行開始アドレスにリセットされ、列アドレスポインタは1だけ増加される。垂直アドレスインクリメントモードの行および列アドレスポイントの移動シーケンスを図24に示します。
•列アドレスマッピング(A [1]) このコマンドビットは、左から右へまたはその逆に配置されたセグメントを有するOLEDモジュールにおけるセグメント信号の柔軟なレイアウトのために作られる。表示方向は、表示データRAM列0〜SEG0端子(A [1] = 0)、または表示データRAM列95をSEG0端子(A [1] = 1)にマッピングする方法です。両方の効果を図25に示します。 Figure 25 - 列アドレスマッピングの例 詳細は省略。SSD1331 Datasheetを確認して下さい。 •RGBマッピング(A [2]) このコマンドビットは、OLEDモジュールのセグメント信号をフレキシブルにレイアウトするために作成されたもので、フィルタ設計にマッチします。 •COM左/右リマップ(A [3]) このコマンドビットは、COM0が左側または右側のいずれかに配置されたOLEDモジュールの共通信号の柔軟なレイアウト用に作成されています。ピン配置の詳細は表12と図26にあります。 •COMスキャン方向のリマップ(A [4]) このビットは、OLEDモジュールにおける共通信号の柔軟なレイアウトのための共通の走査方向を、上から下へ、またはその逆に決定する。ピン配置の詳細は表12と図26にあります。 •COMピン(A [5])の奇数偶数分割 このビットは、COMピンの奇数偶数配列を設定できます。 A [5] = 0:COMスプリット奇数を無効、コモンのピン割り当てはCOM63 COM62 .... COM 33 COM32..SC95..SA0..COM0 COM1.... COM30 COM31 A [5] = 1:COMスプリット奇数を有効、コモンのピン割り当てをCOM63 COM61.... COM3 COM1..SC95..SA0..COM0 COM2.... COM60 COM62 ピン配置の詳細は表12と図26にあります。 •カラーモードを表示する(A [7:6]) 65kまたは256色モードを選択します。異なるモードのディスプレイRAMデータフォーマットについては、セクション7.5で説明しています。 Table 12 - 異なるCOM出力設定の図 Figure 26 - COMピンのハードウェア構成(MUX比:64) これらも長いので省略しています。詳細を確認したい場合はSSD1331 Datasheetを確認して下さい。 これは"0xA0"のリマップとデータフォーマットを設定のためのパラメーター。 "0x72"をビットで見てみると、 A [7 : 0] = 01110010 A [0] = 0、水平アドレスインクリメント A [1] = 1、RAMカラム0〜95はピンセグ(SA、SB、SC)にマップ95〜0 A [2] = 0、順序 SA、SB、SC(例えば、RGB) A [3] = 0、COM上での左右スワッピングを無効にする A [4] = 1、COM [N-1]からCOM0にスキャンする A [5] = 1、COMスプリット奇数を有効にする A [7:6] = 01; 65kカラーフォーマット 以上が、ここで設定されている内容。 |
#define SSD1331_CMD_STARTLINE | 0xA1 | ||||||||||||||||||||
0x0 | |||||||||||||||||||||
行単位で表示開始行レジスタを設定する A[5:0]: 00dから63dまで 9.1.7 表示開始行を設定する (A1h) このコマンドは、Display Start Lineレジスタを設定して、0〜63の値を選択して表示RAMの開始アドレスを決定します。表13および表14に、このコマンドの例を示します。ここでの"Row(行)"は、グラフィック表示データRAM行を意味する。 Table 13 - 表示オフセットを設定し、再設定なしの開始行を表示する例 Table 14 - ディスプレイのオフセットを設定し、リマップでスタートラインを表示する例 これらも長いので省略しています。詳細を確認したい場合はSSD1331 Datasheetを確認して下さい。 |
#define SSD1331_CMD_DISPLAYOFFSET | 0xA2 | ||||||||||||||||||||
0x0 | |||||||||||||||||||||
Comによる垂直オフセットの設定 A[5:0]: 00dから63dまで 9.1.8 ディスプレイのオフセットを設定する (A2h) このコマンドは、表示開始ライン(COM0が表示開始ライン、表示開始ラインレジスタが0)がCOM0-63のいずれかにマッピングされるように指定します。たとえば、COM16をCOM0方向に16行移動するには、2番目のコマンドの6ビットデータを0010000bで指定する必要があります。表13および表14に、このコマンドの例を示します。ここでの"Row(行)"は、グラフィック表示データRAM行を意味する。 Table 13 - 表示オフセットを設定し、再設定なしの開始行を表示する例 Table 14 - ディスプレイのオフセットを設定し、リマップでスタートラインを表示する例 これらも長いので省略しています。詳細を確認したい場合はSSD1331 Datasheetを確認して下さい。 |
#define SSD1331_CMD_NORMALDISPLAY | 0xA4 | ||||||||||||||||||||
A4h=通常表示 A5h=全体表示オン、GS63ですべてのピクセルがオンになります A6h=全体表示OFF、全画素OFF A7h=逆表示 9.1.9 表示モードを設定する (A4h ~ A7h) これらはシングルバイトコマンドであり、通常表示、全体表示ON、全体表示OFF、反転表示の設定に使用されます。 •通常表示(A4h) 上記の効果をリセットし、対応するグレーレベルでデータをONにします。 •全体表示をオンに設定する(A5h) 表示データRAMの内容にかかわらず、ディスプレイ全体を強制的に "GS63"にします。 •全体表示をオフにする(A6h) 表示データRAMの内容にかかわらず、ディスプレイ全体を強制的にグレーレベル "GS0"にします。 •逆表示(A7h) 表示データの階調は、 "GS0"→ "GS63"、 "GS1"→ "GS62"、...と変化する。 |
#define SSD1331_CMD_SETMULTIPLEX | 0xA8 | ||||||||||||||||||||
// 0x3F 1/64 duty | 0x3F | ||||||||||||||||||||
MUX比をN + 1 Muxに設定する N = A[5:0] 15dから63dまで A[5:0] 00dから14dまでは無効な入力です 9.1.10 マルチプレックス比率の設定 (A8h) このコマンドは、デフォルトの1:64のマルチプレクスモードを、16から64のマルチプレックスモードに切り替えます。例えば、多重比が16に設定されている場合、16本の共通ピンのみがイネーブルされます。有効化された共通ピンの開始および終了は、コマンドA2hによってプログラムされた“Display Offset”レジスタの設定に依存する。 |
#define SSD1331_CMD_SETMASTER | 0xAD | ||||||||||||||||||||
0x8E | |||||||||||||||||||||
A[0]=0b, 外部VCC電源を選択 A[0]=1b, 予約済み(RESET) Note (1) RESET後にビットA [0]を0bに設定する必要があります。 (2) TSet Display ONコマンド(AFh)を発行した後で設定が有効になります。 9.1.12 マスター構成の設定 (ADh) このコマンドは、外部VCC電源を選択します。 外部VCC電源はVCCピンに接続する必要があります。RESET後、A [0]ビットを0bに設定する必要があります。 このコマンドは、Set Display ONコマンド(AFh)を発行した後にアクティブになります。 |
#define SSD1331_CMD_POWERMODE | 0xB0 | ||||||||||||||||||||
0x0B | |||||||||||||||||||||
A[7:0]=1Ah, 省電力モードを有効にする(RESET) A[7:0]=0Bh, 省電力モードを無効にする 9.1.14 省電力モード (B0h) このコマンドは、省電力モードを有効または無効にするときに使用します。 |
#define SSD1331_CMD_PRECHARGE | 0xB1 | ||||||||||||||||||||
0x31 | |||||||||||||||||||||
A[3:0] N DCLKでのフェーズ1周期。1〜15 DCLKが許容。 A[7:4] N DCLKでのフェーズ2周期。1〜15 DCLKが許容。 Note (1) フェーズ1およびフェーズ2で0 DCLKは無効となります。 9.1.15 フェーズ1と2の期間調整 (B1h) このコマンドは、ドライバのセグメント波形の位相1と2の長さを設定します。 • Phase 1 (A[3:0]): DCLK単位で1〜15の期間を設定します。OLEDピクセルのより大きなキャパシタンスは、以前のデータ電荷を完全に放電するためにより長い期間を必要とすることがある。 • Phase 2 (A[7:4]): DCLK単位で1〜15の期間を設定します。OLED画素のより大きな容量をA、BおよびCの色の目標電圧VPに充電するためにより長い期間が必要である。 |
#define SSD1331_CMD_CLOCKDIV | 0xB3 | ||||||||||||||||||||
A[7:4] = オシレータ周波数, A[3:0] = CLK Div比 (A[3:0]+1 = 1..16) | 0xF0 | ||||||||||||||||||||
A[3:0] D0h表示クロック(DCLK)の分周比(D)を定義します: 分周比 (D) = A[3:0] + 1 (i.e., 1 to 16) A[7:4] Fosc周波数。 設定値が増加すると周波数が上昇する。 9.1.16 ディスプレイクロック分周比/発振器周波数の設定 (B3h) このコマンドは2つの機能で構成されています: • 表示クロック分周比 (A[3:0]) CLKからDCLK(表示クロック)を発生するように分周比を設定します。分周比は1〜16で、リセット値は1です。DCLKとCLKの関係については、7.3.1項を参照してください。 • オシレータ周波数 (A[7:4]) CLSピンをHighにすると、CLKのソースであるオシレータ周波数Foscをプログラムします。4ビットの値は、以下に示すように16種類の周波数設定を使用可能にします。デフォルト設定は1101bです。 |
#define SSD1331_CMD_PRECHARGEA | 0x8A | ||||||||||||||||||||||||||||
0x64 | |||||||||||||||||||||||||||||
#define SSD1331_CMD_PRECHARGEB | 0x8B | ||||||||||||||||||||||||||||
0x78 | |||||||||||||||||||||||||||||
#define SSD1331_CMD_PRECHARGEC | 0x8C | ||||||||||||||||||||||||||||
0x64 | |||||||||||||||||||||||||||||
A[7:0]: 2番目のプリチャージ速度を設定する。 Ranges: 0000000b〜1111111bでは、A [7:0]の値が高いほど、第2プリチャージ速度が速くなります。 Note (1) 8AhのA [7:0]、8ChのA [7:0]、8ChのA [7:0]のデフォルト値は、それぞれ色A、B、C(コマンド:81h、82h、83h参照)のコントラスト値に等しい。 (2) 6バイト (8Ah A[7:0], 8Bh A[7:0]はすべて一緒に入力する必要があります。たとえば、元の値は次のようになります。
8Ah,80h, 8Bh,75h, 8Ch,80h. 9.1.5 カラー A, B, C の2番目のプリチャージ速度を設定 (8Ah) 設定された値は、色A、B、Cのコントラストと一致する必要があります。最初の試行は、コントラストA、B、Cと同じ値でなければなりません。より速い速度が必要な場合は、より高い値を設定することができ、その逆も可能です。図22は、コマンド8Ah、8Bhおよび8Chを使用して、異なる速度で第2のプリチャージを設定する効果を示しています。 Figure 22 - 異なる速度で第2のプリチャージを設定する効果 これらも長いので省略しています。詳細を確認したい場合はSSD1331 Datasheetを確認して下さい。 |
#define SSD1331_CMD_PRECHARGELEVEL | 0xBB | ||||||||||||||||||||||||||||||||
0x3A | |||||||||||||||||||||||||||||||||
プリチャージ電圧レベルを設定します。3色とも同じプリチャージ電圧を共有します。
9.1.19 プリチャージ電圧の設定 (BBh) このコマンドは、セグメント・ピンのプリチャージ電圧レベルを設定します。VPレベルはVCCを基準にしてプログラムされます。図30は、コマンドBBh A [5:1]によるプリチャージ電圧レベルの設定の詳細を示しています Figure 30 – コマンドBBhによる典型的なプリチャージ電圧レベルの設定 これらも長いので省略しています。詳細を確認したい場合はSSD1331 Datasheetを確認して下さい。 |
#define SSD1331_CMD_VCOMH | 0xBE | ||||||||||||||||||||||||||||||||||||||
0x3E | |||||||||||||||||||||||||||||||||||||||
COMの電圧レベル(V COMH)を選択解除する
9.1.20 VCOMH電圧を設定 (BEh) このコマンドは、共通ピンの高電圧レベルを設定します。VCOMHのレベルはVCCを基準にしてプログラムされています。 |
#define SSD1331_CMD_MASTERCURRENT | 0x87 | ||||||||||||||||||||
0x06 | |||||||||||||||||||||
1/16、2/16〜16/16の減衰に対応するマスタ電流減衰係数A [3:0]を00d〜15dに設定します。 9.1.4 マスター電流制御 (87h) このコマンドはセグメント出力電流をスケーリング係数で制御します。この因子は、色A、BおよびCに共通である。チップには16のマスタ制御ステップがあります。 因子は1 [0000b]〜16 [1111b]の範囲である。RESETは16 [1111b]です。マスターの電流値が小さいほど、OLEDパネルの表示が暗くなります。たとえば、元のセグメント出力電流が倍率= 16で160uAの場合、倍率を8に設定して電流を80uAに減らします。 |
#define SSD1331_CMD_VCOMH | 0xBE | ||||||||||||||||||||||||||||||||||||||
0x3E | |||||||||||||||||||||||||||||||||||||||
COMの電圧レベル(V COMH)を選択解除する
9.1.20 VCOMH電圧を設定 (BEh) このコマンドは、共通ピンの高電圧レベルを設定します。VCOMHのレベルはVCCを基準にしてプログラムされています。 |
#define SSD1331_CMD_CONTRASTA | 0x81 | ||||||||||||||||||||
0x91 | |||||||||||||||||||||
#define SSD1331_CMD_CONTRASTB | 0x82 | ||||||||||||||||||||
0x50 | |||||||||||||||||||||
#define SSD1331_CMD_CONTRASTC | 0x83 | ||||||||||||||||||||
0x7D | |||||||||||||||||||||
すべてのカラー "A"セグメントのコントラストを設定する。 (Pins:SA0 – SA95) A[7:0] 有効範囲:00d〜255d すべてのカラー "B"セグメントのコントラストを設定する。 (Pins:SB0 – SB95) A[7:0] 有効範囲:00d〜255d すべてのカラー "C"セグメントのコントラストを設定する。 (Pins:SC0 – SC95) A[7:0] 有効範囲:00d〜255d 9.1.3 色のコントラストを設定 A, B, C (81h, 82h, 83h) このコマンドは、各色A、B、Cのコントラスト設定を設定するコマンドです。このチップは、色A、BおよびCの3つのコントラスト制御回路を有する。各コントラスト回路は、00hからFFhまでの256のコントラストステップを有する。コントラストステップでセグメント出力電流ISEGが増加するため、カラーが明るくなります。 |
以上が初期化処理で用いられている定数となります。
0 件のコメント:
コメントを投稿