电子说
项目简介
此次项目主要是基于PSOC6 英飞凌 PSoC™62 with CAPSENSE™ evaluation kit 实现OLED 显示温度、气压室内信息。
整体框架如下:
1.通过板载的dap 和uart 进行串口log 打印及程序刷写
2.通过I2C 进行BMP280 的驱动
3.通过I2C 进行oled SSD1306的显示
实现步骤
1.rtt 中添加 软件包
使能sensor 驱动 iic 驱动 uart驱动
2.默认的bmp280 包不能使用,由于使用最新的rt版本 不兼容,进行驱动层修改
#ifndef SENSOR_BS_BMP280_H__
#define SENSOR_BS_BMP280_H__
#include "drivers/sensor.h"
#include "bmp280.h"
#define BMP280_ADDR_DEFAULT BMP280_I2C_ADDR_SEC
#define BMP280_I2CBUS_NAME "i2c1"
int rt_hw_bmp280_init(const char *name, struct rt_sensor_config *cfg);
#endif
定义I2C bus名称
定义BMP280 默认地址
硬件初始化
static struct rt_sensor_ops sensor_ops =
{
_bmp280_fetch_data,
_bmp280_control
};
int rt_hw_bmp280_init(const char *name, struct rt_sensor_config *cfg)
{
int result;
rt_sensor_t sensor_pres = RT_NULL, sensor_temp = RT_NULL;
result = _rt_bmp280_init(&cfg->intf);
if (result != RT_EOK)
{
LOG_E("_rt_bmp280_init err code: %d", result);
return -RT_ERROR;
}
else
{
sensor_pres = rt_calloc(1, sizeof(struct rt_sensor_device));
if (sensor_pres == RT_NULL)
{
LOG_E("rt_calloc error");
return -RT_ERROR;
}
sensor_pres->info.type = RT_SENSOR_TYPE_BARO;
sensor_pres->info.vendor = RT_SENSOR_VENDOR_BOSCH;
sensor_pres->info.name = "bmp280_pres";
sensor_pres->info.unit = RT_SENSOR_UNIT_PA;
sensor_pres->info.intf_type = RT_SENSOR_INTF_I2C;
sensor_pres->info.scale.range_max = SENSOR_PRES_RANGE_MAX;
sensor_pres->info.scale.range_min = SENSOR_PRES_RANGE_MIN;
//sensor_pres->info.period_min = 0;
rt_memcpy(&sensor_pres->config, cfg, sizeof(struct rt_sensor_config));
sensor_pres->ops = &sensor_ops;
result = rt_hw_sensor_register(sensor_pres, name, RT_DEVICE_FLAG_RDWR, (void *)RT_NULL);
if (result != RT_EOK)
{
LOG_E("device register err code: %d", result);
goto __exit;
}
sensor_temp = rt_calloc(1, sizeof(struct rt_sensor_device));
if (sensor_temp == RT_NULL)
{
LOG_E("rt_calloc error");
goto __exit;
}
sensor_temp->info.type = RT_SENSOR_TYPE_TEMP;
sensor_temp->info.vendor = RT_SENSOR_VENDOR_BOSCH;
sensor_temp->info.name = "bmp280_temp";
sensor_temp->info.unit = RT_SENSOR_UNIT_CELSIUS;
sensor_temp->info.intf_type = RT_SENSOR_INTF_I2C;
sensor_temp->info.scale.range_max = SENSOR_TEMP_RANGE_MAX;
sensor_temp->info.scale.range_min = SENSOR_TEMP_RANGE_MIN;
//sensor_temp->info.period_min = 0;
rt_memcpy(&sensor_temp->config, cfg, sizeof(struct rt_sensor_config));
sensor_temp->ops = &sensor_ops;
result = rt_hw_sensor_register(sensor_temp, name, RT_DEVICE_FLAG_RDWR, RT_NULL);
if (result != RT_EOK)
{
LOG_E("device register err code: %d", result);
goto __exit;
}
}
LOG_I("bmp280_sensor init success");
return RT_EOK;
__exit:
if (sensor_pres)
rt_free(sensor_pres);
if (sensor_temp)
rt_free(sensor_temp);
return -RT_ERROR;
}
rt_sensor_info 结构体改变了很多,需要根据sensor 驱动进行相应的修改
设置 bmp 280 更新速度
static rt_err_t _bmp280_set_odr(rt_sensor_t sensor, rt_uint32_t args)
{
int8_t rslt;
struct bmp280_config conf;
if(args==1||args==2||args==4||args==8||args==16||args==2048||args==BMP280_ODR_2000_MS||args==BMP280_ODR_4000_MS)
{
rslt = bmp280_get_config(&conf, &bmp);
if(rslt!=BMP280_OK)
{
print_rslt(" bmp280_get_config status", rslt);
return -RT_ERROR;
}
switch(args)
{
case 1 : conf.odr = BMP280_ODR_1000_MS; break;
case 2 : conf.odr = BMP280_ODR_500_MS; break;
case 4 : conf.odr = BMP280_ODR_250_MS; break;
case 8 : conf.odr = BMP280_ODR_125_MS; break;
case 16 : conf.odr = BMP280_ODR_62_5_MS; break;
case 2048 : conf.odr = BMP280_ODR_0_5_MS; break;
case BMP280_ODR_2000_MS : conf.odr = BMP280_ODR_2000_MS; break;
case BMP280_ODR_4000_MS : conf.odr = BMP280_ODR_4000_MS; break;
default: return -RT_ERROR;
}
rslt = bmp280_set_config(&conf, &bmp);
if(rslt!=BMP280_OK)
{
print_rslt(" bmp280_set_config status", rslt);
return -RT_ERROR;
}
return RT_EOK;
}
else
{
// LOG_E("only 1,2,4,8,16,2048,BMP280_ODR_2000_MS,BMP280_ODR_4000_MS could set");
return -RT_ERROR;
}
}
最新版本的sensor control 去掉了好多控制,做了相应的注释
static rt_err_t _bmp280_control(struct rt_sensor_device *sensor, int cmd, void *args)
{
rt_err_t result = RT_EOK;
switch (cmd)
{
case RT_SENSOR_CTRL_GET_ID:
result = _bmp280_get_id(sensor,args);
break;
#if 0
case RT_SENSOR_CTRL_SET_RANGE:
result = -RT_ERROR;
break;
case RT_SENSOR_CTRL_SET_ODR:
result = _bmp280_set_odr(sensor,(rt_uint32_t)args & 0xffff);
break;
case RT_SENSOR_CTRL_SET_MODE:
break;
case RT_SENSOR_CTRL_SET_POWER:
result = _bmp280_set_POWER(sensor,(rt_uint32_t)args & 0xff);
break;
#endif
case RT_SENSOR_CTRL_SELF_TEST:
result = -RT_ERROR;
break;
default:
// LOG_E("only RT_SENSOR_CTRL_GET_ID,RT_SENSOR_CTRL_SET_POWER,RT_SENSOR_CTRL_SET_ODR could set");
return -RT_ERROR;
}
return result;
}
3.bmp280 app 初始化
#include
#include
#include
#include "sensor_bs_bmp280.h"
#define BMP_NAME "bmp280"
int bmp280_port(void)
{
struct rt_sensor_config cfg;
cfg.intf.dev_name = BMP280_I2CBUS_NAME;
rt_hw_bmp280_init("bmp280", &cfg);
return 0;
}
INIT_APP_EXPORT(bmp280_port);
上电log 打印可以看到device 已经注册成功
4.oled 显示驱动
oled 显示通过u8g2进行驱动,这里参考ssd1306 I2C 初始化过程 代码如下:
u8g2_t u8g2;
// Initialization
u8g2_Setup_ssd1306_i2c_128x64_noname_f( &u8g2, U8G2_R0, u8x8_byte_sw_i2c, u8x8_gpio_and_delay_rtthread);
u8x8_SetPin(u8g2_GetU8x8(&u8g2), U8X8_PIN_I2C_CLOCK, OLED_I2C_PIN_SCL);
u8x8_SetPin(u8g2_GetU8x8(&u8g2), U8X8_PIN_I2C_DATA, OLED_I2C_PIN_SDA);
显示初始化前 ,先寻找驱动
rt_device_t temp_dev =RT_NULL;
rt_device_t baro_dev =RT_NULL;
rt_size_t res =0;
temp_dev = rt_device_find(BMP_TEMP);
if(temp_dev == RT_NULL)
{
rt_kprintf("can not find bmp280 tempn");
return ;
}
baro_dev = rt_device_find(BMP_BARO);
if(temp_dev == RT_NULL)
{
rt_kprintf("can not find bmp280 baron");
return ;
}
if (rt_device_open(temp_dev, RT_DEVICE_FLAG_RDWR) != RT_EOK) {
rt_kprintf("open device failed!n");
return;
}
if (rt_device_open(baro_dev, RT_DEVICE_FLAG_RDWR) != RT_EOK) {
rt_kprintf("open device failed!n");
return;
}
然后显示线程的主循环中按一定的间隔进行sensor 数据读取,然后更新显示到oled 上
res = rt_device_read(temp_dev, 0, &temp_data, 1);
if (res != 1) {
rt_kprintf("read data failed!size is %dn", res);
rt_device_close(temp_dev);
return;
}
res = rt_device_read(baro_dev, 0, &baro_data, 1);
if (res != 1) {
rt_kprintf("read data failed!size is %dn", res);
rt_device_close(baro_dev);
return;
}
u8g2_ClearBuffer(&u8g2);
u8g2_DrawStr(&u8g2, 12, 12, "psoc6 demo");
temp_int =temp_data.data.temp;
//sprintf(buf,"temp:%.2f C",temp_data.data.temp);
sprintf(buf,"temp:%d.%d C",temp_int /10,temp_int %10);
u8g2_DrawStr(&u8g2, 32, 40, buf);
sprintf(buf,"baro:%.0fPa",baro_data.data.baro );
u8g2_DrawStr(&u8g2, 32, 56, buf);
u8g2_SendBuffer(&u8g2);
rt_thread_mdelay(100);
全部0条评论
快来发表一下你的评论吧 !