嵌入式linux:GPIO应用学习

发布时间 2023-12-04 13:19:43作者: 风之忆一

一、准备工作

1、开发板串口连上电脑。

2、挂载nfs文件: 将ubuntu的/nfsroot文件夹映射到将开发板的/mnt文件夹(此处对应笔者的虚拟机)

mount -t nfs -o nolock,vers=3 192.168.3.61:/nfsroot  /mnt

 

二、了解GPIO应用层

1、开发板的GPIO通过sysfs方式进行操作,进入/sys/class/gpio目录下查看有哪些文件。

cd /sys/class/gpio/
ls -al

对应文件如下:

2、具体文件说明

export:

在操作gpio口前需要先导出对应引脚,这里笔者理解成GPIO初始化,此处举例导出编号为0的引脚

echo 0 > export

unexport:

将导出引脚删除

echo  0 > unexport
gpiochipX:
I.MX6UL/I.MX6ULL 一共包含了 5 个 GPIO控制器,分别为 GPIO1、GPIO2、GPIO3、GPIO4、GPIO5,在这里分别对应 gpiochip0、gpiochip32、gpiochip64、gpiochip96、gpiochip128 这 5 个文件夹,每一个 gpiochipX 文件夹用来管理一组 GPIO。
gpioX:

包含 active_low、device、direction 、edge 、power 、subsystem 、uevent、 value 八组文件

1、active_low:配置物理电平与逻辑电平 正常情况下配置物理电平为高,逻辑电平为高 。

2、direction :配置GPIO为输入或者输出模式。    参数:in  out

3、edge: 控制中断触发模式。  参数:none rising falling both

4、value:GPIO在输出模式下输出高低电平。  

 

三、应用编程之输出

执行程序时需要传入两个参数,argv[1]指定 GPIO 的编号、argv[2]指定输出电平状态(0 表示低电平、1 表示高电平)。 
 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <sys/types.h>
 4 #include <sys/stat.h>
 5 #include <fcntl.h>
 6 #include <unistd.h>
 7 #include <string.h>
 8 
 9 static char gpio_path[100];
10 
11 static int gpio_config(const char *attr,const char *val)
12 {
13     char file_path[100];
14     int len;
15     int fd;
16 
17     // 拼接gpio控制文件地址
18     sprintf(file_path,"%s/%s",gpio_path,attr); 
19     // 打开gpio文件失败则返回
20     if(0 > (fd = open(file_path,O_WRONLY)))
21     {
22         perror("open error");
23         return fd;
24     }
25     
26     // 计算字符串长度
27     len = strlen(val);
28     // 字符串长度与写入长度对比,一致则写入成功,否则返回-1
29     if(len != write(fd,val,len))
30     {
31         perror("write fail");
32         close(fd);
33         return -1;
34     }
35 
36     // 关闭文件
37     close(fd);
38     return 0;
39 }
40 
41 int main(int argc, char *argv[])
42 {
43     // 对比传入参数是否为3,不是则报错返回
44     if(3 != argc)
45     {
46         fprintf(stderr, "usage: %s <gpio> <value>\n", argv[0]);
47         exit(-1);
48     }
49 
50     // 拼接gpio目录地址
51     sprintf(gpio_path,"/sys/class/gpio/gpio%s",argv[1]);
52     
53     // 查询目录是否存在,不存在则使用export导出
54     if(access(gpio_path,F_OK))
55     {
56         int fd;
57         int len;
58 
59         // 打开gpio导出配置文件
60         if (0 > (fd = open("/sys/class/gpio/export", O_WRONLY))) 
61         {
62             perror("open error");
63             exit(-1);
64         }
65 
66         // 写入需要导出的gpio
67         len = strlen(argv[1]);
68         if (len != write(fd, argv[1], len)) 
69         {
70             perror("write error");
71             close(fd);
72             exit(-1);
73         }
74 
75         // 导出成功,关闭文件
76         close(fd); 
77     }
78 
79     /* 配置为输出模式 */
80     if (gpio_config("direction", "out"))
81     {
82         exit(-1);
83     }
84 
85     /* 极性设置 */
86     if (gpio_config("active_low", "0"))
87     {
88         exit(-1);
89     }
90 
91     /* 控制 GPIO 输出高低电平 */
92     if (gpio_config("value", argv[2]))
93     {
94         exit(-1);
95     }
96 
97     /* 退出程序 */
98     exit(0);
99 }

 

四、应用编程之输入

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <sys/types.h>
  4 #include <sys/stat.h>
  5 #include <fcntl.h>
  6 #include <unistd.h>
  7 #include <string.h>
  8 
  9 static char gpio_path[100];
 10 
 11 static int gpio_config(const char *attr,const char *val)
 12 {
 13     char file_path[100];
 14     int len;
 15     int fd;
 16 
 17     // 拼接gpio控制文件地址
 18     sprintf(file_path,"%s/%s",gpio_path,attr); 
 19     // 打开gpio文件失败则返回
 20     if(0 > (fd = open(file_path,O_WRONLY)))
 21     {
 22         perror("open error");
 23         return fd;
 24     }
 25     
 26     // 计算字符串长度
 27     len = strlen(val);
 28     // 字符串长度与写入长度对比,一致则写入成功,否则返回-1
 29     if(len != write(fd,val,len))
 30     {
 31         perror("write fail");
 32         close(fd);
 33         return -1;
 34     }
 35 
 36     // 关闭文件
 37     close(fd);
 38     return 0;
 39 }
 40 
 41 int main(int argc, char *argv[])
 42 {
 43     char file_path[100];
 44     char val;
 45     int fd;
 46 
 47     // 对比传入参数是否为2个,不是则报错返回
 48     if(2 != argc)
 49     {
 50         fprintf(stderr, "usage: %s <gpio> <value>\n", argv[0]);
 51         exit(-1);
 52     }
 53 
 54     // 拼接gpio目录地址
 55     sprintf(gpio_path,"/sys/class/gpio/gpio%s",argv[1]);
 56     
 57     // 查询目录是否存在,不存在则使用export导出
 58     if(access(gpio_path,F_OK))
 59     {
 60         int len;
 61 
 62         // 打开gpio导出配置文件
 63         if (0 > (fd = open("/sys/class/gpio/export", O_WRONLY))) 
 64         {
 65             perror("open error");
 66             exit(-1);
 67         }
 68 
 69         // 写入需要导出的gpio
 70         len = strlen(argv[1]);
 71         if (len != write(fd, argv[1], len)) 
 72         {
 73             perror("write error");
 74             close(fd);
 75             exit(-1);
 76         }
 77 
 78         // 导出成功,关闭文件
 79         close(fd); 
 80     }
 81 
 82     /* 配置为输入模式 */
 83     if (gpio_config("direction", "in"))
 84     {
 85         exit(-1);
 86     }
 87 
 88     /* 极性设置 */
 89     if (gpio_config("active_low", "0"))
 90     {
 91         exit(-1);
 92     }
 93 
 94     // 配置为非中断模式
 95     if(gpio_config("edge", "none"))
 96     {
 97         exit(-1);
 98     }
 99 
100     // 读取GPIO电平状态
101     sprintf(file_path,"%s/%s",gpio_path,"value");
102     if(0 > (fd = open(file_path,O_RDONLY)))
103     {
104         perror("open error");
105         exit(-1);
106     }
107 
108     if(0 > read(fd,&val,1))
109     {
110         perror("read error");
111         close(fd);
112         exit(-1);
113     }
114 
115     printf("value: %c\n",val);
116 
117     /* 退出程序 */
118     close(fd);
119     exit(0);
120 }