在《玩转DragronBoard 410c系列之三:使用Shell控制GPIO》这篇文章中,我们介绍了如何使用Shell指令去控制GPIO,这一篇我们讲讲用代码控制GPIO,这里以C语言举例说明。
点亮LED
依旧是先易后难的原则,在Linux系统创建一个文件,命名为blink.c,然后打开该文件,输入如下代码。这段代码的含义是对LED4进行点亮、熄灭操作,间隔1s,总计10个循环。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | #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,编译方法同上。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 | #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。我也会在以后的博客中介绍。
文章评论