Linux I2C调试分享

news2024/11/17 19:44:11

I2C简介

I2C(Inter-Integrated Circuit)是一种多主机、两线制、串行计算机总线,用于连接低速外围设备到处理器或微控制器。这种通信协议由Philips Semiconductor(现在的NXP Semiconductors)在1980年代初期开发。

I2C的特点

  • 两线制总线:只需要两根线,一根是数据线SDA(Serial Data Line),另一根是时钟线SCL(Serial Clock Line)。
  • 多主机能力:允许多个主设备在同一总线上通信。
  • 地址分配:每个从设备都有一个唯一的地址。
  • 简单性和灵活性:硬件实现简单,支持不同速度的数据传输。

I2C通信过程

  1. 起始信号:主设备通过将SDA从高电平拉低到低电平,同时SCL保持高电平来发出起始信号。
  2. 地址和读写位:主设备发送从设备地址和一个读/写位(0表示写,1表示读)。
  3. 应答信号:从设备接收到地址后,如果识别到自己的地址,会在时钟线的下一个高电平期间将数据线拉低,表示应答(ACK)。
  4. 数据传输:数据按字节传输,每个字节后跟一个应答位。
  5. 停止信号:通信结束时,主设备发出停止信号,即在SCL为高电平时,将SDA从低电平变为高电平。

start:开始信号,SCL置高电平 SDA拉低

bit7~bit1:I2C从设备地址

bit0:读写位 写为0,读为1,与bit7~bit1 凑成8位地址,所以有些设备分为读地址,写地址。

 ACK:响应信号,发送完地址后,主设备会置高,从设备响应后会马上拉低,主设备读取到拉低,判断设备存在

stop:结束信号,SCL置高,SDA拉高

数据传输速率

I2C协议支持多种速率模式,包括:

  • 标准模式:最高100kbps
  • 快速模式:最高400kbps
  • 快速模式+:最高1Mbps
  • 高速模式:最高3.4Mbps
  • 超快模式:最高5Mbps(仅限单向传输)

I2C地址格式

I2C设备通常使用7位或10位地址格式,这使得总线上可以有多个设备同时存在而不发生冲突。

I2C总线冲突和仲裁

当两个主设备同时尝试控制总线时,I2C协议提供了仲裁机制来处理冲突,确保只有一个主设备能够控制总线。

i2c驱动开发:

以i2c设备芯片 tda7313为例,数据手册如下

tda7313挂载在i2c5下,设备树如下:

&i2c5 {
    //时钟100k 
	clock-frequency = <100000>;
    status = "okay";
    //@44设备地址
	tda7313: tda7313@44 {
	        status = "okay";
            compatible = "st,tda7313";
            //描述设备地址
            reg = <0x44>;
    };
}

Linux下发送I2C数据有三种方式:

 1.i2c驱动 

 2.系统应用编程

 3.命令发送

//i2c驱动
#include <linux/init.h>
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/of_address.h>

int myprobe(struct i2c_client *cli, const struct i2c_device_id *id)
{
	int ret;
	struct i2c_msg msgs[1];
	char addr[2] = { 0x11,0x22 }; //2个数据
	msgs[0].addr = cli->addr;//设备地址 0x44
	msgs[0].flags = 0;//读写标志位
	msgs[0].len = 2;//数据长度
	msgs[0].buf = addr;//数据地址
    //执行i2c_transfer = 1个开始信号 + 写地址 +  0x11 + 0x22 + 停止信号
    ret = i2c_transfer(cli->adapter, msgs, 1);
	if (ret < 0){
		msleep(10);
	}
	return 0;
}
int myremove(struct i2c_client *cli)
{
	return 0;
}
struct i2c_device_id ids[] = {
	{ "st,tda7313", 0 },
	{},
};
MODULE_DEVICE_TABLE(i2c, ids);
//配对节点
static const struct of_device_id tda7313_of_match[] = {
	{ .compatible = "st,tda7313" },
	{},
};
struct i2c_driver mydrv = {
    .probe = myprobe,
    .remove = myremove,
    .driver = {
        .name = "tda7313",
        .of_match_table = tda7313_of_match,
        .owner = THIS_MODULE,
    },
    .id_table = ids,
};

