1 摘要
嵌入式编程中对GPIO的读写操作是最常见的应用的了,这里介绍一种C语言方式操作GPIO,涉及代码,以源代码的形式提供,方便快速嵌入实际项目开发;这种操作GPIO的方法类似MCU,实现一行代码拉高、拉低GPIO,直接一行代码实现IO的读写,其实质是封装了/sys/class/gpio的读写。代码实现了GPIO初始化、读、写等操作,针对Linux下操作GPIO提供了一套标准流程,同时可以应用于多种Linux平台,最后以zynq平台做测试,但是该代码不单单应用于zynq,像其他运行Linux的芯片平台,都可以使用。
2 应用层使用代码介绍
2.1 初始化GPIO
//set gpio output mode
DEV_GPIO_Mode(GPIO_TEST_PIN, 1);
//set gpio input mode
DEV_GPIO_Mode(KEY0_PIN, 0);
2.2 对GPIO的读写操作
实现一行代码拉高、拉低GPIO
while(1)
{
DEV_Digital_Write(GPIO_TEST_PIN,0);
sleep(1);
DEV_Digital_Write(GPIO_TEST_PIN,1);
sleep(1);
key_value = GET_KEY0;
Debug("key_value = %d\r\n", key_value);
}
2.3 总结
上述对GPIO的操作主要通过DEV_GPIO_Mode/ DEV_Digital_Write完成,实现了类似MCU的操作。
2.4 DEV_GPIO_Mode
该函数的封装实现如下
SYSFS_GPIO_Export(Pin);
if(Mode == 0 || Mode == SYSFS_GPIO_IN){
SYSFS_GPIO_Direction(Pin, SYSFS_GPIO_IN);
printf("IN Pin = %d\r\n",Pin);
}else{
SYSFS_GPIO_Direction(Pin, SYSFS_GPIO_OUT);
printf("OUT Pin = %d\r\n",Pin);
}
2.5 DEV_Digital_Write
该函数的封装实现如下
void DEV_Digital_Write(UWORD Pin, UBYTE Value)
{
SYSFS_GPIO_Write(Pin, Value);
}
具体对/sys/class/gpio的读写函数如下:
int SYSFS_GPIO_Write(int Pin, int value)
{
const char s_values_str[] = "01";
char path[DIR_MAXSIZ];
int fd;
snprintf(path, DIR_MAXSIZ, "/sys/class/gpio/gpio%d/value", Pin);
fd = open(path, O_WRONLY);
if (fd < 0) {
SYSFS_GPIO_Debug( "Write failed : Pin%d,value = %d\n", Pin, value);
return -1;
}
if (write(fd, &s_values_str[value == SYSFS_GPIO_LOW ? 0 : 1], 1) < 0) {
SYSFS_GPIO_Debug( "failed to write value!\n");
return -1;
}
close(fd);
return 0;
}
3 Zynq平台测试
3.1 宏定义说明
首先对zynq的平台IO的宏定义,这里可以修改为自己开发板的IO编号,注意zynq平台的IO编号,参考文档
Zynq-7000、FMQL45T900的GPIO控制(三)---linux管脚编号计算-优快云博客
这里要说明的是,每个平台的IO编号差异比较大,修改后要找到自己平台的IO编号。
#define MIO0_PIN_NUM (906)
#define GPIO_TEST_PIN (MIO0_PIN_NUM + 10)// ZYNQ-7000 MIO10 -> gpio916
#define KEY0_PIN (MIO0_PIN_NUM + 11)
3.2 测试结果
测试结果如下图所示: