- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
-
- #include
- #define DEVICE_NAME "/dev/i2c-1"
- #define I2C_ADDR 0x6f // i2c设备地址
-
- static int i2c_write_bytes(int fd, uint8_t slave_addr, uint8_t reg_addr, uint8_t *values, uint8_t len)
- {
- uint8_t *outbuf = NULL;
- struct i2c_rdwr_ioctl_data packets;
- struct i2c_msg messages[1];
- outbuf = (uint8_t *)malloc(len + 1);
- if (!outbuf)
- {
- printf("Error: No memory for buffer\n");
- return -1;
- }
-
- outbuf[0] = reg_addr; // i2c设备要操作的reg地址
- memcpy(outbuf + 1, values, len);
-
- messages[0].addr = slave_addr; // i2c设备地址
- messages[0].flags = 0; // write flag
- messages[0].len = len + 1;
- messages[0].buf = outbuf; // 向reg写入的值
-
- /* Transfer the i2c packets to the kernel and verify it worked */
- packets.msgs = messages;
- packets.nmsgs = 1;
- if (ioctl(fd, I2C_RDWR, &packets) < 0)
- {
- printf("Error: Unable to send data");
- free(outbuf);
- return -1;
- }
-
- free(outbuf);
-
- return 0;
- }
-
- static int i2c_read_bytes(int fd, uint8_t slave_addr, uint8_t reg_addr, uint8_t *values, uint8_t len)
- {
- uint8_t outbuf[1];
- struct i2c_rdwr_ioctl_data packets;
- struct i2c_msg messages[2];
-
- outbuf[0] = reg_addr; // i2c设备要操作的reg地址
- messages[0].addr = slave_addr; // i2c设备地址
- messages[0].flags = 0; // write flag
- messages[0].len = sizeof(outbuf);
- messages[0].buf = outbuf;
-
- /* The data will get returned in this structure */
- messages[1].addr = slave_addr; // i2c设备地址
- messages[1].flags = I2C_M_RD /* | I2C_M_NOSTART*/; // write flag
- messages[1].len = len;
- messages[1].buf = values;
-
- /* Send the request to the kernel and get the result back */
- packets.msgs = messages;
- packets.nmsgs = 2;
- if (ioctl(fd, I2C_RDWR, &packets) < 0)
- {
- printf("Error: Unable to send data");
- return -1;
- }
-
- return 0;
- }
-
- int main()
- {
- int fd;
- bool cmdIsRd = false;
- char *arg_ptr = NULL;
- unsigned long len;
- unsigned int slave_addr, reg_addr;
- uint8_t buffer[1024];
-
- /* 2.打开I2C总线 */
- fd = open(DEVICE_NAME, O_RDWR);
- if (fd < 0)
- {
- printf("can not open file %s\n", DEVICE_NAME);
- return -1;
- }
- len = 2;
- buffer[0] = 0x11;
- buffer[1] = 0x12;
- // Alarm
- i2c_write_bytes(fd, I2C_ADDR, 0x0c, buffer, len);
- // RTC
- len = 12;
- i2c_read_bytes(fd, I2C_ADDR, 0x00, buffer, len);
-
- printf("read data =");
- for (int i = 0; i < len; i++)
- {
- printf("0x%02X ", buffer[i]);
- }
- printf("\n");
-
- return 0;
- }
一、设备地址是8bit
1、i2cdetect检测有几组i2c总线
i2cdetect -l
2、i2cdetect检测挂载在i2c总线上器件
i2cdetect-r -y 1(检测i2c-1上的挂载情况)
3、i2cdump查看器件所有寄存器的值
i2cdump -f -y 1 0x50 (查看i2c-1总线上0x50设备的所有寄存器值)
4、i2cset设置单个寄存器值
i2cset -f -y 1 0x50 0x01 0xaa (往i2c-1总线上0x50设备0x01寄存器写0xaa)
5、i2cget读取单个寄存器值
i2cget -f -y 1 0x50 0x01 (读取i2c-1总线上0x50设备0x01寄存器的值)
二、设备地址是16bit
例子:i2c总线1上挂设备,设备地址是 0x3020 ,要读取16个字节
i2ctransfer -y -f 1 w2@0x10 0x30 0x20 r16
#w是写,2是写入2个字节,@0x10是寄存器地址,030 0x20是寄存器要设置的地址的高低位,r是读取,16 是读取16个字节
例子:i2c总线1上挂设备,设备地址是 0x3020 ,要写16个字节数据,数据是0x55 0xaa
i2ctransfer -y -f 1 w4@0x10 0x30 0x20 0x55 0xaa
#w是写,4是写入4个字节,@0x10是寄存器地址,0x30 0x20是寄存器要设置的地址的高低位,0x55 0xaa是要写入的值