17.linuxGPIO应用编程

        除了LED类设备可以通过sysfs文件系统控制以外,还可以使用该虚拟文件系统控制GPIO的高低电平,输入以及中断检测。

一、GPIO控制高低电平

        进入目录sys/class/gpio下可以看到有如下文件,其中gpiochip0对应硬件的GPIO0,gpiochip1对应硬件的GPIO1,以此类推。每个gpiochipX都管理一组32个gpio管脚。

        如果要使用某一个gpio管脚,需要先使用export命令将其导出。例如命令echo 0 > export,可以以将GPIO0_IO0导出,同理使用命令echo 0 > unexport命令删除GPIO0_IO0管脚

打开导出的管脚可以看到有如下文件 :

        active_low:代表有效极性
        direction:代表输入或输出
        value:代表管脚电平 

对于给定的一个 GPIO 引脚,如何计算它在 sysfs 中对应的编号?

GPIO4_IO16,GPIO4 对应于 gpiochip96,所以GPIO4_IO16对应的编号就是96 + 16 = 112.

应用程序编写:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>


static char gpio_path[100];
static int gpio_config(const char *attr, const char *val)
{
    char file_path[100];
    int len;
    int fd;
    sprintf(file_path, "%s/%s", gpio_path, attr);
    if (0 > (fd = open(file_path, O_WRONLY))) {
        perror("open error");
        return fd;
    }

    len = strlen(val);
    if (len != write(fd, val, len)) {
        perror("write error");
        close(fd);
    return -1;
    }

    close(fd); //关闭文件
    return 0;
}


int main(int argc, char *argv[])
{
    /* 校验传参 */
    if (3 != argc) {
        fprintf(stderr, "usage: %s <gpio> <value>\n", argv[0]);
        exit(-1);
    }
    /* 判断指定编号的 GPIO 是否导出 */
    sprintf(gpio_path, "/sys/class/gpio/gpio%s", argv[1]);
    if (access(gpio_path, F_OK)) {//如果目录不存在 则需要导出
        int fd;
        int len;
        if (0 > (fd = open("/sys/class/gpio/export", O_WRONLY))) {
        perror("open error");
        exit(-1);
    }
    len = strlen(argv[1]);
    if (len != write(fd, argv[1], len)) {//导出 gpio
            perror("write error");
            close(fd);
            exit(-1);
        }
    close(fd); //关闭文件
    }
    /* 配置为输出模式 */
    if (gpio_config("direction", "out"))
        exit(-1);
    /* 极性设置 */
    if (gpio_config("active_low", "0"))
        exit(-1);
    /* 控制 GPIO 输出高低电平 */
    if (gpio_config("value", argv[2]))
        exit(-1);
    /* 退出程序 */
    exit(0);
}

代码流程:代码使用样例:        ./testApp 36 1,将编号为36的GPIO管脚设置为高电平

        ① 检查是否导出要操作的管脚,如果未导出则将其导出
        ②  将管脚配置为输出模式,有效极性低,输出对应的电平。

 二、GPIO控制高低电平

        

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>


static char gpio_path[100];
static int gpio_config(const char *attr, const char *val)
{
    char file_path[100];
    int len;
    int fd;
    sprintf(file_path, "%s/%s", gpio_path, attr);
    if (0 > (fd = open(file_path, O_WRONLY))) {
        perror("open error");
        return fd;
    }
    len = strlen(val);
    if (len != write(fd, val, len)) {
        perror("write error");
        close(fd);
        return -1;
    }
    close(fd); //关闭文件
    return 0;
}

int main(int argc, char *argv[])
{
    char file_path[100];
    char val;
    int fd;
    /* 校验传参 */
    if (2 != argc) {
        fprintf(stderr, "usage: %s <gpio>\n", argv[0]);
        exit(-1);
    }
    /* 判断指定编号的 GPIO 是否导出 */
    sprintf(gpio_path, "/sys/class/gpio/gpio%s", argv[1]);
    if (access(gpio_path, F_OK)) {//如果目录不存在 则需要导出
        int len;
        if (0 > (fd = open("/sys/class/gpio/export", O_WRONLY))) {
        perror("open error");
        exit(-1);
        }
    len = strlen(argv[1]);
    if (len != write(fd, argv[1], len)) {//导出 gpio
        perror("write error");
        close(fd);
        exit(-1);
        }
    close(fd); //关闭文件
    }

    /* 配置为输入模式 */
    if (gpio_config("direction", "in"))
    exit(-1);
    /* 极性设置 */
    if (gpio_config("active_low", "0"))
    exit(-1);
    /* 配置为非中断方式 */
    if (gpio_config("edge", "none"))
    exit(-1);
    /* 读取 GPIO 电平状态 */
    sprintf(file_path, "%s/%s", gpio_path, "value");
    if (0 > (fd = open(file_path, O_RDONLY))) {
        perror("open error");
        exit(-1);
    }

    if (0 > read(fd, &val, 1)) {
        perror("read error");
        close(fd);
        exit(-1);
    }
    printf("value: %c\n", val);
    /* 退出程序 */
    close(fd);
    exit(0);
}

代码流程:代码使用样例:        ./testApp 36 ,读取编号为36的管脚电平

        ① 检查是否导出要操作的管脚,如果未导出则将其导出
        ②  将管脚配置为输入模式,有效极性低,读取对应电平。

  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值