RK3568平台 (ADC篇)温度传感器芯片SD5075

本文详细介绍了SD5075高精度温度传感器的工作原理,包括其测温原理、寄存器功能以及通过I2C接口的代码实现。还涵盖了驱动程序的初始化和注册过程。
摘要由CSDN通过智能技术生成

一.SD5075芯片简介

SD5075 是一款高准确度温度传感器芯片内含高精度测温 ADC,在-40C ~+100°C 范围内典型误差小于+0.5°C,在-55C~+125°C 范围内典型误差小于士1.0°C。通过两线 IC/SMBus接口可以很方便与其他设备建立通信。设置 A2~A0 的地址线,可支持8 片芯片并联总线连接
本芯片可选 3 种工作模式: 连续测温模式单次测温模式,关断模式。可根据速度或功耗的需求灵活选择和配置。

管脚描述:

                                 

二.SD5075温度检测原理

原理:

SD5075芯片经过ALARM引脚检测温度的变化,经过模数转换器的转换,把温度值写入寄存器中,SOC再通过IIC读取寄存器的值,从而拿到温度值。

寄存器列表:

通过配置0x01寄存器为0x00,通过寄存器0x00读取到温度结果。

三.代码实现

#include <linux/miscdevice.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/fs.h>
#include <linux/i2c-dev.h>
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/notifier.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/compat.h>
#include <linux/printk.h>
#include <linux/kobject.h>
#include <linux/version.h>


#define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x00)
#define DRIVER_NAME "IST_TEMP"



