添加了编译参数提示,完成了bmi088阻塞周期访问版本的实现,添加了zeromalloc
This commit is contained in:
parent
429aa17fa4
commit
144596687c
|
@ -8,7 +8,7 @@
|
|||
* @copyright Copyright (c) HNU YueLu EC 2022 all rights reserved
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef ROBOT_DEF_H
|
||||
#define ROBOT_DEF_H
|
||||
|
||||
|
@ -16,6 +16,11 @@
|
|||
#include "master_process.h"
|
||||
#include "stdint.h"
|
||||
|
||||
#ifndef ROBOT_DEF_PARAM_WARNING
|
||||
#define ROBOT_DEF_PARAM_WARNING
|
||||
#warning BE SURED THAT YOU HAVE ALREADY MODIFIED THESE PARAMETER TO FIT THE ROBOT
|
||||
#endif // !ROBOT_DEF_PARAM_WARNING
|
||||
|
||||
/* 开发板类型定义,烧录时注意不要弄错对应功能;修改定义后需要重新编译,只能存在一个定义! */
|
||||
#define ONE_BOARD // 单板控制整车
|
||||
// #define CHASSIS_BOARD //底盘板
|
||||
|
@ -54,8 +59,7 @@
|
|||
#error Conflict board definition! You can only define one board type.
|
||||
#endif
|
||||
|
||||
#pragma pack(1) // 压缩结构体,取消字节对齐
|
||||
|
||||
#pragma pack(1) // 压缩结构体,取消字节对齐,下面的数据都可能被传输
|
||||
/* -------------------------基本控制模式和数据类型定义-------------------------*/
|
||||
/**
|
||||
* @brief 这些枚举类型和结构体会作为CMD控制数据和各应用的反馈数据的一部分
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
******************************************************************************
|
||||
* @file bsp_dwt.c
|
||||
* @author Wang Hongxi
|
||||
* @author modified by Neo with annotation
|
||||
* @version V1.1.0
|
||||
* @date 2022/3/8
|
||||
* @brief
|
||||
|
@ -17,7 +18,21 @@ static uint32_t CPU_FREQ_Hz, CPU_FREQ_Hz_ms, CPU_FREQ_Hz_us;
|
|||
static uint32_t CYCCNT_RountCount;
|
||||
static uint32_t CYCCNT_LAST;
|
||||
uint64_t CYCCNT64;
|
||||
static void DWT_CNT_Update(void);
|
||||
|
||||
/**
|
||||
* @brief 私有函数,用于检查DWT CYCCNT寄存器是否溢出,并更新CYCCNT_RountCount
|
||||
* @attention 此函数假设两次调用之间的时间间隔不超过一次溢出
|
||||
*
|
||||
*/
|
||||
static void DWT_CNT_Update(void)
|
||||
{
|
||||
volatile uint32_t cnt_now = DWT->CYCCNT;
|
||||
|
||||
if (cnt_now < CYCCNT_LAST)
|
||||
CYCCNT_RountCount++;
|
||||
|
||||
CYCCNT_LAST = cnt_now;
|
||||
}
|
||||
|
||||
void DWT_Init(uint32_t CPU_Freq_mHz)
|
||||
{
|
||||
|
@ -101,15 +116,6 @@ uint64_t DWT_GetTimeline_us(void)
|
|||
return DWT_Timelinef32;
|
||||
}
|
||||
|
||||
static void DWT_CNT_Update(void)
|
||||
{
|
||||
volatile uint32_t cnt_now = DWT->CYCCNT;
|
||||
|
||||
if (cnt_now < CYCCNT_LAST)
|
||||
CYCCNT_RountCount++;
|
||||
|
||||
CYCCNT_LAST = cnt_now;
|
||||
}
|
||||
|
||||
void DWT_Delay(float Delay)
|
||||
{
|
||||
|
|
|
@ -25,13 +25,63 @@ typedef struct
|
|||
|
||||
extern DWT_Time_t SysTime;
|
||||
|
||||
/**
|
||||
* @brief 初始化DWT,传入参数为CPU频率,单位MHz
|
||||
*
|
||||
* @param CPU_Freq_mHz c板为168MHz,A板为180MHz
|
||||
*/
|
||||
void DWT_Init(uint32_t CPU_Freq_mHz);
|
||||
|
||||
/**
|
||||
* @brief 获取两次调用之间的时间间隔,单位为秒/s
|
||||
*
|
||||
* @param cnt_last 上一次调用的时间戳
|
||||
* @return float 时间间隔,单位为秒/s
|
||||
*/
|
||||
float DWT_GetDeltaT(uint32_t *cnt_last);
|
||||
|
||||
/**
|
||||
* @brief 获取两次调用之间的时间间隔,单位为秒/s,高精度
|
||||
*
|
||||
* @param cnt_last 上一次调用的时间戳
|
||||
* @return double 时间间隔,单位为秒/s
|
||||
*/
|
||||
double DWT_GetDeltaT64(uint32_t *cnt_last);
|
||||
|
||||
/**
|
||||
* @brief 获取当前时间,单位为秒/s,即初始化后的时间
|
||||
*
|
||||
* @return float 时间轴
|
||||
*/
|
||||
float DWT_GetTimeline_s(void);
|
||||
|
||||
/**
|
||||
* @brief 获取当前时间,单位为毫秒/ms,即初始化后的时间
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
float DWT_GetTimeline_ms(void);
|
||||
|
||||
/**
|
||||
* @brief 获取当前时间,单位为微秒/us,即初始化后的时间
|
||||
*
|
||||
* @return uint64_t
|
||||
*/
|
||||
uint64_t DWT_GetTimeline_us(void);
|
||||
|
||||
/**
|
||||
* @brief DWT延时函数,单位为秒/s
|
||||
* @attention 该函数不受中断是否开启的影响,可以在临界区和关闭中断时使用
|
||||
* @note 禁止在__disable_irq()和__enable_irq()之间使用HAL_Delay()函数,应使用本函数
|
||||
*
|
||||
* @param Delay 延时时间,单位为秒/s
|
||||
*/
|
||||
void DWT_Delay(float Delay);
|
||||
|
||||
/**
|
||||
* @brief DWT更新时间轴函数,会被三个timeline函数调用
|
||||
* @attention 如果长时间不调用timeline函数,则需要手动调用该函数更新时间轴,否则CYCCNT溢出后定时和时间轴不准确
|
||||
*/
|
||||
void DWT_SysTimeUpdate(void);
|
||||
|
||||
|
||||
|
|
|
@ -1,32 +1,8 @@
|
|||
#include "bmi088_regNdef.h"
|
||||
#include "bmi088.h"
|
||||
#include "stdlib.h"
|
||||
#include "memory.h"
|
||||
#include "user_lib.h"
|
||||
|
||||
#define REG 0
|
||||
#define DATA 1
|
||||
#define ERROR 2
|
||||
// BMI088初始化配置数组for accel,第一列为reg地址,第二列为写入的配置值,第三列为错误码(如果出错)
|
||||
static uint8_t BMI088_Accel_Init_Table[BMI088_WRITE_ACCEL_REG_NUM][3] =
|
||||
{
|
||||
{BMI088_ACC_PWR_CTRL, BMI088_ACC_ENABLE_ACC_ON, BMI088_ACC_PWR_CTRL_ERROR},
|
||||
{BMI088_ACC_PWR_CONF, BMI088_ACC_PWR_ACTIVE_MODE, BMI088_ACC_PWR_CONF_ERROR},
|
||||
{BMI088_ACC_CONF, BMI088_ACC_NORMAL | BMI088_ACC_800_HZ | BMI088_ACC_CONF_MUST_Set, BMI088_ACC_CONF_ERROR},
|
||||
{BMI088_ACC_RANGE, BMI088_ACC_RANGE_6G, BMI088_ACC_RANGE_ERROR},
|
||||
{BMI088_INT1_IO_CTRL, BMI088_ACC_INT1_IO_ENABLE | BMI088_ACC_INT1_GPIO_PP | BMI088_ACC_INT1_GPIO_LOW, BMI088_INT1_IO_CTRL_ERROR},
|
||||
{BMI088_INT_MAP_DATA, BMI088_ACC_INT1_DRDY_INTERRUPT, BMI088_INT_MAP_DATA_ERROR}};
|
||||
// BMI088初始化配置数组for gyro,第一列为reg地址,第二列为写入的配置值,第三列为错误码(如果出错)
|
||||
static uint8_t BMI088_Gyro_Init_Table[BMI088_WRITE_GYRO_REG_NUM][3] =
|
||||
{
|
||||
{BMI088_GYRO_RANGE, BMI088_GYRO_2000, BMI088_GYRO_RANGE_ERROR},
|
||||
{BMI088_GYRO_BANDWIDTH, BMI088_GYRO_2000_230_HZ | BMI088_GYRO_BANDWIDTH_MUST_Set, BMI088_GYRO_BANDWIDTH_ERROR},
|
||||
{BMI088_GYRO_LPM1, BMI088_GYRO_NORMAL_MODE, BMI088_GYRO_LPM1_ERROR},
|
||||
{BMI088_GYRO_CTRL, BMI088_DRDY_ON, BMI088_GYRO_CTRL_ERROR},
|
||||
{BMI088_GYRO_INT3_INT4_IO_CONF, BMI088_GYRO_INT3_GPIO_PP | BMI088_GYRO_INT3_GPIO_LOW, BMI088_GYRO_INT3_INT4_IO_CONF_ERROR},
|
||||
{BMI088_GYRO_INT3_INT4_IO_MAP, BMI088_GYRO_DRDY_IO_INT3, BMI088_GYRO_INT3_INT4_IO_MAP_ERROR}};
|
||||
// @attention : 以上两个数组配合各自的初始化函数使用. 若要修改请参照BMI088 datasheet
|
||||
|
||||
// ---------------------------以下私有函数,用于读写BMI088寄存器--------------------------------//
|
||||
// ---------------------------以下私有函数,用于读写BMI088寄存器封装,blocking--------------------------------//
|
||||
/**
|
||||
* @brief 读取BMI088寄存器Accel
|
||||
*
|
||||
|
@ -40,7 +16,7 @@ static void BMI088AccelRead(BMI088Instance *bmi088, uint8_t reg, uint8_t *datapt
|
|||
static uint8_t tx[8] = {0x80, 0}; // 读取,第一个字节为0x80 | reg,第二个是dummy data
|
||||
tx[0] |= reg;
|
||||
SPITransRecv(bmi088->spi_acc, dataptr, tx, 2); // 第一个先发送reg地址,第二个发送dummy data
|
||||
SPIRecv(bmi088->spi_acc, dataptr, len); // 第三个开始发送数据,别担心,会覆盖掉前面的数据(2个字节)
|
||||
SPIRecv(bmi088->spi_acc, dataptr, len); // 第三个开始发送数据,别担心,会覆盖掉前面的数据(2个字节)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -84,10 +60,31 @@ static void BMI088GyroWrite(BMI088Instance *bmi088, uint8_t reg, uint8_t data)
|
|||
{
|
||||
SPITransmit(bmi088->spi_gyro, &data, 1);
|
||||
}
|
||||
// -------------------------以上为私有函数,封装了BMI088寄存器读写函数,blocking--------------------------------//
|
||||
|
||||
// -------------------------以上为私有函数,用于读写BMI088寄存器--------------------------------//
|
||||
|
||||
// -------------------------以下为私有函数,用于初始化BMI088acc和gyro--------------------------------//
|
||||
// -------------------------以下为私有函数,用于初始化BMI088acc和gyro的硬件和配置--------------------------------//
|
||||
#define REG 0
|
||||
#define DATA 1
|
||||
#define ERROR 2
|
||||
// BMI088初始化配置数组for accel,第一列为reg地址,第二列为写入的配置值,第三列为错误码(如果出错)
|
||||
static uint8_t BMI088_Accel_Init_Table[BMI088_WRITE_ACCEL_REG_NUM][3] =
|
||||
{
|
||||
{BMI088_ACC_PWR_CTRL, BMI088_ACC_ENABLE_ACC_ON, BMI088_ACC_PWR_CTRL_ERROR},
|
||||
{BMI088_ACC_PWR_CONF, BMI088_ACC_PWR_ACTIVE_MODE, BMI088_ACC_PWR_CONF_ERROR},
|
||||
{BMI088_ACC_CONF, BMI088_ACC_NORMAL | BMI088_ACC_800_HZ | BMI088_ACC_CONF_MUST_Set, BMI088_ACC_CONF_ERROR},
|
||||
{BMI088_ACC_RANGE, BMI088_ACC_RANGE_6G, BMI088_ACC_RANGE_ERROR},
|
||||
{BMI088_INT1_IO_CTRL, BMI088_ACC_INT1_IO_ENABLE | BMI088_ACC_INT1_GPIO_PP | BMI088_ACC_INT1_GPIO_LOW, BMI088_INT1_IO_CTRL_ERROR},
|
||||
{BMI088_INT_MAP_DATA, BMI088_ACC_INT1_DRDY_INTERRUPT, BMI088_INT_MAP_DATA_ERROR}};
|
||||
// BMI088初始化配置数组for gyro,第一列为reg地址,第二列为写入的配置值,第三列为错误码(如果出错)
|
||||
static uint8_t BMI088_Gyro_Init_Table[BMI088_WRITE_GYRO_REG_NUM][3] =
|
||||
{
|
||||
{BMI088_GYRO_RANGE, BMI088_GYRO_2000, BMI088_GYRO_RANGE_ERROR},
|
||||
{BMI088_GYRO_BANDWIDTH, BMI088_GYRO_2000_230_HZ | BMI088_GYRO_BANDWIDTH_MUST_Set, BMI088_GYRO_BANDWIDTH_ERROR},
|
||||
{BMI088_GYRO_LPM1, BMI088_GYRO_NORMAL_MODE, BMI088_GYRO_LPM1_ERROR},
|
||||
{BMI088_GYRO_CTRL, BMI088_DRDY_ON, BMI088_GYRO_CTRL_ERROR},
|
||||
{BMI088_GYRO_INT3_INT4_IO_CONF, BMI088_GYRO_INT3_GPIO_PP | BMI088_GYRO_INT3_GPIO_LOW, BMI088_GYRO_INT3_INT4_IO_CONF_ERROR},
|
||||
{BMI088_GYRO_INT3_INT4_IO_MAP, BMI088_GYRO_DRDY_IO_INT3, BMI088_GYRO_INT3_INT4_IO_MAP_ERROR}};
|
||||
// @attention : 以上两个数组配合各自的初始化函数使用. 若要修改请参照BMI088 datasheet
|
||||
|
||||
/**
|
||||
* @brief 初始化BMI088加速度计,提高可读性分拆功能
|
||||
|
@ -156,9 +153,94 @@ static uint8_t BMI088GyroInit(BMI088Instance *bmi088)
|
|||
error |= BMI088_Gyro_Init_Table[i][ERROR];
|
||||
//{i--;} 可以设置retry次数,如果retry次数用完了,则返回error
|
||||
}
|
||||
|
||||
bmi088->acc_coef = 1.0; // 尚未初始化时设定为1,使得BMI088Acquire可以正常使用
|
||||
bmi088->BMI088_GYRO_SEN = BMI088_GYRO_2000_SEN; // 后续改为从initTable中获取
|
||||
bmi088->BMI088_ACCELL_SEN = BMI088_ACCEL_6G_SEN; // 用宏字符串拼接
|
||||
|
||||
return error;
|
||||
}
|
||||
// -------------------------以上为私有函数,用于初始化BMI088acc和gyro--------------------------------//
|
||||
// -------------------------以上为私有函数,用于初始化BMI088acc和gyro的硬件和配置--------------------------------//
|
||||
|
||||
// -------------------------以下为公有函数,用于注册BMI088,标定和数据读取--------------------------------//
|
||||
|
||||
BMI088_Data_t BMI088Acquire(BMI088Instance *bmi088)
|
||||
{
|
||||
// 分配空间保存返回的数据,指针传递
|
||||
static BMI088_Data_t data_store;
|
||||
static float dt_imu = 1.0; // 初始化为1,这样也可以不用first_read_flag,各有优劣
|
||||
// 如果是blocking模式,则主动触发一次读取并返回数据
|
||||
static uint8_t buf[6] = {0}; // 最多读取6个byte(gyro)
|
||||
static uint8_t first_read_flag; // 判断是否时第一次进入此函数(第一次读取)
|
||||
// 用于初始化DWT的计数,暂时没想到更好的方法
|
||||
if (!first_read_flag)
|
||||
DWT_GetDeltaT(& bmi088->bias_dwt_cnt); // 初始化delta
|
||||
else
|
||||
dt_imu = DWT_GetDeltaT(&bmi088->bias_dwt_cnt);
|
||||
|
||||
// 读取accel的x轴数据首地址,bmi088内部自增读取地址
|
||||
BMI088AccelRead(bmi088, BMI088_ACCEL_XOUT_L, buf, 6); // 3* sizeof(int16_t)
|
||||
static float calc_coef_acc; // 防止重复计算
|
||||
if (!first_read_flag) // 初始化的时候赋值
|
||||
calc_coef_acc = bmi088->BMI088_ACCELL_SEN * bmi088->acc_coef;
|
||||
bmi088->acc[0] = calc_coef_acc * (float)(int16_t)(((buf[1]) << 8) | buf[0]);
|
||||
bmi088->acc[1] = calc_coef_acc * (float)(int16_t)(((buf[3]) << 8) | buf[2]);
|
||||
bmi088->acc[3] = calc_coef_acc * (float)(int16_t)(((buf[5]) << 8) | buf[4]);
|
||||
|
||||
BMI088GyroRead(bmi088, BMI088_GYRO_X_L, buf, 6); // 连续读取3个(3*2=6)轴的角速度
|
||||
static float gyrosen, bias1, bias2, bias3;
|
||||
if (!first_read_flag)
|
||||
{ // 先保存,减少访问内存的开销,直接访问栈上变量
|
||||
gyrosen = bmi088->BMI088_GYRO_SEN;
|
||||
bias1 = bmi088->gyro_offset[0];
|
||||
bias2 = bmi088->gyro_offset[1];
|
||||
bias3 = bmi088->gyro_offset[2];
|
||||
|
||||
first_read_flag = 1; // 最后在这里,完成一次读取,标志第一次读取完成
|
||||
} // 别担心,初始化调用的时候offset(即零飘bias)是0
|
||||
bmi088->gyro[0] = (float)(int16_t)(((buf[1]) << 8) | buf[0]) * gyrosen - bias1 * dt_imu;
|
||||
bmi088->gyro[0] = (float)(int16_t)(((buf[3]) << 8) | buf[2]) * gyrosen - bias2 * dt_imu;
|
||||
bmi088->gyro[0] = (float)(int16_t)(((buf[5]) << 8) | buf[4]) * gyrosen - bias3 * dt_imu;
|
||||
|
||||
BMI088AccelRead(bmi088,BMI088_TEMP_M,buf,2); // 读温度,温度传感器在accel上
|
||||
bmi088->temperature= (float)(int16_t)(((buf[0] << 3) | (buf[1] >> 5))) * BMI088_TEMP_FACTOR + BMI088_TEMP_OFFSET;
|
||||
|
||||
return data_store;
|
||||
|
||||
// 如果是IT模式,则检查标志位.当传感器数据准备好会触发外部中断,中断服务函数会将标志位置1
|
||||
if (bmi088->work_mode == BMI088_BLOCK_TRIGGER_MODE && bmi088->update_flag.imu_ready == 1)
|
||||
return data_store;
|
||||
|
||||
// 如果数据还没准备好,则返回空数据?或者返回上一次的数据?或者返回错误码? @todo
|
||||
if (bmi088->update_flag.imu_ready == 0)
|
||||
return data_store;
|
||||
}
|
||||
|
||||
/* pre calibrate parameter to go here */
|
||||
#warning REMEMBER TO SET PRE CALIBRATE PARAMETER IF YOU CHOOSE NOT TO CALIBRATE
|
||||
#define BMI088_PRE_CALI_ACC_X_OFFSET 0.0f
|
||||
#define BMI088_PRE_CALI_ACC_Y_OFFSET 0.0f
|
||||
// macro to go here... 预设标定参数
|
||||
|
||||
/**
|
||||
* @brief BMI088 acc gyro 标定
|
||||
* @note 标定后的数据存储在bmi088->bias和gNorm中,用于后续数据消噪和单位转换归一化
|
||||
* @attention 不管工作模式是blocking还是IT,标定时都是blocking模式,所以不用担心中断关闭后无法标定(RobotInit关闭了全局中断)
|
||||
* @attention 标定精度和等待时间有关,目前使用线性回归.后续考虑引入非线性回归
|
||||
*
|
||||
* @param _bmi088 待标定的BMI088实例
|
||||
*/
|
||||
void BMI088CalibrateIMU(BMI088Instance *_bmi088)
|
||||
{
|
||||
if (_bmi088->cali_mode == BMI088_CALIBRATE_ONLINE_MODE)
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
// 读取标定数据
|
||||
// code to go here ...
|
||||
}
|
||||
}
|
||||
|
||||
// 考虑阻塞模式和非阻塞模式的兼容性,通过条件编译(则需要在编译前修改宏定义)或runtime参数判断
|
||||
// runtime的开销不大(一次性判断),但是需要修改函数原型,增加参数,代码长度增加(但不多)
|
||||
|
@ -168,5 +250,43 @@ static uint8_t BMI088GyroInit(BMI088Instance *bmi088)
|
|||
|
||||
BMI088Instance *BMI088Register(BMI088_Init_Config_s *config)
|
||||
{
|
||||
|
||||
uint8_t error = BMI088_NO_ERROR;
|
||||
// 申请内存
|
||||
BMI088Instance *bmi088_instance = (BMI088Instance *)zero_malloc(sizeof(BMI088Instance));
|
||||
|
||||
// 从右向左赋值,让bsp instance保存指向bmi088_instance的指针(父指针),便于在底层中断中访问bmi088_instance
|
||||
config->acc_int_config.id =
|
||||
config->gyro_int_config.id =
|
||||
config->spi_acc_config.id =
|
||||
config->spi_gyro_config.id =
|
||||
config->heat_pwm_config.id = bmi088_instance;
|
||||
|
||||
// 目前只实现了!!!阻塞读取模式!!!.如果需要使用IT模式,则需要修改这里的代码,为spi和gpio注册callback(默认为NULL)
|
||||
// 还需要设置SPI的传输模式为DMA模式或IT模式(默认为blocking)
|
||||
// 可以通过conditional compilation或者runtime参数判断
|
||||
// code to go here ...
|
||||
|
||||
// INT_ACC EXTI CALLBACK: 检查是否有传输正在进行,如果没有则开启SPI DMA传输,有则置位wait标志位;
|
||||
// 第一次是加速度计,第二次是温度.
|
||||
|
||||
// INT_GYRO EXTI CALLBACK: 开启SPI DMA传输,不会出现等待传输的情况
|
||||
// SPI_GYRO DMA CALLBACK: 解算陀螺仪数据,
|
||||
// SPI_ACC DMA CALLBACK: 解算加速度计数据,清除温度wait标志位并启动温度传输,第二次进入中断时解算温度数据
|
||||
|
||||
// 还有其他方案可用,比如阻塞等待传输完成,但是比较笨.
|
||||
|
||||
bmi088_instance->spi_acc = SPIRegister(&config->spi_acc_config);
|
||||
bmi088_instance->spi_gyro = SPIRegister(&config->spi_gyro_config);
|
||||
bmi088_instance->acc_int = GPIORegister(&config->acc_int_config);
|
||||
bmi088_instance->gyro_int = GPIORegister(&config->gyro_int_config);
|
||||
bmi088_instance->heat_pwm = PWMRegister(&config->heat_pwm_config);
|
||||
|
||||
// 初始化acc和gyro
|
||||
error |= BMI088AccelInit(bmi088_instance);
|
||||
error |= BMI088GyroInit(bmi088_instance);
|
||||
|
||||
// 标定acc和gyro
|
||||
BMI088CalibrateIMU(bmi088_instance);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -7,10 +7,6 @@
|
|||
#include "bsp_pwm.h"
|
||||
#include "stdint.h"
|
||||
|
||||
#define BMI088_PRE_CALI_ACC_X_OFFSET 0.0f
|
||||
#define BMI088_PRE_CALI_ACC_Y_OFFSET 0.0f
|
||||
// macro to go here... 预设标定参数
|
||||
|
||||
// bmi088工作模式枚举
|
||||
typedef enum
|
||||
{
|
||||
|
@ -21,10 +17,23 @@ typedef enum
|
|||
// bmi088标定方式枚举,若使用预设标定参数,注意修改预设参数
|
||||
typedef enum
|
||||
{
|
||||
BMI088_CALIBRATE_MODE = 0, // 初始化时进行标定
|
||||
BMI088_LOAD_PRE_CALI_MODE, // 使用预设标定参数,
|
||||
BMI088_CALIBRATE_ONLINE_MODE = 0, // 初始化时进行标定
|
||||
BMI088_LOAD_PRE_CALI_MODE, // 使用预设标定参数,
|
||||
} BMI088_Calibrate_Mode_e;
|
||||
|
||||
#pragma pack(1) // 1字节对齐
|
||||
/* BMI088数据*/
|
||||
typedef struct
|
||||
{
|
||||
float gyro[3]; // 陀螺仪数据,xyz
|
||||
float acc[3]; // 加速度计数据,xyz
|
||||
float temperature; // 温度
|
||||
|
||||
// uint32_t timestamp; // 时间戳
|
||||
// uint32_t count;
|
||||
} BMI088_Data_t;
|
||||
#pragma pack() // 恢复默认对齐,需要传输的结构体务必开启1字节对齐
|
||||
|
||||
/* BMI088实例结构体定义 */
|
||||
typedef struct
|
||||
{
|
||||
|
@ -53,6 +62,18 @@ typedef struct
|
|||
float BMI088_GYRO_SEN;
|
||||
// 用于计算两次采样的时间间隔
|
||||
uint32_t bias_dwt_cnt;
|
||||
// 数据更新标志位
|
||||
struct // 位域,节省空间提高可读性
|
||||
{
|
||||
uint8_t gyro : 1; // 1:有新数据,0:无新数据
|
||||
uint8_t acc : 1;
|
||||
uint8_t temp : 1;
|
||||
uint8_t gyro_overrun : 1; // 1:数据溢出,0:无溢出
|
||||
uint8_t acc_overrun : 1;
|
||||
uint8_t temp_overrun : 1;
|
||||
uint8_t imu_ready : 1; // 1:IMU数据准备好,0:IMU数据未准备好(gyro+acc)
|
||||
// 后续可添加其他标志位
|
||||
} update_flag;
|
||||
} BMI088Instance;
|
||||
|
||||
/* BMI088初始化配置 */
|
||||
|
@ -68,7 +89,6 @@ typedef struct
|
|||
PWM_Init_Config_s heat_pwm_config;
|
||||
} BMI088_Init_Config_s;
|
||||
|
||||
|
||||
/**
|
||||
* @brief 初始化BMI088,返回BMI088实例指针
|
||||
* @note 一般一个开发板只有一个BMI088,所以这里就叫BMI088Init而不是Register
|
||||
|
@ -78,4 +98,11 @@ typedef struct
|
|||
*/
|
||||
BMI088Instance *BMI088Register(BMI088_Init_Config_s *config);
|
||||
|
||||
/**
|
||||
* @brief 读取BMI088数据
|
||||
* @todo 7个float数据开销较大,后续考虑使用DMA或双缓冲区直接传递指针
|
||||
* @param bmi088 BMI088实例指针
|
||||
* @return BMI088_Data_t 读取到的数据
|
||||
*/
|
||||
BMI088_Data_t BMI088Acquire(BMI088Instance *bmi088);
|
||||
#endif // !__BMI088_H__
|
|
@ -39,7 +39,7 @@ write写入:
|
|||
|
||||
1. 当accel int中断发生,开启DMA SPI传输,完成后将acc ready置位
|
||||
2. 当gyro int中断发生,开启DMA SPI传输,完成后将gyro ready置位
|
||||
3. 当温度数据中断发生,开启DMA传输,完成后将温度标志位置位
|
||||
3. 当温度数据中断(温度传感器在accel内部,也是accel int)发生,开启DMA传输,完成后将温度标志位置位
|
||||
|
||||
> 由于DMA传输非阻塞,启动传输后只有到传输完成时才会拉高片选结束SPI transfer,因此需要在callback中加入标志位置位的操作.
|
||||
这可以通过条件编译完成.
|
||||
|
|
|
@ -25,6 +25,13 @@
|
|||
|
||||
uint8_t GlobalDebugMode = 7;
|
||||
|
||||
void* zero_malloc(size_t size)
|
||||
{
|
||||
void* ptr=malloc(size);
|
||||
memset(ptr,0,size);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
// 快速开方
|
||||
float Sqrt(float x)
|
||||
{
|
||||
|
|
|
@ -87,6 +87,13 @@ extern uint8_t GlobalDebugMode;
|
|||
#define VAL_MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||
#define VAL_MAX(a, b) ((a) > (b) ? (a) : (b))
|
||||
|
||||
/**
|
||||
* @brief 返回一块干净的内存,不过仍然需要强制转换为你需要的类型
|
||||
*
|
||||
* @param size 分配大小
|
||||
* @return void*
|
||||
*/
|
||||
void* zero_malloc(size_t size);
|
||||
|
||||
//<2F><><EFBFBD>ٿ<EFBFBD><D9BF><EFBFBD>
|
||||
float Sqrt(float x);
|
||||
|
|
Loading…
Reference in New Issue