最近一個項目需要測量平面的旋轉角度,考慮到成本問題選擇了HMC5883電子羅盤來進行測向;
HMC5883采用I2C通信,位址預設為0x1E(7bit)
本案例采用nrf52832的硬體I2C庫來進行通信,使用到的函數有
nrf_drv_twi_tx(nrf_drv_twi_t const * p_instance,uint8_t address, uint8_t const * p_data,uint8_t length,bool no_stop)
nrf_drv_twi_rx(nrf_drv_twi_t const * p_instance,uint8_t address, uint8_t * p_data,uint8_t length)
應注意,nrf52832的i2c通信函數内部已經對位址進行了加位處理,也就是說隻需要傳入7位的i2c位址0x1E即可,無需針對讀寫操作進行單獨的加位處理
首先,我們需要對HMC5883進行初始化,查閱資料表:
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsICM38FdsYkRGZkRG9lcvx2bjxiNx8VZ6l2cs0TPB5UMZpnTwEkeOBDOsJGcohVYsR2MMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2X0hXZ0xCMx81dvRWYoNHLrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnL3gTM1AjMwITM4ATNwEjMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
我們需要首先設定好HMC5883的資料輸出速率和采樣平均數
一般情況下我們選擇預設的0x70配置即可(01110000),即采樣平均數為8,資料輸出速率為15Hz
然後需要配置資料的測量方式,即對模式寄存器進行操作
選擇連續測量模式,即為0x00
最後設定一下增益,即操作配置寄存器B
這個可以根據具體的環境進行配置,我采用的是預設的0x20(00100000)
我的初始化代碼如下:
bool HMC5883_init(void)
{
bool transfer_succeeded = true;
if (NRF_SUCCESS == twi_init())
{
HMC5883_register_write(Config_RegA,0x70);//配置寄存器A
transfer_succeeded = HMC5883_register_write(HMC5883_ModeRegisterAddress,0x00);//配置模式寄存器
if(transfer_succeeded==NRF_SUCCESS)
{
if(HMC5883_register_write(Config_RegB,0xE0)==NRF_SUCCESS)//配置寄存器B
{
NRF_LOG_INFO("HMC5883 init success");
transfer_succeeded = true;
}else{
transfer_succeeded = false;
}
}else{
transfer_succeeded = false;
}
}else{
transfer_succeeded = false;
}
return transfer_succeeded;
}
完成配置之後即可進行讀取操作,讀取時通路連續的6個資料輸出寄存器,組合高低位資料即可得到HMC5883測量的結果
void HMC5883_GET_DEG(double *angle)
{
short int x,y,z;
uint8_t BUF[6];
HMC5883_read(HMC5883_device_address,0x03,6,BUF);//連續讀取6位的寄存器
x = BUF[0] << 8 | BUF[1]; //組合高低位
y = BUF[4] << 8 | BUF[5];
//z = BUF[2] << 8 | BUF[3]; //隻測量平面角度,用不到Z軸資料,結合加速度計使用時才會用到
//NRF_LOG_INFO("X:%d,Y:%d",x,y);
*angle=atan2((double)y,(double)x) * (180 / 3.14159265) + 180;//計算角度值
}
要注意,HMC5883輸出的資料是有正負區分的,每個軸的資料為16位,是以需要采用short int的資料類型才能正确解析正負值
得到結果後通過序列槽輸出即可: