i2c指令使用 + 仿照開源i2ctransfer實現的自己的i2ctransfer
1. 列出目前有哪些i2c controller
i2cdetect -l

2.查看某個特定i2c controller下面下掛的設備
i2cdetect -y 0
其中0表示想要查看i2c controller的標號,可以改成命令i2cdetect -l 中列出所有的數字

3.通過i2c指令讀取camera的溫度
i2ctransfer -y 0 w2@0x36 0x4D 0x60 r2@0x36

其中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的值

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; }

浙公網安備 33010602011771號