惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Engineering at Meta
Engineering at Meta
博客园_首页
H
Help Net Security
WordPress大学
WordPress大学
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
罗磊的独立博客
博客园 - 三生石上(FineUI控件)
B
Blog
I
InfoQ
SecWiki News
SecWiki News
T
Tailwind CSS Blog
Spread Privacy
Spread Privacy
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
V
Vulnerabilities – Threatpost
N
Netflix TechBlog - Medium
P
Palo Alto Networks Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Vercel News
Vercel News
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
K
Kaspersky official blog
M
MIT News - Artificial intelligence
S
Schneier on Security
T
Threat Research - Cisco Blogs
F
Fortinet All Blogs
Cyberwarzone
Cyberwarzone
Scott Helme
Scott Helme
aimingoo的专栏
aimingoo的专栏
Martin Fowler
Martin Fowler
MyScale Blog
MyScale Blog
The Cloudflare Blog
Recent Announcements
Recent Announcements
Security Latest
Security Latest
G
GRAHAM CLULEY
IT之家
IT之家
Y
Y Combinator Blog
The Last Watchdog
The Last Watchdog
腾讯CDC
Google DeepMind News
Google DeepMind News
V
V2EX
S
Securelist
TaoSecurity Blog
TaoSecurity Blog
B
Blog RSS Feed
S
SegmentFault 最新的问题
博客园 - 叶小钗
P
Proofpoint News Feed
云风的 BLOG
云风的 BLOG
Project Zero
Project Zero
G
Google Developers Blog
Google DeepMind News
Google DeepMind News
F
Full Disclosure

博客园 - midhillzhou

windows 11关闭防火墙 以使得 外部的开发板可以主动发起ping通电脑 uboot中调试景略以太网phy JL3111A2-NA windows上excel运行macro之后出现错误 在linux上移植sgdisk 在linux上移植phytool + 调试tja1103 以太网phy 使用gdb调试user程序 之 某个线程的调用栈 在uboot中修改tja 1103以太网phy from slave to master porting perf性能观测工具 porting 开源memtester uboot 2020版本下gpio命令的使用 + linux下的libgpiod lib库的移植使用 ubi文件系统的 制作 + 挂载 + 若干问题 windows下outlook 撤回邮件 安装repo 使用lauterbach debug uboot之重定位 uboot中各种memory读写命令 uboot nand flash dump 环境变量 + 制作环境变量分区 + 代码结构详解 uboot bootm代码详解图 Beyond Compare 进行二进制文档的比对时,怎么去对齐(转载) notepad++分析log小技巧 使用继电器控制开发板上下电 uboot debug小技巧
i2c指令使用 + 仿照开源i2ctransfer实现的自己的i2ctransfer
midhillzhou · 2025-08-08 · via 博客园 - midhillzhou

1. 列出目前有哪些i2c controller

i2cdetect -l

image

2.查看某个特定i2c controller下面下挂的设备

i2cdetect -y 0

一般我们还会加上-r选项

其中0表示想要查看i2c controller的标号,可以改成命令i2cdetect -l 中列出所有的数字

image

3.通过i2c指令读取camera的温度

i2ctransfer -y 0 w2@0x36 0x4D 0x60 r2@0x36

image

其中0x36表示slave address

0x4d60表示摄像头温度的寄存器,由于我们要读取两个值,所以写的是r2, 这样我们就可以读取出0x4D60, 0x4D61两个连续的值。

可以这样理解 w2@0x36 0x4D 0x60,设置了 start point是0x4d60,然后往下读两个,即0x4D60 + 0x4D61两个位置的寄存器,加起来总共两个byte,一个整数部分,一个小数部分

转换成人类可读的温度的方法如下

0x4e52因为小于0xc000
HEX2DEC(0x4e)-50+HEX2DEC(0x52)/256=28.3203125
大于0xc000的值为零下,公式中的-50改为-142

上面的结果中 0x4e是寄存器0x4D60的值,0x52是寄存器0x4D61的值

image

 4.通过研究开源i2ctransfer的代码,自己实现的代码如下,这样其他上层app就可以用函数的形式 向底层发出i2c命令。

以等效于命令“i2ctransfer -y 0 w2@0x36 0x4D 0x60 r2@0x36” 来讲解如何调用下面的函数

slave_address: 0x36
reg_part1:0x4D
reg_part2:0x60
result, result_len: 2,用来存放返回的2个byte的数据

所以上层代码调用的示例代码如下

unsigned char *return_array[2];

zhongshan_i2c_transfer(0x36, 0x4D, 0x60, return_array, 2);

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

int zhongshan_i2c_transfer(unsigned char slave_address, unsigned char reg_part1, unsigned char reg_part2, unsigned char *result, int result_len) {
    struct i2c_msg msgs[2];
    unsigned char *buf;
    struct i2c_rdwr_ioctl_data rdwr;
    int file, nmsgs_sent;

    file = open("/dev/i2c-0", O_RDWR);
    if (file < 0)
        printf("can not open /dev/i2c-0.");

    //construct write message.
    msgs[0].addr = slave_address;
    msgs[0].flags = 0;
    msgs[0].len = 2;
    buf = (unsigned char *)malloc(msgs[0].len);
    if (!buf)
        printf("Error: No memory for buffer\n");
    memset(buf, 0, msgs[0].len);
    msgs[0].buf = buf;
    msgs[0].buf[0] = reg_part1;
    msgs[0].buf[1] = reg_part2;

    //construct read message.
    msgs[1].addr = slave_address;
    msgs[1].flags = I2C_M_RD;   // #define I2C_M_RD        0x0001
    msgs[1].len = result_len;
    buf = (unsigned char *)malloc(msgs[1].len);
    if (!buf)
        printf("Error: No memory for buffer\n");
    memset(buf, 0, msgs[1].len);
    msgs[1].buf = buf;

    rdwr.msgs = msgs;
    rdwr.nmsgs = 2;
    nmsgs_sent = ioctl(file, I2C_RDWR, &rdwr);
    if (nmsgs_sent < 0) {
        printf("Error: Sending messages failed\n");
        return 1;
    } else if (nmsgs_sent < rdwr.nmsgs) {
        printf("Error: only %d/%d messages were sent\n", nmsgs_sent, rdwr.nmsgs);
        return 1;
    }
    
    result[0] = msgs[1].buf[0];
    if (result_len > 1)
        result[1] = msgs[1].buf[1];

    close(file);

    for (int i = 0; i < 2; i++)
        free(msgs[i].buf);

    return 0;
}