linux应用开发 —— GPIO控制_linux 应用控制gpio

取值说明
“0”输出高电平即为高电平,输出低电平即为低电平
“1”输出高电平实际输出低电平,输出低电平实际为高电平

active_low对于输入模式同样使用。

value取值:

取值说明
“0”输出,表示设置GPIO低电平;输入,表示读取到低电平
“1”输出,表示设置GPIO高电平;输入,表示读取到高电平

GPIO操作

gpio.h:

/\*
 \* @brief : 
 \* @date : 2021-11-xx
 \* @version : v1.0.0
 \* @copyright(c) 2020 : OptoMedic company Co.,Ltd. All rights reserved
 \* @Change Logs: 
 \* @date author notes: 
 \*/
#ifndef \_\_GPIO\_H\_\_
#define \_\_GPIO\_H\_\_

#include "stdint.h"

enum {
    GPIO_DIR_OUTPUT = 0, 
    GPIO_DIR_INPUT,
};
typedef uint8\_t gpio\_dir\_t;

enum {
    ACTIVE_LOW = 0,
    ACTIVE_HIGH = 1,
};
typedef uint8\_t active\_level\_t;

/\* irq \*/
enum {
    EDGE_NONE = 0,
    EDGE_RISING,
    EDGE_FALLING,
    EDGE_BOTH,
};
typedef uint8\_t edge\_t;  

int gpio\_export(int gpio);
int gpio\_unexport(int gpio);

int gpio\_set\_active(int gpio, active\_level\_t active);
int gpio\_active\_low(int gpio);
int gpio\_active\_high(int gpio);

int gpio\_set\_edge(int gpio, edge\_t edge);
int gpio\_edge\_none(int gpio);
int gpio\_edge\_rising(int gpio);
int gpio\_edge\_falling(int gpio);
int gpio\_edge\_both(int gpio);

int gpio\_set\_direction(int gpio, gpio\_dir\_t dir);
int gpio\_direction\_input(int gpio);
int gpio\_direction\_output(int gpio);

void gpio\_set\_value(int gpio, int value);
int gpio\_get\_value(int gpio);

#endif /\* \_\_GPIO\_H\_\_ \*/

gpio.c:

#include "gpio.h"
#include <stdio.h> 
#include <stdlib.h> 
#include <sys/types.h> 
#include <sys/stat.h> 
#include <fcntl.h> 
#include <unistd.h> 
#include <string.h> 

/\* 
gpio 编号计算
 index = GPIOn\_IOx = (n-1)\*32 + x
 例如蜂鸣器使用的引脚编号为:index = GPIO1\_19 = (1-1)\*32 +19 = 19。
 又例如GPIO4\_IO20的编号为:index = GPIO4\_IO20 = (4-1)\*32+20=116。
\*/
int gpio\_export(int gpio)
{
    int fd;
    char gpio_path[100] = {0};

   /\* GPIO目录路径 \*/
    sprintf(gpio_path, "/sys/class/gpio/gpio%d", gpio); 
    /\* 判断GPIO目录是否存在 \*/
    if (access(gpio_path, F_OK) == 0) return 0; 

    if (0 > (fd = open("/sys/class/gpio/export", O_WRONLY))) 
    { 
        perror("open error"); 
        return -1;
    } 

    /\* 导出 gpio \*/
    char gpio_str[10] = {0};
    sprintf(gpio_str, "%d", gpio);
    int len = strlen(gpio_str);
    if (len != write(fd, gpio_str, len))  
    {
        perror("write error"); 
        return -2;
    } 

    return 0;
}

int gpio\_unexport(int gpio)
{
    int fd;
	fd = open("/sys/class/gpio/unexport", O_WRONLY);
	if(fd < 0)
		return -1;

    char gpio_str[10] = {0};
    sprintf(gpio_str, "%d", gpio);
	write(fd, gpio_str, strlen(gpio_str));
	close(fd);
    return 0;
}

static int gpio\_cfg\_attr(int gpio, char \*attr,  char \*val)
{
    int fd;
    char path[100] = {0};
    sprintf(path, "/sys/class/gpio/gpio%d/%s", gpio, attr);
    if (0 > (fd = open(path, O_WRONLY))) 
    { 
        perror("open error"); 
        return -1;
    } 
 
    int len = strlen(val); 
    if (len != write(fd, val, len)) 
    { 
        perror("write error"); 
        close(fd); 
        return -2; 
    } 

    close(fd);  
    return 0; 
}

