您尚未登录。

楼主 # 2023-06-16 15:39:47

tangloong
会员
注册时间: 2023-04-11
已发帖子: 212
积分: 191

F1C100S在linux下通过 sysfs 方式控制操作IO 点灯 不需要了解寄存器

应用层通过/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

离线

页脚

工信部备案:粤ICP备20025096号 Powered by FluxBB

感谢为中文互联网持续输出优质内容的各位老铁们。 QQ: 516333132, 微信(wechat): whycan_cn (哇酷网/挖坑网/填坑网) service@whycan.cn