platform tree架构下i2c应用实例(HS3003)

目录

概述

1 探究platform tree下的i2c

1.1 platform tree下的i2c驱动

1.2 查看i2c总线下的设备

1.3 使用命令读写设备寄存器

2 认识HS3003

2.1 HS3003特性

2.2 HS3003寄存器

2.2.1 温湿度数据寄存器

2.2.2 参数寄存器

2.2.3 一个参数配置Demo

2.3 温湿度值转换

2.4 HS3003应用电路

2.4.1 PIN引脚定义

2.4.2 sensor 应用电路

3 驱动程序实现

4 测试程序实现

5 编译和验证

6 波形分析


概述

       本文主要介绍platform tree架构下i2c驱动的使用方法,并介绍如何使用i2c-tools来探测总线上的设备信息。然后详细介绍HS3003的芯片的使用方法,并使用i2c驱动接口,实现该芯片的驱动程序,然后再板卡上测试验证该程序,并通过逻辑分析仪查看这个读写过程的波形。

1 探究platform tree下的i2c

1.1 platform tree下的i2c驱动

启动板卡,查询/dev/下驱动情况 , 使用命令:

ls /dev/  -l

执行命名后,可列出该目录下所有的驱动信息,找出i2c驱动,如下:

由上图可得,板卡driver下,由两个i2c接口,分别为i2c-0和i2c-1

1.2 查看i2c总线下的设备

        i2c总线上可以挂载多个device,其要求在同一条总线上,每个设备的地址必须唯一性。如果两个设备的地址一样,会出现时序混乱。

       下面通过命令来探测一下i2c总线下的设备情况

1) 查看i2c-0下设备情况

使用命令

 i2cdetect -a 0

执行该命令后,列出设备地址信息: 该总线下有两个设备,其地址分别为:0x1a和0x1e

2) 查看i2c-1下设备情况

使用命令

i2cdetect -a 1

 执行该命令后,列出设备地址信息: 该总线下有三个设备,其地址分别为:0x40,0x44,和0x44

1.3 使用命令读写设备寄存器

      使用 i2c-tools 工具包提供了一些非常方便的工具来对系统的 I2C 总线进行调试。下面以HS3003为例,使用i2c-tools工具来操作其内部的寄存器。

1)查看设备地址0x44下所有的寄存器信息 

i2cdump  -f -y 1 0x44

2) 读取寄存器的值

i2cget -f -y 1 0x44 0x06

3)写寄存器的值

i2cset -f -y 1 0x44 0xA0 0x10 0x40

2 认识HS3003

2.1 HS3003特性

HS3003是瑞萨公司出品的一款高精度温湿度传感器,下面看看其主要参数:

2.2 HS3003寄存器

       HS3003采用标准的I2C通信方式,对其寄存器的操作必须遵循标准的I2C时序。现在分析如何操作其寄存器,读取数据。

2.2.1 温湿度数据寄存器

温湿度数据寄存器的数据位定义如下,其主要由四个字节组成一个32bit数据, bit-0 和 bit-1为Mask,其主要用来标记当前数据是否有效(mask =0 数据有效), 温度数据(低16 bit ): bit-2 ~ bit ~ 15

湿度数据( 高16 bit): bit-8 ~ bit 13 

采样温湿度数据间隔时间根据配置的ADC精度来选取,精度要求越高,采样所需要的时间就越长。那么读取数据时,需要等待的时间就越长。

2.2.2 参数寄存器

精度参数如下:

参数寄存器列表

如何配置参数呢?芯片手册给了四个步骤

2.2.3 一个参数配置Demo

下面给一个各一个配置参数的范例,配置humidity 的采集精度为12bit, 那么参数设定如下:

  bit-10:  0

  bit-11: 1

