项目简介
此次项目主要是基于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;// initializationu8g2_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);
模拟式电压表常见的四种类型
Bulgin连接器现可提供面向277V应用的更高电压额定值
纺织品拒水性测试仪的介绍
软通动力与华为签署OpenHarmony生态使能合作协议
TI毫米波传感器为自动入口系统带来智能性、高效性和便捷性
求一种基于Infineon的信息采集系统设计方案
虹科Pico向你发来邀请:以技会友、技术交流,相约广州与成都
安装智能家居需要注意什么问题
每日一课 | 智慧灯杆之智慧社区应用案例的项目分析
示波器的概述与历史
风河韩青:基于云计算的vRAN技术和云解决方案可加速5G场景落地
Ryzen 3处理器终于要发布!性能或将超越Intel Core i3
飞利浦照明TrueForce LED路灯光源详解 寿命长达八年
单片机用处广泛,如何快速上手STM32
2024 信心满满!19家元脑生态伙伴与浪潮信息签署亿元分销协议
纸电池:能源储存新兵
两种基于FPGA的软件滤波方法
基于DNA的数字存储受到关注
ADI:将提供可穿戴设备市场一系列创新产品和解决方案
微软×研华科技 混合云与边缘协同 实现多厂协同管理