i2c设备的读写地址换算

 #define     MAX_17040_BATTERY_I2C_ADDR        (0x36)
#define     MAX_17040_BATTERY_WRITE_ADDR    (MAX_17040_BATTERY_I2C_ADDR << 1)
#define     MAX_17040_BATTERY_READ_ADDR      ((MAX_17040_BATTERY_I2C_ADDR << 1) + 1)
一般给出i2c 写地址就可以,读地址i2c核心会去自己算出来。
ioctl函数的使用:原型:struct ioctl(struct file *file,unsigned int cmd,unsigned long arg); cmd有I2C_SLAVE,I2C_SLAVE_FORCE,I2C_TENBIT,I2C_S3C2410_SET_SPEED几个选项;    I2C_SLAVE:对应的arg取值为I2C从机地址,用来设定I2C从机地址;
    I2C_SLAVE_FORCE:对应的arg取值为I2C从机地址,用来修改I2C从机地址;
    I2C_TENBIT:对应的arg取值为0:从机地址为7 bit;对应的arg取值为1:从机地址为10bit。用来指定I2C从机地址的位数;  
    I2C_S3C2410_SET_SPEED:对应的arg取值为I2C总线控制器分频值。用来设置I2C总线控制器时钟频率; 
    常用设置设置I2c从机地址为0xA0,如果选用at24c08设备,那么从机是7 bit地址,所以要右移1位,指定从机地址为7 bit,
ioctl(fd,I2C_TENBIT,0)。ioctl(fd,I2C_SLAVE,0xA0>>1);
 
read()与write()函数的使用  假设子地址为12,向有子地址的器件写进7个字节:
unsigned char buf[8]={12,'s','j','s','u','n','n','y');/*第1个字节12为子地址*/write(fd,buf,9);/*写进7个字节,第1个字节为子地址*/
从有子地址的I2C器件读取7个字节:  unsigned char suba=0;recbuf[20];  write(fd,buf,1);/*发送子地址0*/  read(fd,recbuf,7);/*从子地址12开始读取7个字节*/
 拿一个项目中的例子说,是一个CTP的i2c地址,
 static const struct i2c_device_id tpd_id[] = {{TPD_DEVICE,0},{}};
 unsigned short force[] = {0,0xb8,I2C_CLIENT_END,I2C_CLIENT_END}; //82 38 70
 static const unsigned short * const forces_pixcir[] = { force, NULL };
 static struct i2c_client_address_data addr_data = { .forces = forces_pixcir, };
 
根据其Datasheet来瞧,他的I2c地址是0x5C,但是你用这个地址在kernel中通过I2c控制器去访问的时候是访问不到的,
需要将这个5C 左移1位 ,得到I2c读地址, 写地址比读地址大1 ,那写地址就是(b8<<1)+1=B9,





转载于:https://www.cnblogs.com/yuzaipiaofei/archive/2011/09/09/4124333.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
I2C设备驱动中进行读写操作,通常使用`i2c_transfer`函数来发送和接收数据。下面是一个示例代码,演示了如何在I2C设备驱动中进行读写操作: ```c #include <linux/module.h> #include <linux/init.h> #include <linux/i2c.h> static struct i2c_adapter *my_i2c_adapter; static struct i2c_client *my_i2c_client; static int my_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) { // 初始化I2C设备 my_i2c_client = client; // 其他初始化操作... // 发送读取寄存器数据的命令 u8 reg_addr = 0x00; // I2C设备寄存器地址 u8 buf[2]; // 数据缓冲区 struct i2c_msg msgs[2]; msgs[0].addr = client->addr; msgs[0].flags = 0; // 写命令 msgs[0].buf = &reg_addr; msgs[0].len = sizeof(reg_addr); // 读取寄存器数据 msgs[1].addr = client->addr; msgs[1].flags = I2C_M_RD; // 读数据 msgs[1].buf = buf; msgs[1].len = sizeof(buf); if (i2c_transfer(client->adapter, msgs, 2) != 2) { dev_err(&client->dev, "Failed to read register data\n"); // 错误处理... } // 对读取到的数据进行处理 // ... return 0; } static int my_i2c_remove(struct i2c_client *client) { // 移除I2C设备 // 其他清理操作... return 0; } static const struct i2c_device_id my_i2c_id[] = { { "my_i2c_device", 0 }, { }, }; MODULE_DEVICE_TABLE(i2c, my_i2c_id); static struct i2c_driver my_i2c_driver = { .probe = my_i2c_probe, .remove = my_i2c_remove, .id_table = my_i2c_id, .driver = { .name = "my_i2c_driver", .owner = THIS_MODULE, }, }; static int __init my_i2c_init(void) { // 注册I2C驱动 my_i2c_adapter = i2c_get_adapter(0); return i2c_add_driver(&my_i2c_driver); } static void __exit my_i2c_exit(void) { // 注销I2C驱动 i2c_del_driver(&my_i2c_driver); i2c_put_adapter(my_i2c_adapter); } module_init(my_i2c_init); module_exit(my_i2c_exit); MODULE_AUTHOR("Your Name"); MODULE_DESCRIPTION("I2C Driver Example"); MODULE_LICENSE("GPL");``` 在上述示例中,我们在I2C设备的probe函数中使用`i2c_transfer`函数进行读取操作。首先,我们定义了一个`struct i2c_msg`数组,用于存储要传输的消息。然后,我们设置了两个消息:第一个消息是发送寄存器地址的写命令,第二个消息是读取数据的读命令。最后,我们使用`i2c_transfer`函数将这两个消息传递给I2C核心层进行传输。如果传输成功,我们可以根据需要对读取到的数据进行处理。 当然,这只是一个简单的示例,实际的I2C驱动可能需要根据具体设备和需求进行更多的读写操作。你可以根据你的具体情况进行相应的修改和扩展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值