typedef struct
{unsigned short res1          : 10;unsigned short tempdata      : 2;unsigned short res2          : 4;
} stru_para_bit;typedef struct{union{unsigned short data;stru_para_bit para_bit;};
}stru_para;int hs300x_init(void)
{int ret;unsigned char   buff[4];stru_para para;// step-1 write data from 0x06buff[0] = 0x06;buff[1] = 0;buff[2] = 0;ret = write(fd, buff, 3);if( ret < 0 ){printf("read temper cmd to hs3003 register failure.\n");return -1;}// step -2: read reg - 0x81buff[0] = 0x81;ret = write(fd, buff, 1);if( ret < 0 ){printf("read cmd to hs3003 register failure. \r\n");return -1;}ret = read(fd, buff, 2);if( ret < 0 ){printf("write cmd to hs3003 register failure.\n");return -1;}printf(" read reg: 0x81 - data0 = %02x data1 = %02x \r\n",buff[0],buff[1]);//step -3:  write data from 0x46para.data = buff[0]<<8 | buff[1];para.para_bit.tempdata = 1; buff[0] = 0x46;buff[1] = (unsigned char)para.data;buff[2] = (unsigned char)(para.data>>8);ret = write(fd, buff, 3);if( ret < 0 ){printf("write cmd to hs3003 register failure. \r\n");return -1;}printf("write reg: 0x46 - data0 = %02x data1 = %02x \r\n",buff[0],buff[1]);return 0;
}

2.3 温湿度值转换

datasheet中给的转换公式如下:

下面看看在程序中如何实现温湿度值转换的

首先定义一个数据结构


