/sys/class/gpio/连续读取gpio引脚电平有问题的原因

发布时间 2023-10-18 17:44:48作者: on_the_go

一、通过shell命令读取引脚电平值

/sys/class/gpio/目录下的内容

 可以向export写入相应引脚输出来导出gpio, 例如 echo 66 > export

 进入gpio66下,读取value的值即为gpio输入的值(默认为输入)

二、通过C程序读取引脚电平值 

程序:

int main(int argc, char *argv[])
{
    int fd, retvalue;
    char *filename = "/sys/devices/platform/apb/10010000.pinctrl/gpio/gpio66/value";
    char gpio_in_value;

    if (access(filename, F_OK))
        system("echo 66 > /sys/class/gpio/export");

    fd = open(filename, O_RDWR);
    if(fd < 0){
        printf("file %s open failed!\r\n", argv[1]);
        return -1;
    }

    read(fd, &gpio_in_value, 1);
    printf("gpio in value:%d.\r\n", gpio_in_value);

    read(fd, &gpio_in_value, 1);
    printf("gpio in value:%d.\r\n", gpio_in_value);

    retvalue = close(fd);
    if(retvalue < 0){
        printf("file %s close failed!\r\n", argv[1]);
        return -1;
    }
    return 0;
}

执行结果为:

 引脚的的值读上来应该是0或1, 转成16进制为 0x30或0x31, 即48或49。而第二次都上来的是10,说明程序有问题。

正确的程序如下,第二次读的时候需要使用lseek:

int main(int argc, char *argv[])
{
    int fd, retvalue;
    char *filename = "/sys/devices/platform/apb/10010000.pinctrl/gpio/gpio66/value";
    char gpio_in_value;

    if (access(filename, F_OK))
        system("echo 66 > /sys/class/gpio/export");

    fd = open(filename, O_RDWR);
    if(fd < 0){
        printf("file %s open failed!\r\n", argv[1]);
        return -1;
    }

    read(fd, &gpio_in_value, 1);
    printf("gpio in value:%d.\r\n", gpio_in_value);

    lseek(fd, 0, SEEK_SET);
    read(fd, &gpio_in_value, 1);
    printf("gpio in value:%d.\r\n", gpio_in_value);

    retvalue = close(fd);
    if(retvalue < 0){
        printf("file %s close failed!\r\n", argv[1]);
        return -1;
    }
    return 0;
}

此时可以连续多次的读引脚状态: