linux i2c编程
                                                            生活随笔
收集整理的這篇文章主要介紹了
                                linux i2c编程
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.                        
                                ?
有三種方式實現linux i2c用戶態編程,讀寫i2c外設。
?
1. ioctl
ioctl(file, I2C_RDWR, struct i2c_rdwr_ioctl_data *msgset)
?
#include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <sys/ioctl.h> #include <fcntl.h> #include <linux/i2c-dev.h> #include <linux/i2c.h>#define CHIP "/dev/i2c-0" #define I2C_DEVICE_ADDR 0x56 //eeprom addrstatic int iic_write(int i2c_fd, int device_addr, unsigned int reg_address ,unsigned int reg_val) {struct i2c_rdwr_ioctl_data work_queue;int ret = 0;work_queue.nmsgs = 1;work_queue.msgs = (struct i2c_msg *)malloc(work_queue.nmsgs * sizeof(struct i2c_msg));if(!work_queue.msgs){printf("msgs memery alloc error\n");close(i2c_fd);return -1;} if ((work_queue.msgs[0].buf = (unsigned char *)malloc(2 * sizeof(unsigned char))) == NULL){printf("buf memery alloc error...\n");close(i2c_fd);return -1;}(work_queue.msgs[0]).len = 2;(work_queue.msgs[0]).flags = !I2C_M_RD;(work_queue.msgs[0]).addr = device_addr;(work_queue.msgs[0]).buf[0] = reg_address;(work_queue.msgs[0]).buf[1] = reg_val;work_queue.nmsgs = 1;ret = ioctl(i2c_fd, I2C_RDWR, (unsigned long) &work_queue);if(ret < 0){printf("Error during I2C_RDWR ioctl with error code: %d\n", ret);return -1;}free(work_queue.msgs[0].buf);free(work_queue.msgs);return 0; }static int iic_read(int i2c_fd, int device_addr, unsigned int reg_address) {struct i2c_rdwr_ioctl_data work_queue;unsigned char val;int ret;work_queue.nmsgs = 2;work_queue.msgs = (struct i2c_msg *)malloc(work_queue.nmsgs *sizeof(struct i2c_msg));if(!work_queue.msgs){printf("Memery alloc error\n");close(i2c_fd);return -1;}val =(unsigned char)reg_address;(work_queue.msgs[0]).len = 1;(work_queue.msgs[0]).flags = 0;(work_queue.msgs[0]).addr = device_addr;(work_queue.msgs[0]).buf = &val;(work_queue.msgs[1]).len = 1;(work_queue.msgs[1]).flags = 1;(work_queue.msgs[1]).addr = device_addr;(work_queue.msgs[1]).buf = &val;ret = ioctl(i2c_fd, I2C_RDWR, (unsigned long) &work_queue);if(ret < 0){printf("Error during I2C_RDWR ioctl with error code: %d\n", ret);return -1;}free(work_queue.msgs);return val; }int main() {printf("hello, this is i2c test\n");int ret = 0;int fd = open(CHIP, O_RDWR);if (fd< 0) {printf("open %s failed\n", CHIP);goto exit;}if (ioctl(fd, I2C_SLAVE, I2C_DEVICE_ADDR) < 0) { //device addrprintf("ioictl: set slave address failed\n");goto close;}ret = iic_write(fd, I2C_DEVICE_ADDR, 0, 0xaa);if(ret)printf("write failed\n");usleep(1000 * 1000 * 0.1);ret = iic_write(fd, I2C_DEVICE_ADDR, 1, 0xbb);if(ret)printf("write failed\n");usleep(1000 * 1000 * 0.1);ret = iic_read(fd, I2C_DEVICE_ADDR, 0);printf("read reg addr:0 data:%x\n", ret);ret = iic_read(fd, I2C_DEVICE_ADDR, 1);printf("read reg addr:1 data:%x\n", ret); close:close(fd);exit:return 0; }?
2. write and read
?
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/ioctl.h> #include <fcntl.h> #include <linux/i2c-dev.h> #include <linux/i2c.h>#define CHIP "/dev/i2c-0" #define I2C_DEVICE_ADDR 0x56 //eeprom addrint main(int argc, char* argv[]) {unsigned char rddata;unsigned char rdaddr = 0; /* 將要讀取的數據在芯片中的偏移量*/unsigned char wrbuf[2] = {0, 0xaa}; /*要寫的數據,第1個字節為偏移量, 第二個字節為寫入的數據*/ printf("hello,this is i2c test\n");int fd =open(CHIP, O_RDWR);if (fd< 0) {printf("open %s failed\n", CHIP);goto exit;}if (ioctl(fd, I2C_SLAVE, I2C_DEVICE_ADDR) < 0) {printf("ioictl:setslave address failed\n");goto close;}if(argc == 3){// write and read reg addrwrbuf[0] = atoi(argv[1]);rdaddr = wrbuf[0];// write data, one bytewrbuf[1] = atoi(argv[2]);}printf("write addr:0x%x, data:0x%x\n", wrbuf[0], wrbuf[1]);write(fd, wrbuf, 2);usleep(1000 * 1000 * 0.2);write(fd, &rdaddr, 1); /*讀取之前首先設置讀取的偏移量*/ usleep(1000 * 1000 * 0.2);read(fd, &rddata, 1);printf("read addr:0x%x, value:0x%x \n", rdaddr, rddata); close:close(fd);exit:return 0; }?
3.?libi2c.so library,?i2c_smbus_xxx
https://git.kernel.org/pub/scm/utils/i2c-tools/i2c-tools.git/.
??__s32 i2c_smbus_read_byte(int file);
??__s32 i2c_smbus_write_byte(int file, __u8 value);
......
?
總結
以上是生活随笔為你收集整理的linux i2c编程的全部內容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: linux loop device
 - 下一篇: 2023年春节档票房成春节档影史第二 你