注意事項
定数
定数 | 意味 |
---|---|
const uint8_t SPI_CONF::MSBFIRST | MSB を先頭ビットにする |
const uint8_t SPI_CONF::LSBFIRST | LSB を先頭ビットにする |
const uint8_t SPI_CONF::SPI_MODE0 | SPI MODE 0 に設定する |
const uint8_t SPI_CONF::SPI_MODE1 | SPI MODE 1 に設定する |
const uint8_t SPI_CONF::SPI_MODE2 | SPI MODE 2 に設定する |
const uint8_t SPI_CONF::SPI_MODE3 | SPI MODE 3 に設定する |
初期化と終了
SPIバスの利用手続きはbegin()
メソッドによります。
begin()
void begin(uint8_t slave_select, SPISettings settings)
SPISettings(uint32_t clock, uint8_t bitOrder, uint8_t dataMode)
ハードウェアの初期化を行います。
パラメータ | 解説 |
---|---|
slave_select | 対象のペリフェラルのセレクトピンを指定する。0 : DIO19``1 : DIO0 (DIO 19 は予約されます)``2 : DIO1 (DIO 0,19 は予約されます) |
settings | SPIのバス設定を指定します。clock [hz]でSPIバスの周波数を指定します。指定した周波数に近いディバイザが選択されます。16Mhzまたは16Mhzを偶数で割った値になります。bitOrder はSPI_CONF::MSBFIRST かSPI_CONF::LSBFIRST を指定します。dataMode はSPI_CONF::SPIMODE0..3 を指定します。 |
例
void setup() {
...
SPI.begin(0, SPISettings(2000000, SPI_CONF::MSBFIRST, SPI_CONF::SPI_MODE3));
...
}
void wakeip() {
...
SPI.begin(0, SPISettings(2000000, SPI_CONF::MSBFIRST, SPI_CONF::SPI_MODE3));
...
}
end()
void end()
SPIのハードウェアの利用を終了します。
読み書き
読み書きの手続きは、以下の2種類あります。いずれかを選択して利用します。
- メンバ関数版 (以下のメンバ関数を用いた入出力)
beginTransaction(), endTransaction(), transfer(), transfer16(), transfer32()
- ヘルパークラス版(stream機能が使用可能)
transceiver
使用例
次のサンプルコードは、Analog Devices の温度センサ ADT7310 から1秒おきに温度を取得し、シリアルポートへ出力します。
#include <TWELITE>
#include <SM_SIMPLE>
enum class STATE : uint8_t {
INTERACTIVE = 255,
INIT = 0,
INIT_WAIT,
SENSOR,
LOOP_WAIT
};
SM_SIMPLE<STATE> step;
struct SensorData {
uint8_t highByte;
uint8_t lowByte;
uint16_t rawValue;
int32_t tempValue16th;
div_result_i32 temperature;
} sensorData;
void setup() {
step.setup(); // 状態マシンの初期化
}
void loop() {
do {
switch (step.state()) {
case STATE::INIT: // 初期状態
SPI.begin(0 /* DIO19をチップセレクトとして使用 */
, { 400000UL /* クロック周波数 */
, SPI_CONF::MSBFIRST
, SPI_CONF::SPI_MODE3
}
);
// ソフトウェアリセット
SPI.beginTransaction();
for (int i = 0; i < 4; i++) {
SPI.transfer(0xFF);
}
SPI.endTransaction();
// Continuous Readモード開始
SPI.beginTransaction();
SPI.transfer(0x54);
SPI.endTransaction();
step.set_timeout(300); // 待機時間の設定
step.next(STATE::INIT_WAIT);
break;
case STATE::INIT_WAIT: // 待機
if (step.is_timeout()) {
step.next(STATE::SENSOR);
}
break;
case STATE::SENSOR: // センサーデータの読み取り
SPI.beginTransaction();
sensorData.highByte = SPI.transfer(0x00); // ダミーデータを送信してクロック信号を生成
sensorData.lowByte = SPI.transfer(0x00); // ダミーデータを送信してクロック信号を生成
SPI.endTransaction();
sensorData.rawValue = (((uint16_t)sensorData.highByte << 8) | sensorData.lowByte) >> 3;
if (sensorData.rawValue & 0x1000) {
sensorData.tempValue16th = int32_t(sensorData.rawValue) - 0x2000;
} else {
sensorData.tempValue16th = sensorData.rawValue;
}
// div100()を使用して温度計算
sensorData.temperature = div100((sensorData.tempValue16th * 100) / 16);
// 結果をシリアル出力
Serial << crlf << sensorData.temperature.format() << "°C";
step.set_timeout(1000); // 次のキャプチャまで待機
step.next(STATE::LOOP_WAIT);
break;
case STATE::LOOP_WAIT: // 待機
if (step.is_timeout()) {
step.next(STATE::SENSOR);
}
break;
default:
break;
}
} while (step.b_more_loop());
}
ここでは、メンバ関数版のインタフェースを利用しています。