BNO055是一款性能优越的IUM芯片,数据输出类型多,可根据需要选择读取不同的IMU融合数据。现分享下使用CubeMX生成硬件IIC工程文件,再引入博世官方库文件,形成完整的BNO055驱动代码。单片机使用STM32F429,并使用串口1输出读取的IMU数据。
完整工程文件及BNO055资料链接:BNO055+STM32F429硬件IIC数据读取-嵌入式文档类资源-CSDN下载
第一步:使用CubeMX构造硬件IIC工程文件
1.1 首先在ST官网下载Cubemx安装包,并在电脑上完成安装。安装包下载链接:STM32CubeMX - STM32Cube initialization code generator - STMicroelectronics
1.2 新建硬件IIC工程
1.2.1 新建CubeMx工程,选择芯片型号,然后点击右上角Start Project按钮
1.2.2 设置时钟树 RCC选择外部高速时钟(视单片机硬件配置灵活配置),系统主时钟180MHz。
1.2.3 配置串口,用于输出读取BNO055的各状态及IMU数据,使用串口1,PA9及PA10.
1.2.4 配置硬件IIC,用于与BNO055建立IIC通信,使用IIC1,默认IO为:PB6-->SCL, PB7-->SDA;我自己的工程文件里使用的是PB8,PB9这两个IO,这里需要注意。
1.2.5 配置工程信息 设置工程名,选择存储路径,选择编译器类型,点击右上角Generate Code,生成工程文件。(初次安装Cube时,此步骤会自动下载相应的HAL库文件,稍等一会儿就好了)
到此,包含硬件IIC及串口驱动的HAL库版本的单片机工程就自动构建完成。
第二步:引入博世官方库文件
在博世官网下载官方的驱动文件,链接为:https://github.com/BoschSensortec/BNO055_driver
将官方的bno055.c及bno055.h文件添加至STM32工程内,并注意添加头文件路径。同时新建bno055_api.c及bno055_api.h文件,用于编写自己的驱动代码,如初始化bno055,读取bno055数据等代码。
第三步:BNO055初始化及数据读取
3.1 BNO055初始化,博世官方bno055.c内编写好了相应的初始化函数bno055_init,我们只需要按照官方代码传入相应的指针即可。
需要传入的指针有IIC读、写函数,延时ms函数及bno055IIC地址。即下面代码内的最后四个参数,其他变量在bno055_init函数内自动定义。
struct bno055_t
{
u8 chip_id; /**< chip_id of bno055 */
u16 sw_rev_id; /**< software revision id of bno055 */
u8 page_id; /**< page_id of bno055 */
u8 accel_rev_id; /**< accel revision id of bno055 */
u8 mag_rev_id; /**< mag revision id of bno055 */
u8 gyro_rev_id; /**< gyro revision id of bno055 */
u8 bl_rev_id; /**< boot loader revision id of bno055 */
u8 dev_addr; /**< i2c device address of bno055 */
BNO055_WR_FUNC_PTR; /**< bus write function pointer */
BNO055_RD_FUNC_PTR; /**<bus read function pointer */
void (*delay_msec)(BNO055_MDELAY_DATA_TYPE); /**< delay function pointer */
};
3.1.1 创建bno055句柄:struct bno055_t myBNO;
3.1.2 初始化bno055句柄:
1、读、写函数:调用HAL库IIC读写函数;
static s8 BNO055_Write(u8 dev_addr, u8 reg_addr, u8 *reg_data, u8 wr_len)
{
HAL_StatusTypeDef ret;
ret = HAL_I2C_Mem_Write(&hi2c1,dev_addr<<1,reg_addr,sizeof(reg_addr),reg_data,wr_len,0xFF);
return ret;
}
static s8 BNO055_read(u8 dev_addr, u8 reg_addr, u8 *reg_data, u8 r_len)
{
HAL_StatusTypeDef ret;
ret = HAL_I2C_Mem_Read(&hi2c1,dev_addr<<1,reg_addr,sizeof(reg_addr),reg_data,r_len,0xFF);
return ret;
}
2、 延时函数:使用HAL库内HAL_Delay函数;
3、 IIC地址:BNO055IIC地址由COM3_state引脚电平决定,我使用的是默认地址0x29;
bno055句柄参数初始化:
myBNO.bus_read = BNO055_read;
myBNO.bus_write = BNO055_Write;
myBNO.delay_msec = HAL_Delay;
myBNO.dev_addr = BNO055_I2C_ADDR2;
bno055_init(&myBNO);
bno055完整初始化函数:
void BNO055_Init(void)
{
u8 gyro_calib_stat;
// char *err = "bno055 init failed...\r\n";
// char *sta = "bno055 init succeed!!!\r\n";
BNO055_RETURN_FUNCTION_TYPE ret;
myBNO.bus_read = BNO055_read;
myBNO.bus_write = BNO055_Write;
myBNO.delay_msec = HAL_Delay;
myBNO.dev_addr = BNO055_I2C_ADDR2;
bno055_init(&myBNO);
bno055_set_sys_rst(BNO055_BIT_ENABLE);
HAL_Delay(1000);
ret = bno055_set_operation_mode(BNO055_OPERATION_MODE_NDOF);
while(1)
{
ret += bno055_get_gyro_calib_stat(&gyro_calib_stat);
if(ret == BNO055_SUCCESS && gyro_calib_stat==3)
{
printf("bno055 init succeed!!!\r\n");
// HAL_UART_Transmit(&huart1,(uint8_t *)sta,strlen(sta),1000);
break;
}
HAL_Delay(500);
printf("bno055 init failed...\r\n");
// HAL_UART_Transmit(&huart1,(uint8_t *)err,strlen(err),1000);
}
}
读BNO055数据函数:
s8 BNO055_READ_GYRO(struct bno055_gyro_t *gyro)
{
BNO055_RETURN_FUNCTION_TYPE ret;
ret = bno055_read_gyro_xyz(gyro);
if(ret == BNO055_SUCCESS)
{
printf("GYRO:x=%d, y=%d, z=%d\r\n",gyro->x,gyro->y,gyro->z);
return 0;
}
return 1;
}
s8 BNO055_READ_ACC(struct bno055_accel_t *acc)
{
BNO055_RETURN_FUNCTION_TYPE ret;
ret = bno055_read_accel_xyz(acc);
if(ret == BNO055_SUCCESS)
{
printf("ACC:x=%d, y=%d, z=%d\r\n",acc->x,acc->y,acc->z);
return 0;
}
return 1;
}
s8 BNO055_READ_MAG(struct bno055_mag_t *mag)
{
BNO055_RETURN_FUNCTION_TYPE ret;
ret = bno055_read_mag_xyz(mag);
if(ret == BNO055_SUCCESS)
{
printf("MAG:x=%d, y=%d, z=%d\r\n",mag->x,mag->y,mag->z);
return 0;
}
return 1;
}
在main内调用上面三个读取数据函数:
int main(void)
{
/* USER CODE BEGIN 1 */
//设置变量
struct bno055_gyro_t *GYRO;
struct bno055_accel_t *ACC;
struct bno055_mag_t *MAG;
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_I2C1_Init();
MX_USART1_UART_Init();
/* USER CODE BEGIN 2 */
//初始化BNO055
BNO055_Init();
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
//读数据并串口打印输出
BNO055_READ_GYRO(GYRO);
BNO055_READ_MAG(MAG);
BNO055_READ_ACC(ACC);
}
/* USER CODE END 3 */
}