linux 应用层gpio中断_linux 应用层使用gpio

本文提供了一个通过C语言实现的GPIO控制示例程序,包括GPIO的导出、设置方向、读写操作及中断配置等功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/**

* @author emlsyx

* @email yangx_1118@163.com

* @create date 2020-02-19 19:11:53

* @modify date 2020-02-19 19:11:53

* @desc [description]*/#include#include#include#include#include#include

#define err_out(fmt, ...) \

do\

{ \

printf(fmt, ##__VA_ARGS__); \

printf(" \"%s()\" %d error\n", __FILE__, __FUNCTION__, __LINE__); \

}while (0)#define open_gpio_file(path, flag, fd) \

do\

{ \

fd=open(path, flag); \if (fd < 0) \

{ \

err_out("\"%s\" open failed \n", path); \return (-1); \

} \

}while (0);/**

* @brief : gpio 导出

* @param : pin

* @retval: 0 成功; -1失败*/

static int gpio_export(const intpin)

{intfd, len;char buffer[64];char path[64];

sprintf(&path[0], "/sys/class/gpio/gpio%d", pin);/*文件不存在时,导出gpio*/

if (access(path, F_OK) != 0)

{

memset(path,0, 64);

sprintf(&path[0], "/sys/class/gpio/export");

open_gpio_file(path, O_WRONLY, fd);

len= snprintf(buffer, sizeof(buffer), "%d", pin);if (write(fd, buffer, len) < 0)

{

err_out("write failed to export gpio!\n");return -1;

}

close(fd);

}return 0;

}/**

* @brief : gpio 卸载

* @param : pin

* @retval: 0 成功; -1失败*/

static int gpio_unexport(const intpin)

{intfd, len;char buffer[64];char path[64];

sprintf(&path[0], "/sys/class/gpio/gpio%d", pin);/*文件存在时,卸载gpio*/

if (access(path, F_OK) == 0)

{

memset(path,0, 64);

sprintf(&path[0], "/sys/class/gpio/unexport");

open_gpio_file(path, O_WRONLY, fd);

len= snprintf(buffer, sizeof(buffer), "%d", pin);if (write(fd, buffer, len) < 0)

{

err_out("write failed to unexport gpio!\n");return -1;

}

close(fd);

}return 0;

}/**

* @brief : gpio 方向控制

* @param : dir 方向(in/out)

* @retval: 0 成功; -1失败*/

static int gpio_direction(const int pin, const char *dir)

{intfd;char path[64];int w_len = ((dir[0] == 'i') && (dir[1] == 'n')) ? 2 : 3;

snprintf(path,sizeof(path), "/sys/class/gpio/gpio%d/direction", pin);

open_gpio_file(path, O_WRONLY, fd);if (write(fd, dir, w_len) < 0)

{

err_out("Failed to set direction!\n");return -1;

}

close(fd);return 0;

}/**

* @brief : gpio 写

* @param : 0 / 1

* @retval: 0 成功; -1失败*/

static int gpio_write(const int pin, const intvalue)

{intfd;char path[64];const char *val[] = {"0", "1"};

snprintf(path,sizeof(path), "/sys/class/gpio/gpio%d/value", pin);

open_gpio_file(path, O_WRONLY, fd);if (write(fd, val[value], 1) < 0)

{

err_out("Failed to write value!\n");return -1;

}

close(fd);return 0;

}/**

* @brief : gpio 读

* @param : 读取的引脚值

* @retval: 返回引脚的值 0 / 1*/

static int gpio_read(const intpin)

{intfd;char path[64];char value_str[3];

snprintf(path,sizeof(path), "/sys/class/gpio/gpio%d/value", pin);

open_gpio_file(path, O_RDONLY, fd);if (read(fd, value_str, 3) < 0)

{

err_out("Failed to read value!\n");return -1;

}

close(fd);return(atoi(value_str));

}/**

* @brief : gpio 中断控制

* @param : 0 none 表示引脚为输入,不是中断引脚

* @arg : 1 rising 表示引脚为中断输入,上升沿触发

* @arg : 2 falling 表示引脚为中断输入,下降沿触发

* @arg : 3 both 表示引脚为中断输入,边沿触发

* @retval:*/

static int gpio_edge(const int pin, intedge)

{intfd;char path[64];const char *dir_str[] = {"none", "rising", "falling", "both"};if (edge > 3)

{

err_out("Failed edge parameter error\n");return -1;

}

snprintf(path,sizeof(path), "/sys/class/gpio/gpio%d/edge", pin);

open_gpio_file(path, O_WRONLY, fd);if (write(fd, dir_str[edge], strlen(dir_str[edge])) < 0)

{

err_out("Failed to set edge!\n");return -1;

}

close(fd);return 0;

}intmain()

{char buff[10], res;intled_fd, key_fd;structpollfd fds;/*按键led指示灯*/gpio_export(55);

gpio_direction(55, "out");

gpio_write(55, 0);/*按键引脚初始化*/gpio_export(70);

gpio_direction(70, "in");

gpio_edge(70, 2);

open_gpio_file("/sys/class/gpio/gpio70/value", O_RDONLY, key_fd);/*poll 操作的文件符号*/fds.fd=key_fd;/*经测试io中断产生后,正常会发送POLLPRI 这个中断,循环中必须等待这个事件*/fds.events= POLLPRI |POLLERR;/*真实发生的事件*/fds.revents= 0;while (1)

{int ret = poll(&fds, 1, -1);if (!ret)

{

err_out("poll time out\n");

}else{if (fds.revents &POLLPRI)

{

gpio_write(55, gpio_read(55) ? 0 : 1);

res= lseek(fds.fd, 0, SEEK_SET); /*读取按键值*/

if (res == -1)

{

printf("lseek failed!\n");return -1;

}

res= read(fds.fd, buff, sizeof(buff));if (res == -1)

{

perror("read failed!\n");return -1;

}

printf("fds.revents %d key value %s \n", fds.revents, buff);

}

}

}return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值