一開始拿到芯片手冊雲裏霧裏,根本沒有找到關於磁力數據的寄存器,結果上網一查才知道,這芯片竟然是個膠水芯片。。。
MPU9250內部是MPU6050和AK8963兩個芯片合併在一起的,感覺傻傻的。
內部的AK8963是負責三軸磁力傳感器採樣的芯片,它通過I2C總線與MPU9250連接在一起。
如上圖所示,MPU9250還集成了一個I2C主機控制器。默認情況下MPU9250用它的I2C主機控制器與AK8963通信,把磁力值讀到出放到指定的寄存器中,這需要設置一堆寄存器,真是麻煩得一逼!!!
幸好MPU9250還預留了I2C直通模式,這個模式相當於MPU9250和AK8963共同使用一條I2C總線,因爲它們的通信地址不一樣,
MPU9250的地址:0xD0/0xD1
AK8963的地址:0x18/0x19
在寫驅動程序的時候,可以把它們當作硬件上分離的兩個芯片掛在同一條I2C總線上。
直通模式需要設置MPU9250的第55號寄存器的Bit1寫1即可開啓。
有了直通模式我們就可以直接與AK8963通信了,AK8963的寄存器不多。
下面講講幾個關鍵寄存器操作:
0x00:這個寄存器是芯片ID=0x48,能讀出這個ID證明通信OK了。
0x0A:設置工作模式,建議上電後先寫入0x0F,讀取出芯片校準係數;然後再寫0x01,進行單次採樣。
0x02:狀態寄存器,BIT0爲1表示採樣完成,可以讀取採樣數據了。網上有人說讀不到數據,加上10毫秒延時就能讀出數據,就是因爲沒有檢查狀態值。經過實驗測試單次採樣大概需要6-8毫秒。
0x03-0x08:數據寄存器,三個軸,每個軸的數據都分爲高8位和低8位,組成16位的有符號整數。
0x10-0x12:校準寄存器,出廠設置的校準參數,當0x0A寄存器寫入0x0F後纔可以讀出來。
手冊上寫了數據校準參數的用法:
Hadj是校準後的數據;
H是讀出來的原始採樣數據;
ASA是校準寄存器讀出來的參數;
得到正確的三軸磁力數值後,就可以用來實現一個簡單的電子指南針了。
在水平面的方向=180 + arctan(Y, X) * 180 / PI;
由於環境干擾,還需要加入一個平面校準算法:將芯片在水平面原地轉360度,記錄三個軸的採樣值的最大值和最小值,求得(最大值+最小值)除以2得到偏移值。將原始採樣值減去偏移值之後,再送入上面的公式計算角度會更準確。