• RT-Thread STM32F407 BMI088--SPI


    BMI088是一款高性能6轴惯性传感器,由16位数字三轴±24g加速度计和16位数字三轴±2000°/ s陀螺仪组成。

    这里用SPI来驱动BMI088进行数据解读

    • 第一步,首先在 RT-Thread Settings中进行配置
      在这里插入图片描述

    • 第二步,退出RT-Thread Settings,进入board.h,定义宏
      在这里插入图片描述

    • 第三步,**进入stm32f4xx_hal_conf.h **
      在这里插入图片描述

    • 第四步,STM32 CubeMX配置
      在这里插入图片描述

    • 第五步,添加驱动文件到application
      在这里插入图片描述
      bmi088.c

    #include "bmi088.h"
    #include  
    #include  
    #include 
    #include "drv_spi.h"
    
    #define BMI088_SPI_MAX_SPEED (10 * 1000 * 1000) // M
    #define CSB1_Pin GET_PIN(B, 14)
    #define CSB2_Pin GET_PIN(B, 15)
    
    static rt_err_t _bmi088_spi_read(struct rt_spi_device *dev, rt_uint8_t reg_addr, const rt_uint8_t len, rt_uint8_t *buf)
    {
        reg_addr |= 0x80;
        
        dev->bus->owner = dev;
        rt_spi_send_then_recv(dev, &reg_addr, 1, buf, len);    
        
        return RT_EOK;
    }
    
    static rt_err_t _bmi088_spi_write(struct rt_spi_device *dev, rt_uint8_t reg_addr, const rt_uint8_t len, rt_uint8_t *buf)
    {   
        reg_addr &= 0x7f;
        
        dev->bus->owner = dev;
        rt_spi_send_then_send(dev, &reg_addr, 1, buf, len);
        
        return RT_EOK;
    }
    
    static rt_err_t _bmi088_get_accel_raw(struct bmi08x_dev *dev, struct bmi088_3axes *accel)
    {
        rt_uint8_t buffer[10];
        uint8_t lsb, msb;
        rt_err_t res;
    
        struct rt_spi_device *spi_dev = (struct rt_spi_device *)(dev->accel_bus);
        res = _bmi088_spi_read(spi_dev, ACC_X_LSB_REG, 10, buffer);
        if (res != RT_EOK)
        {
            return res;
        }
        lsb = buffer[1];
        msb = buffer[2];
        accel->x = (rt_int16_t)((msb << 8) | lsb); /* X */
        
        lsb = buffer[3];
        msb = buffer[4];
        accel->y = (rt_int16_t)((msb << 8) | lsb);/* Y */
    
        lsb = buffer[5];
        msb = buffer[6];
        accel->z = (rt_int16_t)((msb << 8) | lsb);/* Z */
    
        return RT_EOK;
    }
    
    static rt_err_t _bmi088_get_gyro_raw(struct bmi08x_dev *dev, struct bmi088_3axes *gyro)
    {
        rt_uint8_t buffer[6];
        uint8_t lsb, msb;
        rt_err_t res;
        
        struct rt_spi_device *spi_dev = (struct rt_spi_device *)(dev->gyro_bus);
        res = _bmi088_spi_read(spi_dev, RATE_X_LSB_REG, 6, buffer);
        if (res != RT_EOK)
        {
            return res;
        }
        lsb = buffer[0];
        msb = buffer[1];
        gyro->x = (rt_int16_t)((msb * 256) + lsb); /* X */
    
        lsb = buffer[2];
        msb = buffer[3];
        gyro->y = (rt_int16_t)((msb * 256) + lsb); /* Y */
    
        lsb = buffer[4];
        msb = buffer[5];
        gyro->z = (rt_int16_t)((msb * 256) + lsb); /* Z */
    
        return RT_EOK;
    }
    
    /**
    * This function gets the data of the accelerometer, unit: m/ss
     *
     * @param dev the pointer of device driver structure
     * @param accel the pointer of 3axes structure for receive data
     *
     * @return the reading number.
     */
    rt_size_t bmi088_get_accel(struct bmi08x_dev *dev, struct bmi088_data *buf)
    { 
        struct bmi088_3axes tmp;
        
        _bmi088_get_accel_raw(dev, &tmp);
        buf->x = ((float)tmp.x) /32768.0f * 6 * G;
        buf->y = ((float)tmp.y) /32768.0f * 6 * G;
        buf->z = ((float)tmp.z) /32768.0f * 6 * G;    
    
        return 1;// just support rw mode
    }
    
    /**
    * This function gets the data of the gyroscope, unit: rad/s
     *
     * @param dev the pointer of device driver structure
     * @param gyro the pointer of 3axes structure for receive data
     *
     * @return the reading number.
     */
    rt_size_t bmi088_get_gyro(struct bmi08x_dev *dev, struct bmi088_data *buf)
    {
        struct bmi088_3axes tmp;
        
        _bmi088_get_gyro_raw(dev, &tmp);
        buf->x = (float)tmp.x / 32767.0f * 2000.0f;
        buf->y = (float)tmp.y / 32767.0f * 2000.0f;
        buf->z = (float)tmp.z / 32767.0f * 2000.0f;   
        
        return 1;
    }
    
    /**
     * This function software reset the accelerometer of bmi08x.
     *
     * @param dev the pointer of bmi08x driver structure
     *
     * @return the status of software reset, RT_EOK represents software reset successfully.
     */
    static rt_err_t _bmi088a_soft_reset(struct bmi08x_dev *dev)
    {
        uint8_t send_cmd = BMI08X_SOFT_RESET_CMD;
        struct rt_spi_device *spi_dev = (struct rt_spi_device *)(dev->accel_bus);
        if (_bmi088_spi_write(spi_dev, ACC_SOFTRESET_REG, 1, &send_cmd) == RT_EOK)
        {
            rt_thread_mdelay(BMI08X_ACCEL_SOFTRESET_DELAY_MS);
            return RT_EOK;
        }
        else
        {
            return RT_ERROR;    
        }
    }
    
    /**
     * This function software reset the gyroscope of bmi08x.
     *
     * @param dev the pointer of bmi08x driver structure
     *
     * @return the status of software reset, RT_EOK represents software reset successfully.
     */
    static rt_err_t _bmi088g_soft_reset(struct bmi08x_dev *dev)
    {
        uint8_t send_cmd = BMI08X_SOFT_RESET_CMD;
        struct rt_spi_device *spi_dev = (struct rt_spi_device *)(dev->gyro_bus);
        if (_bmi088_spi_write(spi_dev, GYRO_SOFTRESET_REG, 1, &send_cmd) == RT_EOK)
        {
            rt_thread_mdelay(BMI08X_GYRO_SOFTRESET_DELAY_MS);
            return RT_EOK;
        }
        else
        {
            return RT_ERROR;    
        }
    }
    
    /**
     * This function initialize the accelerometer of bmi08x.
     *
     * @param dev the pointer of bmi08x driver structure
     *
     * @return the status of initialization, RT_EOK represents initialize successfully.
     */
    static rt_err_t _bmi088a_init(struct bmi08x_dev *dev)
    {
    	rt_err_t res = RT_EOK;
        uint8_t chip_acc_id[2] = {0};
        // config acc to spi mode
        rt_pin_write(dev->accel_id, PIN_LOW);
        rt_thread_mdelay(1);
        rt_pin_write(dev->accel_id, PIN_HIGH);
     
        struct rt_spi_device *spi_dev = (struct rt_spi_device *)(dev->accel_bus);
        _bmi088_spi_read(spi_dev, ACC_CHIP_ID_REG, 2, chip_acc_id);    /* Dummy read */
        if (chip_acc_id[1] != dev->accel_chip_id) 
        {
            LOG_E("Fail initialize acc");
            goto __exit;        
        }
    
        rt_thread_mdelay(10);
        res = _bmi088a_soft_reset(dev);
        
        // config acc to spi mode
        rt_pin_write(dev->accel_id, PIN_LOW);
        rt_thread_mdelay(1);
        rt_pin_write(dev->accel_id, PIN_HIGH);
        
        return res;
    
    __exit:
        return RT_ERROR;    
    }
    
    /**
     * This function initialize the gyroscope of bmi08x.
     *
     * @param dev the pointer of bmi08x driver structure
     *
     * @return the status of initialization, RT_EOK represents initialize successfully.
     */
    static rt_err_t _bmi088g_init(struct bmi08x_dev *dev)
    {
    	rt_err_t res = RT_EOK;
        rt_uint8_t id = 0;  
        
        struct rt_spi_device *spi_dev = (struct rt_spi_device *)dev->gyro_bus;
        _bmi088_spi_read(spi_dev, GYRO_CHIP_ID_REG, 1, &id);
        
        if (id != dev->gyro_chip_id) 
        {
            LOG_E("Fail initialize gyro");
            goto __exit;
        }
        rt_thread_mdelay(10);
        res = _bmi088g_soft_reset(dev);
        return res;
        
    __exit:
        return RT_ERROR;
    }
    
    /**
     * This function set the power mode of accelerometer of bmi08x 
     *
     * @param dev the pointer of bmi08x driver structure
     *
     * @return the setting status, RT_EOK represents reading the data successfully.
     */
    rt_err_t bmi088a_set_power_mode(struct bmi08x_dev *dev)
    {
        uint8_t power_mode = dev->accel_cfg.power;
        uint8_t data[2];
        struct rt_spi_device *spi_dev = (struct rt_spi_device *)(dev->accel_bus);
        
        if (power_mode == BMI08X_ACCEL_PM_ACTIVE) 
        {
            data[0] = BMI08X_ACCEL_PWR_ACTIVE_CMD;
            data[1] = BMI08X_ACCEL_POWER_ENABLE_CMD;
        } 
        else if (power_mode == BMI08X_ACCEL_PM_SUSPEND) 
        {
            data[0] = BMI08X_ACCEL_PWR_SUSPEND_CMD;
            data[1] = BMI08X_ACCEL_POWER_DISABLE_CMD;
        } 
        else 
        {
            LOG_E("Invalid acc power mode!");
            goto __exit;          
        }
    
        if (_bmi088_spi_write(spi_dev, ACC_PWR_CONF_REG, 1, &data[0]) == RT_EOK)
        {
            rt_thread_mdelay(BMI08X_POWER_CONFIG_DELAY);
            data[1] = BMI08X_ACCEL_POWER_ENABLE_CMD;
            if (_bmi088_spi_write(spi_dev, ACC_PWR_CTRL_REG, 1, &data[1]) == RT_EOK)
            {
                rt_thread_mdelay(BMI08X_POWER_CONFIG_DELAY);
                return RT_EOK;
            }
            else
            {
                LOG_E("Failed write CTRL_REG");
                goto __exit;
            }
        }
        else
        {
            LOG_E("Failed write PWR_REG");
            goto __exit;
        }        
        
    __exit:
        return RT_ERROR;
    }
    
    /**
     * This function set the power mode of gyroscope of bmi08x 
     *
     * @param dev the pointer of bmi08x driver structure
     *
     * @return the setting status, RT_EOK represents reading the data successfully.
     */
    rt_err_t bmi088g_set_power_mode(struct bmi08x_dev *dev)
    {
    	uint8_t power_mode = dev->gyro_cfg.power;
        uint8_t read_data;
    	uint8_t is_power_switching_mode_valid = 1;
        
        struct rt_spi_device *spi_dev = (struct rt_spi_device *)(dev->gyro_bus);
        _bmi088_spi_read(spi_dev, GYRO_LPM1_REG, 1, &read_data);
        
        if (power_mode == read_data) 
        {
            return RT_EOK;
        }
        else 
        {
            // only switching between normal mode and the suspend mode is allowed
            if ((power_mode == BMI08X_GYRO_PM_SUSPEND) && (read_data == BMI08X_GYRO_PM_DEEP_SUSPEND)) 
            {
                is_power_switching_mode_valid = 0;
            }  
            if ((power_mode == BMI08X_GYRO_PM_DEEP_SUSPEND) && (read_data == BMI08X_GYRO_PM_SUSPEND))
            {
                is_power_switching_mode_valid = 0;
            }
            
            if (is_power_switching_mode_valid) 
            {
                if (_bmi088_spi_write(spi_dev, GYRO_LPM1_REG, 1, &power_mode) == RT_EOK)
                {
                    rt_thread_mdelay(BMI08X_GYRO_POWER_MODE_CONFIG_DELAY);
                }
            }
            else
            {
                LOG_E("Invalid gyro mode switch");
                goto __exit;        
            }
        
        }
        
    __exit:
        return RT_ERROR;   
    }
    
    /**
     * This function set the bandwidth(bw), output data rate(odr) and range of accelerometer of bmi08x 
     *
     * @param dev the pointer of bmi08x driver structure
     *
     * @return the setting status, RT_EOK represents  reading the data successfully.
     */
    rt_err_t bmi088a_set_meas_conf(struct bmi08x_dev *dev)
    {
        uint8_t data[2] = {0};
        uint8_t reg_val[3] = {0};
        uint8_t bw = dev->accel_cfg.bw;
        uint8_t range = dev->accel_cfg.range;
        uint8_t odr = dev->accel_cfg.odr;
        uint8_t is_odr_invalid = 0, is_bw_invalid = 0, is_range_invalid = 0;
        
        if ((odr < BMI08X_ACCEL_ODR_12_5_HZ) || (odr > BMI08X_ACCEL_ODR_1600_HZ))
        {
            is_odr_invalid = 1;
        }
        if (bw > BMI08X_ACCEL_BW_NORMAL) 
        {
            is_bw_invalid = 1;
        }
        if (range > BMI088_ACCEL_RANGE_24G) 
        {
            is_range_invalid = 1;
        }
        
        if ((!is_odr_invalid) && (!is_bw_invalid) && (!is_range_invalid)) 
        {
            //dummy read
            struct rt_spi_device *spi_dev = (struct rt_spi_device *)(dev->accel_bus);
            if (_bmi088_spi_read(spi_dev, ACC_CONF_REG, 2, data) == RT_EOK)
            {
                data[0] = (1<<7) | (2<<4) | (0xB<<0);// bwp = normal, odr = 800
                _bmi088_spi_write(spi_dev, ACC_CONF_REG, 1, &data[0]);
                
                data[1] = 0x01;// range = 6G
                _bmi088_spi_write(spi_dev, ACC_RANGE_REG, 1, &data[1]);
                
                rt_thread_mdelay(10);
                _bmi088_spi_read(spi_dev, ACC_CONF_REG, 3, reg_val);// dummy read
                if ((reg_val[1] == 0xAB) && (reg_val[2] == 0x01)) 
                {
                    return RT_EOK;
                }
            }
            
        }
        return RT_ERROR;
    }
    
    /**
     * This function set the bandwidth(bw), output data rate(odr) and range of gyroscope of bmi08x 
     *
     * @param dev the pointer of bmi08x driver structure
     *
     * @return the setting status, RT_EOK represents reading the data successfully.
     */
    rt_err_t bmi088g_set_meas_conf(struct bmi08x_dev *dev)
    {
        uint8_t data;
        uint8_t bw_odr = dev->gyro_cfg.bw, range = dev->gyro_cfg.range;
        uint8_t reg_val[2] = {0};
        uint8_t is_range_invalid = 0, is_odr_invalid = 0;
    
        if (bw_odr > BMI08X_GYRO_BW_32_ODR_100_HZ) 
        {
            is_odr_invalid = 1;
        }
        if (range > BMI08X_GYRO_RANGE_125_DPS) 
        {
            is_range_invalid = 1;
        } 
        if ((!is_odr_invalid) && (!is_range_invalid)) 
        {
    //      data = BMI08X_SET_BITS_POS_0(data, BMI08X_GYRO_BW, odr);
            data = 0x01;// ODR = 2000Hz, Filter bandwidth = 230Hz
            struct rt_spi_device *spi_dev = (struct rt_spi_device *)(dev->gyro_bus);
            if (_bmi088_spi_write(spi_dev, GYRO_BANDWIDTH_REG, 1, &data) == RT_EOK)
            {
    //          data = BMI08X_SET_BITS_POS_0(data, GYRO_RANGE_REG, range);
                data = 0x00;// range = 2000deg/s
                if (_bmi088_spi_write(spi_dev, GYRO_RANGE_REG, 1, &data) == RT_EOK) 
                {
                    rt_thread_mdelay(10);
                    _bmi088_spi_read(spi_dev, GYRO_RANGE_REG, 2, reg_val);
                    if ((reg_val[0] == 0x00) && (reg_val[1] == 0x81))// 7 bit always 1
                    {
                        return RT_EOK;
                    }                
                }                
            }
        }
        return RT_ERROR;    
    }
    
    /**
     * This function initialize the bmi088 device.
     *
     * @param acc_spi_name the name of spi device(Accelerometer)
     * @param gyro_spi_name the name of spi device(Gyroscope)
     *
     * @return the pointer of bmi08x driver structure, RT_NULL represents initialization failed.
     */
    struct bmi08x_dev *bmi088_init(const char *acc_spi_name, const char *gyro_spi_name)
    {
        struct bmi08x_dev *dev = RT_NULL;
        rt_uint8_t res = RT_EOK;
    
        RT_ASSERT(acc_spi_name);
        RT_ASSERT(gyro_spi_name);
    
        dev = rt_calloc(1, sizeof(struct bmi08x_dev));
        if (dev == RT_NULL)
        {
            LOG_E("Can't allocate memory for bmi08x device on '%s' and '%s' ", acc_spi_name, gyro_spi_name);
            goto __exit;
        }
        
        dev->accel_bus = rt_device_find(acc_spi_name);
        dev->gyro_bus = rt_device_find(gyro_spi_name);
        
        
        if ((dev->accel_bus == RT_NULL) || (dev->gyro_bus == RT_NULL))
        {
            LOG_E("Can't find device:'%s' of '%s'", acc_spi_name, gyro_spi_name);
            goto __exit;
        }
        
        if (dev->accel_bus->type != dev->gyro_bus->type)
        {
            LOG_E("The bus type of '%s' and '%s' should same", acc_spi_name, gyro_spi_name);
            goto __exit;    
        }
    
        if (dev->accel_bus->type == RT_Device_Class_I2CBUS)
        {
            LOG_E("Bmi08x not support I2C temporarily");
            goto __exit;      
        }
        else if (dev->accel_bus->type == RT_Device_Class_SPIDevice)
        {
    //#ifdef RT_USING_SPI
            struct rt_spi_configuration cfg;
    
            cfg.data_width = 8;
            cfg.mode = RT_SPI_MASTER | RT_SPI_MODE_0 | RT_SPI_MSB;
            cfg.max_hz = BMI088_SPI_MAX_SPEED; /* Set spi max speed */
            struct rt_spi_device *spi_dev = (struct rt_spi_device *)dev->accel_bus;
            spi_dev->bus->owner = spi_dev;
            rt_spi_configure(spi_dev, &cfg);
    //#endif
        }
        else
        {
            LOG_E("Unsupported bus type:'%s'!", acc_spi_name);
            goto __exit;
        }
        
        // acc init
        {
            dev->accel_id = CSB1_Pin;
            dev->accel_chip_id = 0x1E;
            dev->accel_cfg.bw = BMI08X_ACCEL_BW_NORMAL;
            dev->accel_cfg.odr = BMI08X_ACCEL_ODR_800_HZ;
            dev->accel_cfg.power = BMI08X_ACCEL_PM_ACTIVE; 
            dev->accel_cfg.range = BMI088_ACCEL_RANGE_6G;
            res += _bmi088a_init(dev);
            res += bmi088a_set_power_mode(dev);
            res += bmi088a_set_meas_conf(dev);        
        }
        
        // gyro init
        {
            dev->gyro_id = CSB2_Pin;
            dev->gyro_chip_id = 0x0F;
            dev->gyro_cfg.bw = BMI08X_GYRO_BW_230_ODR_2000_HZ;
            dev->gyro_cfg.odr = BMI08X_GYRO_BW_230_ODR_2000_HZ;
            dev->gyro_cfg.power = BMI08X_GYRO_PM_NORMAL;
            dev->gyro_cfg.range = BMI08X_GYRO_RANGE_2000_DPS;
            res += _bmi088g_init(dev);
            res += bmi088g_set_power_mode(dev);
            res += bmi088g_set_meas_conf(dev);
        }
        
        rt_thread_mdelay(20);
        
        if (res == RT_EOK)
        {
            LOG_I("Device init succeed!");
        }
        else
        {
            goto __exit;
        }
    
        return dev;
    
    __exit:
        if (dev != RT_NULL)
        {
            rt_free(dev);
        }
        return RT_NULL;
    
    }
    
    /**
     * This function releases memory
     *
     * @param dev the pointer of bmi08x driver structure
     */
    void bmi088_deinit(struct bmi08x_dev *dev)
    {
        RT_ASSERT(dev);
    
        rt_free(dev);
    }
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240
    • 241
    • 242
    • 243
    • 244
    • 245
    • 246
    • 247
    • 248
    • 249
    • 250
    • 251
    • 252
    • 253
    • 254
    • 255
    • 256
    • 257
    • 258
    • 259
    • 260
    • 261
    • 262
    • 263
    • 264
    • 265
    • 266
    • 267
    • 268
    • 269
    • 270
    • 271
    • 272
    • 273
    • 274
    • 275
    • 276
    • 277
    • 278
    • 279
    • 280
    • 281
    • 282
    • 283
    • 284
    • 285
    • 286
    • 287
    • 288
    • 289
    • 290
    • 291
    • 292
    • 293
    • 294
    • 295
    • 296
    • 297
    • 298
    • 299
    • 300
    • 301
    • 302
    • 303
    • 304
    • 305
    • 306
    • 307
    • 308
    • 309
    • 310
    • 311
    • 312
    • 313
    • 314
    • 315
    • 316
    • 317
    • 318
    • 319
    • 320
    • 321
    • 322
    • 323
    • 324
    • 325
    • 326
    • 327
    • 328
    • 329
    • 330
    • 331
    • 332
    • 333
    • 334
    • 335
    • 336
    • 337
    • 338
    • 339
    • 340
    • 341
    • 342
    • 343
    • 344
    • 345
    • 346
    • 347
    • 348
    • 349
    • 350
    • 351
    • 352
    • 353
    • 354
    • 355
    • 356
    • 357
    • 358
    • 359
    • 360
    • 361
    • 362
    • 363
    • 364
    • 365
    • 366
    • 367
    • 368
    • 369
    • 370
    • 371
    • 372
    • 373
    • 374
    • 375
    • 376
    • 377
    • 378
    • 379
    • 380
    • 381
    • 382
    • 383
    • 384
    • 385
    • 386
    • 387
    • 388
    • 389
    • 390
    • 391
    • 392
    • 393
    • 394
    • 395
    • 396
    • 397
    • 398
    • 399
    • 400
    • 401
    • 402
    • 403
    • 404
    • 405
    • 406
    • 407
    • 408
    • 409
    • 410
    • 411
    • 412
    • 413
    • 414
    • 415
    • 416
    • 417
    • 418
    • 419
    • 420
    • 421
    • 422
    • 423
    • 424
    • 425
    • 426
    • 427
    • 428
    • 429
    • 430
    • 431
    • 432
    • 433
    • 434
    • 435
    • 436
    • 437
    • 438
    • 439
    • 440
    • 441
    • 442
    • 443
    • 444
    • 445
    • 446
    • 447
    • 448
    • 449
    • 450
    • 451
    • 452
    • 453
    • 454
    • 455
    • 456
    • 457
    • 458
    • 459
    • 460
    • 461
    • 462
    • 463
    • 464
    • 465
    • 466
    • 467
    • 468
    • 469
    • 470
    • 471
    • 472
    • 473
    • 474
    • 475
    • 476
    • 477
    • 478
    • 479
    • 480
    • 481
    • 482
    • 483
    • 484
    • 485
    • 486
    • 487
    • 488
    • 489
    • 490
    • 491
    • 492
    • 493
    • 494
    • 495
    • 496
    • 497
    • 498
    • 499
    • 500
    • 501
    • 502
    • 503
    • 504
    • 505
    • 506
    • 507
    • 508
    • 509
    • 510
    • 511
    • 512
    • 513
    • 514
    • 515
    • 516
    • 517
    • 518
    • 519
    • 520
    • 521
    • 522
    • 523
    • 524
    • 525
    • 526
    • 527
    • 528
    • 529
    • 530
    • 531
    • 532
    • 533
    • 534
    • 535
    • 536
    • 537
    • 538
    • 539
    • 540
    • 541
    • 542
    • 543
    • 544
    • 545
    • 546
    • 547
    • 548
    • 549
    • 550
    • 551
    • 552
    • 553
    • 554
    • 555
    • 556
    • 557
    • 558
    • 559
    • 560
    • 561
    • 562

    bmi088.h

    #ifndef __BMI088_H__
    #define __BMI088_H__
    
    #include 
    #include "sensor.h"
    
    
    #define IMU_THREAD_STACK_SIZE 4086
    /*************************** Common Macros for both Accel and Gyro *****************************/
    // Bit #0  : Read/Write bit
    // Bit #1-7: Address AD
    #define BMI08X_SPI_RD_MASK                          UINT8_C(0x80)
    #define BMI08X_SPI_WR_MASK                          UINT8_C(0x7F)
    
    /* CMD: soft reset */
    #define BMI08X_SOFT_RESET_CMD                       UINT8_C(0xB6)
    
    /* CMD: accel power save */
    #define BMI08X_ACCEL_PWR_ACTIVE_CMD                 UINT8_C(0x00)
    #define BMI08X_ACCEL_PWR_SUSPEND_CMD                UINT8_C(0x03)
    
    /* CMD: accel power control */ 
    #define BMI08X_ACCEL_POWER_DISABLE_CMD              UINT8_C(0x00)
    #define BMI08X_ACCEL_POWER_ENABLE_CMD               UINT8_C(0x04)
    
    /* Accel Power Mode */
    #define BMI08X_ACCEL_PM_ACTIVE                      UINT8_C(0x00)
    #define BMI08X_ACCEL_PM_SUSPEND                     UINT8_C(0x03)
    
    /* Gyro Power mode */
    #define BMI08X_GYRO_PM_NORMAL                       UINT8_C(0x00)
    #define BMI08X_GYRO_PM_DEEP_SUSPEND                 UINT8_C(0x20)
    #define BMI08X_GYRO_PM_SUSPEND                      UINT8_C(0x80)
    
    /* Accel Bandwidth */
    #define BMI08X_ACCEL_BW_OSR4                        UINT8_C(0x00)
    #define BMI08X_ACCEL_BW_OSR2                        UINT8_C(0x01)
    #define BMI08X_ACCEL_BW_NORMAL                      UINT8_C(0x02)
    
    /* Accel Output Data Rate */
    #define BMI08X_ACCEL_ODR_12_5_HZ                    UINT8_C(0x05)
    #define BMI08X_ACCEL_ODR_25_HZ                      UINT8_C(0x06)
    #define BMI08X_ACCEL_ODR_50_HZ                      UINT8_C(0x07)
    #define BMI08X_ACCEL_ODR_100_HZ                     UINT8_C(0x08)
    #define BMI08X_ACCEL_ODR_200_HZ                     UINT8_C(0x09)
    #define BMI08X_ACCEL_ODR_400_HZ                     UINT8_C(0x0A)
    #define BMI08X_ACCEL_ODR_800_HZ                     UINT8_C(0x0B)
    #define BMI08X_ACCEL_ODR_1600_HZ                    UINT8_C(0x0C)
    /* Accel Range */
    #define BMI088_ACCEL_RANGE_3G                       UINT8_C(0x00)
    #define BMI088_ACCEL_RANGE_6G                       UINT8_C(0x01)
    #define BMI088_ACCEL_RANGE_12G                      UINT8_C(0x02)
    #define BMI088_ACCEL_RANGE_24G                      UINT8_C(0x03)
    
    /* Gyro Range */
    #define BMI08X_GYRO_RANGE_2000_DPS                  UINT8_C(0x00)
    #define BMI08X_GYRO_RANGE_1000_DPS                  UINT8_C(0x01)
    #define BMI08X_GYRO_RANGE_500_DPS                   UINT8_C(0x02)
    #define BMI08X_GYRO_RANGE_250_DPS                   UINT8_C(0x03)
    #define BMI08X_GYRO_RANGE_125_DPS                   UINT8_C(0x04)
    
    /* Gyro Output data rate and bandwidth */
    #define BMI08X_GYRO_BW_532_ODR_2000_HZ              UINT8_C(0x00)
    #define BMI08X_GYRO_BW_230_ODR_2000_HZ              UINT8_C(0x01)
    #define BMI08X_GYRO_BW_116_ODR_1000_HZ              UINT8_C(0x02)
    #define BMI08X_GYRO_BW_47_ODR_400_HZ                UINT8_C(0x03)
    #define BMI08X_GYRO_BW_23_ODR_200_HZ                UINT8_C(0x04)
    #define BMI08X_GYRO_BW_12_ODR_100_HZ                UINT8_C(0x05)
    #define BMI08X_GYRO_BW_64_ODR_200_HZ                UINT8_C(0x06)
    #define BMI08X_GYRO_BW_32_ODR_100_HZ                UINT8_C(0x07)
    #define BMI08X_GYRO_ODR_RESET_VAL                   UINT8_C(0x80)
    
    #define BMI08X_ACCEL_DATA_SYNC_MODE_OFF 0x00
    #define BMI08X_ACCEL_DATA_SYNC_MODE_400HZ 0x01
    #define BMI08X_ACCEL_DATA_SYNC_MODE_1000HZ 0x02
    #define BMI08X_ACCEL_DATA_SYNC_MODE_2000HZ 0x03
    
    /* Wait Time */
    #define BMI08X_ACCEL_SOFTRESET_DELAY_MS             UINT8_C(1)
    #define BMI08X_GYRO_SOFTRESET_DELAY_MS              UINT8_C(30)
    #define BMI08X_GYRO_POWER_MODE_CONFIG_DELAY         UINT8_C(30)
    #define BMI08X_POWER_CONFIG_DELAY                   UINT8_C(50)
    
    #define G (9.80f)
    #define deg2rad (3.1415926 / 180.0f)
    #define rad2deg (180.0f / 3.1415926)
    
    typedef enum 
    {
        ACC_CHIP_ID_REG             = 0x00,
        ACC_ERR_REG                 = 0x02,
        ACC_STATUS_REG              = 0x03,
        ACC_X_LSB_REG               = 0x12,
        ACC_X_MSB_REG               = 0x13,
        ACC_Y_LSB_REG               = 0x14,
        ACC_Y_MSB_REG               = 0x15,
        ACC_Z_LSB_REG               = 0x16,
        ACC_Z_MSB_REG               = 0x17,
        TEMP_MSB_REG                = 0x22,
        TEMP_LSB_REG                = 0x23,
        ACC_CONF_REG                = 0x40,
        ACC_RANGE_REG               = 0x41,
        INT1_IO_CTRL_REG            = 0x53,
        INT2_IO_CTRL_REG            = 0x54,
        ACC_SELF_TEST_REG           = 0x6D,
        ACC_PWR_CONF_REG            = 0x7C,
        ACC_PWR_CTRL_REG            = 0x7D,
        ACC_SOFTRESET_REG           = 0x7E
    } bmi088a_reg_list_t;
    
    typedef enum 
    {
        GYRO_CHIP_ID_REG            = 0x00,
        RATE_X_LSB_REG              = 0x02,
        RATE_X_MSB_REG              = 0x03,
        RATE_Y_LSB_REG              = 0x04,
        RATE_Y_MSB_REG              = 0x05,
        RATE_Z_LSB_REG              = 0x06,
        RATE_Z_MSB_REG              = 0x07,
        GYRO_INT_STAT_1_REG         = 0x0A,
        GYRO_RANGE_REG              = 0x0F,
        GYRO_BANDWIDTH_REG          = 0x10,
        GYRO_LPM1_REG               = 0x11,
        GYRO_SOFTRESET_REG          = 0x14,
        GYRO_INT_CTRL_REG           = 0x15
    } bmi088g_reg_list_t;
    
    enum bmi08x_intf {
    /*! I2C interface */
    BMI08X_I2C_INTF,
    /*! SPI interface */
    BMI08X_SPI_INTF
    };
    
    struct bmi08x_cfg 
    {
    /*! power mode */
    uint8_t power;
    /*! range */
    uint8_t range;
    /*! bandwidth */
    uint8_t bw;
    /*! output data rate */
    uint8_t odr;
    };
    
    /* bmi088 device structure */
    struct bmi08x_dev 
    {
    /*! Accel chip Id */
    uint8_t accel_chip_id;
    /*! Gyro chip Id */
    uint8_t gyro_chip_id;
    /*! Accel device Id in I2C mode, can be used for chip select pin in SPI mode */
    rt_base_t accel_id;
    /*! Gyro device Id in I2C mode, can be used for chip select pin in SPI mode */
    rt_base_t gyro_id;
    /*! Device of accel bus*/
    rt_device_t accel_bus;
    /*! Device of gyro bus*/
    rt_device_t gyro_bus;
    /*! 0 - I2C , 1 - SPI Interface */
    enum bmi08x_intf intf;
    /*! Structure to configure accel sensor  */
    struct bmi08x_cfg accel_cfg;
    /*! Structure to configure gyro sensor  */
    struct bmi08x_cfg gyro_cfg;
    /*! Config stream data buffer address will be assigned*/
    const uint8_t *config_file_ptr;
    /*! Max read/write length (maximum supported length is 32).
    To be set by the user */
    uint8_t read_write_len;
    };
    
    struct bmi088_3axes
    {
        rt_int16_t x;
        rt_int16_t y;
        rt_int16_t z;
    };
    
    struct bmi088_data
    {
        float x;
        float y;
        float z;
    };
    
    struct bmi08x_dev *bmi088_init(const char *acc_name, const char *gyro_name);
    void bmi088_deinit(struct bmi08x_dev *dev);
    rt_err_t bmi088a_set_power_mode(struct bmi08x_dev *dev);
    rt_err_t bmi088g_set_power_mode(struct bmi08x_dev *dev);
    rt_err_t bmi088a_set_meas_conf(struct bmi08x_dev *dev);
    rt_err_t bmi088g_set_meas_conf(struct bmi08x_dev *dev);
    rt_size_t bmi088_get_accel(struct bmi08x_dev *dev, struct bmi088_data *buf);
    rt_size_t bmi088_get_gyro(struct bmi08x_dev *dev, struct bmi088_data *buf);
    
    
    #endif // BMI088_H
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200

    sensor_intf_bmi088.c

    #include "sensor_intf_bmi088.h"
    #include "bmi088.h"
    #include 
    
    static struct bmi08x_dev *bmi_dev;
    
    static rt_err_t _bmi088_init(struct rt_sensor_intf *acc_intf, struct rt_sensor_intf *gyr_intf)
    {
        bmi_dev = bmi088_init(acc_intf->dev_name, gyr_intf->dev_name);
    
        if (bmi_dev == RT_NULL)
        {
            return -RT_ERROR;
        }
    
        return RT_EOK;
    }
    
    static rt_err_t _bmi088_set_power_mode(rt_sensor_t sensor, rt_uint8_t power)
    {   
        if (sensor->info.type == RT_SENSOR_CLASS_ACCE)
        {
            if (power == RT_SENSOR_POWER_DOWN) 
            {
                bmi_dev->accel_cfg.power = BMI08X_ACCEL_PM_SUSPEND;
            }
            else if (power == RT_SENSOR_POWER_NORMAL)
            {
                bmi_dev->accel_cfg.power = BMI08X_ACCEL_PM_ACTIVE;
            }
            else 
            {
                LOG_E("Unsupported power mode %d", power);
                return -RT_ERROR;        
            }
            
            bmi088a_set_power_mode(bmi_dev);
        }
        else if (sensor->info.type == RT_SENSOR_CLASS_GYRO)
        {
            if (power == RT_SENSOR_POWER_DOWN) 
            {
                bmi_dev->gyro_cfg.power = BMI08X_GYRO_PM_SUSPEND;
            }
            else if (power == RT_SENSOR_POWER_NORMAL)
            {
                bmi_dev->gyro_cfg.power = BMI08X_GYRO_PM_NORMAL;
            }
            else if (power == RT_SENSOR_POWER_NONE)
            {
                bmi_dev->gyro_cfg.power = BMI08X_GYRO_PM_DEEP_SUSPEND;
            }
            else 
            {
                LOG_E("Unsupported power mode %d", power);
                return -RT_ERROR;        
            }
            
            bmi088g_set_power_mode(bmi_dev);
        }
        else 
        {
            LOG_E("Unsupported type %d", sensor->info.type);
            return -RT_ERROR;
        }
        return RT_EOK;
    }
    
    /**
    * This function get the data of bmi088 sensor, unit: mg, mdps
     *
     * @param sensor the pointer of rt_sensor_device.
     * @param data the pointer of rt_sensor_data
     * 
     * @return the reading number.
     */
    static rt_size_t _bmi088_get_data(rt_sensor_t sensor, struct rt_sensor_data *data)
    {
        rt_size_t len;
        if (sensor->info.type == RT_SENSOR_CLASS_ACCE)
        {
            struct bmi088_data acce_m_ss;
            len =  bmi088_get_accel(bmi_dev, &acce_m_ss);
    
            data->type = RT_SENSOR_CLASS_ACCE;
            data->data.acce.x = acce_m_ss.x * 1000;
            data->data.acce.y = acce_m_ss.y * 1000;
            data->data.acce.z = acce_m_ss.z * 1000;
            data->timestamp = rt_sensor_get_ts();
        }
        else if (sensor->info.type == RT_SENSOR_CLASS_GYRO)
        {
            struct bmi088_data gyro_rad_s;
            len = bmi088_get_gyro(bmi_dev, &gyro_rad_s);
    
            data->type = RT_SENSOR_CLASS_GYRO;
            data->data.gyro.x = gyro_rad_s.x * rad2deg * 1000;
            data->data.gyro.y = gyro_rad_s.y * rad2deg * 1000;
            data->data.gyro.z = gyro_rad_s.x * rad2deg * 1000;
            data->timestamp = rt_sensor_get_ts();
        }
        return len;
    }
    
    /**
    * This function get the data of bmi088 sensor
     *
     * @param sensor the pointer of rt_sensor_device.
     * @param buf the pointer of data buffer.
     * @param len the length of data.
     * 
     * @return the reading number.
     */
    static rt_size_t _bmi088_fetch_data(struct rt_sensor_device *sensor, void *buf, rt_size_t len)
    {
        if (sensor->config.mode == RT_DEVICE_OFLAG_RDONLY)
        {
            return _bmi088_get_data(sensor, (struct rt_sensor_data *)buf);
        }
        else
        {
            return 0;
        }
    }
    
    /**
    * This function control the bmi088 sensor
     *
     * @param sensor the pointer of rt_sensor_device.
     * @param cmd the type of command.
     * @param args the null pointer of commmand parameter, notice the pointer is four bytes.
     * 
     * @return the reading number.
     */
    static rt_err_t _bmi088_control(struct rt_sensor_device *sensor, int cmd, void *args)//args��32λ(ָ�붼��4���ֽ�)
    {
        rt_err_t result = RT_EOK;
    
        switch (cmd)
        {
        case RT_SENSOR_CTRL_GET_ID:
            if (sensor->info.type == RT_SENSOR_CLASS_ACCE) 
            {
                *(rt_uint8_t *)args = 0x1E;
            }
            else if (sensor->info.type == RT_SENSOR_CLASS_GYRO)
            {
                *(rt_uint8_t *)args = 0x0F;
            }
            break;
        case RT_SENSOR_CTRL_SET_ODR:
        case RT_SENSOR_CTRL_SET_RANGE:
            if (sensor->info.type == RT_SENSOR_CLASS_ACCE) 
            {
                result = bmi088a_set_meas_conf(bmi_dev);
            }
            else if (sensor->info.type == RT_SENSOR_CLASS_GYRO)
            {
                result = bmi088g_set_meas_conf(bmi_dev);
            }
            break;
        case RT_SENSOR_CTRL_SET_POWER:
            _bmi088_set_power_mode(sensor, (rt_uint32_t)args & 0xff);
            break;
        case RT_SENSOR_CTRL_SET_MODE:
            break;
        case RT_SENSOR_CTRL_SELF_TEST:
            /* TODO */
            result = -RT_EINVAL;
            break;
        default:
            return -RT_EINVAL;
        }
        return result;
    }
    
    static struct rt_sensor_ops sensor_ops =
    {
        _bmi088_fetch_data, 
        _bmi088_control
    };
    
    /**
    * This function initialize the bmi088
     *
     * @param name the name of bmi088, just first three characters will be used.
     * @param acc_cfg the pointer of configuration structure for accelarometer.
     * @param gyr_cfg the pointer of configuration structure for gyroscope.
     * 
     * @return the reading number.
     */
    rt_err_t rt_hw_bmi088_init(const char *name, struct rt_sensor_config *acc_cfg, struct rt_sensor_config *gyr_cfg)
    {   
        rt_int8_t result;
        rt_sensor_t sensor_acce = RT_NULL, sensor_gyro = RT_NULL;
    
    //#ifdef PKG_USING_BMI088_ACCE
        /* accelerometer sensor register */
        {
            sensor_acce = rt_calloc(1, sizeof(struct rt_sensor_device));
            if (sensor_acce == RT_NULL)
            {
                return -1;
            }
                
            sensor_acce->info.type       = RT_SENSOR_CLASS_ACCE;
            sensor_acce->info.vendor     = RT_SENSOR_VENDOR_BOSCH;
            sensor_acce->info.model      = "bmi088_acc";
            sensor_acce->info.unit       = RT_SENSOR_UNIT_MG;
            sensor_acce->info.intf_type  = RT_SENSOR_INTF_SPI;
            sensor_acce->info.range_max  = 16000;
            sensor_acce->info.range_min  = 2000;
            sensor_acce->info.period_min = 5;
    
            rt_memcpy(&sensor_acce->config, acc_cfg, sizeof(struct rt_sensor_config));
            sensor_acce->ops = &sensor_ops;
    
            result = rt_hw_sensor_register(sensor_acce, name, RT_DEVICE_FLAG_RDWR, RT_NULL);
            if (result != RT_EOK)
            {
                LOG_E("device register err code: %d", result);
                goto __exit;
            }
        }
    //#endif
    //#ifdef PKG_USING_BMI088_GYRO
        /* gyroscope sensor register */
        {
            sensor_gyro = rt_calloc(1, sizeof(struct rt_sensor_device));
            if (sensor_gyro == RT_NULL)
            {
                goto __exit;
            }
                
            sensor_gyro->info.type       = RT_SENSOR_CLASS_GYRO;
            sensor_gyro->info.vendor     = RT_SENSOR_VENDOR_BOSCH;
            sensor_gyro->info.model      = "bmi088_gyro";
            sensor_gyro->info.unit       = RT_SENSOR_UNIT_MDPS;
            sensor_gyro->info.intf_type  = RT_SENSOR_INTF_SPI;
            sensor_gyro->info.range_max  = 2000000;
            sensor_gyro->info.range_min  = 250000;
            sensor_gyro->info.period_min = 5;
    
            rt_memcpy(&sensor_gyro->config, gyr_cfg, sizeof(struct rt_sensor_config));
            sensor_gyro->ops = &sensor_ops;
    
            result = rt_hw_sensor_register(sensor_gyro, name, RT_DEVICE_FLAG_RDWR, RT_NULL);
            if (result != RT_EOK)
            {
                LOG_E("device register err code: %d", result);
                goto __exit;
            }
        }
    //#endif
    
        result = _bmi088_init(&acc_cfg->intf, &gyr_cfg->intf);
        if (result != RT_EOK)
        {
            LOG_E("_bmi088_init err code: %d", result);
            goto __exit;
        }
    
        LOG_I("sensor init success");
        return RT_EOK;
    
    __exit:
        if (sensor_acce)
        {
            rt_free(sensor_acce);
        } 
        if (sensor_gyro)
        {
            rt_free(sensor_gyro);
        }  
        if (bmi_dev)
        {
            bmi088_deinit(bmi_dev);
        }
        return -RT_ERROR;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240
    • 241
    • 242
    • 243
    • 244
    • 245
    • 246
    • 247
    • 248
    • 249
    • 250
    • 251
    • 252
    • 253
    • 254
    • 255
    • 256
    • 257
    • 258
    • 259
    • 260
    • 261
    • 262
    • 263
    • 264
    • 265
    • 266
    • 267
    • 268
    • 269
    • 270
    • 271
    • 272
    • 273
    • 274
    • 275
    • 276
    • 277
    • 278
    • 279
    • 280
    • 281

    sensor_intf_bmi088.h

    #ifndef __SENSOR_INTF_BMI088_H__
    #define __SENSOR_INTF_BMI088_H__
    
    #include "sensor.h"
    #include "BMI088.h"
    
    
    rt_err_t rt_hw_bmi088_init(const char *name, struct rt_sensor_config *acc_cfg, struct rt_sensor_config *gyr_cfg);
    
    #endif
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 第六步,到main.c 配置bmi088
      ①配置spi,配置片选引脚
       
        rt_hw_spi_device_attach(BMI088_BUS_NAME, BMI088A_SPI_NAME, GPIOF, GPIO_PIN_3);
        rt_hw_spi_device_attach(BMI088_BUS_NAME, BMI088G_SPI_NAME, GPIOF, GPIO_PIN_4);
    
    • 1
    • 2
    • 3

    ②初始化bmi

        struct rt_sensor_config acc_cfg = {0};
        struct rt_sensor_config gyr_cfg = {0};
    
        acc_cfg.intf.dev_name = BMI088A_SPI_NAME;
        gyr_cfg.intf.dev_name = BMI088G_SPI_NAME;
    
        rt_hw_bmi088_init("bmi", &acc_cfg, &gyr_cfg);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    ③查找 spi 设备获取设备句柄

    
        acce_device_t = rt_device_find("acce_bmi");
        if (acce_device_t == RT_NULL)
        {
            LOG_E("Can't find acce device\r\n");
        }
        else
        {
            rt_device_open(acce_device_t, RT_DEVICE_OFLAG_RDWR);
        }
    
        gyro_device_t = rt_device_find("gyro_bmi");
        if (gyro_device_t == RT_NULL)
        {
            LOG_E("Can't find gyro device\r\n");
        }
        else
        {
            rt_device_open(gyro_device_t, RT_DEVICE_OFLAG_RDWR);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    ④读取姿态数据

        rt_device_read(acce_device_t, 0, &acc_test, 1);   //加速度
        rt_device_read(gyro_device_t, 0, &gyr_test, 1);   //陀螺仪
    
    • 1
    • 2

    main.c

    include <rtthread.h>
    #include 
    #include 
    #include 
    #include "bmi088.h"
    #include "sensor_intf_bmi088.h"
    
    #define DBG_TAG "main"
    #define DBG_LVL DBG_LOG
    
    #define SPI_DEVICE_NAME     "spi10"
    #define SPI_BUS_NAME        "spi1"
    #define BMI088_BUS_NAME "spi1"
    #define BMI088A_SPI_NAME "spi10"
    #define BMI088G_SPI_NAME "spi11"
    
    static rt_device_t acce_device_t;
    static rt_device_t gyro_device_t;
    struct rt_sensor_data acc_test;
    struct rt_sensor_data gyr_test;
    
    int main(void)
    {
    
        // 配置spi,配置片选引脚(要在acc、gyr初始化之前配置,因为器件初始化中涉及到引脚操作)
        rt_hw_spi_device_attach(BMI088_BUS_NAME, BMI088A_SPI_NAME, GPIOF, GPIO_PIN_3);
        rt_hw_spi_device_attach(BMI088_BUS_NAME, BMI088G_SPI_NAME, GPIOF, GPIO_PIN_4);
    
        // 注册传感器
        struct rt_sensor_config acc_cfg = {0};
        struct rt_sensor_config gyr_cfg = {0};
    
        acc_cfg.intf.dev_name = BMI088A_SPI_NAME;
        gyr_cfg.intf.dev_name = BMI088G_SPI_NAME;
    
        rt_hw_bmi088_init("bmi", &acc_cfg, &gyr_cfg);
    
        /* 查找 spi 设备获取设备句柄 */
        acce_device_t = rt_device_find("acce_bmi");
        if (acce_device_t == RT_NULL)
        {
            LOG_E("Can't find acce device\r\n");
        }
        else
        {
            rt_device_open(acce_device_t, RT_DEVICE_OFLAG_RDWR);
        }
    
        gyro_device_t = rt_device_find("gyro_bmi");
        if (gyro_device_t == RT_NULL)
        {
            LOG_E("Can't find gyro device\r\n");
        }
        else
        {
            rt_device_open(gyro_device_t, RT_DEVICE_OFLAG_RDWR);
        }
    
        while (1)
        {
            rt_device_read(acce_device_t, 0, &acc_test, 1);   //加速度
            rt_device_read(gyro_device_t, 0, &gyr_test, 1);   //陀螺仪
    
            rt_kprintf("x=%d  y=%d  z=%d\n",acc_test.data.acce.x,acc_test.data.acce.y,acc_test.data.acce.z);
            //rt_kprintf("x=%d  y=%d  z=%d\n",gyr_test.data.gyro.x,gyr_test.data.gyro.y,gyr_test.data.gyro.z);
            rt_thread_mdelay(500);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68

    如下为加速度计数据:
    在这里插入图片描述

  • 相关阅读:
    2023年05月 C/C++(八级)真题解析#中国电子学会#全国青少年软件编程等级考试
    Facebook的数字社交使命:连接世界的下一步
    【Linux常用命令11】Linux文件与权限详解
    Qt-OpenCV学习笔记--边缘检测--Canny()
    动态SQL---P22,P23,P24
    STM32与GD32笔记
    小程序中用于跳转页面的5个api是什么和区别
    【Leetcode刷题Python】96. 不同的二叉搜索树
    QT windows与linux之间sokcet通信中文乱码问题解决方法
    【5w字】SpringBoot源码分析
  • 原文地址:https://blog.csdn.net/Dustinthewine/article/details/134467777