こんにちはショウです。前回はSPI通信ができているかをWho am Iレジスタを使って確認しました。
今回はジャイロデータの取得をしていきます。
プログラム用意
前回Who am Iレジスタの取得が出来ているので、同じように作成すればレジスタを読むことができるようになるはずです。
MPU9250と通信する時には、レジスタのアドレスの最上位ビットが1の時が読み込み、0の時が書き込みと決められています。
それに合わせて書き込み用関数と読み込み用関数を作成しました。
void MPU9250_WriteByte(uint8_t reg,uint8_t data) { uint8_t tx_data[2]; uint8_t rx_data[2]; tx_data[0] = reg; tx_data[1] = data; SPI_Communication(SPI3, tx_data, rx_data ,2 ,GPIOD,LL_GPIO_PIN_2); } uint8_t MPU9250_ReadByte(uint8_t reg) { uint8_t tx_data[2]; uint8_t rx_data[2]; tx_data[0] = reg | 0x80; tx_data[1] = 0x00; SPI_Communication(SPI3, tx_data, rx_data ,2 ,GPIOD,LL_GPIO_PIN_2); return rx_data[1]; }
読み書きの関数が作れたので、MPU9250のパラメータの設定をします。
データシートを確認してみると4つのレジスタを設定すればデータが取得できそうなことがわかりました。
必要なレジスタ番号は27,28,106,107です。レジスタ27,28は加速度とジャイロの感度の設定をしていて、レジスタ106,107はICの設定をしています。もう一つレジスタ26がConfigurationレジスタになっていて、設定すればローパスフィルタ設定できるようですが、今回は動作確認なので設定していません。詳しくはデータシートを読んで見てください。
MPU9250の設定はMPU9250のPower On時に一度行えばいいので、初期化関数を作成して、main関数のループの前で実行させます。
初期化関数は先程の書き込み関数を使って作成しました。
void MPU9250_init(void) { uint16_t reg107 = 0x6B; uint16_t reg106 = 0x6A; uint16_t reg27 = 0x1B; uint16_t reg28 = 0x1C; MPU9250_WriteByte(reg107,0x80); LL_mDelay(1); MPU9250_WriteByte(reg106,0x11); LL_mDelay(1); MPU9250_WriteByte(reg27,0x18); LL_mDelay(1); MPU9250_WriteByte(reg28,0x18); LL_mDelay(1); }
これで設定ができたので、データを取得します。
MPU9250のジャイロセンサは16bitで角速度を表しますが、レジスタ毎に保存できるbit数は8bitなので、データが上位8bitと下位8bitに分かれて保存されています。なので、2つのレジスタからデータを取得して上位ビットを8ビットシフトさせて下位ビットとつなげます。
先程初期化で設定した感度によって1ビットが表す角速度が決まっているので、データシートに書いてある値を使って変換します。
ジャイロセンサ取得用の関数を作成しました。
void MPU9250_GyroRead(uint8_t reg) { int8_t High; int8_t Low; int16_t data; High = MPU9250_ReadByte(reg); LL_mDelay(1); Low = MPU9250_ReadByte(reg+1); LL_mDelay(1); data = (High<<8|Low); printf("data = %f\n\r",data/16.4); }
動作確認
前回と同じくブレットボードを使います。

DSC_0095
今回はジャイロのX軸(レジスタ67,68)のデータを取得して動作確認をしてみます。
データを取得させながらモジュールを動かすと値が動いていることが確認できました。同じようにレジスタを変更したり、感度を変更すると加速度のデータも取得できます。
実際にマウスで使う時にはタイマー割り込みを使うことが多く、タイマー割り込みでDelayで1ms待ってしまうと処理時間が長くなって使いにくいので、for文を使ってもっと短い時間待つように変更して使います。
参考URL
