RK3568平台 温度传感器芯片SD5075

一.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...)
#endifstruct 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;//charstatic 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");

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/622826.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

网络配置以及命令详解

传统linux中,网络接口为eth0,eth1,eth2,..... RHEL 7以上版本默认命名是基于分配上的固定名称,ens33 接口类型: en:以太网有线接口 wl:无线局域网接口 ww:无线广域网 dmesg:显示开机信息 适配器类型: s:热插拔插槽 o:板载 p:pci类型 ifconfig ens160(命令行配置,临时生效):查…

算法通关村第十五关—海量数据场景下的热门算法题(白银)

海量数据场景下的热门算法题 一、从40个亿中产生一个不存在的整数 题目要求&#xff1a;给定一个输入文件&#xff0c;包含40亿个非负整数&#xff0c;请设计一个算法&#xff0c;产生一个不存在该文件中的整数&#xff0c;假设你有1GB的内存来完成这项任务。 进阶&#xff1a…

玩转 openEuler (一)-- 系统安装

简介 openEuler 是一款开源操作系统。当前 openEuler 内核源于Linux&#xff0c;支持鲲鹏及其它多种处理器&#xff0c;能够充分释放计算芯片的潜能&#xff0c;是由全球开源贡献者构建的高效、稳定、安全的开源操作系统&#xff0c;适用于数据库、大数据、云计算、人工智能等…

电子电器架构车载软件 —— 集中化架构软件开发

电子电器架构车载软件 —— 集中化架构软件开发 我是穿拖鞋的汉子&#xff0c;魔都中坚持长期主义的汽车电子工程师。 老规矩&#xff0c;分享一段喜欢的文字&#xff0c;避免自己成为高知识低文化的工程师&#xff1a; 屏蔽力是信息过载时代一个人的特殊竞争力&#xff0c;任…

Failed to save password Error code: -34018

1. 卸载navicat 2.打开终端&#xff1a;执行下列命令 sudo rm -Rf /Applications/Navicat\ Premium.app sudo rm -Rf /private/var/db/BootCaches/CB6F12B3-2C14-461E-B5A7-A8621B7FF130/app.com.prect.NavicatPremium.playlist sudo rm -Rf ~/Library/Caches/com.apple.help…

汽车ECU的虚拟化技术初探(四)--U2A内存管理

目录 1.内存管理概述 2. 内存保护功能 2.1 SPID 2.2 Slave Guard 3.小结 1.内存管理概述 为了讲清楚U2A 在各种运行模式、特权模式下的区别&#xff0c;其实首先应该搞清楚不同模式下可以操作的寄存器有哪些。 但是看到这个寄存器模型就头大。 再加上之前没有研究过G4MH…

文件操作(二)

͟͟͞͞&#x1f3c0;前言上一篇我们加们讲了什么是文件&#xff0c;为什么使用文件&#xff0c;以及流的概念。我们继续接上一篇来继续讲解我们的文件操作&#xff0c;这一篇将会详细的讲如何对文件进行读写。 目录 &#x1f680;一.文件的顺序读写 1.fgetc和fputc 2.fget…

【ROS2简单例程】基于python的发布订阅实现

1、自定义消息类型Student 1.1 创建base_interfaces_demo包 1.2 创建Student.msg文件 string name int32 age float64 height 1.2 在cmakeLists.txt中增加如下语句 #增加自定义消息类型的依赖 find_package(rosidl_default_generators REQUIRED) # 为接口文件生成源代码 ro…

Shell中cp和mv命令说明

在Shell&#xff08;如Bash&#xff09;中&#xff0c;cp 和 mv 是两个常用的命令&#xff0c;用于处理文件和目录。它们的用法和作用如下&#xff1a; cp 命令 作用&#xff1a;cp&#xff08;copy的缩写&#xff09;用于复制文件或目录。基本用法&#xff1a;cp [选项] 源文…

【OJ】环形链表

目录 1. 环形链表||&#xff08;142&#xff09;1.1 题目描述1.2 题目分析1.3 代码 2. 环形链表&#xff08;141&#xff09;2.1 题目描述2.2 题目分析2.3 代码 1. 环形链表||&#xff08;142&#xff09; 1.1 题目描述 1.2 题目分析 带环链表&#xff1a;尾节点的next指向链…

