linux内核提供了一套在用户态配置GPIO的接口,在/sys/class/gpio/目录下 
这里写图片描述
可以发现其中包含有两个文件exportunexport和若干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操作。

代码如下:

 
  1. poll_test.c

  2. #include <stdio.h>

  3. #include <fcntl.h>

  4. #include <poll.h>

  5. #include <unistd.h>

  6. int main()

  7. {

  8. int fd=open("/sys/class/gpio/gpio7/value",O_RDONLY);

  9. if(fd<0)

  10. {

  11. perror("open '/sys/class/gpio/gpio7/value' failed!\n");

  12. return -1;

  13. }

  14. struct pollfd fds[1];

  15. fds[0].fd=fd;

  16. fds[0].events=POLLPRI;

  17. while(1)

  18. {

  19. if(poll(fds,1,0)==-1)

  20. {

  21. perror("poll failed!\n");

  22. return -1;

  23. }

  24. if(fds[0].revents&POLLPRI)

  25. {

  26. if(lseek(fd,0,SEEK_SET)==-1)

  27. {

  28. perror("lseek failed!\n");

  29. return -1;

  30. }

  31. char buffer[16];

  32. int len;

  33. if((len=read(fd,buffer,sizeof(buffer)))==-1)

  34. {

  35. perror("read failed!\n");

  36. return -1;

  37. }

  38. buffer[len]=0;

  39. printf("%s",buffer);

  40. }

  41. }

  42. return 0;

  43. }

这个小程序的作用就是就是不断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()确实能检测到电平变化。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