Linux下 GPIO控制编程

linux对gpio口操作,一般都是通过设备节点进行读写。
读写基本操作流程如下:

  1. 导出gpio口 。节点:export
  2. 设置gpio输入输出方向。节点:direction
  3. 读写gpio的数值。节点:value,
  4. 另外使能内部上拉通过。节点:pull_enable
    代码如下:
#include 
#include 
#include 
#include 
#include 

#include "gpio_base.h"


/*
**** 检测GPIO是否已经导出
*/
static bool is_gpio_export(const int pin)
{
	char gpio_path[128] =
	{
		0
	};
	sprintf(gpio_path, "/sys/class/gpio/gpio%d", pin);

	if (access(gpio_path, F_OK) == 0)
	{
		return true;
	}

	return false;
}



/*
*** 导出GPIO
*/
static bool gpio_export(const int pin)
{
	/***** 1.检测是否已经配置GPIO *****/
	if (is_gpio_export(pin) == true)
	{
		return true;
	}

	/***** 2.打开gpio export句柄 *****/
	int export_fd = open("/sys/class/gpio/export", O_WRONLY);

	if (export_fd < 0)
	{
		printf("export gpio%d failed \n", pin);
		return false;
	}

	/***** 3.写入pin到export句柄 *****/
	char export_buf[32] =
	{
		0
	};
	int len = sprintf(export_buf, "%d", pin);




	if (write(export_fd, export_buf, len) < 0)
	{
		close(export_fd);
		printf("write export gpio%d failed \n", pin);
		return false;
	}

	close(export_fd);
	return true;
}



/*
*** 设置GPIO输入/输出
*/
bool gpio_direction_set(const int pin, GPIO_DIR dir)
{
	if (gpio_export(pin) == false)
	{
		printf("export gpio%d faild \n", pin);
		return false;
	}

	char direction_buf[128] =
	{
		0
	};
	sprintf(direction_buf, "/sys/class/gpio/gpio%d/direction", pin);
	int direction_fd = open(direction_buf, O_WRONLY);

	if (direction_fd < 0)
	{
		printf("gpio%d direction setting failed \n", pin);
		return false;
	}

	memset(direction_buf, 0, sizeof(direction_buf));
	int len = sprintf(direction_buf, "%s", dir == GPIO_DIR_IN ? "in": "out");

	if (write(direction_fd, direction_buf, len) < 0)
	{
		printf("diection write gpio%d %s faild \n", pin, direction_buf);
		close(direction_fd);
		return false;
	}

	close(direction_fd);
	return true;
}




/*
*** 设置gpio 内置上拉使能
*/
bool gpio_pull_enable(const int pin, bool enable)
{
	if (gpio_export(pin) == false)
	{
		printf("export gpio%d faild \n", pin);
		return false;
	}


	char gpio_pull_buf[128] =
	{
		0
	};
	sprintf(gpio_pull_buf, "/sys/class/gpio/gpio%d/pull_enable", pin);
	int gpio_pull_fd = open(gpio_pull_buf, O_WRONLY);

	if (gpio_pull_fd < 0)
	{
		printf("gpio%d pull_enable setting failed \n", pin);
		return false;
	}

	memset(gpio_pull_buf, 0, sizeof(gpio_pull_buf));
	int len = sprintf(gpio_pull_buf, "%s", enable? "1": "0");

	if (write(gpio_pull_fd, gpio_pull_buf, len) < 0)
	{
		printf("gpio pull write gpio%d %s faild \n", pin, gpio_pull_buf);
		close(gpio_pull_fd);
		return false;
	}

	close(gpio_pull_fd);
	return true;
}




/*
*** 设置IO口电平 
*** 在设置IO电平之前,需要调用 gpio_direction_set 
*/
bool gpio_level_set(const int pin, GPIO_LEVEL level)
{
	char gpio_buf[64] =
	{
		0
	};
	sprintf(gpio_buf, "/sys/class/gpio/gpio%d/value", pin);
	int gpio_fd = open(gpio_buf, O_WRONLY);

	if (gpio_fd < 0)
	{
		printf("gpio%d set value open failed \n", pin);
		return false;
	}

	if (write(gpio_fd, (level == GPIO_LEVEL_LOW) ? "0": "1", 1) < 0)
	{
		printf("gpio%d write %d failed \n", pin,level == GPIO_LEVEL_LOW?0:1);
		close(gpio_fd);
		return false;
	}

	close(gpio_fd);
	return true;
}


/*
*** 读取IO电平
*** 在读取IO电平之前,需要调用 gpio_direction_set 
*/
bool gpio_level_read(const int pin, GPIO_LEVEL * level)
{
	char gpio_buf[64] =
	{
		0
	};
	sprintf(gpio_buf, "/sys/class/gpio/gpio%d/value", pin);
	int gpio_fd = open(gpio_buf, O_RDONLY);

	if (gpio_fd < 0)
	{
		printf("gpio%d set value open failed \n", pin);
		return false;
	}

	memset(gpio_buf,0,sizeof(gpio_buf));
	if (read(gpio_fd, gpio_buf,1) < 0)
	{
		printf("gpio%d read failed \n", pin);
		close(gpio_fd);
		return false;
	}

	close(gpio_fd);


	*level = (gpio_buf[0] =='0')?GPIO_LEVEL_LOW:GPIO_LEVEL_HIGH;
	return true;
}


对外提供接口,头文件如下:



#ifndef _GPIO_BASE_H_
#define _GPIO_BASE_H_
#include 


typedef enum 
{
GPIO_DIR_IN = 0, 
GPIO_DIR_OUT = 1
} GPIO_DIR;


typedef enum 
{
GPIO_LEVEL_LOW = 0x01, 
GPIO_LEVEL_HIGH = 0x02
} GPIO_LEVEL;


/*
*** 设置GPIO输入/输出
*/
bool gpio_direction_set(const int pin, GPIO_DIR dir);




/*
*** 设置IO口电平 
*** 在设置IO电平之前,需要调用 gpio_direction_set 
*/
bool gpio_level_set(const int pin, GPIO_LEVEL level);



/*
*** 读取IO电平
*** 在读取IO电平之前,需要调用 gpio_direction_set 
*/
bool gpio_level_read(const int pin, GPIO_LEVEL * level);




/*
*** 设置gpio 内置上拉使能
*/
bool gpio_pull_enable(const int pin, bool enable);



#endif


你可能感兴趣的:(嵌入式硬件,arm开发,linux)