ROS OpenCV ROI

在图像处理和计算机视觉领域&#xff0c;ROI&#xff08;Region of Interest&#xff09;是一个核心概念&#xff0c;它指的是从原始图像中定义出的特定区域&#xff0c;该区域对于后续的分析、处理或操作具有特别的意义。 ROI的选择通常基于应用需求&#xff0c;例如目标检测…

【Rust日报】Xilem 项目在 2024 年的计划

Xilem 项目在 2024 年的计划 2024 年&#xff0c;Xilem 项目备受关注。Google Fonts 将资助四位开源贡献者&#xff1a;Aaron Muir Hamilton、Daniel McNab、Matt Campbell 和 Olivier Faure&#xff0c;他们将主导项目的不同方面。Aaron 将专注于文本布局和 Android 集成&…

Python异步网络编程库之twisted 详解

概要 Python twisted 是一个强大的异步网络编程框架&#xff0c;它允许开发者轻松构建高性能的网络应用和协议。无论是构建网络服务器、客户端、聊天应用还是实时通信工具&#xff0c;twisted 都提供了丰富的工具和组件。本文将深入探讨 twisted 的基本概念、安装方法以及详细…

Python常用日期函数和日期处理方法

Python常用日期函数和日期处理方法 Python常用的日期处理函数使用案例, 和一些简单的日期处理方法(持续更新) 1. 使用time获取当前的日期和时间 import time from time import gmtime, strftimet time.localtime() print (t) # time.struct_time(tm_year2024, tm_mon1, tm…

sql | 学生参加各科考试次数

学生表: Students------------------------ | Column Name | Type | ------------------------ | student_id | int | | student_name | varchar | ------------------------ 在 SQL 中&#xff0c;主键为 student_id&#xff08;学生ID&#xff09;。 该表内的每…

What is `@PathVariable` does?

PathVariable 是SpringMVC中的注解&#xff0c;用于将HTTP请求的URI路径变量映射到Controller方法参数上。 当URL路径中包含占位符&#xff08;由大括号 {} 包围的部分&#xff09;时&#xff0c;可以使用此注解来绑定这些动态部分到方法参数。 使用样例 获取单个路径变量 …

在控制理论里,单个输入变量被施加了饱和特性处理,那么后续怎么利用李雅普诺夫判据判断系统稳定性呢?

在控制理论中&#xff0c;当一个系统的输入变量被施加了饱和特性&#xff08;即输入被限制在某个范围内&#xff09;&#xff0c;系统的稳定性分析可能变得更复杂。使用李雅普诺夫方法判断这样的系统稳定性通常需要考虑非线性特性。下面是如何使用李雅普诺夫方法进行稳定性分析…

多机TCP通讯之hello world(C++)

文章目录 TCP是什么准备工作CMakeLists.txt服务端代码客户端代码参考 TCP是什么 TCP&#xff08;传输控制协议&#xff09;是一种在计算机网络中广泛使用的协议&#xff0c;它提供了可靠的、面向连接的数据传输服务。TCP 是 OSI 模型中的传输层协议&#xff0c;它确保了数据的…

[NAND Flash 6.4] NAND FLASH基本读操作及原理_NAND FLASH Read Operation源码实现

依公知及经验整理,原创保护,禁止转载。 专栏 《深入理解NAND Flash》 <<<< 返回总目录 <<<< ​全文 6000 字 内容摘要 NAND Flash 引脚功能 读操作步骤 NAND Flash中的特殊硬件结构 NAND Flash 读写时的数据流向 Read 操作时序 读时序操作过…

第 11 章 树结构实际应用

文章目录 11.1 堆排序11.1.1 堆排序基本介绍11.1.2 堆排序基本思想11.1.3 堆排序步骤图解说明11.1.4 堆排序代码实现 11.2 赫夫曼树11.2.1 基本介绍11.2.2 赫夫曼树几个重要概念和举例说明11.2.3 赫夫曼树创建思路图解11.2.4 赫夫曼树的代码实现 11.3 赫夫曼编码11.3.1 基本介绍…