STM32資料 応用編4
SPI通信でセンサーのデータを読み取ってみよう
前回はI2C通信を使ったので同じ操作をSPI通信を使ってやってみよう
ピン設定と回路は前回と同じなので、そのまま使ってね
今回やること
作業の流れ
- 前回と同じピン設定、回路を作成する
- wrapper.cppにコードを書き込む
- TeraTermでデータを受信する
プログラム
前回は読み取りを紹介したので、今回は書き込みの関数を紹介する
SPI通信で書き込みをする関数
引数が少なくレジスタアドレスの引数がないが、後で説明するので気にしないで大丈夫!
関数
HAL_SPI_Transmit(&hspix, TxBuffer, Size, TimeOut);
この関数の引数
送信データはポインタを送る必要がある
SPI通信の場合は後述する理由のため、送信データはほとんど配列を渡すことになる
引数名 | 変数型 | 内容 |
---|---|---|
&hi2cx | SPI_HandleTypeDef* | SPIのポインタ(xはSPIの番号) |
TxBuffer | uint8_t* | 送信データ(ポインタ) |
Size | uint16_t | 送信データサイズ |
TimeOut | uint32_t | 最大実行時間(超えたら諦める) |
データの書き込みと読み取りの流れ
詳しいことまで知る必要はないが、例を出しつつ簡単に紹介する
書き込み
SPI通信での書き込みでは、レジスタアドレス→書き込みたいデータを連続で送信する
この前後、デバイス選択をするためにCSピンにつながっているGPIOを操作している
uint8_t tx_buffer[2] = {};
tx_buffer[0] = REGISTER_ADDR; //書き込みたいレジスタのアドレス
tx_buffer[1] = 0x15; //書き込みたい値
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_RESET);
HAL_SPI_Transmit(&hspi1, tx_buffer, 2, 1000);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_SET);
書き込みの関数
この操作も何回も繰り返す上に、ちょっと長いので関数にまとめてみよう
関数が使えるようになると便利なので、頑張って書いてみてね
Write(uint8_t reg_addr, uint8_t* data, uint8_t len){
//引数
//reg_addr: 書き込みたいレジスタのアドレス
//data: 書き込みたいデータのポインタ(書き込みたい順にデータが格納されている)
//len: 書き込みたいデータの数
//自分で関数を書いてみよう
//読み取りと同じようにfor文で、書き込みデータの要素とレジスタアドレスをインクリメントしよう
}
サンプルコード
実際に通信するためのコードを書いてみよう
前回紹介したReadと今回作ったWriteの関数を使って楽に書いてみよう
使用するレジスタ
レジスタ名 | レジスタアドレス | 内容 | 値 |
---|---|---|---|
ACEEL_DATA_X1_UI | 0x00 | センターデータ(ここから12byteにAccelとGyroのデータがある) | 読み取り専用 |
PWR_MGMT | 0x10 | センサーの電源設定 | 0x0f(LowNoizeMode) |
WIA | 0x72 | 通信チェック用 | 読み取り専用(0xE9が返ってくる) |
今回は普通に難しいので、わからなくて当然に近いかもしれない、、
いつも以上に気軽に質問をしてね!
終わりに
今回は実際にセンサーデータを取得してみました
I2CとSPI通信ができると大体のセンサーを使えるので、これからも使ってみてね