王彦为

聚沙成塔
  1. 首页
  2. 嵌入式
  3. 正文

玩转DragronBoard 410c系列之六:Linux系统使用C语言控制GPIO

2020-09-29 6813点热度 1人点赞 1条评论

在《玩转DragronBoard 410c系列之三:使用Shell控制GPIO》这篇文章中,我们介绍了如何使用Shell指令去控制GPIO,这一篇我们讲讲用代码控制GPIO,这里以C语言举例说明。

点亮LED

依旧是先易后难的原则,在Linux系统创建一个文件,命名为blink.c,然后打开该文件,输入如下代码。这段代码的含义是对LED4进行点亮、熄灭操作,间隔1s,总计10个循环。

#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>

//defining the path to the file in the filesystem that controls the LED
#define LED4 "/sys/class/leds/apq8016-sbc:green:user4/brightness"

int main(void)
{
    //opening the brightness-file
    int led4_fd = open(LED4, O_WRONLY);
    if(led4_fd < 0)
    {
        printf("Could not open File: %s", LED4);
        return 0;
    }
    int i;
    for( i=0; i<10;i++)
    {
        write(led4_fd, "1", 2 ); //Turning the LED ON by writing 1 into the brightness file
        sleep(1); // sleep 1 second in linux
        write(led4_fd, "0", 2 ); //Turning the LED OFF by writing 0 into the brightness file
        sleep(1); 
    }
    close(led4_fd);
    printf("OK");
}

然后使用交叉编译器编译这个文件,命令为“aarch64-none-linux-gnu-g++ blink.c -o blink.arm”,接着我们将“blink.arm”通过FTP上传到嵌入式板卡中,使用root权限运行。最后我们就能看到LED4在交替闪烁了。

控制GPIO

下面的代码描述了,读取GPIO-A的状态以及设置GPIO-B的值为1,编译方法同上。

#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>

void initGpio(int pin)
{
    FILE * fp =fopen("/sys/class/gpio/export","w");
    if (fp == NULL)
    {

        perror("export open filed");
    }
    else
    {
        fprintf(fp,"%d",pin);
    }
    fclose(fp);
}

// direction="in" or "out"
void setGpioDirection(int pin,char *direction)
{
    char path[100] = {0};
    sprintf(path,"/sys/class/gpio/gpio%d/direction",pin);
    FILE * fp =fopen(path,"w");
    if (fp == NULL)
    {

        perror("direction open filed");
    }
    else
    {
        fprintf(fp,"%s",direction);
    }
    fclose(fp);
}

int getGpioValue(int pin)
{
    char path[128];
    char value_str[3];
    int fd;

    snprintf(path, sizeof(path), "/sys/class/gpio/gpio%d/value", pin);
    fd = open(path, O_RDONLY);
    if (fd < 0)
    {
        perror("Failed to open gpio value!");
        return -1;
    }

    if (read(fd, value_str, 3) < 0)
    {
        perror("Failed to read value!");
        return -1;
    }
    close(fd);
    return (atoi(value_str));
}
void setGpioValue(int pin,int value)
{
    char path[128];
    snprintf(path, sizeof(path), "/sys/class/gpio/gpio%d/value", pin);
    FILE * fp =fopen(path,"w");
    if (fp != NULL)
    {
        fprintf(fp,"%d",value);
    }
    else
    {
        perror("Failed to open gpio value!");
    }
    fclose(fp);
}

int main()
{

    int gpio_a=36+390;
    int gpio_b=12+390;

    // read GPIO_A vale
    initGpio(gpio_a);
    setGpioDirection(gpio_a,"in");
    printf("%d\n",getGpioValue(gpio_a));

    // set GPIO_B vale=1
    initGpio(gpio_b);
    setGpioDirection(gpio_b,"out");
    setGpioValue(gpio_b,1);
    return 0;
}

总结

通过这篇文章,我们可以通过代码的方式控制GPIO,但是我们也发现两个问题。第一,我们习惯使用编译器开发程序,而该文章使用命令行方式编译,不方便,那么有没有合适的编译器呢。我这里推荐两款编译器,一款是Eclipse,另一款是QT Creator。无论哪种编译器,都需要使用交叉编译工具链,下个章节我们介绍下如何交叉编译QT Creator。第二个问题是,控制GPIO需要GPIO的导出号,有没有一个通用库帮我们实现物理引脚与导出号的映射,官方推荐的是MRAA。我也会在以后的博客中介绍。

标签: 暂无
最后更新:2022-03-31

王彦为

新生代农民工,十年医疗器械行业从业经验,现居苏州。爱生活,爱做梦。

打赏 点赞
< 上一篇
下一篇 >

文章评论

  • Ana195

    Good <a href="https://shorturl.fm/j3kEj">https://shorturl.fm/j3kEj</a&gt;

    2025-05-24
    回复
  • 取消回复

    COPYRIGHT © 2022 王彦为. ALL RIGHTS RESERVED.

    苏ICP备16063331号-1

    苏公网安备32050702011313号