ILD

树莓派控制数码管显示
作者:YUAN JIANPENG 邮箱:yuanjp@hust.edu.cn
发布时间:2018-7-23 站点:Inside Linux Development

4位,8段,数码管的引脚如下:


四位八段数码管引脚图 <wbr> <wbr> <wbr>嘿嘿


型号可能不对,但是引脚是对的。测试发现是共阴极数码管。


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


Copyright © linuxdev.cc 2017-2024. Some Rights Reserved.