typedef struct
{unsigned int mask          : 2;unsigned int tempdata      : 14;unsigned int humidydata    : 14;unsigned int res           : 2;
} Datafetch_bit;typedef struct{union{unsigned int data;Datafetch_bit fetch_bit;};float tempval;float humival;
}hs300x_data;

       从温湿度的数据寄存器中读取出来有四个分别为8bit的数据, 将该数据拼成一个32bit的数据,在赋值给data, 上述数据结构会自动解析该数据。通过mask位判断数据是否有效。

    phs300x_data->data = ((buff[0] << 24U) |(buff[1] << 16U) |(buff[2] << 8U)|(buff[3]));if( phs300x_data->fetch_bit.mask == HS300X_DATA_VALID){// get temperature value val = phs300x_data->fetch_bit.tempdata;phs300x_data->tempval = (double)val/(double)(HS300X_DATA_FACTOR) * 165.0 - 40;printf(" - TM(C): %.2f \r\n", phs300x_data->tempval);// get humidity value val = phs300x_data->fetch_bit.humidydata;phs300x_data->humival = (double)val/(double)(HS300X_DATA_FACTOR) * 100.0;printf(" - HM(\%): %.2f \r\n", phs300x_data->humival);}

2.4 HS3003应用电路

2.4.1 PIN引脚定义

传感器封装

pin引脚

2.4.2 sensor 应用电路

下面是传感器模块的实际应用电路:

3 驱动程序实现

编写驱动程序代码:

/***************************************************************
Copyright  2024-2029. All rights reserved.
文件名     : drv_hs3003.c
作者       : tangmingfei2013@126.com
版本       : V1.0
描述       : hs3003驱动程序
其他       : 无
日志       : 初版V1.0 2024/02/01***************************************************************/
#include <sys/types.h>
#include <sys/stat.h>
#include <linux/types.h>
#include <linux/i2c-dev.h>
#include <linux/i2c.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <stdlib.h>
#include <linux/fs.h>
#include <errno.h>
#include <assert.h>
#include <string.h>
#include <time.h>/* hs3003 i2c address */
#define HS300X_ADDR                          (0x44U)#define HS300X_DATA_VALID                    (0x00U)
#define HS300X_DATA_STALE                    (0x01U)
#define HS300X_STATUS_MASK                   (0xC0000000U)
#define HS300X_STATUS_POS                    (30U)#define HS300X_DATA_MASK                     (0x3FFFFFFCU)
#define HS300X_HUMI_DATA_MASK                (0x3FFF0000U)
#define HS300X_HUMI_DATA_POS                 (16U)
#define HS300X_TEMP_DATA_MASK                (0x0000FFFCU)
#define HS300X_TEMP_DATA_POS                 (2U)#define HS300X_REG_R_TRG                     0X06
#define HS300X_REG_W_TRG                     0X46/* calculation formula, 2^14 - 1 */
#define HS300X_DATA_FACTOR                   (16383U)#define DEV_FILE                              "/dev/i2c-1"typedef struct
{unsigned int mask          : 2;unsigned int tempdata      : 14;unsigned int humidydata    : 14;unsigned int res           : 2;
} Datafetch_bit;typedef struct{union{unsigned int data;Datafetch_bit fetch_bit;};float tempval;float humival;
}hs300x_data;typedef struct
{unsigned short res1          : 10;unsigned short tempdata      : 2;unsigned short res2          : 4;
} stru_para_bit;typedef struct{union{unsigned short data;stru_para_bit para_bit;};
}stru_para;static int fd = -1;static int hs300x_drv_init(void)
{fd = open(DEV_FILE, O_RDWR);if( fd < 0 ){close( fd );printf("%s %s i2c device open failure: %s\n", __FILE__, __FUNCTION__, strerror(errno));return -1;}ioctl(fd, I2C_TENBIT, 0);ioctl(fd, I2C_SLAVE, HS300X_ADDR);printf("init hs3003!\r\n");return fd;
}int hs300x_init(void)
{int ret;unsigned char   buff[4];stru_para para;hs300x_drv_init();// step-1 write data from 0x06buff[0] = 0x06;buff[1] = 0;buff[2] = 0;ret = write(fd, buff, 3);if( ret < 0 ){printf("read temper cmd to hs3003 register failure.\n");return -1;}// step -2: read reg - 0x81buff[0] = 0x81;ret = write(fd, buff, 1);if( ret < 0 ){printf("read cmd to hs3003 register failure. \r\n");return -1;}ret = read(fd, buff, 2);if( ret < 0 ){printf("write cmd to hs3003 register failure.\n");return -1;}printf(" read reg: 0x81 - data0 = %02x data1 = %02x \r\n",buff[0],buff[1]);//step -3:  write data from 0x46para.data = buff[0]<<8 | buff[1];para.para_bit.tempdata = 1; buff[0] = 0x46;buff[1] = (unsigned char)para.data;buff[2] = (unsigned char)(para.data>>8);ret = write(fd, buff, 3);if( ret < 0 ){printf("write cmd to hs3003 register failure. \r\n");return -1;}printf("write reg: 0x46 - data0 = %02x data1 = %02x \r\n",buff[0],buff[1]);return 0;
}int hs300x_read_value(hs300x_data *phs300x_data)
{int ret;unsigned char buff[4];unsigned int val;stru_para para;// write data to 0xa0para.data = 0;buff[0] = 0xa0;buff[1] = (unsigned char)para.data;buff[2] = (unsigned char)(para.data>>8);ret = write(fd, buff, 3);if( ret < 0 ){printf("write cmd to hs3003 register failure.\n");return -1;}sleep(1);ret = read(fd, buff, 4);if( ret < 0 ){printf("get the hs3003 value failure.\n");return -1;}printf(" - data0 = %02x data1 = %02x data3 = %02x data4 = %02x \r\n",buff[0],buff[1],buff[2],buff[3]);phs300x_data->data = ((buff[0] << 24U) |(buff[1] << 16U) |(buff[2] << 8U)|(buff[3]));if( phs300x_data->fetch_bit.mask == HS300X_DATA_VALID){// get temperature value val = phs300x_data->fetch_bit.tempdata;phs300x_data->tempval = (double)val/(double)(HS300X_DATA_FACTOR) * 165.0 - 40;printf(" - TM(C): %.2f \r\n", phs300x_data->tempval);// get humidity value val = phs300x_data->fetch_bit.humidydata;phs300x_data->humival = (double)val/(double)(HS300X_DATA_FACTOR) * 100.0;printf(" - HM(\%): %.2f \r\n", phs300x_data->humival);}return 0;
}

4 测试程序实现

编写测试程序来验证该驱动程序

int main(void)
{hs300x_data stru_hs300x;int count_run = 10000;int set;set = hs300x_init();if( set < 0){printf("initial hs3003 failure.\r\n");return -1;}while( count_run > 0){set = hs300x_read_value( &stru_hs300x );if(set != -1){//printf( "\r\n lux:  %d ", temper);}else{printf("read isl19035 failure. \r\n");}count_run--;sleep(1);}return 0;
}

5 编译和验证

编写Makefile ,编译测试代码,并将其copy到共享目录下,方便在板卡中运行该App

CFLAGS= -Wall -O2
CC=/home/ctools/gcc-linaro-4.9.4-arm-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc
STRIP=/home/ctools/gcc-linaro-4.9.4-arm-linux-gnueabihf/bin/arm-linux-gnueabihf-stripdev_13_hs3003: dev_13_hs3003.o$(CC) $(CFLAGS) -o dev_13_hs3003 dev_13_hs3003.o$(STRIP) -s dev_13_hs3003clean:rm -f dev_13_hs3003 dev_13_hs3003.o

编译代码

运行App, 测试程序能正确地读取温度和湿度值。

6 波形分析

1)触发数据转换命令

2)读数据波形

3) 逻辑分析仪解析到的数据列表

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

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

