4位,8段,数码管的引脚如下:
型号可能不对,但是引脚是对的。测试发现是共阴极数码管。
1-4是分别控制4个数码管,输出高电平,则数码管使能。
abcdefg,控制数字中的7个LED灯。. 控制小数点。输入低电平,则LED亮。
注意4个数码管共用8个引脚。所以4个数码管的输出结果是一样的。要想达到不同输出的效果。则在非常短的时间内(1ms级)循环输出4个数码管。肉眼看起来是4个同时亮的效果。
代码如下:
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 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 | #include <stdio.h> #include <errno.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <string.h> #define GPIO_DIR_OUT 0 #define GPIO_DIR_IN 1 int export_gpio( int gpio) { char buf[12]; int fd = open( "/sys/class/gpio/export" , O_WRONLY); if (fd < 0) { fprintf (stderr, "open gpio export failed: %s\n" , strerror ( errno )); return -1; } sprintf (buf, "%d" , gpio); if (write(fd, buf, strlen (buf)) != strlen (buf)) { fprintf (stderr, "write gpio export failed: %s\n" , strerror ( errno )); close(fd); return -1; } close(fd); return 0; } int set_gpio_dir( int gpio, int dir) { char path[64]; int fd; char *dir_name; snprintf(path, sizeof (path), "/sys/class/gpio/gpio%d/direction" , gpio); fd = open(path, O_WRONLY); if (fd < 0) { fprintf (stderr, "open gpio %s failed: %s\n" , path, strerror ( errno )); return -1; } if (dir == GPIO_DIR_OUT) dir_name = "out" ; else dir_name = "in" ; if (write(fd, dir_name, strlen (dir_name)) != strlen (dir_name)) { fprintf (stderr, "write gpio %d direction failed: %s\n" , gpio, strerror ( errno )); close(fd); return -1; } close(fd); return 0; } int set_gpio_value( int gpio, int val) { char path[32]; int fd; char *value_name; snprintf(path, sizeof (path), "/sys/class/gpio/gpio%d/value" , gpio); fd = open(path, O_WRONLY); if (fd < 0) { fprintf (stderr, "open gpio export failed: %s\n" , strerror ( errno )); return -1; } if (val) value_name = "1" ; /* Active High */ else value_name = "0" ; if (write(fd, value_name, strlen (value_name)) != strlen (value_name)) { fprintf (stderr, "write gpio %d value failed: %s\n" , gpio, strerror ( errno )); close(fd); return -1; } close(fd); return 0; } int main( int argc, char **argv) { int i, j; int v[4] = { 8,9,7,4}; /* * 21 20 16 12 1 7 * 1 a f 2 3 b * e d . c g 4 * 26 19 13 6 5 0 */ int gpio[] = { 21, 12, 1, 0, /* 1234 */ 20, 7, 6, 19, 26, 16, 5, /* abcdefg */ 13, /* . */ }; /* 0 - 9 * a * --- * f| |b * -g- * e| |c * --- * d */ int code[10] = { /* 0 1 2 3 4 5 6 7 8 9 */ 0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, }; for (i = 0; i < sizeof (gpio)/ sizeof (gpio[0]); i++) { export_gpio(gpio[i]); if (-1 == set_gpio_dir(gpio[i], GPIO_DIR_OUT)) { fprintf (stderr, "set gpio %d dir to out failed\n" , gpio[i]); return 1; } } while (1) { for (j = 0; j < 4; j++) { for (i = 0; i < 8; i++) set_gpio_value(gpio[4+i], 1); for (i = 0; i < 4; i++) { if (i == j) set_gpio_value(gpio[i], 1); /* high select chip */ else set_gpio_value(gpio[i], 0); /* high select chip */ } for (i = 0; i < 8; i++) { if (code[v[j]] & (1 << i)) set_gpio_value(gpio[4+i], 0); /* low light led */ else set_gpio_value(gpio[4+i], 1); } usleep(1000); } } return 0; } |
测试发现CPU占用率高:
1 2 3 4 5 6 7 8 9 10 11 | Mem: 19548K used, 85132K free, 20K shrd, 0K buff, 2344K cached CPU0: 0.0% usr 0.2% sys 0.0% nic 99.7% idle 0.0% io 0.0% irq 0.0% sirq CPU1: 0.0% usr 0.0% sys 0.0% nic 100% idle 0.0% io 0.0% irq 0.0% sirq CPU2: 0.2% usr 0.0% sys 0.0% nic 99.7% idle 0.0% io 0.0% irq 0.0% sirq CPU3: 3.2% usr 54.2% sys 0.0% nic 42.5% idle 0.0% io 0.0% irq 0.0% sirq Load average: 0.42 0.24 0.13 2/57 112 PID PPID USER STAT VSZ %VSZ CPU %CPU COMMAND 109 71 0 R 1612 1.5 3 14.0 ./digit_led 8 2 0 IW 0 0.0 1 0.2 [rcu_preempt] 59 2 0 SW 0 0.0 0 0.1 [w1_bus_master1] 1 0 0 S 3376 3.2 1 0.0 {linuxrc} init |
要达到肉眼看不出闪烁的效果,1s要执行1千次循环,效率较低。
效果图如下:
参考
http://blog.sina.com.cn/s/blog_50d442d80100afz3.html