項(xiàng)目簡(jiǎn)介
此次項(xiàng)目主要是基于PSOC6 英飛凌 PSoC?62 with CAPSENSE? evaluation kit 實(shí)現(xiàn)OLED 顯示溫度、氣壓室內(nèi)信息。
整體框架如下:
1.通過板載的dap 和uart 進(jìn)行串口log 打印及程序刷寫
2.通過I2C 進(jìn)行BMP280 的驅(qū)動(dòng)
3.通過I2C 進(jìn)行oled SSD1306的顯示
實(shí)現(xiàn)步驟
1.rtt 中添加 軟件包
使能sensor 驅(qū)動(dòng) iic 驅(qū)動(dòng) uart驅(qū)動(dòng)
2.默認(rèn)的bmp280 包不能使用,由于使用最新的rt版本 不兼容,進(jìn)行驅(qū)動(dòng)層修改
#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 默認(rèn)地址
硬件初始化
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 結(jié)構(gòu)體改變了很多,需要根據(jù)sensor 驅(qū)動(dòng)進(jìn)行相應(yīng)的修改
設(shè)置 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 去掉了好多控制,做了相應(yīng)的注釋
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 已經(jīng)注冊(cè)成功
4.oled 顯示驅(qū)動(dòng)
oled 顯示通過u8g2進(jìn)行驅(qū)動(dòng),這里參考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);
顯示初始化前 ,先尋找驅(qū)動(dòng)
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;
}
然后顯示線程的主循環(huán)中按一定的間隔進(jìn)行sensor 數(shù)據(jù)讀取,然后更新顯示到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);
-
I2C總線
+關(guān)注
關(guān)注
8文章
391瀏覽量
60936 -
OLED顯示
+關(guān)注
關(guān)注
1文章
55瀏覽量
17001 -
SSD1306
+關(guān)注
關(guān)注
3文章
40瀏覽量
13628 -
BMP280
+關(guān)注
關(guān)注
1文章
20瀏覽量
5731 -
RTThread
+關(guān)注
關(guān)注
8文章
132瀏覽量
40875
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論