大气压计BMP280+BME280+BMP180 在ESP8266 (RTOS3.2)上初调的兼容驱动

  • 大气压计BMP280简介
  • 基础环境
  • 软件原理示意图
  • 数据打印效果
  • 传感器配置参数
  • 代码结构

大气压计BMP280简介

BMP280是一款博世的气压传感器,主要是测量环境大气压强的,量程是300hPa~1100hPa,这个什么概念,海平面气压,即标准大气压是1013.25hPa,海拔近似0,珠穆朗玛海拔8844米,大气压大约在304hPa,和市面上大气压计差不多,每1hPa换算成垂直高度8.43米,具体海拔和气压的关系图如下:

BMP280传感器从名称上看是停产了的BMP180(End of lifetime)的升级款,对比来看,BMP280在绝对精度上提升大约2~4倍,IO口电压BMP280已覆盖了1.2V的电压,适用性会更好些。

另外看手册BME280BMP280除了增加检测湿度的功能外,其他操作是一样的,顺便把湿度的一起加上了,做了一个根据ID判断的兼容程序。

BMP180的驱动相对简单,和BMP085相差不多,但与BME280或BMP280不通用,旧产品。

基础环境

  1. 硬件是esp8266+BMP280模块,通过I2C连接并通讯, 顺便测试了下BMP180;
  2. 软件方面是乐鑫带的RTOSv3.2,本次使用案例工程里I2C例程修改的;
  3. 博世官方的BME280、BMP280、BMP180驱动程序;

由于没有BME280模块测试,只是根据datasheet添加了读取湿度逻辑,没有实际测试,理论上是OK的。

软件原理示意图

  1. BMP280/BME280的Forced模式逻辑:
mode=0x01
读完自动转化状态
初始化IC
读取检验数据
Sleep模式
Forced模式读数据
  1. BMP280/BME280的Normal 模式逻辑:
mode=0x11
mode=0x00
初始化IC
读取检验数据
Sleep模式
Normal 模式读取数据
  1. BMP180的操作流程
初始化IC
读取检验数据
设置读温度模式
读温度ADC值
检验出实际温度
设置读大气压模式
读大气压ADC值
检验出实际数据

数据打印效果

BMP280的打印,内容有识别到的IC型号,参考温度,大气压的数值(hPa):

BME280:
未测

BMP180的数据打印,内容有识别到型号,温度,大气压数值(Pa),已知的当前检验海拔重新校验标准大气压数值,当前参考的海拔高度:

传感器配置参数

  1. I2C地址用的7位地址0x77,我把SDO上拉了,如果下拉或悬空会是0x76:
#define BMX280_I2C_ADDR 0x77
  1. 基本我放在了i2c_task_bme280_bmp280_bmp180初始化函数里面,做了一些变量,作为方便可配置.
    uint8_t osrs_t = 1;             //Temperature oversampling x 1uint8_t osrs_p = 1;             //Pressure oversampling x 1uint8_t osrs_h = 1;             //Humidity oversampling x 1uint8_t mode = 0;               //Sleep modeuint8_t t_sb = 7;               //Tstandby 4000msuint8_t filter = 0;             //Filter offuint8_t spi3w_en = 0;           //3-wire SPI Disable
  1. BMP180的配置简单,只要改下模式就可以:
static uint8_t bmp180_mode = BMP180_OSS_1TIMES_RATE;

代码结构

代码分成3部分的文件,主文件、BMXx80驱动文件、标准I2C协议封装文件:

  • main.c

    • BME280_BMP280_BMP180.c
    • BME280_BMP280_BMP180.h
      • my_iic.h
      • my_iic.c
  1. main.c:
/* mainThis example code is in the Public Domain (or CC0 licensed, at your option.)Unless required by applicable law or agreed to in writing, thissoftware is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES ORCONDITIONS OF ANY KIND, either express or implied.
*/#include <stdio.h>
#include <string.h>
#include <stdlib.h>#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"#include "esp_log.h"
#include "esp_system.h"
#include "esp_err.h"#include "driver/i2c.h"
#include "BME280_BMP280_BMP180.h"void app_main(void)
{//start i2c taskxTaskCreate(i2c_task_bme280_bmp280_bmp180, "i2c_task_bme280_bmp280_bmp180", 2048, NULL, 10, NULL);
}
  1. BME280_BMP280_BMP180.h:
