Beaglebone Black – 連接 GY-91 MPU9250+BMP280 九軸傳感器(1)


本篇內容為,通過 I2C 配置 GY-91 MPU9250+BMP280 里面的 MPU9250 連接 AK8963 磁感應。兩個辦法,1)MPU9250 設置 Master Mode 通過 AUX I2C 讀寫,2)Pass Through Mode 由 Host (單片機或者本文的 BBB)直接用 I2C 讀寫。本文兩種方式都會操作一次。

最初看到淘寶上面有賣 GY91 MPU9250+BMP280 時候,它寫着九軸,是九個軸。地球上原來除了 X Y Z 之外,還有四五維空間里面的 6 個軸,原來所謂的九軸,是陀螺儀三軸,加速度三軸,磁感應三軸(指南針),才叫做九軸。MPU9250 是 InvenSense 出品,它本身就是一個模塊集成了三個東西,還有個自身的溫度計(芯片溫度),FIFO,Digital Motion Processor(DMP,就是姿勢識別,計步器那些),Interrupt(可惜 INT 腳在 GY91 沒有了)。而我買了的 GY91 MPU9250+BMP280,又再集成了 Bosch BMP280 在一起。三個字,比較貴。

其實這個模塊產品我是看了很久很久,一直就在購物車里面,最近才舍得拍下。

上一篇只從I2C總線操作 BMP280,http://www.cnblogs.com/leptonation/p/5210331.html,這次分三篇博文,我希望全面攻克這整個模塊,用於我將來的遙控直升機項目里。上一篇已經介紹過 I2C 的基本操作,這次內容主要是 Data Sheet 資料和快速的命令行操作方式。

第一部分,是I2C接 MPU9250,操作里面的磁感應。

MPU9250 地址

image

接線和原理圖在上一篇。說明書上說,MPU9250 I2C 從機地址是 110100X,LSB取決於 AD0 是否拉低。從原理圖看到是拉低了的,就是 1101000(0x68),見下圖:

image

圖片中另一個地址,0x76,是上一篇博文的 BMP280 溫度氣壓傳感器地址。

Dump 一下:

image

看看說明,Device ID 在,WHO AM I 寄存器,地址 0x75:

Y)T4TH@M0XC~}JGD}@6)I4Y

再看看 Register 描述,只讀 value 為 0x71,與上面 Dump 出來結果一致。

image

image

但事情還沒結束。說明書提到 MPU9250,是磁感應作為一塊,加速和陀螺儀為一塊,分開兩個 die house。看 Register Map 可見,兩者是分開描述的,各自有自己的 Device ID。這是因為,磁感應是 Asahi Kasei Microdevices Corporation 生產的 AKM8963 集成進去的,它是連接着 AUX I2C 引腳的,不是我現在接着的總線。GY-91 MPU9250+BMP280 的情況如下面簡圖:

image

就是說,還有一個 Device ID,AKM8963的。要它出現,兩個辦法,第一,利用加速陀螺儀作為 MASTER 讓它去讀取 AKM8963 的 Device ID Register,或者,Pass-Through Mode,由 Host 接管(本實驗的 Host 即 BBB)。兩個都操作一次看看。

(1)MPU9250 作為 I2C MASTER 從 AUX I2C 與從機交互

MPU9250 作為 Master 最多只能儲存 Slave 的 24 bytes,暫存 AKM 的感應數據,卓卓有余。寄存器是 EXT_SENS_DATA_00 至 23,地址 0x49 至  0x60。多一個從機也是一樣,共用的,相關詳情、順序、重置等等的方法,請自己看說明書。

只讀的話,關鍵部位五個:

  • I2C Master Mode Enable(MPU 作為主機),
  • Slave 0 Enable(啟用第一個從機配置),
  • Slave 0 I2C Address(從機實際總線地址),
  • Slave 0 Register Address (開始讀取的地址),
  • Slave 0 Length (讀取或寫入的數據長度,多少個 byte)。

Slave 0 Enable 與 Slave 0 Length

從機連線讀取數據的配置,在這里:

image

Enable 和 讀取長度,都在 0x27 I2C_SLV0_CTRL 寄存器內設置。bit 7 為 1 時候啟用,我只讀一個 byte 所以 <3:0> 設成 1 即可。就是I2C_SLV0_CTRL(0x27) 設成 10000001 (0x81)。

Slave 0 Register Address

起始讀取位置設置在 0x26 I2C_SLV0_REG。由於 AKM8963 的 Device ID 在 0x00,I2C_SLV0_REG(0x26) 默認值就是 0x00,不用調,我就只讀它。

Slave 0 I2C Address

AKM8963 的從機地址,請參看這里:
http://www.akm.com/akm/en/file/datasheet/AK8963.pdf

image

文檔描述截圖中下半部的是加上的 LSB R/W bit, 只看地址不用管它,RW 在 MPU 那邊配。7 bit 地址就 0001100 至 0001111 可選,視乎接線,我瞎猜,第一個就中了,0001100 (0x0C),然后回到 MPU9250 Data Sheet 的從機地址配置描述:

image

RW 在 MSB 的。我只讀,那整個 I2C_SLV0_ADDR (0x25) 從機地址配置的 8 bit 值,就是 10001100 (0x8C)。

I2C Master Mode Enable

主機模式配置在這里USER_CTRL register (0x6A) 里面,bit5,I2C_MST_EN:

