Open Tigerots opened 3 years ago
@Tigerots 暂时没其他人遇到过 我重新看了下代码,也没发现问题在哪 能把你写的裸机代码发出来,让我看看来对照一下吗
您好, 我今天刚看到您的回复, 恰好有时间, 也仔细跟踪了一次代码, 确实没有发现什么异常, 于是用模拟IIC驱动又测试了下, 结果还是不一样, 我测试的代码发给您, 如果方便, 可以实际测试一下,(测试代码有部分来源于网络)。
头文件 ` /*
测试文件
/*
static struct rt_i2c_bus_device *i2c_bus_dev;
// 配置bmp280气压和温度过采样 工作模式
// 配置bmp280气压IIR滤波器
// 读取的数据长度
typedef struct { uint16_t dig_T1; int16_t dig_T2; int16_t dig_T3; uint16_t dig_P1; int16_t dig_P2; int16_t dig_P3; int16_t dig_P4; int16_t dig_P5; int16_t dig_P6; int16_t dig_P7; int16_t dig_P8; int16_t dig_P9; int32_t t_fine; } bmp280Calib; bmp280Calib bmp280_cal;
static int8_t my_i2c_reg_write(uint8_t i2c_addr, uint8_t reg_addr, uint8_t *reg_data, uint16_t length) { rt_uint8_t tmp = reg_addr; struct rt_i2c_msg msgs[2];
msgs[0].addr = i2c_addr; /* Slave address */
msgs[0].flags = RT_I2C_WR; /* Write flag */
msgs[0].buf = &tmp; /* Slave register address */
msgs[0].len = 1; /* Number of bytes sent */
msgs[1].addr = i2c_addr; /* Slave address */
msgs[1].flags = RT_I2C_WR | RT_I2C_NO_START; /* Read flag */
msgs[1].buf = reg_data; /* Read data pointer */
msgs[1].len = length; /* Number of bytes read */
if (rt_i2c_transfer(i2c_bus_dev, msgs, 2) != 2)
{
return -RT_ERROR;
}
return RT_EOK;
}
static int8_t my_i2c_reg_read(uint8_t i2c_addr, uint8_t reg_addr, uint8_t *reg_data, uint16_t length) { rt_uint8_t tmp = reg_addr; struct rt_i2c_msg msgs[2];
msgs[0].addr = i2c_addr; /* Slave address */
msgs[0].flags = RT_I2C_WR; /* Write flag */
msgs[0].buf = &tmp; /* Slave register address */
msgs[0].len = 1; /* Number of bytes sent */
msgs[1].addr = i2c_addr; /* Slave address */
msgs[1].flags = RT_I2C_RD; /* Read flag */
msgs[1].buf = reg_data; /* Read data pointer */
msgs[1].len = length; /* Number of bytes read */
if (rt_i2c_transfer(i2c_bus_dev, msgs, 2) != 2)
{
return -RT_ERROR;
}
return RT_EOK;
}
uint8_t my_bmp280_chip_Init(void) { uint8_t id = 0x00; char dev_name[] = "i2c1";
rt_thread_delay(1000);
i2c_bus_dev = rt_i2c_bus_device_find(dev_name);
if (i2c_bus_dev == RT_NULL)
{
LOG_E("can't find bmp280 %s device", dev_name);
}
for (int i=0; i<10; i++)
{
my_i2c_reg_read(BMP280_I2C_ADDR, BMP280_CHIP_ID, &id, 1);//读取ID
rt_kprintf("chip280 id = 0x%x \r\n", id);
if (id == BMP280_DEFAULT_CHIP_ID)
{
break;
}
rt_thread_mdelay(10);
}
if (id == BMP280_DEFAULT_CHIP_ID)//读取正常
{
uint8_t temp;
my_i2c_reg_read(BMP280_I2C_ADDR, BMP280_TEMPERATURE_CALIB_DIG_T1_LSB_REG, (uint8_t *)&bmp280_cal, 24);//读取校准数据
temp = BMP280_MODE;
my_i2c_reg_write(BMP280_I2C_ADDR, BMP280_CTRL_MEAS_REG, &temp, 1);//设置过采样率和工作模式
temp = BMP280_FILTER;
my_i2c_reg_write(BMP280_I2C_ADDR, BMP280_CONFIG_REG, &temp, 1);//配置IIR滤波
LOG_I("BMP280 I2C connection OK\r\n");
}
else
{
LOG_I("BMP280 I2C connection FAIL\r\n");
}
return 0;
}
static int32_t bmp280_Pressure = 0; static int32_t bmp280_Temperature = 0; static void my_bmp280_get_press_temp(void) { uint8_t data[BMP280_DATA_FRAME_SIZE];
my_i2c_reg_read(BMP280_I2C_ADDR, BMP280_PRESSURE_MSB_REG, data, BMP280_DATA_FRAME_SIZE);
bmp280_Pressure = (int32_t)((((uint32_t)(data[0])) << 12) | (((uint32_t)(data[1])) << 4) | ((uint32_t)data[2] >> 4));
bmp280_Temperature = (int32_t)((((uint32_t)(data[3])) << 12) | (((uint32_t)(data[4])) << 4) | ((uint32_t)data[5] >> 4));
}
uint32_t bmp280_compensate_temp(int32_t adcT) { int32_t var1, var2, T;
var1 = ((((adcT >> 3) - ((int32_t)bmp280_cal.dig_T1 << 1))) * ((int32_t)bmp280_cal.dig_T2)) >> 11;
var2 = (((((adcT >> 4) - ((int32_t)bmp280_cal.dig_T1)) * ((adcT >> 4) - ((int32_t)bmp280_cal.dig_T1))) >> 12) * ((int32_t)bmp280_cal.dig_T3)) >> 14;
bmp280_cal.t_fine = var1 + var2;
T = (bmp280_cal.t_fine * 5 + 128) >> 8;
return T;
}
uint32_t bmp280_compensate_press(int32_t adcP) { int64_t var1, var2, p; var1 = ((int64_t)bmp280_cal.t_fine) - 128000; var2 = var1 var1 (int64_t)bmp280_cal.dig_P6; var2 = var2 + ((var1(int64_t)bmp280_cal.dig_P5) << 17); var2 = var2 + (((int64_t)bmp280_cal.dig_P4) << 35); var1 = ((var1 var1 (int64_t)bmp280_cal.dig_P3) >> 8) + ((var1 (int64_t)bmp280_cal.dig_P2) << 12); var1 = (((((int64_t)1) << 47) + var1)) ((int64_t)bmp280_cal.dig_P1) >> 33; if (var1 == 0) return 0; p = 1048576 - adcP; p = (((p << 31) - var2) 3125) / var1; var1 = (((int64_t)bmp280_cal.dig_P9) (p >> 13) (p >> 13)) >> 25; var2 = (((int64_t)bmp280_cal.dig_P8) * p) >> 19; p = ((p + var1 + var2) >> 8) + (((int64_t)bmp280_cal.dig_P7) << 4); return (uint32_t)p; }
void bmp280_get_data(float pressure, float temperature, float* asl) { my_bmp280_get_press_temp();
*temperature = bmp280_compensate_temp(bmp280_Temperature)/100.0f; // 单位度
*pressure = bmp280_compensate_press(bmp280_Pressure)/256.0f; // 单位Pa
}
uint8_t bum280_init_flag = 0; static void my_bmp280_entry(void *arg) { char log_buf[100]; float t, p, a; while(1) { if (bum280_init_flag==0) { my_bmp280_chip_Init(); bum280_init_flag = 1; } bmp280_get_data(&p, &t, &a); sprintf(log_buf, "P = %.2f\tT = %.1f\tA = %.2f\r\n", p, t, a); rt_kprintf(log_buf); rt_thread_mdelay(1000); } }
/**函数描述***
INIT_APP_EXPORT(my_bmp280_init_test);
`
@Tigerots 我看你的气压配置的参数跟我的不一样,你可以尝试配置一样的试下效果如何
`
conf.filter = BMP280_FILTER_COEFF_2;
/* Temperature oversampling set at 4x */
conf.os_temp = BMP280_OS_4X;
/* Pressure oversampling set at 4x */
conf.os_pres = BMP280_OS_4X;
/* Setting the output data rate as 1HZ(1000ms) */
conf.odr = BMP280_ODR_1000_MS;
`
int8_t bmp280_get_comp_temp_32bit(int32_t *comp_temp, int32_t uncomp_temp, struct bmp280_dev *dev)
{
int32_t var1, var2;
int8_t rslt;
rslt = null_ptr_check(dev);
if (rslt == BMP280_OK)
{
var1 =
((((uncomp_temp / 8) - ((int32_t) dev->calib_param.dig_t1 << 1))) * ((int32_t) dev->calib_param.dig_t2)) /
2048;
var2 =
(((((uncomp_temp / 16) - ((int32_t) dev->calib_param.dig_t1)) *
((uncomp_temp / 16) - ((int32_t) dev->calib_param.dig_t1))) / 4096) *
((int32_t) dev->calib_param.dig_t3)) /
16384;
dev->calib_param.t_fine = var1 + var2;
温度计算中更新了校准参数 _calib_param.tfine 。
int8_t bmp280_get_comp_pres_32bit(uint32_t *comp_pres, uint32_t uncomp_pres, const struct bmp280_dev *dev)
{
int32_t var1, var2;
int8_t rslt;
rslt = null_ptr_check(dev);
if (rslt == BMP280_OK)
{
var1 = (((int32_t) dev->calib_param.t_fine) / 2) - (int32_t) 64000;
压力计算中会使用这个参数 _calib_param.tfine,所以压力获取不能单独仅仅计算压力,需要先计算温度,再计算压力才会准确;
您好, 我在STM32F412的板子上使用该软件包进行bmp280读取测试, 发现读出的数据和我用bmp085相差较大(bmp280为95, bmp085为103, 且bmp085为以前的量产产品), 为做验证, 我用裸机直接写了个驱动, 读取的数值与bmp085一致, 故猜测问题应该发生在该软件包内, 但我尚未发现问题所在.
不知是我使用不正确, 还是有其他原因, 是否有其他攻城狮遇到过?