Linux系统应用层GPIO控制

文章目录

  • Linux
    • 一.前言
    • 二.GPIO接口创建
      • 1.export和unexport
      • 2.引脚号
    • 三.GPIO口方向
    • 四.GPIO电平
    • 五.代码中应用

Linux

一.前言

从单片机过度到有操作系统的板子,我们都是从控制GPIO口点灯开始,今天就说一下linux系统下如何控制GPIO

之前玩一款ARM A9的板子,当时控制GPIO是通过看开发板电路图来查找相应的管脚,再根据手册来修改对应寄存器的值,来控制GPIO,今天来说一下,直接通过控制文件来控制GPIO

二.GPIO接口创建

1.export和unexport

我们先进入Linux内核中的此路径下

/sys/class/gpio

Linux系统应用层GPIO控制_第1张图片
此路径下有两个节点export和unexport

  • export 创建GPIO新节点
  • unexport 删除已经存在的GPIO节点

这里我们以引脚好为 100 进行创建好删除操作,直接在命令行输入一下命令
创建一个GPIO节点

echo 100 > export

删除一个GPIO节点

echo 100 > export

注意:是在 /sys/class/gpio 路径下执行的

但是我们在虚拟机里面创建的时候,无法创建
Linux系统应用层GPIO控制_第2张图片
原因

  • 引脚号为100的GPIO被其他程序占用着
  • 此引脚不能复用为GPIO口

这里是在虚拟机上测试

2.引脚号

所以引脚号特别的重要,我们如何将引脚号和对管脚对应。我之前用飞凌的OK1012A开发板
它的 /sys/class/gpio 路径下用这四个文件

  • export
  • gpiochip448
  • gpiochip480
  • unexport

查看驱动代码是看到它就加载了两个GPIO分别是GPIO0和GPIOI1,而我查看相关手册引脚就两种GPIO1_x和GPIO2_x

经过测试
GPIO1_x的引脚号=480 + x
GPIO2_x的引脚号=448 + x

注意GPIO1_x和GPIO1[x]代表的是一个GPIO引脚

三.GPIO口方向

我们知道GPIO口有输入和输出模式
查看GPIO口的方向,我们进入gpio路径下

cd /sys/class/gpio/gpioxx

查看方向

cat direction

一般就会显示 in 或者 out

方向的设置
输入模式

echo in > direction

输出模式

echo out > direction

如何输入命令报错误,先查看一下你的路径是不是在gpioxx 下

四.GPIO电平

查看GPIOxx的电平输入下面命令

cd /sys/class/gpio/gpioxx
cat value

会显示出 1 (高电平)或者 0(低电平)
我们可以通过下面命令来设置电平
设置为高电平

echo 1 > value

设置为低电平

echo 0 > value

五.代码中应用

我们一般都是在代码中操作,所有我们可以使用 system这个函数

system("echo 100 > /sys/class/gpio/export");
system("echo out > /sys/class/gpio/gpio100/direction"); //设置为输出模式
system("echo 1 > /sys/class/gpio/gpio100/value"); //设置高电平

还有一种方法就是对文件的操作

#include  
#include  
#include  
#include  

int main(void) 
{ 	
	FILE *p=NULL; 	
	p = fopen("/sys/class/gpio/export","w");
	fprintf(p,"%d",100); 	
	fclose(p); 	
	
	p=fopen("/sys/class/gpio/gpio38/direction","w"); 
	fprintf(p,"out"); 	
	fclose(p); 	

	p = fopen("/sys/class/gpio/gpio38/value","w"); 
	fprintf(p,"%d",1); 	
	fclose(p); 	
	return 0; 
}

这两种方法都是可以实现的大家根据自己的需求来选择

还有一个用途比较广泛的就是,检测GPIO口的电平来赋值给变量,下面程序大家可以参考

#include    
#include   
#include   
#include   
#include    //define O_WRONLY and O_RDONLY  
 
//创建gpio文件
void initGpio(int n)  
{  
    FILE * fp =fdopen("/sys/class/gpio/export","w");  
    if (fp == NULL)  
        perror("export open filed");  
    else  
        fprintf(fp,"%d",n);  
    fclose(fp);  
}   //create gpio file  

//设置gpio方向
void setGpioDirection(int n,char *direction)  
{  
    char path[100] = {0};  
    sprintf(path,"/sys/class/gpio/gpio%d/direction",n);  
    FILE * fp =fdopen(path,"w");  
    if (fp == NULL)  
        perror("direction open filed");  
    else  
        fprintf(fp,"%s",direction);  
    fclose(fp);  
}   //set gpio "in" or "out"  

//设置gpio的电平
void set_gpioValue(int n, int value)
{
	char path[64];      
    snprintf(path, sizeof(path), "/sys/class/gpio/gpio%d/value", n);
	FILE *fp = fopen(path, "w");
	if (fp == NULL)  
        perror("direction open filed");  
    else
		fprintf(fp, "%d", value);
	fclose(fp);
}

 //获取gpio的值
int getGpioValue(int n)  
{  
    char path[64];  
    char value_str[3];  
    int fd;  
  
    snprintf(path, sizeof(path), "/sys/class/gpio/gpio%d/value", n);  
    fd = open(path, O_RDONLY);  
    if (fd < 0) {  
        perror("Failed to open gpio value for reading!");  
        return -1;  
    }  
  
    if (read(fd, value_str, 3) < 0) {  
        perror("Failed to read value!");  
        return -1;  
    }  
  
    close(fd);  
    return (atoi(value_str));  
}   //get gpio(n)'s value  
  
  
int main()  
  
{  
    initGpio(18);  
    setGpioDirection(18,"in");  
    while(1)  
    {  
        printf("%d\n",getGpioValue(18));<span style="white-space:pre">    //每隔1s输出一次gpio18的值  
        sleep(1);  
    }  
  
    return 0;  
  
}  

也可以用shell 命令来测试我们的gpio口

#!/bin/sh
gpio_test(){
    GPIO=$1 #注意等号中间不能有空格
    echo $GPIO > /sys/class/gpio/export
    echo out > /sys/class/gpio/gpio${GPIO}/direction 
    for i in $(seq 1 3)
    do
    echo 0 > /sys/class/gpio/gpio${GPIO}/value
    sleep 1
    echo 1 > /sys/class/gpio/gpio${GPIO}/value
    sleep 1
    done
    echo $GPIO > /sys/class/gpio/unexport
}

#调用函数
gpio_test  898
gpio_test  899

你可能感兴趣的:(Linux,linux,gpio)