i2c设备寄存器读写操作

本文详细介绍了Linux内核中如何使用i2c_transfer函数进行I2C设备的寄存器读写操作,包括函数的参数说明、写入和读取寄存器的具体示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

i2c设备寄存器读写操作主要使用的函数为i2c_transfer
i2c_transfer函数是一个通用的函数名,用于表示在I2C通信协议中实现数据传输的函数。在不同的操作系统或库中,i2c_transfer函数的实现可能会有所不同,但通常它用于执行I2C通信操作。

在Linux内核中,i2c_transfer函数是I2C核心(I2C Core)提供的一个接口,用于在I2C总线上执行数据传输操作。它接受一个I2C适配器(i2c_adapter)和一个I2C消息(i2c_msg)作为参数,并执行数据传输。

在使用i2c_transfer函数时,你需要提供以下参数:
adapter:指向I2C适配器的指针,该适配器定义了与I2C总线的连接和配置信息。
msgs:指向I2C消息数组的指针,该数组包含了要传输的消息列表。
num:消息的数量,表示要传输的消息数量。
在执行完数据传输后,i2c_transfer函数将返回一个整数,表示操作的结果。如果返回值小于0,则表示出现了错误。

I2C从设备寄存器写操作实例:

static struct i2c_client *g_client;

unsigned char dp[2] = {0x77,0xDB}; //0x77为需要操作的寄存器地址,0xDB为向这个寄存填充的数值
XXX_drv_write(dp,2);//写的数据长度为2
static int XXX_drv_write (char *buf,int len)
{
    int ret;
    struct i2c_adapter *adapter = g_client->adapter;
    struct i2c_msg msg;
    
    msg.addr = g_client->addr;//i2c地址
    msg.flags = 0;
    msg.len = len;
    msg.buf = buf; //需要些的数据buf
	
	//printk("%s >>> buf[0] = %x  buf[1] = %x i2c addr = %x",__FUNCTION__,buf[0],buf[1],msg.addr);
    ret = i2c_transfer(adapter,&msg,1);//第三个参数1是消息的个数
	if(ret < 0){
		printk("%s >>> sd1503 >>> %s >>> %d errno is %d",__FILE__,__FUNCTION__,__LINE__,ret);
	}
    return ret;
}

以上是写操作,具体代码解释如下
I2C通信,I2C是一种用于连接微控制器和其他外围设备的串行通信协议。
定义一个i2c_adapter结构体指针adapter,这个指针指向一个I2C适配器对象。这个对象包含了与I2C总线进行通信所需的配置和状态信息。

然后,定义一个i2c_msg结构体变量msg,这个结构体用于表示一个I2C消息。每个I2C消息包含以下信息:

地址(addr):表示要与之通信的I2C设备的地址。
标志(flags):表示消息的属性或标志,这里设置为0,表示没有使用特殊标志。
长度(len):表示要发送或接收的数据的长度。
缓冲区(buf):指向数据缓冲区的指针,用于存储要发送或接收的数据。
接下来,代码设置了msg的消息属性,包括设备地址、消息标志、数据长度和数据缓冲区。

最后,代码调用了i2c_transfer函数,将msg消息发送到I2C总线上。第三个参数是1,表示要发送或接收的消息的数量。这里只有一个消息,所以参数为1。主要目的是通过I2C适配器将一个消息发送到I2C总线上,以便与指定的I2C设备进行通信。

I2C从设备寄存器的读取相对于写要复杂一些:

static int xxxx_drv_read (void)
{
    int ret;
    int getConn = 0;
    struct i2c_adapter *adapter = g_client->adapter;
    struct i2c_msg msg;
	unsigned char data;
	unsigned char getConnect = 0x53; //获取从设备可用状态
    
    msg.addr = g_client->addr;
    msg.flags = 0;//写操作(寄存器地址)
    msg.len = 1;
    msg.buf = &getConnect;
	//printk("%s >>>  i2c addr = 0x%x",__FUNCTION__,msg.addr);
	ret = i2c_transfer(adapter,&msg,1);//num是消息的个数
	if(ret < 0){
		printk("%s >>> xxxx >>> %s >>> %d errno is %d",__FILE__,__FUNCTION__,__LINE__,ret);
	}
	
	msg.addr = g_client->addr;
    msg.flags = I2C_M_RD;//读操作
    msg.len = 1;
    msg.buf = &data;

	//printk("%s >>> buf[0] = %x  buf[1] = %x i2c addr = %x",__FUNCTION__,buf[0],buf[1],msg[1].addr);	
    ret = i2c_transfer(adapter,&msg,1);//num是消息的个数
	if(ret < 0){
		printk("%s >>> xxxx>>> %s >>> %d errno is %d",__FILE__,__FUNCTION__,__LINE__,ret);
	}
		
	//printk("%s >>> data = 0x%x ",__FUNCTION__,data);
	//printk("%s >>000> data&0x20 = 0x%x ",__FUNCTION__,data&0x20);
	if(data&0x20){
		getConn = 1;
		printk("%s >>> data&0x20 = 0x%x ",__FUNCTION__,data&0x20);
	}
	
    return  getConn; //返回读取到的寄存器值
}

I2C设备进行读写操作 以下是代码的详细解释:

定义变量:

struct i2c_adapter *adapter = g_client->adapter;: 定义一个指向i2c_adapter结构体的指针,并从g_client结构体中获取其适配器。
struct i2c_msg msg;: 定义一个i2c_msg结构体变量,用于表示一个I2C消息。
unsigned char data;: 定义一个无符号字符变量,用于存储从I2C设备读取的数据。
unsigned char getConnect = 0x53;: 定义一个无符号字符变量,其值为0x53。从注释来看,这个值似乎是用于获取从设备的可用状态。
设置写消息:

msg.addr = g_client->addr;: 设置消息的目标地址,即要与之通信的I2C设备的地址。
msg.flags = 0;: 设置消息标志为0,表示这是一个写操作(寄存器地址)。
msg.len = 1;: 设置消息的长度为1字节。
msg.buf = &getConnect;: 设置消息的数据缓冲区为之前定义的getConnect变量的地址。
ret = i2c_transfer(adapter,&msg,1);: 使用i2c_transfer函数发送上述设置的消息到I2C总线上。参数1表示要发送的消息数量。
如果返回值ret小于0,则打印相关的错误信息。
设置读消息:

msg.addr = g_client->addr;: 重新设置消息的目标地址。
msg.flags = I2C_M_RD;: 设置消息标志为I2C_M_RD,表示这是一个读操作。
msg.len = 1;: 设置消息的长度为1字节。
msg.buf = &data;: 设置消息的数据缓冲区为之前定义的data变量的地址。
ret = i2c_transfer(adapter,&msg,1);: 使用i2c_transfer函数从I2C总线上读取数据。参数1表示要发送的消息数量。
总体上,这段代码通过I2C适配器向指定的I2C设备发送一个字节的数据(0x53),并尝试从该设备读取一个字节的数据。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值