应用层通过/sys/class/gpio文件操作gpio口
不需要写驱动 不需要改设备树 不需要了解寄存器
本来想做一个LED 翻转效果的,就是在读取灯亮的时候灭灯,灭灯的时候亮灯的
结果发现在设置IO为in的时候,GPIO给拉低了造成读一直是0,实现不了想要的效果了
但是我在终端敲命令 echo in > /sys/class/gpio/gpio137/direction 设置为输入模式就不会拉低
不知道为啥
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#define SYSFS_GPIO_DIR "/sys/class/gpio"
#define MAX_BUF 64
//#define BOARD_SSD201
//uart device name
#ifdef BOARD_SSD201
#define LED_GPIO 85 //PAD_GPIO85 =》 SSD201
#else
#define LED_GPIO 137 //#define LED0 GPIO_PORT_E,GPIO_PIN_9 (A0 B1 C2 D3 E4 F5)=> PE9 = 32*4+9=137 F1C100S
#endif
/**
* function: gpio export
*/
int ss_gpio_export(unsigned int gpio){
int fd, len;
char buf[MAX_BUF];
fd = open(SYSFS_GPIO_DIR "/export", O_WRONLY);
if (fd < 0) {
perror("gpio/export");
return fd;
}
len = snprintf(buf, sizeof(buf), "%d", gpio);
write(fd, buf, len);
close(fd);
return 0;
}
/**
* function: gpio unexport
*/
int ss_gpio_unexport(unsigned int gpio){
int fd, len;
char buf[MAX_BUF];
fd = open(SYSFS_GPIO_DIR "/unexport", O_WRONLY);
if (fd < 0) {
perror("gpio/export");
return fd;
}
len = snprintf(buf, sizeof(buf), "%d", gpio);
write(fd, buf, len);
close(fd);
return 0;
}
/**
* function: gpio set direction
* parameter: out_flag = 1 -- out
* out_flag = 0 -- in
*/
int ss_gpio_set_dir(unsigned int gpio, unsigned int out_flag){
int fd;
char buf[MAX_BUF];
snprintf(buf, sizeof(buf), SYSFS_GPIO_DIR "/gpio%d/direction", gpio);
fd = open(buf, O_WRONLY);
if (fd < 0) {
perror("gpio/direction");
return fd;
}
if (out_flag)
write(fd, "out", 4);
else
write(fd, "in", 3);
close(fd);
return 0;
}
/**
* function: gpio set value
* parameter: value = 1 -- high
* value = 0 -- low
*/
int ss_gpio_set_value(unsigned int gpio, unsigned int value){
int fd;
char buf[MAX_BUF];
snprintf(buf, sizeof(buf), SYSFS_GPIO_DIR "/gpio%d/value", gpio);
fd = open(buf, O_WRONLY);
if (fd < 0) {
perror("gpio/set-value");
return fd;
}
if (value)
write(fd, "1", 2);
else
write(fd, "0", 2);
close(fd);
return 0;
}
/**
* function: gpio get value
*/
int ss_gpio_get_value(unsigned int gpio, unsigned int *value){
int fd;
char buf[MAX_BUF];
char ch;
snprintf(buf, sizeof(buf), SYSFS_GPIO_DIR "/gpio%d/value", gpio);
fd = open(buf, O_RDONLY);
if (fd < 0) {
perror("gpio/get-value");
return fd;
}
read(fd, &ch, 1);
if (ch != '0') {
*value = 1;
} else {
*value = 0;
}
close(fd);
return 0;
}
/**
* function: gpio_set edge
* parameter: edge = "none", "rising", "falling", "both"
*/
int ss_gpio_set_edge(unsigned int gpio, char *edge){
int fd;
char buf[MAX_BUF];
snprintf(buf, sizeof(buf), SYSFS_GPIO_DIR "/gpio%d/edge", gpio);
fd = open(buf, O_WRONLY);
if (fd < 0) {
perror("gpio/set-edge");
return fd;
}
write(fd, edge, strlen(edge) + 1);
close(fd);
return 0;
}
/**
* function: gpio open fd
*/
int ss_gpio_open(unsigned int gpio){
int fd;
char buf[MAX_BUF];
snprintf(buf, sizeof(buf), SYSFS_GPIO_DIR "/gpio%d/value", gpio);
fd = open(buf, O_RDONLY | O_NONBLOCK);
if (fd < 0) {
perror("gpio/fd_open");
}
return fd;
}
/**
* function: gpio close fd
*/
int ss_gpio_close(int fd){
return close(fd);
}
void led_switch(){
int value = 0;
ss_gpio_export(LED_GPIO); //
ss_gpio_set_dir(LED_GPIO, 0);// 不能通过读取IO值,因为设置读会拉低IO
ss_gpio_get_value(LED_GPIO, &value);
printf("gpio[%d] value = %d\n", LED_GPIO, value);
ss_gpio_set_dir(LED_GPIO, 1);// set LEDIO putput
if(value == 0){
ss_gpio_set_value(LED_GPIO, 1);
}else{
ss_gpio_set_value(LED_GPIO, 0);
}
ss_gpio_unexport(LED_GPIO);
}
#if 1
int main(int argc, char *argv[]){
int fd = -1, value = 0;
if (argc < 2){
printf("eg:./gpio_main input\n");
printf("eg:./gpio_main output 1\n");
return -1;
}
ss_gpio_export(LED_GPIO);
if (!strcmp(argv[1], "input")){
ss_gpio_set_dir(LED_GPIO, 0);// set input then pin low ??
ss_gpio_get_value(LED_GPIO, &value);
printf("gpio[%d] value = %d\n", LED_GPIO, value);
}else if (!strcmp(argv[1], "output")){
if (argc < 3){
ss_gpio_unexport(LED_GPIO);
return -1;
}
value = atoi(argv[2]);
ss_gpio_set_dir(LED_GPIO, 1);
ss_gpio_set_value(LED_GPIO, value);
}else{
printf("unknown commamd\n");
}
ss_gpio_unexport(LED_GPIO);
// led_switch();
return 0;
}
#endif
离线