接上一篇:【CW32L012】6、驱动ST7735TFTLCD屏-电子产品世界论坛
CW32L012的IO复用非常的方便,由于饭盒派的SPI点用了原来的I2C1的PB6、PB7的端口,因此本篇将分享如何换个i2C接口并驱动二氧化碳传感,来实现一个家居的环境监测系统。
【STCC4传感器简介】
二氧化碳传感器有助于开发各种智能设备,提高生活舒适度、身体健康和能源效率,适用于暖通空调(HVAC)、消费和医疗等 各种应用。通过运用不同测量原理的最新研究成果,我们可为各种需求场景提供解决方案。从最初的构思到产品发布的整个 开发过程,Sensirion可提供原型构建、设计支持和批量生产期间的在线测试等方面的专业支持。我们的传感器产品组合还涵 盖用于监测诸如湿度、温度、挥发性有机化合物 (VOC)、颗粒物 (PM)、甲醛和氮氧化物 (NOx)等环境参数的传感器解决 方案。
二氧化碳传感的测量原理 透射式非色散红外(NDIR) CO2 分子会吸收特定波长的红外 (IR) 光。NDIR CO2 传感器将红外光穿过测量池并使用检测器测量有多少 光通过测量池(即未被 CO2 分子吸收)。通过与参考光 强度进行比较,可以得出 CO2 浓度。NDIR CO2 传感器 有两种类型:单通道和双通道。双通道 NDIR 中的参考 测量通道能增强长期稳定性。


stcc4采用IIC来驱动。
【接口】
饭盒派的扩展板在接上TFTLCD屏后,点用了PB6、PB7的IIC接口,因此我找到了开发板的通用接口来与STCC4进行通信,I2C1_SCL为PB10,I2C1_SDA为PB11。

找到数据手册,其复用为AF3

【I2C配置以及初始化】
创建文件my_iic.c/h并将它加入工程中。代码如下:
#include "my_iic.h"
#include "cw32l012_gpio.h"
#include "cw32l012_sysctrl.h"
#include "cw32l012_lpi2c.h"
#define I2C1_SCL_GPIO_PORT CW_GPIOB
#define I2C1_SCL_GPIO_PIN GPIO_PIN_10
#define I2C1_SDA_GPIO_PORT CW_GPIOB
#define I2C1_SDA_GPIO_PIN GPIO_PIN_11
#define I2C1_SCL_LOW() PB10_SETLOW()
#define I2C1_SDA_LOW() PB11_SETLOW()
#define I2C1_SCL_HIGH() PB10_SETHIGH()
#define I2C1_SDA_HIGH() PB11_SETHIGH()
#define I2C1_SCL2GPIO() PB10_AFx_GPIO()
#define I2C1_SDA2GPIO() PB11_AFx_GPIO()
#define GPIO2I2C1_SCL() PB10_AFx_I2C1SCL()
#define GPIO2I2C1_SDA() PB11_AFx_I2C1SDA()
static void I2C_Stop_SW(void)
{
I2C1_SCL_LOW();
I2C1_SDA_LOW();
#ifdef HSI48MHZ_EN
FirmwareDelay(24); // delay 4us@48MHz
I2C1_SCL_HIGH();
FirmwareDelay(24);
#else
FirmwareDelay(4); // delay 4us@8MHz
I2C1_SCL_HIGH();
FirmwareDelay(4);
#endif
I2C1_SDA_HIGH();
}
void I2C_ExceptionHandling(void)
{
I2C1_SCL2GPIO();
I2C1_SDA2GPIO();
I2C_Stop_SW();
#ifdef HSI48MHZ_EN
FirmwareDelay(6000); // delay 1ms@48MHz
#else
FirmwareDelay(1000); // delay 1ms@8MHz
#endif
GPIO2I2C1_SCL();
GPIO2I2C1_SDA();
}
static void MY_I2C_Config(void)
{
I2C_DeInit(CW_I2C1);
I2C_MasterConfigTypeDef I2C_InitStruct;
GPIO2I2C1_SCL();
GPIO2I2C1_SDA();
I2C_MasterInitDefault(&I2C_InitStruct); // I2C初始化为默认值
I2C_MasterInit(CW_I2C1, &I2C_InitStruct, 96000000UL); // I2C配置
I2C_MasterCmd(CW_I2C1, ENABLE); // I2C模块使能
I2C_Stop_SW();
}
static void MY_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure = {0};
/* 开启GPIOB时钟 */
__SYSCTRL_GPIOB_CLK_ENABLE();
/* 复用引脚为IIC AF3 */
PB10_AFx_I2C1SCL();
PB11_AFx_I2C1SDA();
/* 配置IO的为输出模式 */
GPIO_InitStructure.Pins = I2C1_SCL_GPIO_PIN | I2C1_SDA_GPIO_PIN;
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_OD;
GPIO_Init(I2C1_SCL_GPIO_PORT, &GPIO_InitStructure);
}
void my_iic_Init(void)
{
MY_GPIO_Init();
MY_I2C_Config();
if (I2C_MasterPollingFlag(CW_I2C1, I2C_IT_BUSBUSY) == I2C_Status_Success)
{
I2C_ExceptionHandling();
}
}在这里我们配置i2c两个IO为开漏输出,因此,需要外接上拉电阻。
在my_iic.h中只需要开放初始化函数就行:
#ifndef __MY_IIC_H
#define __MY_IIC_H
#ifdef __cplusplus
extern "C"
{
#endif
void my_iic_Init(void);
#ifdef __cplusplus
}
#endif
#endif /* __MY_IIC_H */ 【移植STCC4驱动】
1、在stcc4的github中下载到他的C驱动包。
2、将其驱动添加到工程中:

3、添加接口读写函数,以及延时函数,在sensirion_i2c_hal.c中
int8_t sensirion_i2c_hal_read(uint8_t address, uint8_t* data, uint8_t count) {
/* TODO:IMPLEMENT */
return I2C_MasterReceiveDataFromSlave(CW_I2C1,
(uint16_t)(address),
data,
I2C_REG_ADDR_16BIT,
data, count);
}
int8_t sensirion_i2c_hal_write(uint8_t address, const uint8_t* data,
uint8_t count) {
/* TODO:IMPLEMENT */
return I2C_MasterSendDataToSlave(CW_I2C1, (uint16_t)(address), (uint8_t*)data, count);
}
void sensirion_i2c_hal_sleep_usec(uint32_t useconds) {
/* TODO:IMPLEMENT */
uint32_t msec = useconds / 1000;
if (useconds % 1000 > 0) {
msec++;
}
SysTickDelay(msec);
}【验证】
在app.c中添加初始化、开始转换,成功后显示到TFT——LCD屏中
my_iic_Init();
Lcd_Init();
Lcd_Clear(GRAY0); //清屏
Gui_DrawFont_GBK16(15,5,BLACK,GRAY0,"HELLO world");
Gui_DrawFont_GBK16(15,25,RED,GRAY0,"LCD OK DISPLAY");
stcc4_init(0x64);
erro = stcc4_get_product_id(&product_id, &serial_number);
Lcd_Clear(GRAY0); //清屏
if(erro != 0)
{
Gui_DrawFont_GBK16(15,5,BLACK,GRAY0,"stcc4 erro");
}
else{
sttc4_sta = 1;
}
SysTickDelay(2000);
if(sttc4_sta ==1)
{
erro = stcc4_start_continuous_measurement();
if(erro != 0)
{
Lcd_Clear(GRAY0); //清屏
sttc4_sta = 0;
Gui_DrawFont_GBK16(15,5,BLACK,GRAY0,"stcc4sarterro");
}
SysTickDelay(1000);
}
Lcd_Clear(GRAY0); //清屏
Gui_DrawFont_GBK16(15,5,BLACK,GRAY0,"HelloSTTC4");
while(1)
{
erro = stcc4_read_measurement_raw(&co2_concentration_raw,
&temperature_raw,
&relative_humidity_raw,
&sensor_status_raw) ;
if(erro == 0)
{
hum = (25.0f * relative_humidity_raw) / 13107.0f - 6.0f;
temp = (175.0f * temperature_raw) / 65535.0f - 45.0f;
sprintf(buf,"CO2:%04d",co2_concentration_raw);
Gui_DrawFont_GBK16(10,24,BLACK,GRAY0,buf);
sprintf(buf,"TEMP:%.2f",temp);
Gui_DrawFont_GBK16(10,48,BLACK,GRAY0,buf);
sprintf(buf,"HUM:%.1f",hum);
Gui_DrawFont_GBK16(10,64,BLACK,GRAY0,buf);
Gui_DrawFont_GBK16(10,120,BLACK,GRAY0,"err:0");
}
else
{
Gui_DrawFont_GBK16(10,120,BLACK,GRAY0,"err:1");
SysTickDelay(2000);
}
SysTickDelay(2000);
}下载后可以看到正常读出传感器数据:

【总结】
cw32L012的IO复用非常方便。但是需要使用上拉电阻才能正常使用。
附:stcc4驱动包:stcc4_i2c.zip
工程源码:TFT_STCC4.zip
我要赚赏金
