嵌入式linux:GPIO应用学习
一、准备工作
1、开发板串口连上电脑。
2、挂载nfs文件: 将ubuntu的/nfsroot文件夹映射到将开发板的/mnt文件夹(此处对应笔者的虚拟机)
1 | 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 }
分类:
正点原子嵌入式linux
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)