资讯详情

【Renesas RA6M4开发板之I2C读取BMP180气压温度】

【Renesas RA6M4开发板之I2C读取BMP180气压温度】

  • 1.0 BMP180
    • 1.1 BMP180介绍
    • 1.2 BMP180特点
    • 1.3 产品应用
  • 2. RT-theard配置
    • 2.1 硬件需求
    • 2.2 软件配置
  • 3. 代码分析
  • 4. 下载验证

1.0 BMP180

在这里插入图片描述

本篇通过Renesas RA6M4开发板采用I2C读取BMP演示180传感器气压温度示例程序。

1.1 BMP180介绍

1、BMP180是一种高精度、小体积、低能耗的压力传感器,可用于移动设备; 2.精度低,可达0.03hPa; 3、BMP180采用强大的8-pin承载陶瓷无引线芯片(LCC)超薄包装,可通过I2C总线直接连接到各种微处理器

1.2 BMP180特点

1.压力范围:300-11000hPa(海拔9000米1500米) 2.电源电压:5V 3.低功耗:标准模式下5uA 4.高精度:低功耗模式下,分辨率为0.06hPa(0.5米) 5.在高线性模式下,分辨率为0.03hPa(0.25米) 6.带温度输出 7.I2C8.温度补偿 9.MSL1秒响应 10.待机电流:0.1uA 11.液体和反接电源需要在气体环境中工作

尺寸如下:

1.3 产品应用

1.GPS导航(航位计算、上下桥检测等) ⒉.室内外导航 3.休闲、体育等监测 4.天气预报 5.垂直速度指示(上升/下沉速度)

2. RT-theard配置

2.1 硬件需求

1、需要BMP在气体环境下采集气压和温度,I2C通讯接线,地址后面的仓库配置不需要注意,和ssd1306不同

实现功能: I2C读取BMP180传感器的气压温度

2、RA6M4开发板 3、USB下载线,ch340串口和6条母线,

2.2 软件配置

Renesas RA6M4开发板环境配置参考:基于 RT-Thread Studio的CPK-RA6M4 开发板环境建设】 1、新建项目RA6M4-bmp180工程

2、点击RT-theard Setting,在软件包下添加软件包,然后搜索bmp相关软件支持包,点击添加,然后出现相应的包。

3、配置ssd306,右键选择配置项

在软件包中打开示例程序。

5硬件中,启动I2C,设置端口SDA—p503;SCL—p504 6.保存所有刚性配置,更新当前配置文件

3. 代码分析

1.刚加载软件包packages文件夹下,bmp180.c和bmp180_sample.c示例代码更改如下 (或添加头文件#include "bsp_api.h",否则会报错unitx_t,根据提示全部改为rt_unitx_t也OK,以下是第二种方法。 bmp180.c

 /* * Copyright (c) 2020 panrui <https://github.com/Prry/rtt-bmp180> * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes * 2020-03-12 panrui the first version */   #include <rtthread.h> #include <rtdevice.h> #include <rtdbg.h> #include "sensor.h" #include "bmp180.h"  #define PKG_USING_BMP180  #ifdef PKG_USING_BMP180  #define BMP180_ADDR 0x77 /* i2c slave address */  #define BMP_REG_CHIP_ID 0xD0  #define BMP_REG_RESET 0xE0
#define BMP_REG_CTRL_ADDR 0xF4
#define BMP_REG_AD_MSB 0xF6
#define BMP_REG_AD_LSB 0xF7
#define BMP_REG_AD_XLSB 0xF8
#define BMS_CAL_AC1 0xAA

#define BMP_REG_CTRL_TEMP 0x2E
#define BMP_REG_CTRL_POSS0 0x34
#define BMP_REG_CTRL_POSS1 0x74
#define BMP_REG_CTRL_POSS2 0xB4
#define BMP_REG_CTRL_POSS3 0xF4
#define BMP_REG_RESET_VALUE 0xB6
		
#define BMP180_I2C_BUS "i2c1" /* i2c linked */
#define BMP180_DEVICE_NAME "bmp180" /* register device name */


/* bmp clalc param */
struct bmp180_calc
{ 
        
	short ac1;
	short ac2;
	short ac3;
	short b1;
	short b2;
	short mb;
	short mc;
	short md;
	unsigned short ac4;
	unsigned short ac5;
	unsigned short ac6;	
};

/* bmp180 private data */
struct bmp180_dev
{ 
        
	struct bmp180_calc calc_param;
	struct rt_i2c_bus_device *i2c_bus;	/* linked i2c bus */
};

static rt_err_t  bmp180_read_regs(rt_sensor_t psensor, rt_uint8_t reg, rt_uint8_t *data, rt_uint8_t data_size)
{ 
        
    struct rt_i2c_msg msg[2];
	struct bmp180_dev *dev = RT_NULL;
	struct rt_i2c_bus_device *i2c_bus = RT_NULL;
	rt_uint32_t slave_addr = 0;
	
	slave_addr = (rt_uint32_t)psensor->config.intf.user_data;	/* get i2c slave address */
	dev = (struct bmp180_dev*)psensor->parent.user_data;/* bmp180 private data */
	i2c_bus = (struct rt_i2c_bus_device*)dev->i2c_bus; /* get i2c bus device */
	
    msg[0].addr  = (rt_uint8_t)slave_addr;
    msg[0].flags = RT_I2C_WR;
    msg[0].len   = 1;
    msg[0].buf   = &reg;
    msg[1].addr  = (rt_uint8_t)slave_addr;
    msg[1].flags = RT_I2C_RD;
    msg[1].len   = data_size;
    msg[1].buf   = data;

    if(rt_i2c_transfer(i2c_bus, msg, 2) == 2)
	{ 
        
        return RT_EOK;
    }
    else
    { 
        
	  	LOG_E("i2c bus read failed!\r\n");
        return -RT_ERROR;
    }
}

static rt_err_t  bmp180_write_regs(rt_sensor_t psensor, rt_uint8_t reg, rt_uint8_t *data, rt_uint8_t data_size)
{ 
        
    struct rt_i2c_msg msg[2];
	struct bmp180_dev *dev = RT_NULL;
	struct rt_i2c_bus_device *i2c_bus;
	rt_uint32_t slave_addr = 0;

	slave_addr = (rt_uint32_t)psensor->config.intf.user_data;
	dev = (struct bmp180_dev*)psensor->parent.user_data;
	i2c_bus = (struct rt_i2c_bus_device*)dev->i2c_bus;  
	
    msg[0].addr		= (rt_uint8_t)slave_addr;
    msg[0].flags	= RT_I2C_WR;
    msg[0].len   	= 1;
    msg[0].buf   	= &reg;
    msg[1].addr  	= (rt_uint8_t)slave_addr;
    msg[1].flags	= RT_I2C_WR | RT_I2C_NO_START;
    msg[1].len   	= data_size;
    msg[1].buf   	= data;
    if(rt_i2c_transfer(i2c_bus, msg, 2) == 2)
	{ 
        
        return RT_EOK;
    }
    else
    { 
        
	  	LOG_E("i2c bus write failed!\r\n");
        return -RT_ERROR;
    }
}

static rt_err_t bmp180_write_reg(rt_sensor_t psensor, rt_uint8_t reg, rt_uint8_t data)
{ 
        
	return bmp180_write_regs(psensor, reg, &data, 1);
}

static long bmp180_read_ut(rt_sensor_t psensor)
{ 
        
    rt_uint8_t buf[2] = { 
        0};
	long   data = 0;
	
	bmp180_write_reg(psensor, BMP_REG_CTRL_ADDR, BMP_REG_CTRL_TEMP);
	rt_thread_delay(1);	/* max conversion time: 4.5ms */
	bmp180_read_regs(psensor, BMP_REG_AD_MSB, buf, 2);
	data = (buf[0]<<8) | buf[1];
	
	return data;
}

static long bmp180_read_up(rt_sensor_t psensor)
{ 
        
    rt_uint8_t buf[2] = { 
        0};
	long   data = 0;
	
	bmp180_write_reg(psensor, BMP_REG_CTRL_ADDR, BMP_REG_CTRL_POSS0);
	rt_thread_delay(1);	/* max conversion time: 4.5ms */
	bmp180_read_regs(psensor, BMP_REG_AD_MSB, buf, 2);
	data = (buf[0]<<8) | buf[1];
	
	return data;
}

static rt_size_t bmp180_polling_get_data(rt_sensor_t psensor, struct rt_sensor_data *sensor_data)
{ 
        
	long x1, x2, b5, b6, x3, b3, p;
	unsigned long b4, b7;
	short temperature=0;
	long ut,up,pressure=0;
	struct bmp180_dev *dev = RT_NULL;
	struct bmp180_calc *param = RT_NULL;
	
	ut = bmp180_read_ut(psensor);
	up = bmp180_read_up(psensor);
	
	
	dev = (struct bmp180_dev*)psensor->parent.user_data;/* bmp180 private data */
	param = &dev->calc_param;	/* get calc param */
	
	/* temperature calc */
	x1 = (((long)ut - (long)param->ac6)*(long)param->ac5) >> 15;
  	x2 = ((long)param->mc << 11) / (x1 + param->md);
  	b5 = x1 + x2;
  	temperature = ((b5 + 8) >> 4);

	/* pressure calc */
	b6 = b5 - 4000;
	x1 = (param->b2 * (b6 * b6)>>12)>>11;
	x2 = (param->ac2 * b6)>>11;
	x3 = x1 + x2;
	b3 = (((((long)param->ac1)*4 + x3)<<0) + 2)>>2;
	
	x1 = (param->ac3 * b6)>>13;
	x2 = (param->b1 * ((b6 * b6)>>12))>>16;
	x3 = ((x1 + x2) + 2)>>2;
	b4 = (param->ac4 * (unsigned long)(x3 + 32768))>>15;
	b7 = ((unsigned long)(up - b3) * (50000>>0));
	if (b7 < 0x80000000)
	{ 
        
		p = (b7<<1)/b4;
	}
	else
	{ 
        
		p = (b7/b4)<<1;
	}
	x1 = (p>>8) * (p>>8);
	x1 = (x1 * 3038)>>16;
	x2 = (-7357 * p)>>16;
	pressure = p+((x1 + x2 + 3791)>>4);	
	
	if(psensor->info.type == RT_SENSOR_CLASS_BARO)
	{ 
        /* actual barometric */
	  	sensor_data->type = RT_SENSOR_CLASS_BARO;
		sensor_data->data.baro = pressure;
		sensor_data->timestamp = rt_sensor_get_ts();
	}
	else if(psensor->info.type == RT_SENSOR_CLASS_TEMP)
	{ 
        /* actual temperature */
		sensor_data->type = RT_SENSOR_CLASS_TEMP;
		sensor_data->data.temp = temperature;
		sensor_data->timestamp = rt_sensor_get_ts();
	}
	else
	{ 
        
		return 0;
	}
	
    return 1;
}

static rt_size_t bmp180_fetch_data(struct rt_sensor_device *psensor, void *buf, rt_size_t len)
{ 
        
    RT_ASSERT(buf);
	RT_ASSERT(psensor);
	
	//if(psensor->parent.open_flag & RT_DEVICE_FLAG_RDONLY)
	if(psensor->config.mode == RT_SENSOR_MODE_POLLING)
	{ 
        
        return bmp180_polling_get_data(psensor, buf);
    }

    return 0;
}

static rt_err_t bmp180_control(struct rt_sensor_device *psensor, int cmd, void *args)
{ 
        
	rt_err_t	ret = RT_EOK;
    rt_uint8_t 	*chip_id;
	
    RT_ASSERT(psensor);

    switch (cmd)
    { 
        
    	/* read bmp180 id */
        case RT_SENSOR_CTRL_GET_ID:
		  	chip_id = (rt_uint8_t*)args;
	       	ret = bmp180_read_regs(psensor, BMP_REG_CHIP_ID, chip_id, 1);
        break;

        default:
        break;
	}
    return ret;
}

static struct rt_sensor_ops bmp180_ops =
{ 
        
    bmp180_fetch_data,
    bmp180_control,
};

int rt_hw_bmp180_init(const char *name, struct rt_sensor_config *cfg)
{ 
        
  	rt_err_t ret = RT_EOK;
	rt_sensor_t sensor_baro = RT_NULL, sensor_temp = RT_NULL;
    struct rt_sensor_module *module = RT_NULL;
	struct bmp180_dev 		*bmp180 = RT_NULL;
	rt_uint8_t bmbuf[22] = { 
        0};
	
	bmp180 = rt_calloc(1, sizeof(struct bmp180_dev));
	if(bmp180 == RT_NULL)
	{ 
        
	  	LOG_E("malloc memory failed\r\n");
		ret = -RT_ERROR;
		goto __exit;
	}
	
    bmp180->i2c_bus = rt_i2c_bus_device_find(cfg->intf.dev_name);
    if(bmp180->i2c_bus == RT_NULL)
    { 
        
        LOG_E("i2c bus device %s not found!\r\n", cfg->intf.dev_name);
		ret = -RT_ERROR;
		goto __exit;
    }	
	
	module = rt_calloc(1, sizeof(struct rt_sensor_device));
    if(module == RT_NULL)
	{ 
        
	  	LOG_E("malloc memory failed\r\n");
	  	ret = -RT_ERROR;
		goto __exit;
	}
	module->sen[0] = sensor_baro;
    module->sen[1] = sensor_temp;
    module->sen_num = 2;
	
	/* barometric pressure sensor register */
    { 
        
        sensor_baro = rt_calloc(1, sizeof(struct rt_sensor_device));
        if (sensor_baro == RT_NULL)
		{ 
        
		  	goto __exit;
		}
		rt_memset(sensor_baro, 0x0, sizeof(struct rt_sensor_device));
        sensor_baro->info.type       = RT_SENSOR_CLASS_BARO;
        sensor_baro->info.vendor     = RT_SENSOR_VENDOR_BOSCH;
        sensor_baro->info.model      = "bmp180_baro";
        sensor_baro->info.unit       = RT_SENSOR_UNIT_PA;
        sensor_baro->info.intf_type  = RT_SENSOR_INTF_I2C;
        sensor_baro->info.range_max  = 110000;	/* 1Pa */
        sensor_baro->info.range_min  = 30000;
        sensor_baro->info.period_min = 100;	/* read ten times in 1 second */

        rt_memcpy(&sensor_baro->config, cfg, sizeof(struct rt_sensor_config));
        sensor_baro->ops = &bmp180_ops;
        sensor_baro->module = module;
        
        ret = rt_hw_sensor_register(sensor_baro, name, RT_DEVICE_FLAG_RDWR, (void*)bmp180);
        if (ret != RT_EOK)
        { 
        
            LOG_E("device register err code: %d", ret);
            goto __exit;
        }
    }
    /* temperature sensor register */
    { 
        
        sensor_temp = rt_calloc(1, sizeof(struct rt_sensor_device));
        if (sensor_temp == RT_NULL)
		{ 
        
			goto __exit;
		}
		rt_memset(sensor_temp, 0x0, sizeof(struct rt_sensor_device));
        sensor_temp->info.type       = RT_SENSOR_CLASS_TEMP;
        sensor_temp->info.vendor     = RT_SENSOR_VENDOR_BOSCH;
        sensor_temp->info.model      = "bmp180_temp";
        sensor_temp->info.unit       = RT_SENSOR_UNIT_DCELSIUS;
        sensor_temp->info.intf_type  = RT_SENSOR_INTF_I2C;
        sensor_baro->info.range_max  = 850;	/* 0.1C */
        sensor_baro->info.range_min  = -400;
        sensor_temp->info.period_min = 100;	/* read ten times in 1 second */

        rt_memcpy(
        标签: 100mb温度传感器ts4温度传感器

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台