(2)ARM40-A5板应用程序——GPIO输出高低电平

时间:2021-08-21 17:54:43

(2)ARM40-A5板应用程序——GPIO输出高低电平

2017.03.19


一、在 shell 中控制一个IO的高低电平

        (1) echo 138 > /sys/class/gpio/export                      // 138对应的是pioE10,输入这个命令后,即出现/sys/class/gpio/pioE10

        (2) echo out  > /sys/class/gpio/pioE10/direction      // 设置pioE10为 out 

        (3) echo 1     > /sys/class/gpio/pioE10/value           // 设置pioE10为高电平,此时万用表可测得pioE10的确为高电平 

        (4) echo 0     > /sys/class/gpio/pioE10/value           // 设置pioE10为低电平,此时万用表可测得pioE10的确为低电平 

        (5) echo 138 > /sys/class/gpio/unexport                 // 不再使用时,需要unexport


二、GPIO输出高低电平的C语言源码

        文件名为 test_gpio.c,代码见本文的最后。该代码的核心就是第一节中的5句命令。



三、交叉编译

         arm-none-linux-gnueabi-gcc -o test_gpio test_gpio.c -static


四、执行程序

        将交叉编译得到的 test_gpio 文件拷贝到ARM40-A5板中,执行程序:

                ./test_gpio  pioE10

        用示波器即可观察到pioE10这个IO上出现高低电平的变化。



参考文章:

http://blog.csdn.net/luyejie8888/article/details/38172705

BeagleBone Black板第四课:简单LED控制实验

http://blog.csdn.net/luyejie8888/article/details/38361525

BeagleBone Black板第五课:Shell脚本编程实验

https://developer.ridgerun.com/wiki/index.php/How_to_use_GPIO_signals

How_to_use_GPIO_signals
http://blog.csdn.net/drivermonkey/article/details/20132241?utm_source=tuicool
LinuxGPIO驱动使用其实很简单

附:

(1)test_gpio.c 的代码

/* 
 * 注: 
 * 随意指定io可能会报错,例如: 
 * PC31已为蜂鸣器BUZZ,如果在本程序中也包含进来,运行程序的时候会报: 
 *  sh: write error: Device or resource busy   
 */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <termios.h>
#define MAX_BUF 36
#define STR_GPIO struct {       \
        char* gpio;     \
        char* num;      \


/**
 * STR_GPIO 结构体把类似pioE10与138这样的对应关系罗列出来
 * 只有出现在这个结构体中的io,才能被该程序执行到,没有出现的,如果命令行输入了,会报错
 * 请谨慎使用这里的io
 */
STR_GPIO str_io[] = {
        {"pioE31","159"},
        {"pioE5","133"},
        {"pioE3","131"},
        {"pioE10","138"},
        {"pioD28","124"},
        {"pioD30","126"},
        {"pioD23","119"},
        {"pioD22","118"}, 
        {"pioD21","117"},
        {"pioD20","116"},
        {"pioD19","115"}, 
        {"pioD18","114"},
        {"pioD17","113"},
        {"pioD16","112"},
        {"pioE20","148"},
        {"pioE23","151"},
        {"pioE24","152"},
        {"pioE25","153"}, 
        {"pioE26","154"},
        {"pioE19","147"},
        {"pioE18","146"},
        {"pioE17","145"},
        {"pioE16","144"},
        {"pioE15","143"},
        {"pioB25","57"},
        {"pioB26","58"},
        {"pioB27","59"},
        {"pioB28","60"},
        {"pioB29","61"},
        {"pioC22","86"},
        {"pioC23","87"},
        {"pioC24","88"},
        {"pioC25","89"},
        {"pioC26","90"},
        {"pioC27","91"},
        {"pioC28","92"},
        {"pioB24","56"},
        {"pioB23","55"},
        {"pioB22","54"},
        {"pioB21","53"},
        {"pioB20","52"},
        {"pioB19","51"},
//        {"pioD0","96"},
//        {"pioD1","97"},
//        {"pioD2","98"},
//        {"pioD3","99"},
//        {"pioD4","100"},
        {"pioD5","101"},
        {"pioD6","102"},
        {"pioD7","103"},
        {"pioD8","104"},
//        {"pioD9","105"},
        {}
};

int gpio_export(char* ver);
int gpio_unexport(char* ver);
int gpio_set_dir(char* str);
int gpio_set_value(char *str, unsigned int value);
int match_ver(char* str, char *ver);
int gpio_flash(char* str);

/*
 * 执行程序 ./test_gpio pioE10
 */
int main(int argc, char** argv)
{
        char ver[3];
        if(2 != argc) {               // 命令为 ./test_gpio pioE10, 如果不是两个参数,则报错  
                printf("ERR: need 1 arg.\n ");
                return -1;
        }
        printf("eg:pioE10, argv[1]=%s\n", argv[1]);

        if(match_ver(argv[1], ver)) {
                printf("err: argv[1]=%s isn't enabled\n",argv[1]);
                return -1;
        }

        gpio_export(ver);       // echo 138 > /sys/class/gpio/export
        gpio_flash(argv[1]);    // eg: argv[1]=pioE10       
        gpio_unexport(ver);     // echo 138 > /sys/class/gpio/unexport
        printf("finish!\n");
        return 0;
}

// eg: str=pioE10, ver=138, return 0;
// eg: str=pioE111, return 1;
int match_ver(char* str, char *ver)
{
        int i;

        for(i=0; str_io[i].gpio!=NULL; i++) {
                if(0 == strcmp(str_io[i].gpio, str)) {
                        strcpy(ver, str_io[i].num);
                        return 0;
                }
        }

        return 1;       // 如果在结构体列表中没有找到,则返回1
}

// eg: ver=138
// echo 138 > /sys/class/gpio/export
int gpio_export(char * ver)
{
        int fd;
        fd = open("/sys/class/gpio/export", O_WRONLY);  // write only
        if (fd < 0) {
                perror("gpio/export");
                return fd;
        }
        write(fd, ver ,sizeof(ver));
        close(fd);

        return 0;
}

// eg: ver=138
// echo 138 > /sys/class/gpio/unexport
int gpio_unexport(char * ver)
{
        int fd;
        fd = open("/sys/class/gpio/unexport", O_WRONLY);        // write only
        if (fd < 0) {
                perror("gpio/uexport");
                return fd;
        }
        write(fd, ver ,sizeof(ver));
        close(fd);

        return 0;
}

/**
 * echo out > /sys/class/gpio/pioE10/direction 
 * str  : pioE10,...
 * 0    : sucess
 * other: err
 */
int gpio_set_dir(char* str)
{
        int fd;
        int len;
        char buf[MAX_BUF];
        len = snprintf(buf,sizeof buf,"/sys/class/gpio/%s/direction", str);
        printf("str=%s,buf=%s\n",str,buf);
        fd = open(buf, O_WRONLY);       // write only
        if (fd < 0) {
                perror("gpio/direction");
                return fd;
        }
        write(fd, "out", sizeof("out"));
        close(fd);

        return 0;
}

/**
 * echo 1 > /sys/class/gpio/pioE10/value
 * str   :  "pioE10", ...
 * value :  "1","0"
 */
int gpio_set_value(char *str, unsigned int value)
{
        int fd;
        int len;
        char buf[MAX_BUF];
        len = snprintf(buf,sizeof buf,"/sys/class/gpio/%s/value", str);
//      printf("buf=%s\n",buf);
        fd = open(buf, O_RDWR);
        if (fd < 0) {
                perror("gpio/set_value");
                return fd;
        }
        if(value)
                write(fd, "1", sizeof("1"));
        else
                write(fd, "0", sizeof("0"));

        close(fd);
        return 0;
}
/**
 * str :  pioE10...
 * bool :  1,0
 * gpio_flash("pioE10");
 */
int gpio_flash(char* str)
{
        int count = 10;
        gpio_set_dir(str);                      // echo out > /sys/class/gpio/pioE10/direction 
        while(count--) {
                gpio_set_value(str, 1);         // echo 1 > /sys/class/gpio/pioE10/value
                usleep(1000000);
                gpio_set_value(str, 0);         // echo 0 > /sys/class/gpio/pioE10/value
                usleep(1000000);
        }
        return 0;
}