diff --git a/User/device/bmp280_i2c.c b/User/device/bmp280_i2c.c new file mode 100644 index 0000000..1cac0f2 --- /dev/null +++ b/User/device/bmp280_i2c.c @@ -0,0 +1,301 @@ +#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; +} diff --git a/User/device/bmp280_i2c.h b/User/device/bmp280_i2c.h new file mode 100644 index 0000000..9ec329d --- /dev/null +++ b/User/device/bmp280_i2c.h @@ -0,0 +1,49 @@ +#pragma once + +/*底层接口定义*/ +#include "bsp/i2c.h" +#include "stdint.h" + +#define BMP280_I2C_ADDR 0x76 // BMP280 默认 I2C 地址 + +/*寄存器地址*/ +#define BMP280_ID 0xD0 // 设备ID地址 +#define BMP280_RESET 0xE0 // 设备重启 +#define BMP280_STATUS 0xF3 // 设备状态 +#define BMP280_CTRL_MEAS 0xF4 // 数据采集和模式设置 +#define BMP280_CONFIG 0xF5 // 采样速率,滤波器和接口设置 +#define BMP280_DIGT 0x88 // 温度校准系数起始位置 +#define BMP280_DIGP 0x8E // 气压校准系数起始位置 +#define BMP280_TEMP 0xFA // 温度储存起始位置 +#define BMP280_PRES 0xF7 // 气压储存起始位置 + +#define BMP2_CHIP_ID 0x58 // 设备ID地址 + +#define bmp280_msblsb_to_u16(msb, lsb) (((uint16_t)msb << 8) | ((uint16_t)lsb)) + +typedef struct { + unsigned short dig_t1; + signed short dig_t2; + signed short dig_t3; + unsigned short dig_p1; + signed short dig_p2; + signed short dig_p3; + signed short dig_p4; + signed short dig_p5; + signed short dig_p6; + signed short dig_p7; + signed short dig_p8; + signed short dig_p9; +} bmp280_calib; + +uint8_t bmp280_get_id(void); +uint8_t bmp280_reset(void); +uint8_t bmp280_getStatus(void); +uint8_t bmp280_setMode(uint8_t mode); +uint8_t bmp280_setOversampling(uint8_t osrs_p, uint8_t osrs_t); +uint8_t bmp280_setConfig(uint8_t Standbyt, uint8_t filter); +void bmp280_getCalibration(bmp280_calib *calib); +void bmp280_getTemperature(bmp280_calib *calib, double *temperature, int32_t *t_fine); +void bmp280_getPressure(bmp280_calib *calib, double *pressure, int32_t *t_fine); +uint8_t bmp280_init(bmp280_calib *calib); +void bmp280_getdata(bmp280_calib *calib, float *temperature, float *pressure);