Linux GPIO的操作
linux内核提供了一套在用户态配置GPIO的接口,在/sys/class/gpio/目录下可以发现其中包含有两个文件export、unexport和若干gpiochipN类型文件夹。export:用于将指定编号的引脚导出,作为GPIO使用unexport :用于将导出的GPIO删除掉gpiochipN:当前芯片中包含的GPIO控制器GPIO使用方法添加设备接口GPIO167输入:echo 167
linux内核提供了一套在用户态配置GPIO的接口,在/sys/class/gpio/
目录下
可以发现其中包含有两个文件export
、unexport
和若干gpiochipN
类型文件夹。
export :用于将指定编号的引脚导出,作为GPIO使用
unexport :用于将导出的GPIO删除掉
gpiochipN :当前芯片中包含的GPIO控制器
GPIO使用方法
添加设备接口GPIO167
输入:echo 167 > export
可以发现,目录下出现了gpio167,如果执行命令后没有反应,表示当前的GPIO已经用作其他的功能,例如作为IIC的引脚等
删除设备接口GPIO167 。
输入:echo 167 > unexport
可以发现当前导出的接口被删除。
direction : 设置输出还是输入模式
设置为输入:echo “in” > direction
设置为输出:echo “out” > direction
value : 输出时,控制高低电平;输入时,获取高低电平
高电平:echo 1 > value
低电平:echo 0 > value
edge : 控制中断触发模式,引脚被配置为中断后可以使用poll() 函数监听引脚
非中断引脚: echo “none” > edge
上升沿触发:echo “rising” > edge
下降沿触发:echo “falling” > edge
边沿触发:echo “both” > edge
用户态使用gpio监听中断
比如我想监听PA7上的电平变化(也就是边沿触发),那么应该先向“/sys/class/gpio/gpio7/direction”写入“in”,然后向“/sys/class/gpio/gpio7/edge”写入“both”,然后对”/sys/class/gpio/gpio7/value”执行select/poll操作。
代码如下:
-
poll_test.c
-
#include <stdio.h>
-
#include <fcntl.h>
-
#include <poll.h>
-
#include <unistd.h>
-
int main()
-
{
-
int fd=open("/sys/class/gpio/gpio7/value",O_RDONLY);
-
if(fd<0)
-
{
-
perror("open '/sys/class/gpio/gpio7/value' failed!\n");
-
return -1;
-
}
-
struct pollfd fds[1];
-
fds[0].fd=fd;
-
fds[0].events=POLLPRI;
-
while(1)
-
{
-
if(poll(fds,1,0)==-1)
-
{
-
perror("poll failed!\n");
-
return -1;
-
}
-
if(fds[0].revents&POLLPRI)
-
{
-
if(lseek(fd,0,SEEK_SET)==-1)
-
{
-
perror("lseek failed!\n");
-
return -1;
-
}
-
char buffer[16];
-
int len;
-
if((len=read(fd,buffer,sizeof(buffer)))==-1)
-
{
-
perror("read failed!\n");
-
return -1;
-
}
-
buffer[len]=0;
-
printf("%s",buffer);
-
}
-
}
-
return 0;
-
}
这个小程序的作用就是就是不断poll(“/sys/class/gpio/gpio7/value”)。一旦poll()返回,就输出PA7的值。假设代码放在~目录下,然后输入如下命令:
cd ~ gcc poll_test.c -o poll_test echo in > /sys/class/gpio/gpio7/direction echo both > /sys/class/gpio/gpio7/edge ./poll_test
用1K电阻把PA7上拉到VCC,然后用一根导线把PA7与GND连接又断开,会发现不断输出1和0(当PA7连上GND的瞬间输出0,与GND断开的瞬间输出1)。说明poll()确实能检测到电平变化。
更多推荐
所有评论(0)