int gpio\_set\_direction(int gpio, gpio\_dir\_t dir)
{
    char dirs[10] = {0};
    if (dir == GPIO_DIR_OUTPUT)
    {
        sprintf(dirs, "%s", "out");
    }
    else
    {
        sprintf(dirs, "%s", "in");
    }
    return gpio\_cfg\_attr(gpio, "direction", dirs);
}

int gpio\_direction\_output(int gpio)
{
    return gpio\_set\_direction(gpio, GPIO_DIR_OUTPUT);
}

int gpio\_direction\_input(int gpio)
{
    return gpio\_set\_direction(gpio, GPIO_DIR_INPUT); 
}

int gpio\_set\_active(int gpio, active\_level\_t active)
{
    char active_str[10] = {0};
    
    if (active == ACTIVE_LOW)
    {
        gpio\_cfg\_attr(gpio, "active\_low", "0");
    }
    else
    {
        gpio\_cfg\_attr(gpio, "active\_low", "1");
    }
}

int gpio\_active\_low(int gpio)
{
    return gpio\_cfg\_attr(gpio, "active\_low", "0");
}

int gpio\_active\_high(int gpio)
{
    return gpio\_cfg\_attr(gpio, "active\_low", "1");
}

int gpio\_set\_edge(int gpio, edge\_t edge)
{
    int ret;
    edge\_t edge_index[4] = {EDGE_NONE, EDGE_RISING, EDGE_FALLING, EDGE_BOTH};
    char str_edge_index[4][10] = {{"none"}, {"rising"}, {"falling"}, {"both"}};
    for (int i = 0; i < 4; i++)
    {
        if (edge == edge_index[i])
        {
            ret = gpio\_cfg\_attr(gpio, "edge", str_edge_index[i]);
            break;
        }
    }
    return ret;
}

int gpio\_edge\_none(int gpio)
{
    return gpio\_set\_edge(gpio, EDGE_NONE);
}

int gpio\_edge\_rising(int gpio)
{
    return gpio\_set\_edge(gpio, EDGE_RISING);
}

int gpio\_edge\_falling(int gpio)
{
    return gpio\_set\_edge(gpio, EDGE_FALLING);
}

int gpio\_edge\_both(int gpio)
{
    return gpio\_set\_edge(gpio, EDGE_BOTH);
}


void gpio\_set\_value(int gpio, int value)
{
    char val[10] = {0};
    if (value == 0)
    {
        sprintf(val, "%d", 0);
    }
    else
    {
        sprintf(val, "%d", 1);
    }

    gpio\_cfg\_attr(gpio, "value", val);
}

int gpio\_get\_value(int gpio)
{
    char gpio_path[100] = {0};
    char vals[5] = {0};
    int fd;

    sprintf(gpio_path, "/sys/class/gpio/gpio%d/value", gpio);
    if (0 > (fd = open(gpio_path, O_WRONLY))) 
    { 
        perror("open error"); 
        return -1;
    } 

    if (0 > read(fd, vals, sizeof(vals))) 
    { 
        perror("read error"); 
        close(fd); 
        return -1;
    } 

    int value = atoi(vals);
    
    return value;
}

使用控制GPIO蜂鸣器

GPIO编号的计算:

index = GPIOn_IOx = (n-1)\*32 + x

例如蜂鸣器使用的引脚编号为:index = GPIO1_19 = (1-1)\*32 +19 = 19。

又例如GPIO4_IO20的编号为:index = GPIO4_IO20 = (4-1)\*32+20=116。

beep.h:

#ifndef \_\_BEEP\_H\_\_
#define \_\_BEEP\_H\_\_

int beep\_init(void);
int beep\_on(void);
int beep\_off(void);
int beep\_deinit(void);

#endif /\* \_\_BEEP\_H\_\_ \*/

beep.c:

#include "gpio.h"
#include "beep.h"


#define BEEP\_GPIO\_INDEX 19


int beep\_init(void)
{
    int ret;
    ret = gpio\_export(BEEP_GPIO_INDEX);
    ret = gpio\_direction\_output(BEEP_GPIO_INDEX);
    return ret;
}

int beep\_on(void)
{
    gpio\_set\_value(BEEP_GPIO_INDEX, 1);
    return 0;
}

int beep\_off(void)
{
    gpio\_set\_value(BEEP_GPIO_INDEX, 0);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值