linux下gpio控制
文章目录
- linux下gpio控制
- 1.中断命令控制
- /sys/class/gpio/export
- 终端命令控制led
- 2.应用程序控制
- 3.驱动代码控制
1.中断命令控制
通用GPIO主要用于产生输出信号和捕捉输入信号。每组GPIO均可以配置为输出输入以及特定的复用功能。
当作为输入时,内置有上拉电阻,可以配置上拉、下拉、浮空(高阻态), GPIO也可配置为中断触发,触发方式有:电平触发、边沿触发。软件可配置。
pin控制器需要通过软件编程来控制,在Linux系统中表现为pin controller driver,Linux为了统一各厂商的pin脚管理,提供了pinctrl子系统,对上为其他软件模块提供
统一的API操作pin脚,对下为各芯片厂商实现pin controller driver提供统一的软件模型。
• GPIO操作放发1: “/sys/class/gpio”该文件对所有GPIO编号,从0开始。 GPIOn_x的编号为32*n+x
/sys/class/gpio/export
/sys/class/gpio/export
是 Linux 系统中用于控制 GPIO(General Purpose Input/Output)引脚的虚拟文件。它的作用是允许用户请求并使能特定的 GPIO 引脚,以便可以通过 /sys/class/gpio/
路径进行后续的读写操作。
作用
当你希望在 Linux 系统中使用某个特定的 GPIO 引脚时,你需要通过 export
文件将其导出。具体来说,export
文件的作用是将指定的 GPIO 引脚暴露给用户空间,这样你就可以对它进行控制(例如配置为输入或输出,并读取或写入数据)。
使用流程
-
导出 GPIO 引脚
-
用户通过向
/sys/class/gpio/export
文件写入 GPIO 引脚的编号来导出该引脚。例如,如果你想控制 GPIO 引脚 17(编号通常与硬件有关),可以通过以下命令导出它:
echo 17 > /sys/class/gpio/export
-
写入数字
17
后,系统会在/sys/class/gpio/
下创建一个新的目录gpio17
,这个目录中包含了用于配置和操作 GPIO 17 的文件和设置。
-
-
访问和控制 GPIO 引脚
-
一旦导出某个 GPIO 引脚,就可以通过
/sys/class/gpio/gpioX/
目录进行进一步的配置和操作。这里的x
是你导出的 GPIO 引脚编号。例如,对于 GPIO 17,路径会是
/sys/class/gpio/gpio17/
。
direction
:设置该引脚为输入(in
)或输出(out
)。value
:读取(输入)或写入(输出)该引脚的状态(0 或 1)。edge
:配置该引脚的中断触发方式(例如:rising
、falling
、both
)。
-
-
卸载 GPIO 引脚
-
如果你不再需要某个 GPIO 引脚,可以通过向
/sys/class/gpio/unexport
文件写入该引脚的编号来卸载它。例如:
echo 17 > /sys/class/gpio/unexport
-
这会删除
/sys/class/gpio/gpio17/
目录,释放该 GPIO 引脚。
-
示例:
-
导出 GPIO 17:
echo 17 > /sys/class/gpio/export
-
设置 GPIO 17 为输出:
echo out > /sys/class/gpio/gpio17/direction
-
设置 GPIO 17 输出为高电平(1):
echo 1 > /sys/class/gpio/gpio17/value
-
读取 GPIO 17 的输入值:
cat /sys/class/gpio/gpio17/value
-
卸载 GPIO 17:
echo 17 > /sys/class/gpio/unexport
总结
/sys/class/gpio/export
的作用是允许用户请求并启用某个 GPIO 引脚,通过将 GPIO 引脚编号写入该文件,用户可以在 /sys/class/gpio/
下找到该引脚的控制文件,进而对该 GPIO 引脚进行操作。
Linux下/sys目录介绍_嵌入式linux sys 每一个目录含义-CSDN博客
终端命令控制led
led1 PB5 32+5 = 37
led2 PB4 32+4 = 36
echo 36 > /sys/class/gpio/export
echo out > /sys/class/gpio/gpio36/direction
echo 1 > /sys/class/gpio/gpio36/value
led2 亮
echo high > /sys/class/gpio/gpio36/direction
直接设置方向并点亮
echo low > /sys/class/gpio/gpio36/direction
直接设置方向并熄灭
# echo in > /sys/class/gpio/gpio36/direction
# cat /sys/class/gpio/gpio36/value
0
现象:灯灭
echo 37 > /sys/class/gpio/export
echo high > /sys/class/gpio/gpio37/direction
直接设置方向并点亮
echo "rising" > /sys/class/gpio/gpio36/edge
echo " falling" > /sys/class/gpio/gpio36/edge
echo " both" > /sys/class/gpio/gpio36/edge
echo " none" > /sys/class/gpio/gpio36/edge
在 Linux 系统中,通过 /sys/class/gpio/gpio36/edge 文件可以设置引脚的边沿触发方式。具体来说:
echo "rising" > /sys/class/gpio/gpio36/edge
这个命令设置 GPIO36 引脚为 上升沿触发。即,当 GPIO36 从 低电平 (0) 变为 高电平 (1) 时,会产生中断或事件。
echo "falling" > /sys/class/gpio/gpio36/edge
这个命令设置 GPIO36 引脚为 下降沿触发。即,当 GPIO36 从 高电平 (1) 变为 低电平 (0) 时,会产生中断或事件。
echo "both" > /sys/class/gpio/gpio36/edge
这个命令设置 GPIO36 引脚为 双边沿触发。即,不管是上升沿(低电平到高电平)还是下降沿(高电平到低电平)都会产生中断或事件。
echo "none" > /sys/class/gpio/gpio36/edge
这个命令禁用引脚的边沿触发。也就是说,GPIO36 的电平变化不会产生中断或事件响应。
总结:
这些命令的作用是通过设置 edge 文件来定义 GPIO36 引脚在何种电平变化时触发中断。可以选择:
上升沿 (rising)
下降沿 (falling)
双边沿 (both)
无边沿触发 (none)
使用这些配置后,GPIO36 的状态变化将根据设置的触发模式,激发对应的事件或中断,可以用于进一步的编程响应。
2.应用程序控制
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
/***************************************************************************
* 文件名称:main.c
* 文件标识:main.c
* 摘 要:GPIOB4/GPIOB5引脚操作函数,GPIOB4作为输出,LED1每隔1S闪烁一次
* GPIOB5作为输入,每隔1S,读取一次该引脚的状态
* 注 意:PB5默认读到0,LED将PB5引脚拉低,读1,需要给PB5接高电平
*****************************************************************************/
/**
* @brief GPIOB5引脚读取线程
* @param Pdata: 无
* @return 无
*
*/
void *CallBack_get_gpiob5(void *Pdata)
{
FILE *p=NULL;
char buff[10]= {0};
while(1)
{
p = fopen("/sys/class/gpio/gpio37/value","r");
fseek(p,0,0);
fread(buff,1,1,p);
printf("GPIOB input value is %d\n",buff[0] - '0');
buff[0] = 0;
sleep(1);
fclose(p);
}
}
int main()
{
FILE *p=NULL;
pthread_t pid;
int ret = 0;
p = fopen("/sys/class/gpio/export","w");
fprintf(p,"%d",36);
fclose(p);
p = fopen("/sys/class/gpio/gpio36/direction","w");
fprintf(p,"out");
fclose(p);
p = fopen("/sys/class/gpio/export","w");
fprintf(p,"%d",37);
fclose(p);
p = fopen("/sys/class/gpio/gpio37/direction","w");
fprintf(p,"in");
fclose(p);
//创建接收线程
ret = pthread_create(&pid,NULL,CallBack_get_gpiob5,NULL);
if(ret <0)
{
perror("pthread creat err \n");
return -1;
}
while(1)
{
p = fopen("/sys/class/gpio/gpio36/direction","w");
fprintf(p,"high");
sleep(1);
fclose(p);
p = fopen("/sys/class/gpio/gpio36/direction","w");
fprintf(p,"low");
sleep(1);
fclose(p);
}
}
现象:
led2闪烁
线程读取led1引脚状态
3.驱动代码控制
驱动代码控制一般结合设备树和对应的驱动代码即可,具体可见正点原子和韦东山linux驱动教学视频
本章不做重点介绍