树莓派驱动4位数码管显示时间

20141012215423910-0

数码管的显示分为静态和动态两种。静态就是一个GPIO控制一个LED小灯管。
但是随着控制数码管数量的增加,GPIO口就占用太多了,所以多个数码管可以有 共阴 和 共阳 两种共享引脚。这个时候如果采用静态点亮数码管的方式,共享引脚的数码管显示完全一样。所谓动态方式,就是通过GPIO选择引脚,选择要点亮的某个数码管,然后通过共享引脚点亮LED小灯管。然后快速切换点亮其他数码管,由于点亮的切换频率非常快所以感觉上数码管一直亮着。

当然也可以使用辅助芯片,如MAX7129等,只需要用更加简化的方式控制显示数据。
点击查看详细文档

这里我使用树莓派自己编码,动态刷新各个数码管。买的数码管有24位引脚,37个led小灯,这个掩饰只使用了4 × 7 = 28 个led灯。
代码:

import RPi.GPIO as GPIO
import time, random

"""
Display date to LED lights
There are four lights, it displays 4 number
"""

GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)


def setp(n, status='on'):
    if status == 'on':
        GPIO.output(n, GPIO.HIGH)
    else:
        GPIO.output(n, GPIO.LOW)

for i in pins + sels:
    GPIO.setup(i, GPIO.OUT)
    setp(i, 'off')

for i in sels:
    setp(i, 'on')

#
#     __2_
#    |     |    |  0 ->  011 1111 -> 0x3f
#  1 |     | 3  |  1 ->  010 0001 -> 0x21
#    |__7__|    |  2 ->  111 0110 -> 0x76
#    |     |    |  4 ->  ...
#  6 |     | 4  |        ...
#    |__5__|    |  9 ->  ...      -> 0x5f
#

pins = [27, 17, 22, 10, 25, 24, 11] #GPIO ports
sels = [14, 15, 18, 23] #GPIO ports to select led, there are four led lights
nums = [0x3f, 0x21, 0x76, 0x5e, 0x4d, 0x5b, 0x7b, 0x0e, 0x7f, 0x5f]

def flush(sel, n):
    setp(sels[sel], 'off')
    n = nums[n]
    for i in sels:
        if i != sels[sel]:
            setp(i, 'on')

    for i in range(7):
        if (n & (1 << i)):
            setp(pins[i], 'on')

    for i in range(7):
        if (n & (1 << i)):
            setp(pins[i], 'off')

try:
    while True:
        t = time.gmtime()
        flush(3, t.tm_min / 10)
        flush(2, t.tm_min % 10)
        flush(1, t.tm_sec / 10)
        flush(0, t.tm_sec % 10)
except:
    GPIO.cleanup()

其中灯管编号,引脚对应关系可以根据自己的连线方式自定义和修改:

#
#     __2_
#    |     |    |  0 ->  011 1111 -> 0x3f
#  1 |     | 3  |  1 ->  010 0001 -> 0x21
#    |__7__|    |  2 ->  111 0110 -> 0x76
#    |     |    |  4 ->  ...
#  6 |     | 4  |        ...
#    |__5__|    |  9 ->  ...      -> 0x5f
pins = [27, 17, 22, 10, 25, 24, 11] #GPIO ports
sels = [14, 15, 18, 23] #GPIO ports to select led, there are four led lights
nums = [0x3f, 0x21, 0x76, 0x5e, 0x4d, 0x5b, 0x7b, 0x0e, 0x7f, 0x5f] #0,1,2,3~9 对应编码

演示视频:(为了效果明显这里显示的是 分钟 和 秒)

这是一篇发布于 10年 前的文章,其中的信息可能已经有所发展或是发生改变,请了解。


3 评论

  1. 您好,我有个数码管,是8位的,上有VCC、SCLK、RCLK、DIO、GND,然后我的树莓派是v2 B的,麻烦您给指点一下如何接线。

    zxjlwt at 126.com

  2. 本文所介绍的程序是针对无驱动的4位数码管,所以略显复杂。而你这个看起来应该是带有驱动的数码管。接法就简单了。
    VCC — 外接电源(3.3V到5V) 2.GND — 外接地 3.DIO — 数据输入管脚 4.SCLK — 移位寄存器时钟管脚 5.RCLK — 输出寄存器时钟管脚

    74HC595 最多需要5 根控制线,即SDA、SH_CP、ST_CP、CLR 和EN。其中CLR 可以直接接到高电平, 用软件来实现寄存器清零; 如果不需要软件改变亮度, EN可以直接接到低电平, 而用硬件来改变亮度。把其余三根线和单片机的I/ O 口相接, 即可实现对 LED 的控制。

    via http://evelock.com/Produces/Peripheral/Display/Eight_digital_tube.html

发表评论

你的邮件地址不会公开


*