/* BME280 BMP280 BMX180 exampleThis example code is in the Public Domain (or CC0 licensed, at your option.)Unless required by applicable law or agreed to in writing, thissoftware is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES ORCONDITIONS OF ANY KIND, either express or implied.
*/#include <stdio.h>
#include <string.h>
#include <stdlib.h>#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"#include "esp_log.h"
#include "esp_system.h"
#include "esp_err.h"#include "my_iic.h"#define BMX280_I2C_ADDR 0x77#define BMP180_CHIP_ID 0x55#define BMP280_CHIP_ID 0x58
#define BME280_CHIP_ID 0x60
#define BMX280_RESET_VALUE 0xB6#define BMP280_DIG_AC1_MSB_REG               0xAA#define BMP280_DIG_T1_LSB_REG                0x88
#define BMP280_DIG_H1_LSB_REG                0xA1
#define BMP280_DIG_H2_LSB_REG                0xE1#define BMX280_CHIPID_REG                    0xD0  /*Chip ID Register */
#define BMX280_RESET_REG                     0xE0  /*Softreset Register */
#define BME280_CTRLHUM_REG                   0xF2  /*Ctrl Humidity Register */
#define BMX280_STATUS_REG                    0xF3  /*Status Register */
#define BMX280_CTRLMEAS_REG                  0xF4  /*Ctrl Measure Register */
#define BMX280_CONFIG_REG                    0xF5  /*Configuration Register */
#define BMX280_PRESSURE_MSB_REG              0xF7  /*Pressure MSB Register */
#define BMX280_PRESSURE_LSB_REG              0xF8  /*Pressure LSB Register */
#define BMX280_PRESSURE_XLSB_REG             0xF9  /*Pressure XLSB Register */
#define BMX280_TEMPERATURE_MSB_REG           0xFA  /*Temperature MSB Reg */
#define BMX280_TEMPERATURE_LSB_REG           0xFB  /*Temperature LSB Reg */
#define BMX280_TEMPERATURE_XLSB_REG          0xFC  /*Temperature XLSB Reg */#define BMP180_OSS_1TIMES_RATE  0    /* wait 4.5ms */
#define BMP180_OSS_2TIMES_RATE  1    /* wait 7.5ms */
#define BMP180_OSS_4TIMES_RATE  2    /* wait 13.5ms */
#define BMP180_OSS_8TIMES_RATE  3    /* wait 25.5ms */#define BMP180_START_CONVERSION     1<<5#define BMP180_READ_TEMPERATURE     0x0e
#define BMP180_READ_PRESSURE        0x14#define BMP180_DATA_MSB_REG         0xF6    /* MSB Reg */
#define BMP180_DATA_LSB_REG         0xF7    /* LSB Reg */
#define BMP180_DATA_XLSB_REG        0xF8    /* XLSB Reg */void i2c_task_bme280_bmp280_bmp180(void *arg);
  1. BME280_BMP280_BMP180.c:
