GPIO全称: General-Purpose Input/Output(通用输入输出),是一种软件运行期间能够动态配置和控制的通用引脚。在RK平台上,除了部分有专门用途的pin(比如DDR、MIPI等),其他的pin,如果不配置复用的话,默认复用状态都是GPIO。RK的GPIO驱动,对上提供的是Linux下标准的GPIO接口。Linux下有一组用户态操作GPIO的sysfs节点。应用层对GPIO编程主要就是通过操作这几个节点来实现。
下面以操作GPIO3_A5为例进行介绍。此GPIO位置如下
“/sys/class/gpio” 下面的节点需要root权限才能操作,使用命令行或者C语言编译出来的程序操作gpio都需要root权限。如果是ssh或者使用LX终端的,先执行如下命令获取root权限。
sudo su
在通用的Linux框架下面,所有GPIO都是用数字编号的。对于RK平台的芯片,其编号计算方式为
(gpio控制器号-0)*32+(端口号-‘A’)*8+索引序号
GPIO3_A5的控制器号为3,端口号为A,索引序号5,故编号为
(3-0)32+08+5=101
将GPIO 101设置为用户态操作
echo 101 > /sys/class/gpio/export
将GPIO 101设置为输出
echo out > /sys/class/gpio/gpio101/direction
在GPIO 101为输出的情形下,设置电平
高电平
echo 1 > /sys/class/gpio/gpio101/value
低电平
echo 0 > /sys/class/gpio/gpio101/value
将GPIO 101设置为输入
echo in > /sys/class/gpio/gpio101/direction
在GPIO 101为输入的情形下,读取其电平,1为高,0为低
cat sys/class/gpio/gpio101/value
取消GPIO 101用户态操作
echo 101 > /sys/class/gpio/unexport
如图
通过连接 libperipheral_api.a 静态库,可以使用C语言调用以下接口来操作GPIO
typedef enum {
PIN_DIRECTION_IN = 0,
PIN_DIRECTION_OUT = 1
} Enum_PinDirection;
/**
* @name: user_gpio_init
* @description: 将某个pin配置为gpio
* @param pin_num: 引脚号
* @return 等于0 - 成功 小于0 - 失败
*/
int user_gpio_init(int pin_num);
/**
* @name: user_gpio_deinit
* @description: 将某个pin释放
* @param pin_num: 引脚号
* @return 等于0 - 成功 小于0 - 失败
*/
int user_gpio_deinit(int pin_num);
/**
* @name: user_gpio_set_level
* @description: 设置gpio电平
* @param pin_num: 引脚号
* @param level: 电平 0 - 低 1- 高
* @return 等于0 - 成功 小于0 - 失败
*/
int user_gpio_set_level(int pin_num, unsigned char level);
/**
* @name: user_gpio_get_level
* @description: 获取gpio电平
* @param pin_num: 引脚号
* @param level: 电平 0 - 低 1- 高
* @return 等于0 - 成功 小于0 - 失败
*/
int user_gpio_get_level(int pin_num, unsigned char *level);
/**
* @name: user_gpio_set_direction
* @description: 设置gpio方向
* @param pin_num: 引脚号
* @param direction: PIN_DIRECTION_IN - 输入 PIN_DIRECTION_OUT - 输出
* @return 等于0 - 成功 小于0 - 失败
*/
int user_gpio_set_direction(int pin_num, unsigned char direction);
/**
* @name: user_gpio_get_direction
* @description: 获取gpio方向
* @param pin_num: 引脚号
* @param direction: PIN_DIRECTION_IN - 输入 PIN_DIRECTION_OUT - 输出
* @return 等于0 - 成功 小于0 - 失败
*/
int user_gpio_get_direction(int pin_num, unsigned char *direction);
测试demo如下,以操作下图所示的GPIO0_D5和GPIO3_A5为例
void gpio_api_test(void)
{
unsigned char level = 0;
// GPIO0_D5 为29脚 GPIO3_A5 为101脚
user_gpio_init(29);
user_gpio_init(101);
user_gpio_set_direction(29, PIN_DIRECTION_OUT);
user_gpio_set_direction(101, PIN_DIRECTION_IN);
user_gpio_set_level(29, 1);
user_gpio_get_level(101, &level);
printf("1.pin 101 level %d\n", level);
usleep(10);
user_gpio_set_level(29, 0);
user_gpio_get_level(101, &level);
printf("2.pin 101 level %d\n", level);
user_gpio_deinit(29);
user_gpio_deinit(101);
return;
}
int main()
{
gpio_api_test();
return 0;
}
运行结果如下