image

需要給它值,00100000(0x20)。

總結,用命令行的話,就是這樣操作:

i2cset -y 1 0x68 0x25 0x8C
i2cset -y 1 0x68 0x27 0x81
i2cset -y 1 0x68 0x6A 0x20

MPU9250 直接讀取從機 AKM 磁感應 Register 效果

再 dump 一次看看效果:

{7TEJK~I7X7%NM3{)Q$VDO6

剛才說過,用來放從機讀取值的第一個寄存器,EXT_SENS_DATA_00,地址 0x49,現在有值了,它就是從 AKM8963 的 0x00 Device ID 寄存器讀取到的值,01001000(0x48),與 AKM 的 Data Sheet 描述一致:

image

image

成功。

從 MPU9250 對 AKM8963 的寄存器寫入值

然后到 MPU 對 AKM 寄存器寫入值。說在前面,說明書的建議是 I2C Pass Through 由 Host 做好 AKM 的配置,然后才使用 AUX I2C,從 SLV0 不斷讀取。

要 AKM 工作測量,就要設置它的工作模式,CNTL1 Register,地址 0x0A:

image

image

我選擇連續測量模式,100Hz,16bit Output ,參考上圖,0x0A 的值就應該設置為 000 1 0110(0x16),測試而已。知道了要設置哪個寄存器,知道要寫入什么值,然后就是如何操作 MPU9250 的 AUX Slave 寫入。方法就是把寫入的值放在 I2C_SLV0_DO (0x63)。但首先,要配置好 SLV0 先。

指定 SLV0 參數,同上 0x25 指定AKM的 I2C地址,不過這次 bit 7 為零,寫入模式。寫入的寄存器地址是 0x0A。然后啟用 SLV0,雖然是寫入,但同樣長度是一個byte,所以寫入 0x81 到 0x27 寄存器:

i2cset -y 1 0x68 0x25 0x0C
i2cset -y 1 0x68 0x26 0x0A

i2cset -y 1 0x68 0x27 0x81

啟用 I2C MASTER 模式(如果你之前還沒啟用的話):

i2cset -y 1 0x68 0x6A 0x20

最后寫入值到 I2C_SLV0_DO,讓 MPU 傳給 AKM,0x16:

i2cset -y 1 0x68 0x63 0x16

怎么驗證是否正確寫入了?讀出來就知道了,把地址 bit 7 改為 1:

i2cset -y 1 0x68 0x25 0x8C

效果:
image

上圖紅框,儲存在寄存器 EXT_SENS_DATA_00 (0x49)的值 0x16 ,它就是通過 MPU 讀取 AKM 的 0x0A 寄存器的值,同樣地是我剛剛通過 MPU 寫入的值。這樣就確認了寫入正確。指南針已經處於連續測量狀態,你喜歡的還可以用 AKM 的狀態寄存器讀取狀態,或者做些更有意義的事,看看已測量到的值:

image

目標數據,在 0x03 至 0x08,共 6 bytes。

i2cset -y 1 0x68 0x25 0x8C
i2cset -y 1 0x68 0x26 0x03

i2cset -y 1 0x68 0x27 0x86

image

取得的值,單位是 μT,上圖中 X 值占 2 bytes,0x49 地址是 LSB,就是說十進位值為 32:

X

32 μT

 

Y

65394 μT

(注)

Z

65452 μT

(注)

(注)上表的 Y / Z 是錯誤的。寫這部分時候,我實在非常大意,沒注意是二補數,帶正負值的。感謝網友RealMagic 提點指出問題,詳見評論五樓,和六樓我的回復。

(2)Pass Through Mode,從 Host 用 I2C 總線直接連 AKM

Pass Through Mode 的設置,在 INT Pin / ByPass Register,寄存器地址 0x37,說明如下圖:

image

image

之前提到這說明書建議,出自這里,Pass-Through mode is useful for configuring the external sensors,or for keeping MPU in a low-power mode ….。先看看怎么做,然后才判斷到底應該怎樣做。

MASTER 禁用然后 Pass Through 啟用后,i2cdetect 就會看到 0x0c 直接出現在總線上,0x0c 就是磁感應的 I2C 地址。

image

操作一下,連續讀取模式,然后 dump 就看到磁感應數據了。

image

就是普通的 I2C 通訊方式,非常簡單。其他的寫入值到寄存器等等,與其他 I2C 一樣,不寫出來了。

為何要用 Master Mode

既然 Pass Through 那么簡單,為何不用 Pass Through 而要用 Master mode?因為我希望,生死攸關的數據,用最高速度傳給控制器,然后它迅速作出適當反應。SPI 比 I2C 快,傾斜角,對於飛控是生死攸關,所以,我選用 SPI 連。

但是,GY91 這模塊沒有暴露 AKM 指南針的 SPI 接口給我,引腳的片選只有兩個,一個是溫度計,一個是 MPU,這情況,用 SPI 之后要接 AKM 我別無選擇,只能 MASTER MODE。下一篇,SPI 通訊,讀取 Accelerometer/Gyroscope(飛控當前姿態),再通過 Master Mode 用 AUX I2C 定時獲取 Magnetometer(飛控航角)。希望在下一篇,事情會變得稍為有趣一些。

我在這群里,歡迎加入交流:
開發板玩家群 578649319開發板玩家群 578649319
硬件創客 (10105555)硬件創客 (10105555)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM