这里只是为了练习GPIO的使用,没有加任何的译码设备,也没加任何的放大设备,直接用树莓派的16个gpio引脚,连接一个8*8LED点阵的16个引脚,考虑到树莓派所能提供的电流不能太大,所以统一在点阵的8个阳极各加了一个1kΩ的电阻
8*8电阻的16个引脚,8个阳极,8个阴极,我们可以第一为R1~R8、C1~C8(考虑到点阵是方形的,所以不去区分行列,只区分阴阳,上面的R/C和“阴/阳”的对应关系,请根据实际共阴还是共阳区分清楚)
当我们给R1/C1两个管脚上电时(即在树莓派中,将R1对应的GPIO口拉到高电平,C1拉到低电平),第一行、第一列的这个点就会亮起来,同理,给R3/C5上电,[3, 5]的这个点会连起来
于是,我们可以通过这种方式依次点亮所有的点
。。。
于是,问题来了
如果我想同时点亮[3, 5]/[3, 6]/[4, 6]三个点,就需要同时拉高C3/C4,拉低R5/R6,可是,如果我做了这个操作,[4, 5]这个点也会亮起。。。这怎么办哪?
答案时,依次先点亮[3, 5]/[3, 6],熄灭这两个点,再点亮[4, 6],。。。熄灭[4, 6],点亮[3, 5]/[3, 6],如此往复,当这种切换的频率足够高时,由于认得视觉暂留,看到这三个点就是同时亮起的,也就是说,同一时刻,自会有单独一行、或者一列有点在发光
呵呵,很熟悉吧,电影、大屁股显示器什么的,和这个原理类似
好的,明白了原理,就可以动手写程序吧
这里使用树莓派最主流的编程语言:python,显示的东西,是“Hello word”,左右移动显示
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 | import RPi.GPIO as GPIO #导入必要的python库 import time #Hello World 字模 vhws = [ [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,1,1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,1,0,0,1,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,1,0,0,0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,1,0,0,0,1,0,0,0,0,0,0,1,0,0,0,1,1,0,1,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,1,1,1,1,1,0,1,1,1,1,1,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,1,0,0,0,1,0,1,0,0,0,1,0,0,0,0,0,1,0,1,0,0,0,1,1,0,0,0,1,0,0,0,0,0,1,1,1,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,1,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,1,0,1,0,0,0,1,0,1,0,0,0,0,0,1,0,0,0,1,0,0,1,0,0,0,0,1,0,0,0,0,1,0,0,1,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,1,0,0,1,0,0,1,0,1,0,0,1,0,1,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,1,0,1,0,0,0,0,0,0,1,0,1,0,0,0,1,0,0,0,0,1,0,1,0,0,1,0,0,1,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,1,1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,1,1,1,1,0,0,0,0,0], ] #左移还是右移 isRig = 1 vhwi = 0 #此函数返回当前时间点当前帧需要显示的8*8数组 def hwv(): global isRig global vhwi l = len(vhws[0]) if isRig > 0: vhwi += 1 else: vhwi -= 1 if vhwi >= (l - 8): isRig = 0 if vhwi 0): if timeLine % 10 == 0: nowV = hwv() #双层循环实现的扫描显示 for i in range(0, len(nowV)): allOver() #拉低所有阴极 GPIO.output(rs[i], GPIO.LOW) for j in range(0, len(nowV[i])): if nowV[i][j] > 0: GPIO.output(cs[j], GPIO.HIGH) #点亮这个点 else: GPIO.output(cs[j], GPIO.LOW) #不点亮 time.sleep(sleepTime) timeLine = timeLine - 1 return #ledtest 17 27 22 5 6 13 19 26 18 23 24 25 12 16 20 21 #这里是管脚对应关系 rs = [21, 20, 16, 12, 25, 24, 23, 18] #R1:13 R2:3 R3:4 R4:10 R5:6 R6:11 R7:15 R8:16 cs = [26, 19, 13, 6, 5, 22, 27, 17] #C1:5 C2:2 C3:7 C4:1 C5:12 C6:8 C7:14 C8:9 #开始 def startVs(): GPIO.setmode(GPIO.BCM) for i in xrange(8): GPIO.setup(cs[i], GPIO.OUT) GPIO.setup(rs[i], GPIO.OUT) allOver() return #关闭 def stopVs(): GPIO.cleanup() return #将所有管脚置为反响,即熄灭所有 def allOver(): for i in xrange(8): GPIO.output(cs[i], GPIO.LOW) GPIO.output(rs[i], GPIO.HIGH) return #timeLine = 1000 frames = 60 #显示一个8*8数组 def viewArr(): timeLine = 1000 sleepTime = 0.0001 #1 / (frames * 8) while(timeLine > 0): if timeLine % 10 == 0: nowV = hwv() for i in range(0, len(nowV)): allOver()#每次点亮前,先熄灭所有 GPIO.output(rs[i], GPIO.LOW) for j in range(0, len(nowV[i])): if nowV[i][j] > 0: GPIO.output(cs[j], GPIO.HIGH) #点亮 else: GPIO.output(cs[j], GPIO.LOW) #不点亮 time.sleep(sleepTime) #扫屏的时延 timeLine = timeLine - 1 #显示时常控制 return if __name__ == '__main__': startVs() viewArr() stopVs() |
转载请注明出处:昆仑的山头