/* BME280 BMP280 BMX180 exampleThis example code is in the Public Domain (or CC0 licensed, at your option.)Unless required by applicable law or agreed to in writing, thissoftware is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES ORCONDITIONS OF ANY KIND, either express or implied.
*/#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>#include "BME280_BMP280_BMP180.h"static const char *TAG = "BME280_BMP280_BMP180";/**
*   code auto select ic
*   0->BMP280
*   1->BME280
*   2->BMP180
*/
static uint8_t sensor_type =0;static uint8_t bmp180_mode =BMP180_OSS_1TIMES_RATE;static unsigned long int hum_raw, temp_raw, pres_raw;
static signed long int t_fine;static uint16_t dig_T1;
static int16_t dig_T2;
static int16_t dig_T3;
static uint16_t dig_P1;
static int16_t dig_P2;
static int16_t dig_P3;
static int16_t dig_P4;
static int16_t dig_P5;
static int16_t dig_P6;
static int16_t dig_P7;
static int16_t dig_P8;
static int16_t dig_P9;
static int8_t  dig_H1;
static int16_t dig_H2;
static int8_t  dig_H3;
static int16_t dig_H4;
static int16_t dig_H5;
static int8_t  dig_H6;static int16_t dig_ac1;
static int16_t dig_ac2;
static int16_t dig_ac3;
static uint16_t dig_ac4;
static uint16_t dig_ac5;
static uint16_t dig_ac6;
static int16_t dig_b1;
static int16_t dig_b2;
static int16_t dig_mb;
static int16_t dig_mc;
static int16_t dig_md;
static int32_t dig_b5;/*  软复位芯片 */
static void chip_reset(i2c_port_t i2c_num)
{uint8_t rbuf = BMX280_RESET_VALUE;ESP_ERROR_CHECK(i2c_m_write(i2c_num,BMX280_RESET_REG, &rbuf, 1));vTaskDelay(100 / portTICK_RATE_MS);
}/**
*
*/
static void readTrim(i2c_port_t i2c_num)
{uint8_t data[32]= {0};if(sensor_type==2)  //select BMP180{ESP_ERROR_CHECK(i2c_m_read(i2c_num, BMP280_DIG_AC1_MSB_REG, &data[0], 22));dig_ac1 = (data[0] << 8) | data[1];dig_ac2 = (data[2] << 8) | data[3];dig_ac3 = (data[4] << 8) | data[5];dig_ac4 = (data[6] << 8) | data[7];dig_ac5 = (data[8] << 8) | data[9];dig_ac6 = (data[10] << 8) | data[11];dig_b1 = (data[12] << 8) | data[13];dig_b2 = (data[14] << 8) | data[15];dig_mb = (data[16] << 8) | data[17];dig_mc = (data[18] << 8) | data[19];dig_md = (data[20] << 8) | data[21];}else    //select BMP280 or BME280{ESP_ERROR_CHECK(i2c_m_read(i2c_num, BMP280_DIG_T1_LSB_REG, &data[0], 24));if (sensor_type == 1){ESP_ERROR_CHECK(i2c_m_read(i2c_num, BMP280_DIG_H1_LSB_REG, &data[24], 1));ESP_ERROR_CHECK(i2c_m_read(i2c_num, BMP280_DIG_H2_LSB_REG, &data[25], 7));dig_H1 = data[24];dig_H2 = (data[26] << 8) | data[25];dig_H3 = data[27];dig_H4 = (data[28] << 4) | (0x0F & data[29]);dig_H5 = (data[30] << 4) | ((data[29] >> 4) & 0x0F);dig_H6 = data[31];}dig_T1 = (data[1] << 8) | data[0];dig_T2 = (data[3] << 8) | data[2];dig_T3 = (data[5] << 8) | data[4];dig_P1 = (data[7] << 8) | data[6];dig_P2 = (data[9] << 8) | data[8];dig_P3 = (data[11] << 8) | data[10];dig_P4 = (data[13] << 8) | data[12];dig_P5 = (data[15] << 8) | data[14];dig_P6 = (data[17] << 8) | data[16];dig_P7 = (data[19] << 8) | data[18];dig_P8 = (data[21] << 8) | data[20];dig_P9 = (data[23] << 8) | data[22];}
}/** @brief init bme(p)280 chip 此处主要是启动芯片和做兼容判断
*   BME280多了湿度参数,处理数据时需要加上
*/
static esp_err_t bme280_bmp280_init(i2c_port_t i2c_num)
{uint8_t rbuf;uint8_t osrs_t = 1;             //Temperature oversampling x 1uint8_t osrs_p = 1;             //Pressure oversampling x 1uint8_t osrs_h = 1;             //Humidity oversampling x 1uint8_t mode = 0;               //Sleep modeuint8_t t_sb = 7;               //Tstandby 4000msuint8_t filter = 0;             //Filter offuint8_t spi3w_en = 0;           //3-wire SPI Disableuint8_t ctrl_meas_reg = (osrs_t << 5) | (osrs_p << 2) | mode;uint8_t config_reg    = (t_sb << 5) | (filter << 2) | spi3w_en;uint8_t ctrl_hum_reg  = osrs_h;i2c_addr = BMX280_I2C_ADDR;vTaskDelay(100 / portTICK_RATE_MS);i2c_master_init();/* 读芯片ID,做BME280和BMP280的兼容*/ESP_ERROR_CHECK(i2c_m_read(i2c_num, BMX280_CHIPID_REG, &rbuf, 1)); //idif (rbuf == BMP280_CHIP_ID){sensor_type = 0;ESP_LOGI(TAG, "Get BMP280 sensor...\n");}else if (rbuf == BME280_CHIP_ID){sensor_type = 1;ESP_LOGI(TAG, "Get BME280 sensor...\n");}else if (rbuf == BMP180_CHIP_ID){sensor_type = 2;ESP_LOGI(TAG, "Get BMP180 sensor...\n");}else{ESP_LOGE(TAG, "No chip id, Get fail sensor.....\n");}readTrim(i2c_num);chip_reset(i2c_num);/*手册提到只要2ms就可以启动,可根据时间情况加减 */vTaskDelay(4 / portTICK_RATE_MS);if (sensor_type == 1 )  //select  BME280{ESP_ERROR_CHECK(i2c_m_write(i2c_num,BME280_CTRLHUM_REG, &ctrl_hum_reg, 1));}if(sensor_type < 2 )    //select BMP280 or BME280{ESP_ERROR_CHECK(i2c_m_write(i2c_num,BMX280_CTRLMEAS_REG, &ctrl_meas_reg, 1));ESP_ERROR_CHECK(i2c_m_write(i2c_num,BMX280_CONFIG_REG, &config_reg, 1));/* 解决开机第一次数据不稳的问题 */vTaskDelay(2000 / portTICK_RATE_MS);}return ESP_OK;
}static signed long int calibration_T(signed long int adc_T)
{signed long int var1, var2, T;var1 = ((((adc_T >> 3) - ((signed long int)dig_T1 << 1))) * ((signed long int)dig_T2)) >> 11;var2 = (((((adc_T >> 4) - ((signed long int)dig_T1)) * ((adc_T >> 4) - ((signed long int)dig_T1))) >> 12) * ((signed long int)dig_T3)) >> 14;t_fine = var1 + var2;T = (t_fine * 5 + 128) >> 8;return T;
}static unsigned long int calibration_P(signed long int adc_P)
{signed long int var1, var2;unsigned long int P;var1 = (((signed long int)t_fine) >> 1) - (signed long int)64000;var2 = (((var1 >> 2) * (var1 >> 2)) >> 11) * ((signed long int)dig_P6);var2 = var2 + ((var1 * ((signed long int)dig_P5)) << 1);var2 = (var2 >> 2) + (((signed long int)dig_P4) << 16);var1 = (((dig_P3 * (((var1 >> 2) * (var1 >> 2)) >> 13)) >> 3) + ((((signed long int)dig_P2) * var1) >> 1)) >> 18;var1 = ((((32768 + var1)) * ((signed long int)dig_P1)) >> 15);if (var1 == 0){return 0;}P = (((unsigned long int)(((signed long int)1048576) - adc_P) - (var2 >> 12))) * 3125;if (P < 0x80000000){P = (P << 1) / ((unsigned long int) var1);}else{P = (P / (unsigned long int)var1) * 2;}var1 = (((signed long int)dig_P9) * ((signed long int)(((P >> 3) * (P >> 3)) >> 13))) >> 12;var2 = (((signed long int)(P >> 2)) * ((signed long int)dig_P8)) >> 13;P = (unsigned long int)((signed long int)P + ((var1 + var2 + dig_P7) >> 4));return P;
}static unsigned long int calibration_H(signed long int adc_H)
{signed long int v_x1;v_x1 = (t_fine - ((signed long int)76800));v_x1 = (((((adc_H << 14) - (((signed long int)dig_H4) << 20) - (((signed long int)dig_H5) * v_x1)) +((signed long int)16384)) >> 15) * (((((((v_x1 * ((signed long int)dig_H6)) >> 10) *(((v_x1 * ((signed long int)dig_H3)) >> 11) + ((signed long int) 32768))) >> 10) + (( signed long int)2097152)) *((signed long int) dig_H2) + 8192) >> 14));v_x1 = (v_x1 - (((((v_x1 >> 15) * (v_x1 >> 15)) >> 7) * ((signed long int)dig_H1)) >> 4));v_x1 = (v_x1 < 0 ? 0 : v_x1);v_x1 = (v_x1 > 419430400 ? 419430400 : v_x1);return (unsigned long int)(v_x1 >> 12);
}static void readData(i2c_port_t i2c_num)
{uint8_t data[8];if (sensor_type == 1 ){ESP_ERROR_CHECK(i2c_m_read(I2C_EXAMPLE_MASTER_NUM, BMX280_PRESSURE_MSB_REG, &data[0], 8));hum_raw  = (data[6] << 8) | data[7];}else{ESP_ERROR_CHECK(i2c_m_read(I2C_EXAMPLE_MASTER_NUM, BMX280_PRESSURE_MSB_REG, &data[0], 6));}pres_raw = (data[0] << 12) | (data[1] << 4) | (data[2] >> 4);temp_raw = (data[3] << 12) | (data[4] << 4) | (data[5] >> 4);}/* read uncompensated temperature value */
static uint16_t readUT(i2c_port_t i2c_num)
{uint8_t buf[2]= {0};//buf[0] = BMP180_READ_TEMPERATURE|BMP180_START_CONVERSION|(bmp180_mode<<6);buf[0] =0x2e;ESP_ERROR_CHECK(i2c_m_write(i2c_num, BMX280_CTRLMEAS_REG, &buf[0], 1));vTaskDelay(10 / portTICK_RATE_MS);ESP_ERROR_CHECK(i2c_m_read(i2c_num, BMP180_DATA_MSB_REG, buf, 2));return (buf[0]<<8|buf[1]);
}/* read uncompensated pressure value */
static int32_t readUP(i2c_port_t i2c_num)
{uint8_t buf[3]= {0};int32_t wait_time = 40;int32_t ret = 0;if(bmp180_mode ==0){wait_time=10;}else if(bmp180_mode ==1){wait_time=20;}else if(bmp180_mode ==2){wait_time=30;}else if(bmp180_mode ==3){wait_time=40;}buf[0] = BMP180_READ_PRESSURE | BMP180_START_CONVERSION | (bmp180_mode<<6);ESP_ERROR_CHECK(i2c_m_write(i2c_num, BMX280_CTRLMEAS_REG, &buf[0], 1));vTaskDelay(wait_time / portTICK_RATE_MS);ESP_ERROR_CHECK(i2c_m_read(i2c_num, BMP180_DATA_MSB_REG, buf, 3));ret =  (buf[0]<<16|buf[1]<<8|buf[0])>>(8-bmp180_mode);return ret;
}int32_t computeB5(int32_t ut)
{int32_t x1, x2;x1 = (((long)ut - (long)dig_ac6)*(long)dig_ac5) >> 15;x2 = ((long)dig_mc << 11)/(x1 + dig_md);return x1 + x2;
}// Calculate temperature in deg C
static float calculateTrueTemperature(void)
{float temp;int32_t ut;ut = readUT(I2C_EXAMPLE_MASTER_NUM);dig_b5  = computeB5(ut);temp = ((dig_b5 + 8)>>4);temp /= 10;return temp;
}// Calculate pressure given up
// calibration values must be known
// b5 is also required so bmp085GetTemperature(...) must be called first.
// Value returned will be pressure in units of Pa.
static int32_t calculateTruePressure(void)
{int32_t up, x1, x2, x3, b3, b6, p;uint32_t b4, b7;up = readUP(I2C_EXAMPLE_MASTER_NUM);b6 = dig_b5 - 4000;// Calculate B3x1 = ((int)dig_b2 * (b6 * b6)>>12)>>11;x2 = ((int)dig_ac2 * b6)>>11;x3 = x1 + x2;b3 = (((((int)dig_ac1)*4 + x3)<<bmp180_mode) + 2)>>2;// Calculate B4x1 = ((int)dig_ac3 * b6)>>13;x2 = ((int)dig_b1 * ((b6 * b6)>>12))>>16;x3 = ((x1 + x2) + 2)>>2;b4 = ((unsigned int)dig_ac4 * (unsigned long)(x3 + 32768))>>15;b7 = (((unsigned int)up - b3) * (unsigned int)(50000>>bmp180_mode));if (b7 < 0x80000000)p = (b7<<1)/b4;elsep = (b7/b4)<<1;x1 = (p>>8) * (p>>8);x1 = (x1 * 3038)>>16;x2 = (-7357 * p)>>16;p += (x1 + x2 + 3791)>>4;return p;
}int32_t calcSealevelPressure(float altitude_meters)
{float pressure = calculateTruePressure();return (int32_t)(pressure / pow(1.0-altitude_meters/44330, 5.255));
}float calcAltitude(int32_t pressure)
{float A = (float)pressure/101325.0f;float B = 1.0f/5.25588f;float C = pow(A,B);C = 1.0f - C;C *= 44330.0f;return C;
}void i2c_task_bme280_bmp280_bmp180(void *arg)
{uint8_t rbuf;double temp_act = 0.0, press_act = 0.0, hum_act = 0.0;signed long int temp_cal;unsigned long int press_cal = 0;unsigned long int hum_cal = 0;int32_t pressure;int32_t atm = 0; // "standard atmosphere"float altitude = 0; //Uncompensated caculation - in Meters//int32_t temp_udata;float temp_fdata;/* For print flaot data*/int32_t for_print_temp,for_print_temp1;bme280_bmp280_init(I2C_EXAMPLE_MASTER_NUM);while(1){if(sensor_type <2)  //select BMP280 or BME280{// Set forced mode again and again.ESP_ERROR_CHECK(i2c_m_read(I2C_EXAMPLE_MASTER_NUM, BMX280_CTRLMEAS_REG, &rbuf, 1)); //statusvTaskDelay(4 / portTICK_RATE_MS);rbuf &= (~0x03);rbuf &= 0xff;rbuf |= 0x1;// write to Forced modeESP_ERROR_CHECK(i2c_m_write(I2C_EXAMPLE_MASTER_NUM, BMX280_CTRLMEAS_REG, &rbuf, 1));vTaskDelay(20 / portTICK_RATE_MS);//status 不为0时,可能数据没有准备好,或数据不稳定ESP_ERROR_CHECK(i2c_m_read(I2C_EXAMPLE_MASTER_NUM,BMX280_STATUS_REG, &rbuf, 1));if (rbuf != 0){ESP_LOGE(TAG, "Data not ready.. skip [status =0x%02x]\n", rbuf);vTaskDelay(30000 / portTICK_RATE_MS);}else{readData(I2C_EXAMPLE_MASTER_NUM);temp_cal = calibration_T(temp_raw);press_cal = calibration_P(pres_raw);temp_act = (double)temp_cal / 100.0;press_act = (double)press_cal / 100.0;for_print_temp = (int)temp_act;for_print_temp1 = (int)press_act;ESP_LOGI(TAG, "TEMP : %d.%d°C PRESS : %d.%dhPa ",for_print_temp,(int)((temp_act-for_print_temp)*100),for_print_temp1, (int)((press_act-for_print_temp1)*100));if (sensor_type == 1 )   //BME280{hum_cal = calibration_H(hum_raw);hum_act = (double)hum_cal / 1024.0;for_print_temp = (int)hum_act;ESP_LOGI(TAG,"HUM : %d.%d%%\n",for_print_temp, (int)((hum_act-for_print_temp)*100));}else    //BMP280{//ESP_LOGI(TAG, " \n");}vTaskDelay(60000 / portTICK_RATE_MS);}}else    //select BMP180{temp_fdata = calculateTrueTemperature();pressure = calculateTruePressure();atm = calcSealevelPressure(200.0f);//200 meters's pressurealtitude =  calcAltitude(pressure);for_print_temp = (int)temp_fdata;ESP_LOGI(TAG,"temperature : %d.%dC\n",for_print_temp, (int)((temp_fdata - for_print_temp)*100));ESP_LOGI(TAG,"pressure : %dPa\n",pressure);ESP_LOGI(TAG,"If the altitude of this place is 200 meters,standard atmosphere is %dPa \n",atm);for_print_temp = (int)altitude;ESP_LOGI(TAG,"altitude: %d.%dm\n",for_print_temp, (int)((altitude - for_print_temp)*100));vTaskDelay(5000 / portTICK_RATE_MS);}}i2c_driver_delete(I2C_EXAMPLE_MASTER_NUM);
}
  1. my_iic.h:
/* I2C exampleThis example code is in the Public Domain (or CC0 licensed, at your option.)Unless required by applicable law or agreed to in writing, thissoftware is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES ORCONDITIONS OF ANY KIND, either express or implied.
*/#include <stdio.h>
#include <string.h>
#include <stdlib.h>#include "driver/i2c.h"/*** TEST CODE BRIEF** This example will show you how to use I2C module by running two tasks on i2c bus:** - read external i2c sensor, here we use a BME280 & BMP280 sensor for instance.* - Use one I2C port(master mode) to read or write the other I2C port(slave mode) on one ESP8266 chip.** Pin assignment:** - master:*    GPIO14 is assigned as the data signal of i2c master port*    GPIO2 is assigned as the clock signal of i2c master port** Connection:** - connect sda/scl of sensor with GPIO14/GPIO2* - no need to add external pull-up resistors, driver will enable internal pull-up resistors.** Test items:** - read the sensor data, if connected.*/#define I2C_EXAMPLE_MASTER_SCL_IO           2                /*!< gpio number for I2C master clock */
#define I2C_EXAMPLE_MASTER_SDA_IO           14               /*!< gpio number for I2C master data  */
#define I2C_EXAMPLE_MASTER_NUM              I2C_NUM_0        /*!< I2C port number for master dev */
#define I2C_EXAMPLE_MASTER_TX_BUF_DISABLE   0                /*!< I2C master do not need buffer */
#define I2C_EXAMPLE_MASTER_RX_BUF_DISABLE   0                /*!< I2C master do not need buffer */#define WRITE_BIT                           I2C_MASTER_WRITE /*!< I2C master write */
#define READ_BIT                            I2C_MASTER_READ  /*!< I2C master read */
#define ACK_CHECK_EN                        0x1              /*!< I2C master will check ack from slave*/
#define ACK_CHECK_DIS                       0x0              /*!< I2C master will not check ack from slave */
#define ACK_VAL                             0x0              /*!< I2C ack value */
#define NACK_VAL                            0x1              /*!< I2C nack value */
#define LAST_NACK_VAL                       0x2              /*!< I2C last_nack value */uint8_t i2c_addr;esp_err_t i2c_master_init();
esp_err_t i2c_m_write(i2c_port_t i2c_num, uint8_t reg_address, uint8_t *data, size_t data_len);
esp_err_t i2c_m_read(i2c_port_t i2c_num, uint8_t reg_address, uint8_t *data, size_t data_len);
  1. my_iic.c:
/* BMP280&BME280 sensor pressure exampleThis example code is in the Public Domain (or CC0 licensed, at your option.)Unless required by applicable law or agreed to in writing, thissoftware is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES ORCONDITIONS OF ANY KIND, either express or implied.
*/#include "my_iic.h"/*** @brief i2c master initialization*/
esp_err_t i2c_master_init()
{int i2c_master_port = I2C_EXAMPLE_MASTER_NUM;i2c_config_t conf;conf.mode = I2C_MODE_MASTER;conf.sda_io_num = I2C_EXAMPLE_MASTER_SDA_IO;conf.sda_pullup_en = 0;conf.scl_io_num = I2C_EXAMPLE_MASTER_SCL_IO;conf.scl_pullup_en = 0;ESP_ERROR_CHECK(i2c_driver_install(i2c_master_port, conf.mode));ESP_ERROR_CHECK(i2c_param_config(i2c_master_port, &conf));return ESP_OK;
}/**
*    @brief follow the NXP I2C protocal write
*
* 1. send data
* ___________________________________________________________________________________________________
* | start | slave_addr + wr_bit + ack | write reg_address + ack | write data_len byte + ack  | stop |
* --------|---------------------------|-------------------------|----------------------------|------|
*
* @param i2c_num I2C port number
* @param reg_address slave reg address
* @param data data to send
* @param data_len data length
*
* @return
*     - ESP_OK Success
*     - ESP_ERR_INVALID_ARG Parameter error
*     - ESP_FAIL Sending command error, slave doesn't ACK the transfer.
*     - ESP_ERR_INVALID_STATE I2C driver not installed or not in master mode.
*     - ESP_ERR_TIMEOUT Operation timeout because the bus is busy.
*/
esp_err_t i2c_m_write(i2c_port_t i2c_num, uint8_t reg_address, uint8_t *data, size_t data_len)
{int ret;i2c_cmd_handle_t cmd = i2c_cmd_link_create();i2c_master_start(cmd);i2c_master_write_byte(cmd, i2c_addr << 1 | WRITE_BIT, ACK_CHECK_EN);i2c_master_write_byte(cmd, reg_address, ACK_CHECK_EN);i2c_master_write(cmd, data, data_len, ACK_CHECK_EN);i2c_master_stop(cmd);ret = i2c_master_cmd_begin(i2c_num, cmd, 1000 / portTICK_RATE_MS);i2c_cmd_link_delete(cmd);return ret;
}/***  @brief follow the NXP I2C protocal read** 1. send reg address* ______________________________________________________________________* | start | slave_addr + wr_bit + ack | write reg_address + ack | stop |* --------|---------------------------|-------------------------|------|** 2. read data* ___________________________________________________________________________________* | start | slave_addr + wr_bit + ack | read data_len byte + ack(last nack)  | stop |* --------|---------------------------|--------------------------------------|------|** @param i2c_num I2C port number* @param reg_address slave reg address* @param data data to read* @param data_len data length** @return*     - ESP_OK Success*     - ESP_ERR_INVALID_ARG Parameter error*     - ESP_FAIL Sending command error, slave doesn't ACK the transfer.*     - ESP_ERR_INVALID_STATE I2C driver not installed or not in master mode.*     - ESP_ERR_TIMEOUT Operation timeout because the bus is busy.*/
esp_err_t i2c_m_read(i2c_port_t i2c_num, uint8_t reg_address, uint8_t *data, size_t data_len)
{int ret;i2c_cmd_handle_t cmd = i2c_cmd_link_create();i2c_master_start(cmd);i2c_master_write_byte(cmd, i2c_addr << 1 | WRITE_BIT, ACK_CHECK_EN);i2c_master_write_byte(cmd, reg_address, ACK_CHECK_EN);i2c_master_stop(cmd);ret = i2c_master_cmd_begin(i2c_num, cmd, 1000 / portTICK_RATE_MS);i2c_cmd_link_delete(cmd);if (ret != ESP_OK){return ret;}cmd = i2c_cmd_link_create();i2c_master_start(cmd);i2c_master_write_byte(cmd, i2c_addr << 1 | READ_BIT, ACK_CHECK_EN);i2c_master_read(cmd, data, data_len, LAST_NACK_VAL);i2c_master_stop(cmd);ret = i2c_master_cmd_begin(i2c_num, cmd, 1000 / portTICK_RATE_MS);i2c_cmd_link_delete(cmd);return ret;
}

