SHT20传感器
这是一款完全校准的温湿度传感器集成电路芯片,用数字输出 I2C接口。具有良好的长期稳定性和低功耗特性。用于读设备进行温度监控。
SHT20的I2C接口
7bit的设备地址:‘1000’000',1bit读写选择(read:'1' write:'0')
command:‘1110’0011’ for temperature, ‘1110’0101’ for relative humidity’
命令参数表:
拥有宿主的模式指令为:(下面是以读取湿度RH的command为例)
温湿度计算公式
I2C驱动设备树
设备树dts文件的设置
/*-------------------------------------------------------------------------------------------------------------------
i2c clock-frequency = <100000>; normal speed clock-frequency = <400000>; high speed-----------------------------------------------------------------------------------------------------------------------*/
&i2c0 {
pinctrl-names = "default";
pinctrl-0 = <&i2c0_pins>;
status = "okay";
clock-frequency = <100000>;
tps: tps@2d {
reg = <0x2d>;
};
sgtl5000: sgtl5000@0a {
compatible = "ti,sgtl5000";
reg = <0x0a>;
clocks = <&mcasp0_fck>;
status = "okay";
};
};
dtsi文件的配置i2c0: i2c@44e0b000 {
compatible = "ti,omap4-i2c";
#address-cells = <1>;
#size-cells = <0>;
ti,hwmods = "i2c1";
reg = <0x44e0b000 0x1000>;
interrupts = <70>;
status = "disabled";
};
i2c1: i2c@4802a000 {
compatible = "ti,omap4-i2c";
#address-cells = <1>;
#size-cells = <0>;
ti,hwmods = "i2c2";
reg = <0x4802a000 0x1000>;
interrupts = <71>;
status = "disabled";
};
i2c2: i2c@4819c000 {
compatible = "ti,omap4-i2c";
#address-cells = <1>;
#size-cells = <0>;
ti,hwmods = "i2c3";
reg = <0x4819c000 0x1000>;
interrupts = <30>;
status = "disabled";
};
I2C驱动层代码
在i2cdev.c中的关于设备节点i2c-0的read write ioctl函数的用法、
static ssize_t i2cdev_read(struct file *file, char __user *buf, size_t count,
loff_t *offset)
{
char *tmp;
int ret;
struct i2c_client *client = file->private_data;
if (count > 8192)
count = 8192;
tmp = kmalloc(count, GFP_KERNEL);
if (tmp == NULL)
return -ENOMEM;
pr_debug("i2c-dev: i2c-%d reading %zu bytes.\n",
iminor(file_inode(file)), count);
ret = i2c_master_recv(client, tmp, count);
if (ret >= 0)
ret = copy_to_user(buf, tmp, count) ? -EFAULT : ret;
kfree(tmp);
return ret;
}
static ssize_t i2cdev_write(struct file *file, const char __user *buf,
size_t count, loff_t *offset)
{
int ret;
char *tmp;
struct i2c_client *client = file->private_data;
if (count > 8192)
count = 8192;
tmp = memdup_user(buf, count);
if (IS_ERR(tmp))
return PTR_ERR(tmp);
pr_debug("i2c-dev: i2c-%d writing %zu bytes.\n",
iminor(file_inode(file)), count);
ret = i2c_master_send(client, tmp, count);
kfree(tmp);
return ret;
I2C应用层代码
需要注意sht20的每个芯片都有自己的序列号,这个序列号的地址是fa0f 和fcc9两个地址下。这个信息是在网上搜索到的。datasheet中没有。
#include<stdio.h>
#include<fcntl.h>
#include<unistd.h>
#include<sys/ioctl.h>
#include<linux/types.h>
#include <sys/stat.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <string.h>
#include <stdint.h>
#define I2C_DEV "/dev/i2c-0"
#define I2C_RDWR 0x0707
#define READLEN 4
#define SENDLEN 2
int main()
{
int fd;
int slaveaddr;
uint8_t readbuf[READLEN];
uint8_t sendbuf[2];
float tem;
float rh;
unsigned int serial_number1;
unsigned int serial_number2;
struct i2c_rdwr_ioctl_data data;
data.msgs = (struct i2c_msg *) malloc(sizeof(struct i2c_msg));
//1.打开通用设备文件
if((fd = open(I2C_DEV, O_RDWR)) < 0)
{
printf("i2c device open failed...\n");
return (-1);
}
slaveaddr = 0x40;
ioctl(fd,I2C_TENBIT,0); //not 10bit
ioctl(fd,I2C_SLAVE,slaveaddr); //设置I2C从设备地址[6:0]
memset(sendbuf,0,SENDLEN);
sendbuf[0] = 0xe3;
write(fd, sendbuf, 1);
memset(readbuf,0,READLEN);
read(fd, readbuf, 2);
printf("readbuf[0]=%x readbuf[1]=%x\n", readbuf[0], readbuf[1]);
tem = 175.72 * (((((int) readbuf[0]) << 8) + readbuf[1]) / 65536.0) - 46.85;
memset(sendbuf,0,SENDLEN);
sendbuf[0] = 0xe5;
write(fd, sendbuf, 1);
memset(readbuf,0,READLEN);
read(fd, readbuf, 2);
printf("readbuf[0]=%x readbuf[1]=%x\n", readbuf[0], readbuf[1]);
rh = 125 * (((((int) readbuf[0]) << 8) + readbuf[1]) / 65536.0) - 6;
printf("tem = %lf rh = %lf\n", tem, rh);
memset(sendbuf,0,SENDLEN);
sendbuf[0] = 0xfa;
sendbuf[1] = 0x0f;
write(fd, sendbuf, SENDLEN);
memset(readbuf,0,READLEN);
read(fd, readbuf, READLEN);
printf("readbuf[0]=%x readbuf[1]=%x readbuf[2]=%x readbuf[3]=%x\n", readbuf[0], readbuf[1], readbuf[2], readbuf[3]);
// serial_number1 = ((unsigned long)readbuf[0] << (8*5))
// serial_number2
memset(sendbuf,0,SENDLEN);
sendbuf[0] = 0xfc;
sendbuf[1] = 0xc9;
write(fd, sendbuf, SENDLEN);
memset(readbuf,0,READLEN);
read(fd, readbuf, READLEN);
printf("readbuf[0]=%x readbuf[1]=%x readbuf[2]=%x readbuf[3]=%x\n", readbuf[0], readbuf[1], readbuf[2], readbuf[3]);
//6.关闭设备
close(fd);
}
终于经历一下午时间、设备可以通过从sht20中读取温湿度了。撒花。。。