取值 | 说明 |
---|---|
“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;
}