/*define logging*/
#define IST_TEMP_DEBUG	0
#if IST_TEMP_DEBUG
#define DBG(format, args...)					\
	printk(KERN_DEBUG "%s: " format, DRIVER_NAME, ##args)
#define ERR(format, args...)					\
	printk(KERN_ERR "%s: " format, DRIVER_NAME, ##args)
#define WARNING(format, args...)				\
	printk(KERN_WARN "%s: " format, DRIVER_NAME, ##args)
#define INFO(format, args...)					\
	printk(KERN_INFO "%s: " format, DRIVER_NAME, ##args)
#else
#define DBG(format, args...)
#define ERR(format, args...)
#define WARNING(format, args...)
#define INFO(format, args...)
#endif

struct temp_dev {
	struct device *dev;
	struct miscdevice miscdev;
	struct i2c_client *client;
	u32 value;
};

struct temp_dev *g_temp;
struct temp_dev *temp;
static int last_value = 0;//char

static void i2c_wr(struct temp_dev *temp, u16 reg, u8 *val, u32 n)
{
	struct i2c_msg msg;
	struct i2c_client *client = temp->client;
	int err;
	u8 data[128];

	data[0] = reg;
	memcpy(&data[1], val, n);
	msg.addr = client->addr;
	msg.flags = 0;
	msg.buf = data;
	msg.len = n + 1;

	err = i2c_transfer(client->adapter, &msg, 1);
	if (err != 1) {
		ERR("%s: writing register 0x%x from 0x%x failed\n", __func__,
		    reg, client->addr);
	} else {
		switch (n) {
		case 1:
			INFO("I2C write 0x%02x = 0x%02x\n", reg, data[1]);
			break;
		case 2:
			INFO("I2C write 0x%02x = 0x%02x%02x\n", reg, data[2],
			     data[1]);
			break;
		case 4:
			INFO("I2C write 0x%02x = 0x%02x%02x%02x%02x\n", reg,
			     data[4], data[3], data[2], data[1]);
			break;
		default:
			INFO("I2C write %d bytes from address 0x%02x\n", n,
			     reg);
		}
	}
}

static void i2c_rd(struct temp_dev *temp, u16 reg, u8 *val, u32 n)
{
	struct i2c_msg msg[2];
	struct i2c_client *client = temp->client;
	int err;
	u8 buf[1] = { reg };

	/*msg[0] addr to read*/
	msg[0].addr = client->addr;
	msg[0].flags = 0;
	msg[0].buf = buf;
	msg[0].len = 1;

	/*msg[1] read data*/
	msg[1].addr = client->addr;
	msg[1].flags = I2C_M_RD;
	msg[1].buf = val;
	msg[1].len = n;

	err = i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg));
	if (err != ARRAY_SIZE(msg)) {
		ERR("%s: reading register 0x%x from 0x%x failed\n", __func__,
		    reg, client->addr);
	}
}

static void i2c_rd8(struct temp_dev *temp, u16 reg, u8 *val)
{
	i2c_rd(temp, reg, val, 1);
}

static void i2c_wr8(struct temp_dev *temp, u16 reg, u8 buf)
{
	i2c_wr(temp, reg, &buf, 1);
}

static void i2c_wr_word(struct temp_dev *temp, u16 reg, u16 val)
{
	unsigned char data[2] = {0};
	data[0] = (unsigned char)(val & 0xFF);
	data[1] = (unsigned char)((val & 0xFF00) >> 8);
	i2c_wr(temp, reg, data, 2);
}

static void i2c_rd_word(struct temp_dev *temp, u16 reg, u8 *val)
{
	i2c_rd(temp, reg, val, 2);
}


static long temperature_ioctl(struct file *file, uint32_t cmd, unsigned long arg)
{
	return 0;
}

static ssize_t temperature_write(struct file *file, const char __user *buf,
			     size_t size, loff_t *ppos)
{
	return 1;
}

static ssize_t temperature_read(struct file *file, char __user *buf, size_t size,
			    loff_t *ppos)
{
	return 1;
}

static ssize_t temperature_value_read(struct device *dev,
				      struct device_attribute *attr, char *buf)
{
	struct temp_dev *temp = g_temp;

	int result = -1;
    unsigned char reg;
    unsigned char reg_value;
    unsigned short value = 0;
    unsigned char value1[2] = {0};
    reg = 0x01;
    reg_value = 0x00;
	i2c_wr8(temp, reg, reg_value);
    reg = 0x00;
	i2c_rd_word(temp, reg, value1);

    value = (value1[0]<<8|value1[1])>>4;

    if(value >= 0x800)
    {
        printk(" temperature_value_read !!!");
        value = (value - 2048)>>4;
        result = value - 128;
    }
    else
    {
        result = value>>4;
		printk(" temperature_value_read !!!");
    }
    if(result == -1)
    {
        result -= last_value;
		printk(" temperature_value_read !!!");
        if((result > 8) || (result < (-8)))
        {
            result = last_value;
        }
        else
        {
            result = -1;
        }
    }
    temp->value = result;
	return sprintf(buf, "%d\n", temp->value);
}

static ssize_t temperature_value_write(struct device *dev,
				       struct device_attribute *attr,
				       const char *buf, size_t count)
{
	return count;
}

static DEVICE_ATTR(value, 0644,
		temperature_value_read, temperature_value_write);

static void temp_init(struct temp_dev *temp)
{
	
}

static const struct file_operations temp_fops = {
	.owner = THIS_MODULE,
	.read = temperature_read,
	.write = temperature_write,
	.unlocked_ioctl = temperature_ioctl,
};

struct miscdevice temp_miscdev = {
	.minor = MISC_DYNAMIC_MINOR,
	.name = "temp_dev",
	.fops = &temp_fops,
};

static int temp_probe(struct i2c_client *client,
			 const struct i2c_device_id *id)
{
	struct temp_dev *temp;
	struct device *dev = &client->dev;
	int ret;

	dev_info(dev, " driver version: %02x.%02x.%02x",
		DRIVER_VERSION >> 16,
		(DRIVER_VERSION & 0xff00) >> 8,
		DRIVER_VERSION & 0x00ff);

	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
		return -EIO;
	DBG("chip found @ 0x%x (%s)\n", client->addr << 1,
	    client->adapter->name);

	temp = devm_kzalloc(dev, sizeof(struct temp_dev), GFP_KERNEL);
	if (!temp)
		return -ENOMEM;

	temp->client = client;
	client->flags |= I2C_CLIENT_SCCB;

	ret = misc_register(&temp_miscdev);
	if (ret) {
		ERR(" temp ERROR: could not register ist_temp device\n");
		return ret;
	}

	ret = device_create_file(temp_miscdev.this_device,
				&dev_attr_value);
	if (ret) {
		dev_err(temp->dev, " failed to create attr hdmirxsel!\n");
		return ret;
	}

	temp_init(temp);
	g_temp = temp;
	
	INFO("%s  found @ 0x%x (%s)\n", client->name, client->addr << 1,
	     client->adapter->name);

	return 0;
}

static int temp_remove(struct i2c_client *client)
{
	misc_deregister(&temp_miscdev);
	kfree(temp);

	return 0;
}

static const struct of_device_id temp_of_match[] = {
	{ .compatible = "temperature" },
	{}
};
MODULE_DEVICE_TABLE(of, temp_of_match);

static struct i2c_driver temp_driver = {
	.probe = temp_probe,
	.remove = temp_remove,
	.driver = {
		.owner = THIS_MODULE,
		.name = DRIVER_NAME,
		.of_match_table = of_match_ptr(temp_of_match),
	},
};

static int __init temp_driver_init(void)
{
	return i2c_add_driver(&temp_driver);
}

static void __exit temp_driver_exit(void)
{
	i2c_del_driver(&ist_temp_driver);
}

device_initcall_sync(temp_driver_init);
module_exit(temp_driver_exit);

MODULE_DESCRIPTION("temperature sensor");
MODULE_AUTHOR("");
MODULE_LICENSE("GPL v2");

  • 16
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
rk3568平台是一款针对高性能应用的芯片集成电路,被广泛应用于智能家居、智能终端等领域。在安卓开发中,传感器系统是其中非常重要的一部分,主要用于检测设备的姿态、位置、加速度、角速度等物理量,为应用提供相关的数据。本文将就rk3568平台安卓系统中的传感器系统进行分析。 首先,rk3568平台支持多种常见的传感器类型,包括加速度传感器、陀螺仪、磁场传感器、光线传感器、环境温湿度传感器等。这些传感器的数据在应用中可以被收集并解析,以展现设备在不同物理环境下的状态。 其次,rk3568平台上的传感器系统也支持传感器的扩展。用户可以通过添加更多的传感器模块来扩展设备的功能,从而实现更丰富的应用场景。这种扩展性在智能家居、智能终端等领域非常有用。 除了传感器的收集和解析,rk3568平台在安卓系统中还提供了传感器管理服务。这些服务可用于控制传感器的采样频率和精度,从而实现更好的能耗管理和性能优化。用户可以根据自己的应用需求,通过调整传感器管理服务的配置,达到最佳的使用效果。 最后,值得注意的是,rk3568平台上的传感器系统也存在一定的局限性。例如,在某些物理环境下,传感器数据可能会受到干扰和误差,导致应用使用不正常。因此,在应用开发中,需要对传感器数据进行有效处理和校准,以保证应用的稳定性和准确性。 总之,rk3568平台在安卓系统中的传感器系统具有非常重要的作用。它不仅为应用提供了丰富的物理数据,还通过传感器管理服务实现了能耗管理和性能优化。但是,开发者需要注意传感器数据的处理和校准,以确保应用的稳定性和准确性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

嵌入式_笔记

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

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

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

打赏作者

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

抵扣说明:

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

余额充值