#include "bmp280_i2c.h" #include "bsp/i2c.h" #define I2C_Handle BSP_I2C_GetHandle(BSP_I2C_BMP280) /** * @brief 读寄存器 * @param regAdd 寄存器开始地址 * @param pdata 存储数据的指针 * @param size 寄存器个数 * @retval 无 */ void bmp280_readReg(uint8_t regAdd, uint8_t *pdata, uint8_t size) { HAL_I2C_Mem_Read(I2C_Handle, BMP280_I2C_ADDR << 1, regAdd, I2C_MEMADD_SIZE_8BIT, pdata, size, 1000); } /** * @brief 写1个寄存器 * @param regAdd 寄存器开始地址 * @param pdata 存储数据的指针 * @retval 0 写入成功 * 1 写入失败 */ uint8_t bmp280_writeReg(uint8_t regAdd, uint8_t *pdata) { if (HAL_I2C_Mem_Write(I2C_Handle, BMP280_I2C_ADDR << 1, regAdd, I2C_MEMADD_SIZE_8BIT, pdata, 1, 1000) == HAL_OK) { return 0; } return 1; } /** * @brief 读取设备物理id,用于调试 * @param 无 * @retval 设备id */ uint8_t bmp280_get_id(void) { uint8_t temp = 0; bmp280_readReg(BMP280_ID, &temp, 1); return temp; } /** * @brief 重启设备 * @param 无 * @retval 0 重启成功 * 1 重启失败 */ uint8_t bmp280_reset(void) { uint8_t temp = 0xB6; return bmp280_writeReg(BMP280_RESET, &temp); } /** * @brief 获取设备状态 * @param 无 * @retval 0 空闲 * 1 正在测量或者正在复制 */ uint8_t bmp280_getStatus(void) { uint8_t temp = 0; bmp280_readReg(BMP280_STATUS, &temp, 1); return (temp & 0x09) ? 1 : 0; } /** * @brief 工作模式设置推荐 * @param mode 0 睡眠模式 * 1 单次测量模式,测量完成后回到休眠模式 * 2 连续测量模式 * @retval 0 设置成功 * 1 设置失败 */ uint8_t bmp280_setMode(uint8_t mode) { uint8_t temp=0; bmp280_readReg(BMP280_CTRL_MEAS,&temp,1); switch(mode) { case 0: temp&=0xFC; break; case 1: temp&=0xFC; temp|=0x01; break; case 2: temp&=0xFC; temp|=0x03; break; default: return 1; } return bmp280_writeReg(BMP280_CTRL_MEAS,&temp); } /** * @brief 过采样设置 * @param mode temp&press 0 禁用 * 1 过采样×1 * 2 过采样×2 * 3 过采样×4 * .. ..... * 5 过采样×16 * @retval 0 设置成功 * 1 设置失败 */ uint8_t bmp280_setOversampling(uint8_t osrs_p,uint8_t osrs_t) { uint8_t temp=0; bmp280_readReg(BMP280_CTRL_MEAS,&temp,1); temp&=0xE3; osrs_p = osrs_p<<2; osrs_p&= 0x1C; temp|=osrs_p; temp&=0x1F; osrs_t = osrs_t<<5; osrs_t&= 0xE0; temp|=osrs_t; return bmp280_writeReg(BMP280_CTRL_MEAS,&temp); } /** * @brief 滤波器系数和采样间隔时间设置 * @param Standbyt 0 0.5ms filter 0 关闭滤波器 * 1 62.5ms 1 2 * 2 125ms 2 4 * 3 250ms 3 8 * 4 500ms 4 16 * 5 1000ms * 6 2000ms * 7 4000ms * @retval 0 设置成功 * 1 设置失败 */ uint8_t bmp280_setConfig(uint8_t Standbyt,uint8_t filter) { uint8_t temp=0; temp = Standbyt<<5; filter&=0x07; filter=filter<<2; temp|=filter; return bmp280_writeReg(BMP280_CONFIG,&temp); } /** * @brief 获取校准系数 * @param calib 储存系数的结构体 * @retval 无 */ void bmp280_getCalibration(bmp280_calib *calib) { uint8_t buf[20]; bmp280_readReg(BMP280_DIGT,buf,6); calib->dig_t1 =(uint16_t)(bmp280_msblsb_to_u16(buf[1], buf[0])); calib->dig_t2 =(int16_t)(bmp280_msblsb_to_u16(buf[3], buf[2])); calib->dig_t3 =(int16_t)(bmp280_msblsb_to_u16(buf[5], buf[4])); bmp280_readReg(BMP280_DIGP,buf,18); calib->dig_p1 = (uint16_t)(bmp280_msblsb_to_u16(buf[1], buf[0])); calib->dig_p2 =(int16_t)(bmp280_msblsb_to_u16(buf[3], buf[2])); calib->dig_p3 =(int16_t)(bmp280_msblsb_to_u16(buf[5], buf[4])); calib->dig_p4 =(int16_t)(bmp280_msblsb_to_u16(buf[7], buf[6])); calib->dig_p5 =(int16_t)(bmp280_msblsb_to_u16(buf[9], buf[8])); calib->dig_p6 =(int16_t)(bmp280_msblsb_to_u16(buf[11], buf[10])); calib->dig_p7 =(int16_t)(bmp280_msblsb_to_u16(buf[13], buf[12])); calib->dig_p8 =(int16_t)(bmp280_msblsb_to_u16(buf[15], buf[14])); calib->dig_p9 =(int16_t)(bmp280_msblsb_to_u16(buf[17], buf[16])); } /** * @brief 获取温度 * @param calib 系数的结构体 * *temperature 温度值指针 * *t_fine 精细分辨率温度值指针 * @retval 无 */ void bmp280_getTemperature(bmp280_calib *calib,double *temperature,int32_t *t_fine) { uint8_t buf[3]; uint32_t data_xlsb; uint32_t data_lsb; uint32_t data_msb; int32_t uncomp_temperature; double var1, var2; bmp280_readReg(BMP280_TEMP,buf,3); data_msb = (int32_t)buf[0] << 12; data_lsb = (int32_t)buf[1] << 4; data_xlsb = (int32_t)buf[2] >> 4; uncomp_temperature = (int32_t)(data_msb | data_lsb | data_xlsb); var1 = (((double) uncomp_temperature) / 16384.0 - ((double) calib->dig_t1) / 1024.0) * ((double) calib->dig_t2); var2 = ((((double) uncomp_temperature) / 131072.0 - ((double) calib->dig_t1) / 8192.0) * (((double) uncomp_temperature) / 131072.0 - ((double) calib->dig_t1) / 8192.0)) * ((double) calib->dig_t3); *t_fine = (int32_t) (var1 + var2); *temperature = (var1 + var2) / 5120.0; } /** * @brief 获取气压 * @param calib 系数的结构体 * *pressure 气压值指针 * *t_fine 精细分辨率温度值指针 * @retval 无 */ void bmp280_getPressure(bmp280_calib *calib,double *pressure,int32_t *t_fine) { uint8_t buf[3]; uint32_t data_xlsb; uint32_t data_lsb; uint32_t data_msb; int32_t uncomp_pressure; double var1, var2; bmp280_readReg(BMP280_PRES,buf,3); data_msb = (uint32_t)buf[0] << 12; data_lsb = (uint32_t)buf[1] << 4; data_xlsb = (uint32_t)buf[2] >> 4; uncomp_pressure = (data_msb | data_lsb | data_xlsb); var1 = ((double) *t_fine / 2.0) - 64000.0; var2 = var1 * var1 * ((double) calib->dig_p6) / 32768.0; var2 = var2 + var1 * ((double) calib->dig_p5) * 2.0; var2 = (var2 / 4.0) + (((double) calib->dig_p4) * 65536.0); var1 = (((double)calib->dig_p3) * var1 * var1 / 524288.0 + ((double)calib->dig_p2) * var1) / 524288.0; var1 = (1.0 + var1 / 32768.0) * ((double) calib->dig_p1); *pressure = 1048576.0 - (double)uncomp_pressure; *pressure = (*pressure - (var2 / 4096.0)) * 6250.0 / var1; var1 = ((double)calib->dig_p9) * *pressure * *pressure / 2147483648.0; var2 = *pressure * ((double)calib->dig_p8) / 32768.0; *pressure = *pressure + (var1 + var2 + ((double)calib->dig_p7)) / 16.0; } /** * @brief 初始化 * @param *calib 系数的结构体指针 * @retval 0 设置成功 * 1 设置失败 */ uint8_t bmp280_init(bmp280_calib *calib) { uint8_t rslt; rslt = bmp280_get_id(); if(rslt == BMP2_CHIP_ID) { bmp280_getCalibration(calib); rslt = bmp280_setOversampling(5,2); if(rslt) { return 1; } rslt = bmp280_setConfig(0,4); if(rslt) { return 1; } rslt = bmp280_setMode(2); if(rslt) { return 1; } } else { return 1; } return 0; } /** * @brief 获取最终数据 * @param *calib 系数的结构体指针 * @retval 无 */ void bmp280_getdata(bmp280_calib *calib,float *temperature,float *pressure) { double temp_T,temp_P; int32_t t_fine; bmp280_getTemperature(calib,&temp_T,&t_fine); bmp280_getPressure(calib,&temp_P,&t_fine); *temperature = (float)temp_T; *pressure = (float)temp_P; }