module_i2c_driver(mydrv);
MODULE_LICENSE("GPL");

Linux系统编程:

 设备树打开i2c-5后会在产生/dev/i2c-5节点:

rk3568_s:/ $ ls /dev/i2c-5 -l
crw-rw-rw- 1 system system 89,   5 2017-08-04 17:00 /dev/i2c-5

可以对该节点操作i2c

 i2c_test.c

// 2.系统应用编程
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#include <stdint.h>
#define I2C_ADDR 0x44
int fd;
unsigned char Tuner_WriteBuffer(unsigned char *buf, uint16_t len)
{
	uint16_t i;
	uint8_t r;
	if (fd < 0)
	{
		printf("fd < 0");
		return -1;
	}
    //i2c数据填充
	struct i2c_msg msgs[1] = {
		{I2C_ADDR, 0, len, buf},//第一个I2c地址,写标志位,长度,buf数据地址
	};
	struct i2c_rdwr_ioctl_data idata = {
		.msgs = msgs,
		.nmsgs = 1, //对应msgs长度
	};
    //下发i2c驱动,驱动帮你写数据
	if (ioctl(fd, I2C_RDWR, &idata) < 0)
	{
		printf("ioctl I2C_RDWR error %d", fd);
		return -1;
	}
	usleep(1 * 1000);
	return 1;
}

unsigned char Tuner_ReadBuffer(unsigned char *addr, uint16_t addrLen, unsigned char *buf, uint16_t len)
{
	if (fd < 0)
	{
		printf("fd < 0");
		return -1;
	}
	unsigned char reg = 0;
	uint16_t i = 1;
	struct i2c_msg msgs[2] = {
		{I2C_ADDR, 0, addrLen, addr},
		{I2C_ADDR, I2C_M_RD, len, buf},
	};

	struct i2c_rdwr_ioctl_data idata = {
		.msgs = msgs,
		.nmsgs = 2,
	};

	if (ioctl(fd, I2C_RDWR, &idata) < 0)
	{
		printf("chenjx I2C_RDWR error");
		return -1;
	}
	return 1;
}


void Tuner_I2C_Init()
{
	fd = open("/dev/i2c-5", I2C_RDWR);
	if (fd < 0)
	{
		printf("open %s false", "/dev/i2c-5");
		return;
	}
	printf("open %s succuss", "/dev/i2c-5");
}
void Tuner_I2C_UnInit()
{ 
   close(fd);
}

int main(){
    unsigned char data[2] = {0x11,0x22};
    Tuner_I2C_Init();
    Tuner_WriteBuffer(data,2);
    Tuner_I2C_UnInit();
}

3.Linux命令:

i2ctransfer -f -y 5 w2@0x44 0x11 0x22
-y 5:哪条总线
w2:写两个字节地址
0x11 0x22:数据

I2C调试 经验分享 :

i2cdetect -y -r 5 :扫描5总线上挂载的是有设备地址

一.查不到设备地址

1. i2cdetect -y 5如果没有扫到该地址确认供电部分 

2.有些设备需要时钟信号i2c才能正常工作(大部分图像处理芯片,xs9922)

无法写入数据:

1.无法写入数据返回-5,确认同一总线挂载上的设备影响被拉低,确认它们的电压

2.先用示波器测量数据,发现从设备应答电压无法拉低,改变上拉电阻阻值,尝试是否恢复

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

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

相关文章

英语四六级有线调频听力广播-厦门华厦学院有线调频听力广播系统建设深度解析

英语四六级有线调频听力广播-厦门华厦学院有线调频听力广播系统建设深度解析 由北京海特伟业任洪卓发布于2024年3月14日 随着社会的快速发展和国际交流的日益频繁&#xff0c;英语已成为我们日常生活中不可或缺的一部分。作为衡量大学生英语水平的重要标准之一&#xff0c;大学…

javaweb数据传参类型(2)