移动端设置position: fixed;固定定位,底部出现一条缝隙,不知原因,欢迎探讨!!!

1、问题 在父盒子中有一个子盒子&#xff0c;父盒子加了固定定位&#xff0c;需要子盒子上下都有要边距&#xff0c;用margin或者padding挤开时&#xff0c;会出现缝隙是子盒子背景颜色的。 测试过了&#xff0c;有些手机型号有&#xff0c;有些没有&#xff0c;微信小程序同移…

LeetCode 0993. 二叉树的堂兄弟节点:深度优先搜索(BFS)

【LetMeFly】993.二叉树的堂兄弟节点&#xff1a;深度优先搜索(BFS) 力扣题目链接&#xff1a;https://leetcode.cn/problems/cousins-in-binary-tree/ 在二叉树中&#xff0c;根节点位于深度 0 处&#xff0c;每个深度为 k 的节点的子节点位于深度 k1 处。 如果二叉树的两个…

java_error_in_pycharm.hprof文件是什么?能删除吗?

java_error_in_pycharm.hprof文件是什么&#xff1f;能删除吗&#xff1f; &#x1f335;文章目录&#x1f335; &#x1f333;引言&#x1f333;&#x1f333;hprof格式文件介绍&#x1f333;&#x1f333;java_error_in_pycharm.hprof文件什么情况下能删除&#x1f333;&…

【Nicn的刷题日常】之有序序列合并

1.题目描述 描述 输入两个升序排列的序列&#xff0c;将两个序列合并为一个有序序列并输出。 数据范围&#xff1a; 1≤&#xfffd;,&#xfffd;≤1000 1≤n,m≤1000 &#xff0c; 序列中的值满足 0≤&#xfffd;&#xfffd;&#xfffd;≤30000 0≤val≤30000 输入描述…

Java 将TXT文本文件转换为PDF文件

与TXT文本文件&#xff0c;PDF文件更加专业也更适合传输&#xff0c;常用于正式报告、简历、合同等场合。项目中如果有使用Java将TXT文本文件转为PDF文件的需求&#xff0c;可以查看本文中介绍的免费实现方法。 免费Java PDF库 本文介绍的方法需要用到Free Spire.PDF for Java…

波卡 2023 四季度报告:开发者数量位列加密生态前三,五项新技术将于今年发布

作者&#xff1a;Nicholas Garcia&#xff5c;Messari 研究分析师 编译&#xff1a;OneBlock 原文&#xff1a;https://messari.io/report/state-of-polkadot-q4-2023?utm_mediumorganic_social&utm_sourcetwitter_messari&utm_campaignstate_of_polkadot_q4_2023 …

07:Kubectl 命令详解|K8S资源对象管理|K8S集群管理(重难点)

Kubectl 命令详解&#xff5c;K8S资源对象管理&#xff5c;K8S集群管理 kubectl管理命令kubectl get 查询资源常用的排错命令kubectl run 创建容器 POD原理pod的生命周期 k8s资源对象管理资源文件使用资源文件管理对象Pod资源文件deploy资源文件 集群调度的规则扩容与缩减集群更…

Mysql-Explain-使用说明

Explain 说明 explain SELECT * FROM tb_category_report;id&#xff1a;SELECT识别符&#xff0c;这是SELECT查询序列号。select_type&#xff1a;表示单位查询的查询类型&#xff0c;比如&#xff1a;普通查询、联合查询(union、union all)、子查询等复杂查询。table&#x…

[设计模式Java实现附plantuml源码~行为型]请求的链式处理——职责链模式

前言&#xff1a; 为什么之前写过Golang 版的设计模式&#xff0c;还在重新写Java 版&#xff1f; 答&#xff1a;因为对于我而言&#xff0c;当然也希望对正在学习的大伙有帮助。Java作为一门纯面向对象的语言&#xff0c;更适合用于学习设计模式。 为什么类图要附上uml 因为很…

多维时序 | Matlab实现RF-Adaboost随机森林结合Adaboost多变量时间序列预测

多维时序 | Matlab实现RF-Adaboost随机森林结合Adaboost多变量时间序列预测 目录 多维时序 | Matlab实现RF-Adaboost随机森林结合Adaboost多变量时间序列预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 1.Matlab实现RF-Adaboost随机森林结合Adaboost多变量时间序列预…

YOLOv8改进 | 利用训练好权重文件计算YOLOv8的FPS、推理每张图片的平均时间(科研必备)

一、本文介绍 本文给大家带来的改进机制是利用我们训练好的权重文件计算FPS,同时打印每张图片所利用的平均时间,模型大小(以MB为单位),同时支持batch_size功能的选择,对于轻量化模型的读者来说,本文的内容对你一定有帮助,可以清晰帮你展示出模型速度性能的提升以及轻量…

极致成本,如何基于容器计算服务 ACS 打造企业级幻兽帕鲁私服 SaaS 服务?

作者&#xff1a;韩运韬&#xff08;青炽&#xff09; 《幻兽帕鲁》是一款最近大热的开放世界生存游戏。据报道。上市不到一周&#xff0c;《幻兽帕鲁》销量已突破 700 万份&#xff0c;成为名副其实的现象级游戏。根据游戏数据库网站 SteamDB 的数据显示&#xff0c;《幻兽帕…

QTabWidget和QTabBar控件样式设置(qss)

QTabWidget和QTabBar控件样式设置 1、QTabWidget样式可自定义的有哪些示例&#xff1a;效果图 2、QTabBar样式可自定义的有哪些示例效果图 1、QTabWidget样式可自定义的有哪些 QTabWidget::pane{} 定义tabWidgetFrameQTabWidget::tab-bar{} 定义TabBar的位置QTabWidget::tab{}定…

性能篇:如何解决高并发下 I/O 瓶颈?

我们可以有效地解决高并发下I/O瓶颈的问题&#xff0c;提升系统的性能。当然&#xff0c;实际场景中的优化可能涉及到更多的细节和技术&#xff0c;但希望这篇文章能为大家提供一些思路和方法。​ 引言 大家好&#xff0c;我是小米&#xff01;今天我们来聊一个在高并发场景…

【Netty技术专题】「原理分析系列」Netty强大特性之Native transports扩展开发实战

Netty强大特性之Native transports技术原理分析 背景介绍JNI概念介绍不同平台的JNI实现 使用Native transports库Maven的分类器&#xff08;Classifier&#xff09;使用Linux native transport使用MacOS/BSD native transport库构建native transport库Linux版本要求MacOS/BSD版…

制度下降算法c语言

#include<stdio.h> #include<string.h> int location0; //遍历字符串的当前位置 char arr[20]"idid*id#"; void error(); //错误提示函数 /* 每一个非终结符都构造一个函数 */ void E(char t); void Ep(char t); void T(char t); void Tp(char t);…

Python 线性回归可视化 并将回归函数放置到图像上

import matplotlib.pyplot as plt import scipy import seaborn as sns# 加载内置的数据集 df sns.load_dataset(tips)#create regplot p sns.regplot(xtotal_bill, ytip, datadf)#calculate slope and intercept of regression equation slope, intercept, r, p, sterr sci…

基于BatchNorm的模型剪枝【详解+代码】

文章目录 1、BatchNorm&#xff08;BN&#xff09;2、L1与L2正则化2.1 L1与L2的导数及其应用2.2 论文核心点 3、模型剪枝的流程 ICCV经典论文&#xff0c;通俗易懂&#xff01;论文题目&#xff1a;Learning Efficient Convolutional Networks through Network Slimming卷积后能…

《动手学深度学习(PyTorch版)》笔记7.6

注&#xff1a;书中对代码的讲解并不详细&#xff0c;本文对很多细节做了详细注释。另外&#xff0c;书上的源代码是在Jupyter Notebook上运行的&#xff0c;较为分散&#xff0c;本文将代码集中起来&#xff0c;并加以完善&#xff0c;全部用vscode在python 3.9.18下测试通过&…

CC工具箱使用指南:【获取字段的所有唯一值】

一、简介 这个工具的目的是获取选定要素图层的字段的所有唯一值。 一般就是用于查看&#xff0c;比如说看一下规划用地有多少种地类&#xff0c;都是哪些地类。 二、工具参数介绍 点击【信息获取】组里的【获取字段的所有唯一值】工具&#xff1a; 即可打开下面的工具框界面…