在《玩转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。我也会在以后的博客中介绍。
文章评论