安卓9 调试温湿度传感器TH09C

        相比于TH06C,TH09C精度更高,温度和湿度都有24位数据(3个字节),需要先发送指定位为1才能开始测数据,相比TH06C麻烦了一点(th06只有16位数据,而且直接读0xe3和0xe5就可以了)。调试OK只要cat  /sys/bus/i2c/devices/2-0043/temperature 和 cat  /sys/bus/i2c/devices/2-0043/humidity查看数据即可。

下面附上代码

/**
 &i2c0 {
      th09: th09@43 {
          compatible = "th09";
          reg = <0x43>;
      };
 };     //th09
 */
 

#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/gpio.h>
#include <linux/interrupt.h>
#include <linux/i2c.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/delay.h>


#define HDC1080_REG_TEMP			0x00
#define HDC1080_REG_HUMIDITY			0x01

#define HDC1080_REG_CONFIG			0x02
#define HDC1080_REG_CONFIG_HEATER_EN		BIT(13)



#define COMPATILE_NAME "th09"


struct i2c_demo_priv {
	struct i2c_client *client;
};

static const struct i2c_device_id i2c_demo_id[] = {
	{ COMPATILE_NAME, 0 },
	{ },
};
MODULE_DEVICE_TABLE(i2c, i2c_demo_id);

#ifdef CONFIG_OF
static const struct of_device_id i2c_demo_of_table[] = {
	{ .compatible = COMPATILE_NAME },
	{ }
};
MODULE_DEVICE_TABLE(of, i2c_demo_of_table);
#endif

static int debug_enable = 0;
module_param(debug_enable,int, 0644);


static ssize_t temp_value_show(struct device *dev, struct device_attribute *attr,
                             char *buf)
{
       struct i2c_demo_priv  *priv = dev_get_drvdata(dev);
       int err = 0;
       char data[6];
	   char DataBuf[3];
	   
       int val, temp;
        dev_info(dev, "%s addr=%d\n", __func__, priv->client->addr);
			
		DataBuf[0] = 0x21;
		DataBuf[1] = 0x00;
		DataBuf[2] = 0x03;
        err = i2c_master_send(priv->client, DataBuf, 3);
        if(err != 3){
        	dev_err(dev, "i2c_master_send fail, err=%d\n", err);
        }
        msleep(130);
		
        data[0] = 0x30;
        err = i2c_master_send(priv->client, data, 1);
        if(err != 1){
        	dev_err(dev, "i2c_master_send fail, err=%d\n", err);
        }
        msleep(20);
		
        memset(data, 0 , sizeof(data));
        err = i2c_master_recv(priv->client, data, 6);
        if(err != 6){
        	dev_err(dev, "i2c_master_recv fail, err=%d\n", err);
        }
    //    val = (data[0] << 8) + data[1];	
    //    temp = 17572 * val  / 65536 - 4686 - 250;
		val = (data[2] << 16) + (data[1] << 8)+ data[0];
		if(((val >> 16) & 0x0001) == 1)			
		{
			temp = ((((val & 0xFFFF)*100) / 64) - 27315);
		}
		else
			temp = 0;
			
        dev_info(dev, "val=%d, temp=%d\n", val, temp);
       return sprintf(buf, "%d\n",temp);
}


static ssize_t humidity_value_show(struct device *dev, struct device_attribute *attr,
                             char *buf)
{
       struct i2c_demo_priv  *priv = dev_get_drvdata(dev);
       int err = 0;
       char data[6];
	   char DataBuf[3];
       int val, temp;
        dev_info(dev, "%s addr=%d\n", __func__, priv->client->addr);
 
		DataBuf[0] = 0x21;
		DataBuf[1] = 0x00;
		DataBuf[2] = 0x03;
        err = i2c_master_send(priv->client, DataBuf, 3);
        if(err != 3){
        	dev_err(dev, "i2c_master_send3 fail, err=%d\n", err);
        }
        msleep(130);
		
        data[0] = 0x30;
        err = i2c_master_send(priv->client, data, 1);
        if(err != 1){
        	dev_err(dev, "i2c_master_send1 fail, err=%d\n", err);
        }
        msleep(20);		
		
        memset(data, 0 , sizeof(data));
        err = i2c_master_recv(priv->client, data, 6);
        if(err != 6){
        	dev_err(dev, "i2c_master_recv fail, err=%d\n", err);
        }
       //   val = (data[0] << 8) + data[1];
	   //   temp = 125 * val  / 65536 - 6;	   
	    val = (data[5] << 16) + (data[4] << 8) + data[3];
		if(((val >> 16) & 0x0001) == 1)			
		{
			temp = (((val & 0xFFFF)*100) / 512);
		}
		else
			temp = 0;
		//dev_info(dev, "data[5]=%d, data[4]=%d, data[3]=%d\n", data[5], data[4],data[3]);
	
        dev_info(dev, "val=%d, temp=%d\n", val, temp);
       return sprintf(buf, "%d\n",temp);
}



static DEVICE_ATTR(temperature, S_IRUGO, temp_value_show, NULL);
static DEVICE_ATTR(humidity, S_IRUGO, humidity_value_show, NULL);


static int i2c_demo_probe(struct i2c_client *client,
				   const struct i2c_device_id *id)
{
	struct device_node *node;
	struct i2c_demo_priv *chip;
	int ret;
	dev_info(&client->dev, "%s enter\n", __func__);
	node = client->dev.of_node;
	chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
	if (chip == NULL)
		return -ENOMEM;
	chip->client = client;
	i2c_set_clientdata(client, chip);
	ret = device_create_file(&client->dev, &dev_attr_temperature);
	if(ret){
	    dev_err(&client->dev, "Unable to device_create_file: %d\n", ret);
	}
	ret = device_create_file(&client->dev, &dev_attr_humidity);
	if(ret){
	    dev_err(&client->dev, "Unable to device_create_file: %d\n", ret);
	}
	return 0;

}

static int i2c_demo_remove(struct i2c_client *client)
{
	//struct i2c_demo_priv *chip = i2c_get_clientdata(client);
	dev_info(&client->dev, "%s enter\n", __func__);
	return 0;
}

void i2c_demo_shutdown(struct i2c_client *client)
{
//	struct i2c_demo_priv *chip = i2c_get_clientdata(client);
	dev_info(&client->dev, "%s enter\n", __func__);
}

static struct i2c_driver i2c_demo_driver = {
	.driver = {
		.name		= "i2c_demo",
		.owner		= THIS_MODULE,
		.of_match_table	= of_match_ptr(i2c_demo_of_table),
	},
	.probe		= i2c_demo_probe,
	.remove		= i2c_demo_remove,
	.id_table	= i2c_demo_id,
	.shutdown = i2c_demo_shutdown,
};

static int __init i2c_demo_init(void)
{
	return i2c_add_driver(&i2c_demo_driver);
}
/* register after i2c postcore initcall and before
 * subsys initcalls that may rely on these GPIOs
 */
#if 1
subsys_initcall_sync(i2c_demo_init);
#else
module_init(i2c_demo_init);
#endif
static void __exit i2c_demo_exit(void)
{
	i2c_del_driver(&i2c_demo_driver);
}
module_exit(i2c_demo_exit);

MODULE_AUTHOR("tj <tj_wust@163.com>");
MODULE_DESCRIPTION("i2c th09 driver");
MODULE_LICENSE("GPL");

  • 12
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wq2249358611

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值