2025-03-22
在用户态访问i2c从设备也是比较常用的功能。下面的例子就实现了如何读取和设置i2c从设备的GPIO引脚?
raspberry pi3b
Linux raspberrypi 6.1.21-v8+ #1642 SMP PREEMPT Mon Apr 3 17:24:16 BST 2023 aarch64 GNU/Linux
// simple.c
#include <assert.h>
#include <fcntl.h>
#include <linux/i2c-dev.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <unistd.h>
int main(int argc, char *argv[]) {
unsigned char data[2];
int i2c_bus = open("/dev/i2c-0", O_RDWR);
if (i2c_bus < 0) {
perror("open /dev/i2c-0");
return -1;
}
if (ioctl(i2c_bus, I2C_SLAVE, 0x16) < 0) {
perror("ioctl I2C_SLAVE");
close(i2c_bus);
return -1;
}
// 设置LED GPIO引脚为输出方向
data[0] = 0x0;
data[1] = 0xfe;
if (write(i2c_bus, data, 2) != 2) {
perror("write GPIO direction");
close(i2c_bus);
return -1;
}
// 设置LED GPIO电平
data[0] = 0x14;
if (argc > 1) {
data[1] = atoi(argv[1]) > 0;
} else {
data[1] = 0x0;
}
if (write(i2c_bus, data, 2) != 2) {
perror("set GPIO");
close(i2c_bus);
return -1;
}
// 设置Button要读取的位置
data[0] = 0x12;
if (write(i2c_bus, data, 1) != 0) {
perror("button address write");
close(i2c_bus);
return -1;
}
// 读取Button数据
if (read(i2c_bus, data, 1) != 1) {
perror("button data read");
close(i2c_bus);
return -1;
}
printf("button is %s\n",
((data[0] & (1 << 1)) > 0) ? "pressed" : "not pressed");
close(i2c_bus);
return 0;
}
#!/bin/sh
all: simple.c
gcc -g -o simple simple.c
clean:
-rm simple
安装依赖:sudo apt install libi2c-dev i2c-tools
查看i2c从设备:sudo i2cdetect -y 0
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- 16 -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
编译程序:make
点亮LED:sudo ./simple 1
关闭LED:sudo ./simple 0