树莓派GPIO入门(四) :用数码管做个简单的计数器

一、实验要求

利用树莓派驱动数码管,使数码管能在0000-9999之间进行计数,当按下按键时,数值会清零。

二、实验材料

  • 按键1个
  • 4位8段数码管(共阴极) 1个
  • 杜邦线若干
  • 树莓派4B、RPi.GPIO库

三、数码管简介

(1)一般来说,标准的数码管从显示内容上分7段和8段数码管两种。8段比7段多一个右下角的小数点。8段数码管由8个发光二极管组成,其中7个用于组成数字,1个用于显示小数点。每一根的编号如下图的右上角所示(A-G,DP)。

树莓派GPIO入门(四) :用数码管做个简单的计数器_第1张图片

(2)数码管从电源极性上分共阳和共阴两种。如果数码管上每一个独立的发光二极管都单独引出两根引脚,一根接正极(阳)一根接负极(阴),那么一个8段数码管就需要16根引脚来控制。但其实这8段数码管完全可以在内部共用一个阳级,只控制各段发光二极管的阴级联通即可,这就是共阳。反之亦然,叫共阴。共阳或共阴的每个8段数码管只需要引出9个引脚,1个阳(阴)级接到树莓派vcc(gnd)上,另外8个分别连到gpio口上,通过控制io口高低电平即可显示所需数字。比如一只共阳数码管想显示数字1,看LED编号图可知需要点亮b段和c段,其他全灭。那么连到共阳端引脚的io口输出高电平,连到引脚b、c的io口输出低电平,连到引脚a、d、e、f、g、dp的io口均输出高电平即可。

四、动态扫描显示

 数码管动态显示接口是单片机中应用最为广泛的一种显示方式之一,动态驱动是将所有数码管的8个显示笔划"a,b,c,d,e,f,g,dp"的同名端连在一起引出8个引脚,每个数字再单独引出共阳(阴)端,这样总引脚数就只要8 + 数字个数即可,本文使用的8段4位数码管正是引出了12个引脚。至于哪个引脚对应哪一段,哪几个引脚分别对应各数字的共阳(阴)端,就需要商家提供电路图了。

当树莓派输出8个段信号时,所有数码管都会接收到相同的信号,但究竟是哪个数码管会显示出字形,取决于这个数码管对应的共阳(阴)极(后统称位选端)有无导通。所以我们只要将需要显示的数码管的位选端选通,该位就显示出字形,没有选通的数码管就不会亮。通过分时轮流控制各个数码管的的位选端,就使各个数码管轮流受控显示,这就是动态驱动。

在轮流显示过程中,每位数码管的点亮时间为1~2ms,由于人的视觉暂留现象及发光二极管的余辉效应,尽管实际上各位数码管并非同时点亮,但只要扫描的速度足够快,给人的印象就是一组稳定的显示数据,不会有闪烁感,动态显示的效果和静态显示是一样的,能够节省大量的I/O端口,而且功耗更低。

五、实验代码

import RPi.GPIO as GPIO 
import time

GPIO.setmode(GPIO.BCM)

# 定义单个数码管各段led对应的GPIO口
LED_A = 26
LED_B = 19
LED_C = 13
LED_D = 6
LED_E = 5
LED_F = 22
LED_G = 27
LED_pins = [LED_A,LED_B,LED_C,LED_D,LED_E,LED_F,LED_G]

# 定义1到4号数码管阴极对应的GPIO口
DIG1 = 12
DIG2 = 16
DIG3 = 20
DIG4 = 21
All_dig = [DIG1, DIG2, DIG3, DIG4]
All_pins = [LED_A,LED_B,LED_C,LED_D,LED_E,LED_F,LED_G,DIG1,DIG2,DIG3,DIG4]

# 定义按钮输入的GPIO口
btn = 24
GPIO.setup(24, GPIO.IN, pull_up_down=GPIO.PUD_UP)  #在24号引脚处设置上拉电阻

#将数码管LED段引脚设置为输出模式
GPIO.setup(All_pins, GPIO.OUT)


#0-9的各段LED状态,1表示高电平,0表示低电平
zero = [1, 1, 1, 1, 1, 1, 0]
one = [0, 1, 1, 0, 0, 0, 0]
two = [1, 1, 0, 1, 1, 0, 1]
three = [1, 1, 1, 1, 0, 0, 1]
four = [0, 1, 1, 0, 0, 1, 1]
five = [1, 0, 1, 1, 0, 1, 1]
six = [1, 0, 1, 1, 1, 1, 1]
seven = [1, 1, 1, 0, 0, 0, 0]
eight = [1, 1, 1, 1, 1, 1, 1]
nine = [1, 1, 1, 1, 0, 1, 1]



#初始化,让所有LED段熄灭状态
GPIO.output(All_pins, False)

def showDigit(order, num):
    # 先将负极拉高,关掉显示
    GPIO.output(All_dig, True)
    
    if (num == 0):
        GPIO.output(LED_pins, zero)    
    elif (num == 1):
        GPIO.output(LED_pins, one)    
    elif (num == 2):
        GPIO.output(LED_pins, two)    
    elif (num == 3):        
        GPIO.output(LED_pins, three)    
    elif (num == 4):
        GPIO.output(LED_pins, four)    
    elif (num == 5):
        GPIO.output(LED_pins, five)    
    elif (num == 6):
        GPIO.output(LED_pins, six)    
    elif (num == 7):
        GPIO.output(LED_pins, seven)    
    elif (num == 8):
        GPIO.output(LED_pins, eight)    
    elif (num == 9):
        GPIO.output(LED_pins, nine)    
    
    if (order == 1):
        GPIO.output(DIG1, False)
    elif (order == 2):
        GPIO.output(DIG2, False)
    elif (order == 3):
        GPIO.output(DIG3, False)
    elif (order == 4):
        GPIO.output(DIG4, False)
        
try:
    t=0.005
    start = time.time()
    while True:
        if (GPIO.input(btn) == 0):
            time.sleep(t)
            start = time.time()
        else:
            now = time.time()
            count = now - start            
            time.sleep(t)
            showDigit(1, int(count / 1000))       
            time.sleep(t)
            showDigit(2, int(count % 1000 / 100))   
            time.sleep(t)
            showDigit(3, int(count % 100 / 10)) 
            time.sleep(t)
            showDigit(4, int(count % 10))           
except KeyboardInterrupt:
    pass
GPIO.cleanup()  #最后清理GPIO口

六、视频演示

七、参考资料

http://blog.mangolovecarrot.net/2015/05/05/raspi-study05/

 

 

你可能感兴趣的:(树莓派)