大气压计BMP280+BME280+BMP180 在ESP8266 (RTOS3.2)上初调的兼容驱动相关推荐

  1. 乐鑫esp8266学习rtos3.0笔记第9篇:整理分享那些我在项目中常用的esp8266 rtos3.0版本的常见驱动,Button按键长短按、PWM平滑调光等。(附带demo)

    本系列博客学习由非官方人员 半颗心脏 潜心所力所写,仅仅做个人技术交流分享,不做任何商业用途.如有不对之处,请留言,本人及时更改. 1. Esp8266之 搭建开发环境,开始一个"hello ...

  2. 乐鑫esp8266学习rtos3.0笔记第4篇:带你捋一捋微信公众号 airkiss 配网 esp8266 并绑定设备的过程,移植并成功实现在 esp8266 rtos3.1 sdk。(附带demo)

    本系列博客学习由非官方人员 半颗心脏 潜心所力所写,仅仅做个人技术交流分享,不做任何商业用途.如有不对之处,请留言,本人及时更改. 1. Esp8266之 搭建开发环境,开始一个"hello ...

  3. ESP8266和双向可控硅在调速调光中的应用

    ESP8266和双向可控硅在调速调光中的应用 本文章基于ESP8266-10P上所写,只适合像我这样的小白看 微信名:you-yu 欢迎加好友讨论 过零检测 调速和调光分开来讲 先说调光 说说调速 调 ...

  4. 发挥大数据及其产业在推动发展方式转变上的作用

    大数据时代的到来,互联网成为基础设施,数据变成重要资源,这不仅意味着海量.多样.快速的数据处理和技术创新,更为重要的是改变了传统要素的组合方式.这种变化客观上要求必须转变传统的经济增长方式,实现创新驱 ...

  5. Science公布2020十大科学突破,AI预测蛋白结构等上榜 | AI日报

    2020 ACM杰出科学家名单出炉:智源学者叶杰平.崔鹏等26位华人学者上榜 近日,ACM(国际计算机协会)公布了2020年度ACM杰出科学家(Distinguished Member)名单! 今年全 ...

  6. indesign照片放入太大_猪肚鸡做法复杂,量太大,那来个简易版,用上大厨教的妙招更香了...

    [猪肚鸡做法复杂,量太大,那来个简易版,用上大厨教的妙招更香了]天气越来越冷了,今天准备炖鸡汤,正好老妈给了小半个已经处理好的猪肚,所以决定炖个简易版胡椒猪肚鸡.说实话外面的胡椒猪肚鸡做法是比较复杂的 ...

  7. 《大数据》2015年第2期“前沿”——大数据技术发展的十个前沿方向(上)

    大数据技术发展的十个前沿方向(上) 吴甘沙 英特尔中国研究院 doi:10.11959/j.issn.2096-0271.2015023 Ten Fronties for Big Data Techn ...

  8. 《真心话大冒险》微电影启动 张宁江献青涩初吻_0

    <真心话大冒险>微电影启动 张宁江献青涩初吻</div>            </script></div>            <div c ...

  9. 王家林大咖新书预发布:清华大学出版社即将出版《Spark大数据商业实战三部曲:内核解密|商业案例|性能调优》第二版 及《企业级AI技术内幕讲解》

    王家林大咖新书预发布:清华大学出版社即将出版<Spark大数据商业实战三部曲:内核解密|商业案例|性能调优>第二版,新书在第一版的基础上以Spark 2.4.3版本全面更新源码,并以Ten ...

  10. TML5期末大作业:奶茶饮料网站设计——Coco线上订奶茶饮料(6页) 关于饮料奶茶的HTML网页设计-----甜品

    HTML5期末大作业:奶茶饮料网站设计--Coco线上订奶茶饮料(6页) 关于饮料奶茶的HTML网页设计-----甜品 常见网页设计作业题材有 个人. 美食. 公司. 学校. 旅游. 电商. 宠物. ...

