SPI接続を使う
RaspberryPi PICではハードウエアレベルで SPI(Serial Peripheral Interface) 接続がサポートされています。SPIの詳細は【IC 間のデータ通信 SPI】を参照してください。
ArduinodIDEでRaspberryPi PICOのスケッチを作成する場合に、ボードライブラリを選ぶことが出来ます。
ボードライブラリによってピ割り当てや設定方法が異なるので、ここではArduinoIDEの公式(Arduino Mbed OS RP2040)のボードライブラリを使用します。
ArduinoIDEで使用する場合には 使用可能なGPIOピンが決まっています。
信号名 | GPIOピン |
---|---|
SCK | GP2 |
MOSI | GP3 |
MISO | GP4 |
SPIの動作モード設定
SPIを使用する場合には、SCKの動作クロック、ビットモード、SPIモードの設定が必要です。Mbedのボードライブラリを使用する場合には、この設定は
SPI.beginTransaction(SPISettings settings) メソッドを使用して行う。
設定値は SPISettings(SCLのクロック周波数, ビットモード, SPIモード) で指定
この指定値を SPI.beginTransaction() で設定する
#include <SPI.h>クロックの周波数はRaspberryPi PICOの動作クロックよりは速くできない他、デバイスの動作条件を逸脱する値にするとデバイスがどうさしない。
SPISettings settings = SPISettings(4000000, MSBFIRST, SPI_MODE0);
SPI.beginTransaction(settings);
OLED SD1306で試した範囲では16MHzまでは動作したが32MHzでは表示が乱れました。
OLED SSD1306 と 日本語フォントROM GT20L16J1Y を使ってみる
手持ちのSPIデバイスがコレだけなので (;´Д`)各デバイスの使用方法は【OLED SSD1306】 【日本語フォントROM GT20L16J1Y】 を参照してください。
▼ 解説動画で使用している「吾輩は猫である」冒頭表示スケッチ
KanjiDisp_DEMO02.zip
個別に使用する場合には問題ありませんが、SSD1306はSPIモード0、GT20L16J1YはSPIモード3で動作しているため、この二つを同時に使用する場合には、各々にデータを送る前に SPI.beginTransaction(settings) で SPIモードを切り替える必要があります。
※ <>を全角<>に置き換えています。コピペの際は注意してください。
// 漢字ROM READ : ASCIIコード
void KANJIROM::readASCIIFont(uint8_t asciiCode)
{
uint32_t Address = 0;
// ASCII文字
if (asciiCode >= 0x20 && asciiCode <= 0x7F) {
Address = ( asciiCode - 0x20) * 16 + 255968;
}
// 漢字ROMにデータを送信
SPI.beginTransaction(ROMSettings); // ★SPIモードをGT20L16J1Y用に変更
digitalWrite(ROMSPI_SS, HIGH);
digitalWrite(ROMSPI_SS, LOW); //通信開始
SPI.transfer(0x03);
SPI.transfer(Address >> 16 & 0xff);
SPI.transfer(Address >> 8 & 0xff);
SPI.transfer(Address & 0xff);
// 漢字ROMからデータを受信
for (int i = 0; i < 16; i++) {
matrixData[i] = SPI.transfer(0x00);
}
digitalWrite(ROMSPI_SS, HIGH); //通信終了
}
// OLEDに複数のコマンドを送信::Wireクラスの制限により最大32Byte
// 長さのチェックはしてないのでプログラマ責任で上手い事やってちょ
void OLED::oledSendCommands(int commandLen,uint8_t commands[]) {
SPI.beginTransaction(OLEDSettings); // ★SPIモードをSSD用に変更
digitalWrite(OLED_CS, LOW); // SSD1306セレクト
digitalWrite(OLED_DC, LOW); // Command mode
SPI.transfer(commands,commandLen);
digitalWrite(OLED_CS, HIGH); // SSD1306解放
}