1 Star 0 Fork 0

乐乐0101/ONEOS_IIC_SHT30

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
sht30.c 9.92 KB
一键复制 编辑 原始数据 按行查看 历史
乐乐0101 提交于 2021-12-22 15:02 . oneos
#include <drv_cfg.h>
#include <os_memory.h>
#include <sensors/sensor.h>
#include <math.h>
#include <shell.h>
#include <dlog.h>
#define DBG_TAG "sensor.sensirion.sht30"
/* ADDR Pin Conect to VSS */
// 0x44 左移一位,最后一位是0为读,1为写
uint8_t MEDIUM_2_CMD[2]={0x22,0x20};
uint8_t READOUT_FOR_PERIODIC_MODE[2]={0xE0,0x00};
uint8_t SOFT_RESET_CMD[2]={0x30,0xA2};
typedef struct
{
struct os_sensor_device sensor;
struct os_i2c_client i2c;
os_uint8_t id;
union
{
float tempreture;
float humidity;
} value;
} sht30_info_t;
static os_err_t write_regs(struct os_i2c_client *client, os_uint16_t reg, os_uint8_t *buf, os_uint8_t len)
{
struct os_i2c_msg msgs;
os_uint8_t databuf[9];
os_uint8_t device_addr = 0;
os_uint8_t reg_addr = 0;
OS_ASSERT(len <= 8);
if (reg > 255)
{
device_addr = OS_SHT30_I2C_ADDR | 0x01;
}
else
{
device_addr = OS_SHT30_I2C_ADDR;
}
reg_addr = reg & 0xFF;
databuf[0] = reg_addr;
memcpy(&databuf[1], buf, len);
msgs.addr = device_addr;
msgs.flags = OS_I2C_WR;
msgs.buf = databuf;
msgs.len = len + 1;
if (os_i2c_transfer(client->bus, &msgs, 1) == 1)
{
return OS_EOK;
}
else
{
os_kprintf("Writing command error\n");
return -OS_ERROR;
}
}
static os_err_t read_regs(struct os_i2c_client *client, os_uint16_t reg, os_uint8_t *buf, os_uint8_t len)
{
struct os_i2c_msg msgs[2];
os_uint8_t device_addr = 0;
os_uint8_t reg_addr = 0;
if (reg > 255)
{
device_addr = OS_SHT30_I2C_ADDR | 0x01;
}
else
{
device_addr = OS_SHT30_I2C_ADDR;
}
reg_addr = reg & 0xFF;
msgs[0].addr = device_addr;
msgs[0].flags = OS_I2C_WR;
msgs[0].buf = &reg_addr;
msgs[0].len = 1;
msgs[1].addr = device_addr;
msgs[1].flags = OS_I2C_RD;
msgs[1].buf = buf;
msgs[1].len = len;
if (os_i2c_transfer(client->bus, msgs, 2) == 2)
{
return OS_EOK;
}
else
{
os_kprintf("Reading command error\n");
return -OS_ERROR;
}
}
static void sht30_reset(sht30_info_t *sht30)
{
//write_regs(&sht30->i2c, 0, SOFT_RESET_CMD,sizeof(SOFT_RESET_CMD));
os_i2c_client_write(&sht30->i2c,0,0,SOFT_RESET_CMD,sizeof(SOFT_RESET_CMD));
}
/* SHT30 初始化,开启连续读取模式*/
static void sht30_init_all(sht30_info_t *sht30)
{
//write_regs(&sht30->i2c, 0, MEDIUM_2_CMD,sizeof(MEDIUM_2_CMD));
os_i2c_client_write(&sht30->i2c,0,0,MEDIUM_2_CMD,sizeof(MEDIUM_2_CMD));
}
#define CRC8_POLYNOMIAL 0x31
uint8_t SHT3x_CheckCrc(uint8_t* const message, uint8_t initial_value)
{
uint8_t remainder; //余数
uint8_t i = 0, j = 0; //循环变量
/* 初始化 */
remainder = initial_value;
for(j = 0; j < 2;j++)
{
remainder ^= message[j];
/* 从最高位开始依次计算 */
for (i = 0; i < 8; i++)
{
if (remainder & 0x80)
{
remainder = (remainder << 1)^CRC8_POLYNOMIAL;
}
else
{
remainder = (remainder << 1);
}
}
}
/* 返回计算的CRC码 */
return remainder;
}
static float SHT3x_CalcTemperatureC(unsigned short u16sT)
{
float temperatureC = 0;
/* T= -46.85 + 175.72 * ST/2^16 */
temperatureC = -45 + 175*((float)u16sT/65535);
os_kprintf("tempature=%d \n",(int)temperatureC);
return temperatureC;
}
static float SHT3x_CalcRH(unsigned short u16sRH)
{
float humidityRH = 0;
/* HumidityRH = -6.0 + 125.0/65536 * (float)u16sRH */
humidityRH = 100 * ((float)u16sRH / 65535);
os_kprintf("humidityRH= %d \n",(int)humidityRH);
return humidityRH;
}
static unsigned short SHT3x_MeasureHM(sht30_info_t *sht30, unsigned char cmd )
{
uint8_t buff[6];
buff[0] = 0;
/* 发送周期读命令函数 */
//write_regs(&sht30->i2c, 0, READOUT_FOR_PERIODIC_MODE,sizeof(READOUT_FOR_PERIODIC_MODE));
os_i2c_client_write(&sht30->i2c,0,0,READOUT_FOR_PERIODIC_MODE,sizeof(READOUT_FOR_PERIODIC_MODE));
os_task_msleep(80);
//这里连续读6个字节
//read_regs(&sht30->i2c,0,buff,sizeof(buff));
os_i2c_client_read(&sht30->i2c,0,0,buff,sizeof(buff));
//os_i2c_client_read(&sht30->i2c, OS_SHT30_I2C_ADDR, 1, buff, 1);
/*buff[0] = sht30_read_user_reg(sht30);
buff[1] = sht30_read_user_reg(sht30);
buff[2] = sht30_read_user_reg(sht30);
buff[3] = sht30_read_user_reg(sht30);
buff[4] = sht30_read_user_reg(sht30);
buff[5] = sht30_read_user_reg(sht30);*/
os_kprintf("buff= %d %d\n",buff[0],buff[3]);
if(SHT3x_CheckCrc(buff, 0xFF) != buff[2] || SHT3x_CheckCrc(&buff[3], 0xFF) != buff[5])
{
os_kprintf("crc is error\n");
return 1;
}
else
{
if(cmd == 0x01)
{
return ((buff[0] << 8) | buff[1]);
}
if(cmd == 0x02)
{
return ((buff[3] << 8) | buff[4]);
}
}
return (unsigned short)-1;
}
static void sht30_get_temp(sht30_info_t *sht30)
{
unsigned short tmp;
tmp = SHT3x_MeasureHM(sht30, 0x01);
sht30->value.tempreture = SHT3x_CalcTemperatureC(tmp);
}
static void sht30_get_humi(sht30_info_t *sht30)
{
unsigned short tmp;
tmp = SHT3x_MeasureHM(sht30, 0x02);
sht30->value.humidity = SHT3x_CalcRH(tmp);
}
static sht30_info_t *sht30_init(const char *bus_name, os_uint16_t addr)
{
sht30_info_t *sht30 = NULL;
sht30 = os_calloc(1, sizeof(sht30_info_t));
if (sht30 == OS_NULL)
{
return NULL;
}
sht30->i2c.bus = os_i2c_bus_device_find(bus_name);
if (sht30->i2c.bus == NULL)
{
os_free(sht30);
return NULL;
}
sht30->i2c.client_addr = addr;
sht30_reset(sht30);
os_task_msleep(50);
sht30_init_all(sht30);
os_task_msleep(10);
return sht30;
}
static os_size_t sht30_temp_fetch_data(struct os_sensor_device *sensor, void *buf, os_size_t len)
{
sht30_info_t *sht30 = NULL;
struct os_sensor_data *data = NULL;
OS_ASSERT(sensor);
OS_ASSERT(sensor->info.type == OS_SENSOR_CLASS_TEMP);
OS_ASSERT(buf);
sht30 = (sht30_info_t *)sensor;
data = (struct os_sensor_data *)buf;
sht30_get_temp(sht30);
data->type = sensor->info.type;
data->data.temp = sht30->value.tempreture;
data->timestamp = os_sensor_get_ts();
return 0;
}
static os_err_t sht30_temp_control(struct os_sensor_device *sensor, int cmd, void *args)
{
os_err_t result = OS_EOK;
sht30_info_t *sht30 = (sht30_info_t *)sensor;
switch (cmd)
{
case OS_SENSOR_CTRL_GET_ID:
*(uint8_t *)args = sht30->id;
break;
default:
return OS_ERROR;
}
return result;
}
static struct os_sensor_ops sht30_temp_ops =
{
sht30_temp_fetch_data,
sht30_temp_control,
};
static int os_hw_sht30_temp_init(void)
{
os_int8_t result;
sht30_info_t *sht30;
sht30 = sht30_init(OS_SHT30_I2C_BUS_NAME, OS_SHT30_I2C_ADDR);
if (sht30 == NULL)
{
goto __exit;
}
/* Temp */
sht30->sensor.info.type = OS_SENSOR_CLASS_TEMP;
sht30->sensor.info.vendor = OS_SENSOR_VENDOR_SENSIRION;
sht30->sensor.info.model = "sht30";
sht30->sensor.info.unit = OS_SENSOR_UNIT_MDCELSIUS;
sht30->sensor.info.intf_type = OS_SENSOR_INTF_I2C;
sht30->sensor.info.range_max = 100000;
sht30->sensor.info.range_min = 0;
sht30->sensor.info.period_min = 300;
sht30->sensor.ops = &sht30_temp_ops;
result = os_hw_sensor_register(&sht30->sensor, "sht30", OS_NULL);
if (result != OS_EOK)
{
goto __exit;
}
return OS_EOK;
__exit:
if (sht30)
os_free(sht30);
return OS_ERROR;
}
OS_DEVICE_INIT(os_hw_sht30_temp_init, OS_INIT_SUBLEVEL_LOW);
static os_size_t sht30_humi_fetch_data(struct os_sensor_device *sensor, void *buf, os_size_t len)
{
sht30_info_t *sht30 = NULL;
struct os_sensor_data *data = NULL;
OS_ASSERT(sensor);
OS_ASSERT(sensor->info.type == OS_SENSOR_CLASS_HUMI);
OS_ASSERT(buf);
sht30 = (sht30_info_t *)sensor;
data = (struct os_sensor_data *)buf;
sht30_get_humi(sht30);
data->type = sensor->info.type;
data->data.humi = sht30->value.humidity;
data->timestamp = os_sensor_get_ts();
return 0;
}
static os_err_t sht30_humi_control(struct os_sensor_device *sensor, int cmd, void *args)
{
os_err_t result = OS_EOK;
sht30_info_t *sht30 = (sht30_info_t *)sensor;
switch (cmd)
{
case OS_SENSOR_CTRL_GET_ID:
*(uint8_t *)args = sht30->id;
break;
default:
return OS_ERROR;
}
return result;
}
static struct os_sensor_ops sht30_humi_ops =
{
sht30_humi_fetch_data,
sht30_humi_control,
};
static int os_hw_sht30_humi_init(void)
{
os_int8_t result;
sht30_info_t *sht30;
sht30 = sht30_init(OS_SHT30_I2C_BUS_NAME, OS_SHT30_I2C_ADDR);
if (sht30 == NULL)
{
LOG_E(DBG_TAG,"sht30 humi init failed.");
goto __exit;
}
/* humi */
sht30->sensor.info.type = OS_SENSOR_CLASS_HUMI;
sht30->sensor.info.vendor = OS_SENSOR_VENDOR_SENSIRION;
sht30->sensor.info.model = "sht30";
sht30->sensor.info.unit = OS_SENSOR_UNIT_MPERMILLAGE;
sht30->sensor.info.intf_type = OS_SENSOR_INTF_I2C;
sht30->sensor.info.range_max = 100000;
sht30->sensor.info.range_min = 0;
sht30->sensor.info.period_min = 300;
sht30->sensor.ops = &sht30_humi_ops;
result = os_hw_sensor_register(&sht30->sensor, "sht30", OS_NULL);
if (result != OS_EOK)
{
LOG_E(DBG_TAG,"device humi register err code: %d", result);
goto __exit;
}
LOG_D(DBG_TAG,"sht30 humi init success");
return OS_EOK;
__exit:
if (sht30)
os_free(sht30);
return OS_ERROR;
}
OS_DEVICE_INIT(os_hw_sht30_humi_init, OS_INIT_SUBLEVEL_LOW);
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
C
1
https://gitee.com/lele_0101/oneos_-iic_-sht30.git
git@gitee.com:lele_0101/oneos_-iic_-sht30.git
lele_0101
oneos_-iic_-sht30
ONEOS_IIC_SHT30
master

搜索帮助