最新文章

  1. tomcat server.xml中文版
  2. 中科院计算所实习-深度学习方向
  3. CENTOS7 高性能Linux集群 通过yum进行 haproxy配置 !安装 !使用!HAProxy配置文件详解
  4. 【转】Android中dp,px,sp概念梳理以及如何做到屏幕适配
  5. CorrTracker解读
  6. java中线程的6种状态
  7. 58 到家数据库 30 条军规解读
  8. 基于JAVA+SpringMVC+Mybatis+MYSQL的汽车租赁系统
  9. 拓端tecdat|R语言基于温度对城市层次聚类、kmean聚类、主成分分析和Voronoi图可视化
  10. angular的运行机制_Angular开发实践(二):HRM运行机制
  11. 23hh小说网——爬虫0.1python
  12. 如何用excel做正交分析_excel表格分析正交数据处理-excel中怎么对正交试验进行F值检验...
  13. Invisible Backdoor Attack with Sample-Specific Triggers 论文笔记
  14. Windows没有应用商店情况安装英特尔集成显卡控制面板
  15. android 头像球_Android自定义View实现圆形头像效果
  16. 舰r最新服务器,战舰少女R官方网站—战舰少女-与心爱的舰娘一起守护这片海域...
  17. Java四大引用(强、软、弱、虚)
  18. 大众软件:2010中国电脑游戏产业报告
  19. 芯片破壁者(十九):显卡的战国与帝国
  20. Delphi Pdf的使用方法

热门文章

  1. 【Spring + Vue前后端分离】可商用的开源后台管理框架软件eladmin剖析
  2. 计算机财务模型管理实验内容,计算机财务管理实验报告详细分解.doc
  3. matlab信号探测,雷达信号检测matlab程序
  4. 分析图片相似度的软件,图片相似度比对算法
  5. lqr matlab,MATLAB中的LQR函数用法
  6. JS实现继承的几种方法总结
  7. 【滑动窗口协议模拟】
  8. 中州韵输入法 linux 小鹤双拼,Rime输入法配置——小鹤双拼
  9. 一文读懂单点登录系统对企业的价值
  10. 四纵四横客运专线(高铁)