在全志H616核桃派开发板上配置I2C引脚并读取温度数据

news2024/11/16 15:57:39

配置引脚

找到板子上的i2c引脚

为了方便查找,我们加入了一个显示功能引脚位置的功能,运行以下命令,查看板子的40pin引脚上有几个可用i2c

gpio pin i2c

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

启用i2c

我们使用set-device指令来使能/关闭指定设备的底层驱动,使能后,引脚就会由gpio模式切换为对应的引脚复用功能。(配置后要重启才能生效)

首先查看各设备的状态

set-device status

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

运行指令启用i2c1,注意要重启后才能生效

sudo set-device enable i2c1

重启后查看引脚状态,可以看到3和5都处于alt5了 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

并且存在/dev/i2c-1这个文件,因为后续我们需要通过操作这个文件来控制i2c通讯

i2c读写程序

linux下一切皆是文件。而i2c1也被抽象为/dev/i2c-1这个文件。通过open打开它,用ioctl触发读写,close关闭文件。

1. 打开文件

linux下一切皆是文件,先使用open函数打开我们要操作的设备对应文件,获取文件描述符。

需要这些头文件

#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>

open设备节点

int fd =open("/dev/i2c-1", O_RDWR);
if(fd <0)
{
perror("Fail to Open\n");
return-1;
}

2. i2c_msg

linux下操作i2c不是使用write和read函数,而是使用一个i2c_msg结构体来配置从i2c从起始到停止之间要做的内容。

  • addr: 目标地址
  • flags: 读还是写
  • buf : buf的地址,根据flags是读还是写,会在地址帧发送后,将其内容发送出去,或是读取总线内容存放进来。
  • len : buf的大小

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

3. 向i2c总线写

从德州仪器那下载的i2c时序图↓ 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

加入我现在想往地址是0x3c的设备上,把寄存器0x01赋值为0x55,那msg结构体的设置就该如下。addrflags共同决定第一帧地址帧的内容。因为flags是写,所以在地址帧发送完后,会将buf的内容依次发送出去。

首先,需要这些头文件

#include<sys/ioctl.h>
#include<linux/i2c.h>
#include<linux/i2c-dev.h>
uint8_t addr =0x3c;
uint8_t reg =0x01;
uint8_t value =0x55;

uint8_t buf[2];
    buf[0]= reg;//寄存器
    buf[1]= value;//数据

structi2c_msg msg;
    msg.addr = addr;//目标地址
    msg.flags =0;//读写标志
    msg.len =2;//buf长度
    msg.buf = buf;

编写完msg后,还需要创建i2c_rdwr_ioctl_data结构体,写清楚本次i2c通信要处理几个msg,然后用ioctl函数触发一次i2c通信。

structi2c_rdwr_ioctl_data data;
    data.msgs =&msg;
    data.nmsgs =1;

int ret =ioctl(fd, I2C_RDWR,&data);
if(ret <0)
printf("i2c write failed");
return ret;

4. 从i2c总线读

从德州仪器那下载的i2c时序图↓ 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我现在想往地址是0x3c的设备上,读取寄存器0x01的值.

根据时序图,需要两个msg,第一个msg是写,地址帧后只跟寄存器编号。第二个msg是读,地址帧发完就是从机将该寄存器的内容返回。

uint8_t addr =0x3c;
uint8_t reg =0x01;
uint8_t value;

structi2c_msg msgs[2];
    msgs[0].addr = addr;
    msgs[0].flags =0;
    msgs[0].len =1;
    msgs[0].buf =&reg;

    msgs[1].addr = addr;
    msgs[1].flags = I2C_M_RD;
    msgs[1].len =1;
    msgs[1].buf =&value;

编写完msg后,还需要创建i2c_rdwr_ioctl_data结构体,写清楚本次i2c通信要处理几个msg,然后用ioctl函数触发一次i2c通信。

structi2c_rdwr_ioctl_data data;
    data.msgs = msgs;
    data.nmsgs =2;

int res =ioctl(fd, I2C_RDWR,&data);
if(res <0)
printf("Read failed\n");

return res;

5. 关闭文件

每次open后记得调用close来手动关闭,不然文件描述符会保留直到程序关闭。而系统限制单个程序最大只能同时打开1024个文件,如果程序不停的open却不close,没一会就要报错退出了。

close(fd);

示例-从mlx90614中读取温度数据

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

首先阅读mlx90614的手册,查看他的读写时序↓

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

根据手册给的时序,这里要创建两个msg,第一个是写,buf内存放读取温度的命令0x07。第二个是读,连续3个字节,其中前两个是温度数据。再加上mlx90614的地址是0,最后代码如下

#include<stdio.h>
#include<stdint.h>
#include<string.h>

#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>

#include<sys/ioctl.h>
#include<linux/i2c.h>
#include<linux/i2c-dev.h>


#defineDEV_I2C"/dev/i2c-1"

//计算mlx9614实际温度值
uint16_tmlx_data_transform(uint8_t Data[3])
{
uint16_t temp;
    temp =(Data[1]<<8)+ Data[0];// 高位与低位结合
    temp = temp *2-27315;// 将数据扩大100倍
return temp;
}

intmain()
{

int fd =open(DEV_I2C, O_RDWR);
if(fd <0)
{
perror("Fail to Open\n");
return-1;
}

uint8_t addr =0;
uint8_t reg =0x07;
uint8_t value[3];

structi2c_msg msgs[2];
    msgs[0].addr = addr;
    msgs[0].flags =0;
    msgs[0].len =1;
    msgs[0].buf =&reg;

    msgs[1].addr = addr;
    msgs[1].flags = I2C_M_RD;
    msgs[1].len =3;
    msgs[1].buf = value;

structi2c_rdwr_ioctl_data data;
    data.msgs = msgs;
    data.nmsgs =2;

while(1)
{

int res =ioctl(fd, I2C_RDWR,&data);
if(res <0)
printf("Read failed\n");
printf("temp=[%d]\r\n",mlx_data_transform(value));
sleep(1);
}
}

我将代码写在文件i2c.c内,想将其编译成名为exe的可执行文件,只需要执行下面这一句

gcc i2c.c -o exe

执行结果如下,显示我周围环境的温度是30左右,手靠近后上升到34:

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

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

相关文章

视频汇聚/云存储/安防监控EasyCVR接入GB28181设备未回复ack信息的原因排查

安防视频监控/视频集中存储/云存储/磁盘阵列EasyCVR平台部署轻快&#xff0c;可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等&#xff0c;以及支持厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等。 用户反馈&#xff0c;设备通过国标GB28181注…

Docker 容器间通讯

1、虚拟ip/访问 同一网络 安装docker时&#xff0c;docker会默认创建一个内部的桥接网络docker0&#xff0c;每创建一个容器分配一个虚拟网卡&#xff0c;容器之间(包括宿主机)可以根据分配的ip互相访问(ps:其他主机(包括其他主机的容器)无法ping通docker容器ip无法访问&#…

RepOptimizer原理与代码解析(ICLR 2023)

paper&#xff1a;Re-parameterizing Your Optimizers rather than Architectures offcial implementation&#xff1a;https://github.com/dingxiaoh/repoptimizers 背景 神经网络的结构设计是将先验知识融入模型中。例如将特征转换建模成残差相加的形式&#xff08;\(yf(x…

Zoho CRM怎么样?云衔科技为企业提供采购优惠!

企业对于客户关系管理&#xff08;CRM&#xff09;系统的需求日益增加&#xff0c;Zoho CRM作为一款备受赞誉的国际CRM服务提供商&#xff0c;凭借其全面的功能、出色的用户体验和卓越的性价比&#xff0c;成为了众多企业数字化转型的得力助手。 Zoho CRM是一款覆盖客户全生命…

Vue状态管理深度剖析:Vuex vs Pinia —— 从原理到实践的全面对比

&#x1f525; 个人主页&#xff1a;空白诗 文章目录 &#x1f44b; 引言&#x1f4cc; Vuex 基础知识核心构成要素示例代码 &#x1f4cc; Pinia 基础知识核心构成要素示例代码 &#x1f4cc; Vuex与Pinia的区别&#x1f4cc; 使用示例与对比&#x1f4cc; 总结 &#x1f44b;…

Transormer(2)-位置编码

位置编码公式 偶数位置用sin,奇数位置用cos. d_model 表示token的维度&#xff1b;pos表示token在序列中的位置&#xff1b;i表示每个token编码的第i个位置&#xff0c;属于[0,d_model)。 torch实现 import math import torch from torch import nn from torch.autograd im…

Vue 3 的 setup语法糖工作原理

前言 我们每天写vue3项目的时候都会使用setup语法糖&#xff0c;但是你有没有思考过下面几个问题。setup语法糖经过编译后是什么样子的&#xff1f;为什么在setup顶层定义的变量可以在template中可以直接使用&#xff1f;为什么import一个组件后就可以直接使用&#xff0c;无需…

【如何让论文中摘要后面的内容不出现在目录中】

首先选择摘要二字&#xff0c;设置为一级标题&#xff0c;然后选择摘要后面的内容设置为正文样式&#xff0c;再选择这一部分看一下是不是都是正文大纲级别&#xff0c;如果是那就可以了。 具体流程如下 1、选择摘要二字&#xff0c;设置为一级标题样式 2、选择摘要后面的文…

FreeRTOS学习——FreeRTOS队列(下)之队列创建

本篇文章记录我学习FreeRTOS队列创建的知识。主要分享队列创建需要使用的初始化函数、队列复位函数。 需要进一步了解FreeRTOS队列的相关知识&#xff0c;读者可以参考以下文章&#xff1a; FreeRTOS学习——FreeRTOS队列&#xff08;上&#xff09;_freertos 单元素队列-CSDN博…

scikit-learn机器学习要点总结

目录 一、机器学习总体流程二、引入数据集三、将数据集转换为DataFrame四、可视化数据五、数据预处理&#xff08;一&#xff09;数据标准化&#xff08;二&#xff09;独热编码 六、数据集划分为训练集和测试集七、创建模型估计器(estimator)&#xff08;一&#xff09;用于回…

人力资源(HR)OKR 案例

HR人员 #OKR# 是一个很好的方法来建立一致性&#xff0c;吸引团队成员&#xff0c;并实现高绩效。 在本文中&#xff0c;我们将回答以下问题&#xff1a; 如何写好HR OKR &#xff1f; 什么是好的HR OKR 的例子 &#xff1f; 我应该在我的HR OKR 中填写什么 &#xff1f; 如何…

stream( ).collect ( Collectors.groupingBy ( ) ) 的用法

文章目录 第一种解释1、基本用法2、指定值收集器3、多级分组4、常见应用场景和用处 第二种解释1、基本语法2、示例3、更复杂的用法 第一种解释 Collectors.groupingBy 是 Java 8 引入的 Stream API 中的一个收集器&#xff08;Collector&#xff09;&#xff0c;它用于将流&am…

【NumPy】关于numpy.transpose()函数,看这一篇文章就够了

&#x1f9d1; 博主简介&#xff1a;阿里巴巴嵌入式技术专家&#xff0c;深耕嵌入式人工智能领域&#xff0c;具备多年的嵌入式硬件产品研发管理经验。 &#x1f4d2; 博客介绍&#xff1a;分享嵌入式开发领域的相关知识、经验、思考和感悟&#xff0c;欢迎关注。提供嵌入式方向…

16.js数学方法和进制转换

数学方法 &#xff08;1&#xff09;Math.random() 默认生成0-1的随机数 var resMath.random() console.log(res) &#xff08;2&#xff09;Math.round(数字) 取整&#xff1a;正数-四舍五入 负数-5舍6入 var resMath.round(11)console.log(res) //11var res1Math.round(1…

2024-5-6-从0到1手写配置中心Config之实现配置中心客户端

配置加载原理 在Spring中PropertySource类实现了所有属性的实例化。 启动赋值&#xff1a; 定义自定义属性配置源&#xff0c;从config-server获取全局属性&#xff1b;Spring启动时&#xff0c;插入自定义属性配置源&#xff1b;绑定属性会优先使用&#xff0c;给自定义属性…

下拉框操作/键鼠操作/文件上传

在我们做UI自动化测试的时候&#xff0c;会有一些元素需要特殊操作&#xff0c;比如下拉框操作/键鼠操作/文件上传。 下拉框操作 在我们很多页面里有下拉框的选择&#xff0c;这种元素怎么定位呢&#xff1f;下拉框分为两种类型&#xff1a;我们分别针对这两种元素进行定位和…

移动硬盘容量消失无法读取的解决方案

在数字化时代&#xff0c;数据的存储和备份变得尤为重要。移动硬盘作为一种便捷、大容量的存储设备&#xff0c;受到许多人的青睐。然而&#xff0c;有时我们可能会遭遇这样的问题&#xff1a;移动硬盘不显示容量且无法访问。这种情况无疑给我们的数据存储和管理带来了巨大的困…

sequence cache太小导致enq: SQ – contention

当业务卡的时候&#xff0c;发现大量等待事件为enq: SQ – contention&#xff0c;检查awr的top 5事件&#xff1a; sql语句对sequence的调用非常频繁&#xff1a; 对这些语句排查发现sequence cache值均为默认20&#xff0c;调大cache到1000值&#xff1a; SQL> select SE…

基于YOLOV8/YOLOV5的PCB板缺陷检测识别系统

摘要&#xff1a; 本文详细阐述了一个利用深度学习进行PCB板缺陷检测的系统&#xff0c;该系统集成了最新的YOLOv8算法&#xff0c;并与YOLOv7、YOLOv6、YOLOv5等先前版本进行了性能比较。该系统能够在图像、视频、实时视频流和批量文件中精确地识别和分类PCB板缺陷。文中不仅深…

WiFi蓝牙模块厂家带你了解蓝牙模块功率的等级

目前蓝牙技术的突破已经让许多蓝牙模块厂家从业者忘记了很多专业术语&#xff0c;比如Class1&#xff0c;Class2等&#xff0c;那么我们就蓝牙模块发射功率来做个详细了解。   针对功率来说&#xff0c;低功耗蓝牙和经典蓝牙又有区别。   低功耗蓝牙没有功率的级别&#xf…