该图为泰山派的IO口空间分配列表,此次要控制的IO口为GPIO1的PA4
方式一:终端实现
通过进入 /sys/class/gpio 直接操作文件的内容修改GPIO的值
查看需要控制的GPIO口在Linux里对应的标号
想要查看上图中GPIO1_A4的GPIO标号,可以在终端使用命令行输入
cat /sys/kernel/debug/gpio
可以得到所有GPIO口的标号,得到的结果是:
gpiochip0: GPIOs 0-31, parent: platform/fdd60000.gpio, gpio0:
gpio-23 ( |mdio-reset ) out hi
gpiochip1: GPIOs 32-63, parent: platform/fe740000.gpio, gpio1:
gpio-40 ( |rgb-led-b ) out lo
gpio-41 ( |rgb-led-g ) out lo
gpio-42 ( |rgb-led-r ) out lo
gpiochip2: GPIOs 64-95, parent: platform/fe750000.gpio, gpio2:
gpio-73 ( |reset ) out hi
gpio-77 ( |bt_default_rts ) out lo
gpio-79 ( |bt_default_reset ) out hi
gpio-80 ( |bt_default_wake_host) in hi
gpio-81 ( |bt_default_wake ) out hi
gpiochip3: GPIOs 96-127, parent: platform/fe760000.gpio, gpio3:
gpiochip4: GPIOs 128-159, parent: platform/fe770000.gpio, gpio4:
gpio-148 ( |vcc5v0_host ) out hi
gpiochip5: GPIOs 511-511, parent: platform/rk805-pinctrl, rk817-gpio, can sleep:
由此可得在gpio1这组里是由编号为32开始的,所以GPIO1_A0的标号为32,则GPIO1_A4标号为32+4=36。
进入 "sys/class/gpio/"里创建IO口
cd进去之后使用ls查看所有文件,可以看到有
export gpio36 gpiochipo gpiochip128 gpiochip32 gpiochip511 gpiochip64 gpiochip96 unexport
在这里每一个gpiochipX 文件夹用来管理一组GPIO 。进入gpiochip0 ,显示为:
base: 表示这组GPIO的最小标号
label: 表示这组GPIO对应的名字,均为gpio
ngpio:表示该控制器管理的GPIO引脚数量
在使用GPIO之前需要将该IO口设置为可配置模式,使用
echo 标号 > export
在这里是标号36,所以是 echo 36 > export
输入命令之后再用 ls 查看文件夹发现多出一个名为 gpio36 的文件夹,这就是可以控制的36号IO口的文件夹。
进入 gpioxx 操作IO口
cd进入,在这里使用 ls 可以看到有
我们主要关心的文件是:active_low 、 direction 、edge 、value 这四个属性文件
active_low:这个属性文件用于控制IO口的输出极性,默认情况下为0
direction:引脚为输入或输出模式 可以配置为 "out" 或者 "in"
value:输出模式下,向value 文件写入0/1,控制gpio 引脚输出高/低电平
输入模式下,该值为读取到的电平状态
edge:控制中断的触发模式,在设置为中断之前需要将IO口设置为输入模式
- 非中断引脚:
echo "none" > edge
- 上升沿触发:
echo "rising" > edge
- 下降沿触发:
echo "falling" > edge
- 边沿触发:
echo "both" > edge
当设置为中断输入之后可以通过poll() 函数监听输入
例如,现在需要这个IO口输出高电平,则终端输入如下:
echo "out" > direction
echo 1 > value
即可
需要读取一次作为输入状态的IO口电平(输出状态也可以读电平)则是:
echo "in" > direction
cat /sys/class/gpio/gpio36/value
即可
至此,终端进入 /sys/class/gpio 直接操作文件的内容修改GPIO的值结束。
方式二:C语言编程实现
在vim里编写main.c文件,编译后执行
读取电平如下:
#include "stdio.h"
#include "fcntl.h"
#include "unistd.h"//引用需要的头文件
int main(void)
{
int fd;
char value=0;
fd = open("/sys/class/gpio/export",O_RDWR); //fd作为可读可写的/sys/class/gpio/export
write(fd,"36",2); //启用36号ID引脚,返回的期望值为2个字符
close(fd); //释放FD
fd = open("/sys/class/gpio/gpio36/direction",O_RDWR);
write(fd,"in",3); //36号ID设为输入
close(fd);
fd = open("/sys/class/gpio/gpio36/value",O_RDWR); //fd作为IO口的电平状态value
while(1)
{
read(fd,&value,1); //读入电平
printf("Value =%c \r\n",value); //打印电平状态
sleep(1); //延时1S
}
return 0;
}
如果需要修改IO电平则:
#include "stdio.h"
#include "fcntl.h"
#include "unistd.h"//引用需要的头文件
int main(void)
{
int fd;
char value=0;
fd = open("/sys/class/gpio/export",O_RDWR); //fd作为可读可写的/sys/class/gpio/export
write(fd,"36",2); //启用36号ID引脚,返回的期望值为2个字符
close(fd); //释放FD
fd = open("/sys/class/gpio/gpio36/direction",O_RDWR);
write(fd,"out",3); //36号ID设为输出
close(fd);
fd = open("/sys/class/gpio/gpio36/value",O_RDWR); //fd作为IO口电平
while(1)
{
write(fd,1,3); //修改为高电平
sleep(1); //延时1S
write(fd,0,3); //修改为低电平
sleep(1); //延时1S
}
return 0;
}
未完待续...