读取时不会返回I2C写入的缓冲区
我写入后尝试从I2C总线上的存储单元读取一个值.当我在终端中运行它时,我得到奇怪的输出.
这是我的计划 #include <stdio.h> #include <stdlib.h> #include <stdint.h> #include <inttypes.h> #include <errno.h> #include <string.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <linux/i2c.h> #include <linux/i2c-dev.h> #include <sys/ioctl.h> #define I2C_ADAPTER "/dev/i2c-0" #define I2C_DEVICE 0x00 int main (int argc,char *argv[]) { int file; int addr = 0X00; /* XGPIOPS_DATA_LOW_OFFSET */ if((file = open(I2C_ADAPTER,O_RDWR)) < 0) { printf("Failed to open the bus"); return -1; } if(ioctl(file,I2C_SLAVE,addr) < 0) { printf("Unable to open device as slave %s",strerror(errno)); return -1; } char buf[10]; buf[0] = addr; buf[1] = 0x10; if(write(file,buf,2) != 2) { printf("Failed to write to bus %s.nn",strerror(errno)); } else { printf("Successful writen"); printf(buf); printf("nn"); } if(read(file,2) != 2) { printf("Failed to read from the i2c bus. %snn",strerror(errno)); } else { printf("Successful readn"); printf(buf); printf("nn"); } return 0; }
在我的终端上,这些街区看起来更像钻石内的问号.我不确定在ASCII中对应什么. 为什么我不读回0x10,这是我最初写入的地址字节后的第二个字节? 根据第一组答案,这里是更新的代码: #include <stdio.h> #include <stdio.h> #include <stdlib.h> #include <stdint.h> #include <inttypes.h> #include <errno.h> #include <string.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <linux/i2c.h> #include <linux/i2c-dev.h> #include <sys/ioctl.h> #define I2C_ADAPTER "/dev/i2c-0" #define I2C_DEVICE 0x00 int main (int argc,char *argv[]) { int file; long addr,reg_addr; char *end; if(argc == 3) { addr = strtol(argv[1],&end,16); printf("Value of addr is: %ldn",addr); reg_addr = strtol(argv[2],16); printf("Value of reg_addr is: %ldn",reg_addr); } else { printf("arg failednn."); addr = 0x00; } if((file = open(I2C_ADAPTER,O_RDWR)) < 0) { printf("Failed to open the busn"); return -1; } if(ioctl(file,addr) < 0) { printf("Unable to open device as slave n%sn",strerror(errno)); return -1; } char buf[10]; buf[0] = addr; buf[1] = reg_addr; buf[2] = 0x10; if(write(file,3) != 3) { printf("Failed to write to bus %s.nn",strerror(errno)); } else { printf("Successful writen"); printf(buf); printf("nn"); } if(read(file,3) != 3) { printf("Failed to read from the i2c bus.n %snn",strerror(errno)); } else { printf("Successful readn"); printf("Buf = [%02X,%02X,%02X]n",buf[0],buf[1],buf[2]); printf("nn"); } return 0; } 此时,每当我使用0x00作为addr时,无论argv [2]是什么,我都会得到FF,FF,FF作为输出.以下是设备树文件的适用部分.请注意,这是模拟的,所以我无法探测物理设备. &i2c0 { status = "okay"; clock-frequency = <400000>; pinctrl-names = "default"; i2cswitch@74 { compatible = "nxp,pca9548"; #address-cells = <1>; #size-cells = <0>; reg = <0x74>; i2c@0 { #address-cells = <1>; #size-cells = <0>; reg = <0>; si570: clock-generator@5d { #clock-cells = <0>; compatible = "silabs,si570"; temperature-stability = <50>; reg = <0x5d>; factory-fout = <156250000>; clock-frequency = <148500000>; }; }; i2c@2 { #address-cells = <1>; #size-cells = <0>; reg = <2>; eeprom@54 { compatible = "at,24c08"; reg = <0x54>; }; }; i2c@3 { #address-cells = <1>; #size-cells = <0>; reg = <3>; gpio@21 { compatible = "ti,tca6416"; reg = <0x21>; gpio-controller; #gpio-cells = <2>; }; }; i2c@4 { #address-cells = <1>; #size-cells = <0>; reg = <4>; rtc@51 { compatible = "nxp,pcf8563"; reg = <0x51>; }; }; i2c@7 { #address-cells = <1>; #size-cells = <0>; reg = <7>; hwmon@52 { compatible = "ti,ucd9248"; reg = <52>; }; hwmon@53 { compatible = "ti,ucd9248"; reg = <53>; }; hwmon@54 { compatible = "ti,ucd9248"; reg = <54>; }; }; }; }; 以下是几个示例测试 尝试测试SiLabs时钟发生器
尝试测试eeprom设备
这是我的第三次尝试的程序.在记下答案中的笔记之后,我写了这篇文章 #include <stdio.h> #include <stdio.h> #include <stdlib.h> #include <stdint.h> #include <inttypes.h> #include <errno.h> #include <string.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <linux/i2c.h> #include <linux/i2c-dev.h> #include <sys/ioctl.h> #define I2C_ADAPTER "/dev/i2c-0" #define DEVICE_ADDRESS 0x54 int main (int argc,char *argv[]) { int file; uint8_t reg,value; char *end; printf("The device address on the bus: %d",DEVICE_ADDRESS); if(argc == 3) { reg = strtol(argv[1],16); printf("Value of register address: %dn",reg); value = strtol(argv[2],16); printf("value to write is: %dn",value); } else { printf("arg failednn."); } if((file = open(I2C_ADAPTER,DEVICE_ADDRESS) < 0) { printf("Unable to open device as slave n%sn",strerror(errno)); return -1; } char buf[10]; buf[0] = reg; buf[1] = value; if(write(file,2) != 2) { printf("Failed to write to bus %s.nn",2) != 2) { printf("Failed to read from the i2c bus.n %snn",buf[2]); printf("nn"); } return 0; } 不幸的是,即便如此,我也遇到了同样的错误.
解决方法
编辑2:我认为你可能没有正确设置你的I2C设备地址.您拥有的I2C_ADAPTER(“/ dev / i2c-0”)表示设备所在的I2C总线.您甚至没有使用I2C_DEVICE宏,但这应该是您应该传递给ioctl调用的内容(例如ioctl(文件,I2C_DEVICE);)它应该是您要访问的设备的I2C地址(例如0x5D)对于时钟发生器而不是0x00.
我也认为你的读/写不正确.一旦你通过open()和ioctl()指定了总线和设备,你就不用再担心了.您只需要担心要访问的寄存器(如果您的I2C设备使用寄存器)和实际数据. 要写入I2C设备,假设它使用一个字节的寄存器,写入两个字节的缓冲区:第一个是寄存器,第二个是要写入的值: bool i2cdev_byte_write(int file,uint8_t reg,uint8_t val) { uint8_t bytes[2]; bytes[0] = reg; bytes[1] = val; /* Write the register followed by the value */ if (write(file,bytes,2) != 2) return false; return true; } 要从I2C设备读取,写入一个字节的缓冲区(寄存器地址),然后读取一个或多个字节的缓冲区(该寄存器和后续寄存器的值): bool i2cdev_bytes_read(int file,unsigned int count,uint8_t *out_buf) { if (!out_buf) return false; /* Write the register */ if (write(file,®,1) != 1) { printf("Failed to write register valuen"); return false; } /* Read the specified number of bytes */ if (read(file,out_buf,count) != count) { printf("Failed to read from the i2c busn"); return false; } return true; } 再次注意,上述所有注释都取决于它是使用单字节寄存器地址的I2C器件,并且它支持在一次读取多个字节时自动递增寄存器地址.您需要检查I2C设备的数据表,以确切地确定它是如何被访问的. 编辑:这是一个printf()新手失败.你不能只尝试printf一个字节数组.这不是printf()的工作原理. 试试这个: printf("Buf = [%02X,buf[1]); 另外,正如我在原始响应中所写的那样,在读取寄存器内容之前,您可能需要再次将寄存器地址写回. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |