• Nvidia Jetson Nano学习笔记--使用C语言实现GPIO 输入输出


    系列文章目录

    一.实现PC和Nvidia远程连接
    二.Nvidia 交叉编译程序
    三.Nvidia 使用命令行实现GPIO控制



    前言

    在上一文中采用命令行实现了GPIO控制,本次将使用C语言来实现GPIO输入输出功能,编辑器为VScode。

    一、思路

    回顾一下上文中实现GPIO口控制的流程。

    1.进入到Nano的 /sys/class/gpio 目录下。

    cd /sys/classs/gpio
    
    • 1

    2.导出目标IO口的 GPIO文件(假设 目标IO口编号为216,实际对应Nano上的第7号管脚)

    echo 216 > expoet
    
    • 1

    3.进入所导出的gpio216文件夹。

    cd /sys/class/gpio/gpio216
    
    • 1

    4.如果需要该引脚输出高低电平则

    //设置direction为输出模式,默认为输入模式
    echo "out" > direction
    
    //输出高电平,
    echo 1 > value
    
    //输出低电平
    echo 0 > value
    
    //active_low 级性为0,表示 1--高电平,0--低电平, 极性为1则相反
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    其实使用C语言来实现上述功能,就是将上述的步骤写成代码来实现。

    二、具体实现代码

    1.main函数–GPIO输出

    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    
    static char gpio_path[100];
    static int gpio_config(const char *attr, const char *val);
    
    int main(int argc, char *argv[]) //传入参数格式: ./gpio_out 216 1 ;216号输出高电平
    {
        /* 校验传参  传入的参数必须为3个*/
        if (3 != argc) {
            fprintf(stderr, "usage: %s  \n", argv[0]); //stderr标准错误
            exit(-1);
        }
    
        /* 判断指定编号的GPIO是否导出 */
        //这一步是生成目标IO口的文件路径,并存入gpio__path中
        sprintf(gpio_path, "/sys/class/gpio/gpio%s", argv[1]); 
    
        if (access(gpio_path, F_OK))  //判断标IO口的文件路径是否存在 不存在则需要生成文件路径
        { 
    
            int fd;
            int len;
    				//等同于echo io口编号 > expoet 
            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);  //关闭文件
        }
    
    		//下面三条语句是配置IO口状态
        /* 配置为输出模式 */
        if (gpio_config("direction", "out")) //echo "int" > direction
            exit(-1);
    
        /* 极性设置 */
        if (gpio_config("active_low", "0")) //echo "0" > active_low
            exit(-1);
    
        /* 控制GPIO输出高低电平 */
        if (gpio_config("value", argv[2])) //echo argc[2] > value
            exit(-1);
    
        /* 退出程序 */
        exit(0);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60

    2.main函数–GPIO输入

    输入与输出的区别在于 设置direction为in(默认),在配置完状态后需要阅读一次value的值,在将值打印出来

    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    
    static char gpio_path[100];
    static int gpio_config(const char *attr, const char *val);
    
    int main(int argc, char *argv[])
    {
        char file_path[100];
        char val;
        int fd;
    
        /* 校验传参 */
        if (2 != argc) {
            fprintf(stderr, "usage: %s \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"))//echo "in" > direction
            exit(-1);
    
        /* 极性设置 */
        if (gpio_config("active_low", "0"))//echo "0" > active_low
            exit(-1);
    
        /* 配置为非中断方式 */
        if (gpio_config("edge", "none")) //echo "none" > edge
            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);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77

    3.配置函数

    static int gpio_config(const char *attr, const char *val)
    {
        char file_path[100];
        int len;
        int fd;
        
    		//得到文件路径(direction/dege/active_low...)
        sprintf(file_path, "%s/%s", gpio_path, attr); 
        
        //打开文件(direction/dege/active_low...)
        if (0 > (fd = open(file_path, O_WRONLY))) 
        {
            perror("open error");
            return fd;
        }
    		
    		//写文件(direction/dege/active_low...)
        len = strlen(val);
        if (len != write(fd, val, len)) //write file
        {
            perror("write error");
            close(fd);
            return -1;
        }
    
        close(fd);  //关闭文件
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    总结

    通过如上的步骤便可以通过C语言来实现Nano的GPIO控制。

  • 相关阅读:
    11. 第一章总结
    『忘了再学』Shell基础 — 11、变量定义的规则和分类
    DPDK-A1:Centos配置MLX5驱动
    Redis 实现 用户输入密码错误5次锁定
    化繁为简 面板式空调网关亮相上海智能家居展 智哪儿专访青岛中弘赵哲海
    基于jsp+mysql+ssm在线音乐网站-计算机毕业设计
    长安链共识模块优化中的“精益求精”
    简析Acrel-1000安科瑞变电站综合自动化系统选型与应用
    vivado产生报告阅读分析7-时序报告3
    面试题 17.04. 消失的数字
  • 原文地址:https://blog.csdn.net/weixin_43903002/article/details/126917996