前言 友友们好呀&#xff0c;今天来分享一下对于各种数据类型传参的问题&#xff0c;今天陪伴我们的云海 目录 前言 数组集合传参 补充 日期参数 补充 Json格式数据传参 补充 路径参数 补充 今日分享 ​​​​​​​数组集合传参 类似于我们之前进行的简单的参数传递…

深度学习模型部署(五)onnx模型以及相应工具

ONNX概念 onnx不仅仅一种模型参数存储的格式&#xff0c;还是一套完整的用于描述计算函数的编程语言&#xff0c;它的作用就是定义计算图&#xff0c;他本身无法进行。 这个概念和Verilog有点像&#xff0c;一个是硬件描述语言&#xff0c;一个是模型描述语言。 onnx模型或者说…

Learn OpenGL 10 Assimp+网格+模型

Assimp 一个非常流行的模型导入库是Assimp&#xff0c;它是Open Asset Import Library&#xff08;开放的资产导入库&#xff09;的缩写。Assimp能够导入很多种不同的模型文件格式&#xff08;并也能够导出部分的格式&#xff09;&#xff0c;它会将所有的模型数据加载至Assim…

git基础命令(一)

目录 基础概念git statusgit addgit diffgit loggit commit文件可以处于以下三种状态之一远程存储库与本地存储库参考 用于知识记录。后续有新的的内容&#xff0c;例子&#xff0c;将持续更新本文档。 基础概念 工作树&#xff1a;git add 之前&#xff0c;变动内容的文件列表…

经典数组和指针笔试题解析——C语言

【本节内容】 1. 数组和指针笔试题解析 2. 指针运算笔试题解析 1. 数组和指针笔试题解析 1.1 一维数组 #include <stdio.h> int main() {int a[] { 1,2,3,4 };printf("%zd\n", sizeof(a));printf("%zd\n", sizeof(a 0));printf("%zd\n&qu…

【金三银四】掌趣科技24.3.7 H项目 服务端开发笔试题

考试题型&#xff1a; 不定项选择题 10 道 &#xff0c; 填空题 10 道 &#xff0c; 问答题 2 道 &#xff0c; 编程题 4 道 目录 不定项选择题 10 道填空题 10 道问答题 2 道编程题 4 道 不定项选择题 10 道 在TCP协议中&#xff0c;发送方的窗口大小是由两个关键因素共同决定…

三个表联合查询的场景分析-场景1:a表关联了b表和c表

本场景对应情景如下&#xff1a; 三个数据表&#xff0c;一个表的两个字段分别关联了另外两个表各自的id数据&#xff0c;可能包含多个id&#xff08;两个1对多关联&#xff09;。 目录 数据表准备 需求1、查询c表的列表数据&#xff0c;要求获得关联的b表中的name&#xf…

工业界真实的推荐系统(小红书)-涨指标的方法:召回、排序、多样性、特殊人群、利用交互行为

课程特点&#xff1a;系统、清晰、实用&#xff0c;原理和落地经验兼具 b站&#xff1a;https://www.bilibili.com/video/BV1HZ421U77y/?spm_id_from333.337.search-card.all.click&vd_sourceb60d8ab7e659b10ea6ea743ede0c5b48 讲义&#xff1a;https://github.com/wangsh…

CSDN 编辑器设置图片缩放和居中

CSDN 编辑器设置图片缩放和居中 文章目录 CSDN 编辑器设置图片缩放和居中对齐方式比例缩放 对齐方式 Markdown 编辑器插入图片的代码格式为 ![图片描述](图片路径)CSDN 的 Markdown 编辑器中插入图片&#xff0c;默认都是左对齐&#xff0c;需要设置居中对齐的话&#xff0c;…

项目性能优化—性能优化的指标、目标

项目性能优化—性能优化的指标、目标 性能优化的终极目标是什么 性能优化的目标实际上是为了更好的用户体验&#xff1a; 一般我们认为用户体验是下面的公式&#xff1a; 用户体验 产品设计&#xff08;非技术&#xff09; 系统性能 ≈ 系统性能 快 那什么样的体验叫快呢…

STM32第九节(中级篇):RCC——时钟树讲解(第一节)

