求一种基于Infineon的信息采集系统设计方案

电子说

1.3w人已加入

描述

项目简介

此次项目主要是基于PSOC6 英飞凌 PSoC™62 with CAPSENSE™ evaluation kit 实现OLED 显示温度、气压室内信息。

整体框架如下:

RTThread

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);

RTThread

上电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);
打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分