原理图:
传感器旋转方向:
SPI参数:
SPI写波形:
SPI读取波形:
SPI 写入波形:
BMG250的SPl接口支持两种模式。 CPOL=0 CPHA= 0 和CPOL=1 CPHA= 1。根据CSB下降边后的SCK值控制在’00’和’11’之间的自动选择。BMG250支持两种SPI接口配置:4线制和3线制。两种配置使用相同的协议。设备默认以4线配置运行。通过将’1’写入寄存器(0x6B) IF CONF spi3,可以切换到3线配置。3线制配置中常用数据引脚SDI。对于单字节的读和写操作,使用16位协议。BMG250还支持多字节读写操作。 由此可设置为8位CPOL=1 CPHA= 1模式,位数为8位,频率1MHZ-2MHZ经测试通讯成功。
SPI多字节读取:
通过保持CSB较低并继续数据传输,多个读操作是可能的。只需要写第一个注册地址。只要CSB处于低活动状态,地址就会在每次读访问后自动增加。多位读写已经解决代码如下:
/*多位读取*/
#define BMG250_SPI_RD_MASK UINT8_C(0x80)
#define BMG250_SPI_WR_MASK UINT8_C(0x7F)
uint8_t bsp_bmg250_read_muti_byte(uint8_t addr,uint8_t *rxdata,uint8_t len)
{
uint8_t tdata[len+1],rdata[len+1],i;
tdata[0] = (addr | BMG250_SPI_RD_MASK);
/*填充tdata,发送确定的数值*/
for(i=1;i<len+1;i++)
{
tdata[i] = 0xA5;
}
CS_PIN_L;
HAL_SPI_TransmitReceive(&hspi3,tdata,rdata,len+1,0xff);
CS_PIN_H;
/*抛弃最开始一位数据*/
memcpy(rxdata,&rdata[1],len);
}
/*单BYTE 读取*/
#define BMG250_SPI_RD_MASK UINT8_C(0x80)
#define BMG250_SPI_WR_MASK UINT8_C(0x7F)
uint8_t bsp_bmg250_read_one_byte(uint8_t addr,uint8_t *rxdata)
{
uint8_t tdata[2],rdata[2];
tdata[0] = (addr | BMG250_SPI_RD_MASK);
tdata[1] = 0x00;
CS_PIN_L;
HAL_SPI_TransmitReceive(&hspi3,tdata,rdata,2,0xff);
CS_PIN_H;
*rxdata = rdata[1];
}
/*单BYTE 写入*/
#define BMG250_SPI_RD_MASK UINT8_C(0x80)
#define BMG250_SPI_WR_MASK UINT8_C(0x7F)
uint8_t bsp_bmg250_write_one_byte(uint8_t addr,uint8_t txdata)
{
uint8_t tdata[2];
tdata[0] = (addr & BMG250_SPI_WR_MASK);
tdata[1] = txdata;
CS_PIN_L;
HAL_SPI_Transmit(&hspi3,tdata,2,0xff);
CS_PIN_H;
}
/******************************************************************
* @brief 读取GYRO 数据
*
* @brief函数使用方法备注
*
* @param
*
* @return
*******************************************************************/
void bsp_mag250_get_data(void)
{
uint8_t lsb;
uint8_t msb;
uint8_t idx = 0;
uint8_t tdata[2];
bsp_bmg250_read_muti_byte(BMG250_DATA_ADDR,bmg_250_spi.raw_data,6);
bsp_bmg250_read_muti_byte(BMG250_TEMPERATURE_ADDR,tdata,2);
bmg_250_spi.raw_temp = ((uint16_t)tdata[1] << 8) | tdata[0];
bmg_250_spi.temp= (((int16_t) bmg_250_spi.raw_temp * INT32_C(1000)) / INT32_C(512)) + INT32_C(23000);
lsb = bmg_250_spi.raw_data[idx++];
msb = bmg_250_spi.raw_data[idx++];
bmg_250_spi.raw_x = (int16_t)(((uint16_t)msb << 8) | lsb);
lsb = bmg_250_spi.raw_data[idx++];
msb = bmg_250_spi.raw_data[idx++];
bmg_250_spi.raw_y = (int16_t)(((uint16_t)msb << 8) | lsb);
lsb = bmg_250_spi.raw_data[idx++];
msb = bmg_250_spi.raw_data[idx++];
bmg_250_spi.raw_z = (int16_t)(((uint16_t)msb << 8) | lsb);
/***********
±2000°/s | 16.4
±1000°/s | 32.8
±500°/s | 65.6
±250°/s | 131.2
±125°/s | 262.4
************/
bmg_250_spi.gyro_x = (float)bmg_250_spi.raw_x/65.6f;//加f取消warning
bmg_250_spi.gyro_y = (float)bmg_250_spi.raw_y/65.6f;
bmg_250_spi.gyro_z = (float)bmg_250_spi.raw_z/65.6f;
DataScope_Get_Channel_Data(bmg_250_spi.gyro_x,1);
DataScope_Get_Channel_Data(bmg_250_spi.gyro_y,2);
DataScope_Get_Channel_Data(bmg_250_spi.gyro_z,3);
DataScope_Send_Channel_Data(&hlpuart1,3);
}
}
ODR 配置:
HZ = 100/2(8-VAR)
例如:0b1100 = 0x0C 100X2X2X2X2 = 1600 HZ
当滤波模式设置为OSR2 (gyr bwp-0b001)时,使用两级数字滤波器,数据过采样,过采样率为2。这意味着对于特定的过滤器配置,ODR必须是普通过滤器模式下的2倍。相反,对于某种滤波器配置,滤波器带宽大约是相同ODR在普通滤波器模式下实现的带宽的一半。例如,对于ODR-50Hz,我们将有一个3dB截止频率10.7Hz。当滤波模式设置为OSR4 (gyr bwp=0b000)时,使用两级数字滤波器,数据过采样,过采样率为4。这意味着对于特定的过滤器配置,ODR必须比正常的过滤器模式高出4倍。相反,对于某种滤波器配置,滤波器带宽将比相同ODR在正常滤波器模式下实现的带宽大约小4倍。例如,对于ODR=100Hz,我们将有一个3dB截止频率10.7Hz。陀螺仪数据处理没有欠采样模式。(注:3dm-gx5 bw:250hz 3dm-cv5 bw:500HZ 300°/s)
初始化流程:其中寄存器的宏定义参考官方GITHUB
void bsp_bmg250_get_chip_id(void)
{
bsp_bmg250_read_one_byte(BMG250_SPI_COMM_TEST_ADDR,&bmg_250_spi.data);
bsp_bmg250_read_one_byte(BMG250_SPI_COMM_TEST_ADDR,&bmg_250_spi.data);
bsp_bmg250_read_one_byte(BMG250_CHIP_ID_ADDR, &bmg_250_spi.chip_id);
}
void bsp_bmg250_init(void)
{
bsp_bmg250_get_chip_id();
if(bmg_250_spi.chip_id == BMG250_CHIP_ID)
{
/*读取PMU 状态*/
bsp_bmg250_read_one_byte(BMG250_PMU_STATUS_ADDR,&bmg_250_spi.power_mode);
/*设置电源模式为正常模式*/
bsp_bmg250_write_one_byte(BMG250_COMMAND_REG_ADDR,BMG250_GYRO_NORMAL_MODE);
/*延时81ms,必要不可取消*/
HAL_Delay(81);
/*设置输出速率3200hz 滤波模式为4倍过采样,bw为 500hz*/
//bsp_bmg250_write_one_byte(BMG250_GYRO_CONFIG_ADDR,0x0D);
/*设置输出速率3200hz 滤波模式为4倍过采样,bw为 250z*/
bsp_bmg250_write_one_byte(BMG250_GYRO_CONFIG_ADDR,0x0C);
/*设置陀螺仪采样范围 0x00 2000 °/s 0x01 1000°/s 0x02 500°/s 0x03 250°/s 0x04 125°/s*/
bsp_bmg250_write_one_byte(BMG250_GYRO_RANGE_ADDR,0x02);
}
}
采样范围和分辨率:
3dm-gx5 标称值 ±300°/s ,3dm-cv5 ±250 ±500 ±1000 可配置