目录 前言 STM32第九节&#xff08;中级篇&#xff09;&#xff1a;RCC——时钟树讲解 时钟树主系统时钟讲解 HSE时钟 HSI时钟 锁相环时钟 系统时钟 SW位控制 HCLK时钟 PCLKI时钟 PCLK2时钟 RTC时钟 MCO时钟输出 6.2.7时钟安全系统(CSS&#xff09; 小结 前言 从…

基于HarmonyOS ArkTS中秋国庆祝福程序、以代码之名,写阖家团圆祝福

中秋、国庆双节将至&#xff0c;作为程序员&#xff0c;以代码之名&#xff0c;表达对于阖家团圆的祝福。本节将演示如何在基于HarmonyOS ArkUI的SwiperController、Image、Swiper等组件来实现节日祝福轮播程序。 规则要求具体要求如下&#xff1a; 1、根据主题&#xff0c;用…

遗嘱消息(Will Message)介绍与示例 _ MQTT 5.0 特性详解

什么是 MQTT 遗嘱消息&#xff1f; 在现实世界中&#xff0c;一个人可以制定一份遗嘱&#xff0c;声明在他去世后应该如何分配他的财产以及应该采取什么行动。在他去世后&#xff0c;遗嘱执行人会将这份遗嘱公开&#xff0c;并执行遗嘱中的指示。 在 MQTT 中&#xff0c;客户端…

honle电源维修UV电源控制器维修EVG EPS60

好乐UV电源控制器维修&#xff1b;honle控制器维修&#xff1b;UV电源维修MUC-Steuermodul 2 LΛmpen D-82166 主要维修型号&#xff1a; EVG EPS 60/120、EVG EPS 100、EVG EPS200、EVG EPS 220、EVG EPS 340、EVG EPS40C-HMI、EVG EPS60 HONLE好乐uv电源维修故障包括&#…

Python实时追踪关键点组成人体模型

项目背景 最近遇到这样一个需求&#xff1a; 1&#xff1a;实时追踪关键点组成人体模型&#xff08;手臂包括三个点&#xff1a;手腕&#xff0c;肘关节&#xff0c;双肩&#xff1b;腿部包括胯骨&#xff0c;膝盖&#xff0c;脚踝&#xff09; 2&#xff1a;运用追踪到的关键…

【c++】string类的使用及模拟实现

1.我们为什么要学习string类&#xff1f; 1.1 c语言中的字符串 我们先了解一下什么是OOP思想 OOP思想&#xff0c;即面向对象编程&#xff08;Object-Oriented Programming&#xff09;的核心思想&#xff0c;主要包括“抽象”、“封装”、“继承”和“多态”四个方面。 抽象…

Day16 面向对象进阶——接Day15

Day16 面向对象进阶——接Day15 文章目录 Day16 面向对象进阶——接Day15一、抽象类及抽象方法二、接口三、多态四、对象转型五、内部类 一、抽象类及抽象方法 //抽象类 public abstract class 类名{//抽象方法public abstract void method(); }1、抽象方法交给非抽象的子类去…

轻松驾驭时间流:MYSQL日期与时间函数的实用技巧

​&#x1f308; 个人主页&#xff1a;danci_&#x1f525; 系列专栏&#xff1a;《MYSQL应用》&#x1f4aa;&#x1f3fb; 制定明确可量化的目标&#xff0c;坚持默默的做事。 轻松驾驭时间流&#xff1a;MYSQL日期与时间函数的实用技巧 MYSQL日期时间函数是数据库操作中不可…

第五十八回 吴用赚金铃吊挂 宋江闹西岳华山-飞桨图像分割套件PaddleSeg初探

鲁智深被贺太守抓住&#xff0c;押入死牢。武松得信后&#xff0c;正想回梁山报信&#xff0c;正好戴宗来了&#xff0c;就请戴宗赶快回梁山搬救兵。宋江说兄弟有难&#xff0c;怎能不救&#xff1f; 于是带了十六个头领来到少华山。 因为华州城池厚壮&#xff0c;宋江等无计可…