厦门律师网站建设,河西做网站的公司,wordpress响应式视频,华为云做的网站怎么样树莓派性能非常强悍#xff0c;但是对于某些复杂的项目来说#xff0c;会出现心有余而口不足的情况#xff0c;为了解决这类问题#xff0c;可以在树莓派上使用扩展板#xff0c;我们介绍几款常见的扩展板#xff0c;不仅可以扩展到树莓派#xff0c;其他单片机或嵌入式…树莓派性能非常强悍但是对于某些复杂的项目来说会出现心有余而口不足的情况为了解决这类问题可以在树莓派上使用扩展板我们介绍几款常见的扩展板不仅可以扩展到树莓派其他单片机或嵌入式处理器均可以扩展。这几种扩展板分别是IIC Bus Expansion Board 、TM1638、PCA9685、PCF8574。
1、IIC Bus Expansion Board
这个也叫IIC集线器Hub我们之前介绍过凡是IIC总线设备均可以接一共可扩展8个IIC设备如OLED、PCF8591、气压传感器光照强度传感器等使用IIC总线通信的芯片还是很多的这个设备不仅可以扩展还可以级联用起来非常方便。 2、TM1638
下图是扩展板的正面图方方正正规规整整看着真舒服比接一堆杜邦线好看多了。而且淘宝售价仅5元。它是按键数码管LED显示模块只需要连接树莓派3根GPIO线就可以实现基本功能的输入输出。玩过单片机的同学都知道按键LED数码管各8个是非常消耗IO口的至少也需要十几个端口把通过这个芯片全部解决我后面的实验都用这个来做输入输出了但是要想玩好还需要理解Python语言的多线程与异步编程后面有机会我也会详细介绍。 1简介
TM1638是深圳市天微电子有限公司设计的一款带键盘扫描接口的LED发光二极管显示器驱动控制专用芯片内部集成有MCU数字接口、数据锁存器、LED高压驱动、键盘扫描等电路。主要应用于冰箱、空调 、家庭影院等产品的高段位显示屏驱动。
2器件特性
采用功率CMOS 工艺显示模式 10 段×8 位键扫描8×3bit8级辉度可调串行接口CLKSTBDIO振荡方式RC 振荡450KHz5%内置上电复位电路采用SOP28封装
3TM1638引脚图 4TM1638的寄存器
TM1638芯片寄存器还是很多的这个还是要看数据手册网上的资料也有很多我本来不想再复制过来了但是我觉得这个资料还是经常需要参考学习毕竟如果不了解这些驱动程序就没有办法写。
a、显示寄存器LED与数码管 b、按键地址 5指令表 7数据格式
TM1638的数据读取和发送都在CLK的上升沿进行因为DIO在时钟的下降沿控制N管动作此时读数不稳定。TM1638采取低位在前的数据格式每次发送和读取都是1byte长度即8位二进制数据每次STB拉低之后的第一个字节作为指令处理指令时当前其它处理被终止。 3、Python下的驱动程序
这个驱动需要根据时序写我找了mircoPython的驱动引入了GPIO库对此进行了修改整个代码太长我把用到的放一下。
from micropython import const
import time
import RPi.GPIO as GPIO# 指定编号规则为BOARD
GPIO.setmode(GPIO.BOARD)
# 关闭警告
GPIO.setwarnings(False)TM1638_CMD1 const(64) # 0x40 data command
TM1638_CMD2 const(192) # 0xC0 address command
TM1638_CMD3 const(128) # 0x80 display control command
TM1638_DSP_ON const(8) # 0x08 display on
TM1638_READ const(2) # 0x02 read key scan data
TM1638_FIXED const(4) # 0x04 fixed address mode# 0-9, a-z, blank, dash, star
_SEGMENTS bytearray(b\x3F\x06\x5B\x4F\x66\x6D\x7D\x07\x7F\x6F\x77\x7C\x39\x5E\x79\x71\x3D\x76\x06\x1E\x76\x38\x55\x54\x3F\x73\x67\x50\x6D\x78\x3E\x1C\x2A\x76\x6E\x5B\x00\x40\x63)class TM1638(object):Library for the TM1638 LED display driver.def __init__(self, stb, clk, dio, brightness7):self.stb stbself.clk clkself.dio dioif not 0 brightness 7:raise ValueError(Brightness out of range)self._brightness brightnessself._on TM1638_DSP_ONGPIO.setup(self.clk, GPIO.OUT,initial1)GPIO.setup(self.dio, GPIO.OUT,initial0)GPIO.setup(self.stb, GPIO.OUT,initial1)self.clear()self._write_dsp_ctrl()def _write_data_cmd(self):# data command: automatic address increment, normal modeself._command(TM1638_CMD1)def _set_address(self, addr0):# address command: move to addressself._byte(TM1638_CMD2 | addr)def _write_dsp_ctrl(self):# display command: display on, set brightnessself._command(TM1638_CMD3 | self._on | self._brightness)def _command(self, cmd):GPIO.output(self.stb,0)self._byte(cmd)GPIO.output(self.stb,1)def _byte(self, b):GPIO.setup(self.dio, GPIO.OUT)for i in range(8):GPIO.output(self.clk,0)GPIO.output(self.dio,(b i) 1)#self.dio((b i) 1)GPIO.output(self.clk,1)def _scan_keys(self):Reads one of the four bytes representing which keys are pressed.pressed 0GPIO.setup(self.dio, GPIO.IN, pull_up_downGPIO.PUD_UP)for i in range(8):GPIO.output(self.clk,0)#if self.dio.value():if GPIO.input(self.dio):pressed | 1 iGPIO.output(self.clk,1)#GPIO.output(self.clk,0)GPIO.setup(self.dio, GPIO.OUT)return presseddef power(self, valNone):Power up, power down or check statusif val is None:return self._on TM1638_DSP_ONself._on TM1638_DSP_ON if val else 0self._write_dsp_ctrl()def brightness(self, valNone):Set the display brightness 0-7.# brightness 0 1/16th pulse width# brightness 7 14/16th pulse widthif val is None:return self._brightnessif not 0 val 7:raise ValueError(Brightness out of range)self._brightness valself._write_dsp_ctrl()def clear(self):Write zeros to each addressself._write_data_cmd()GPIO.output(self.stb,0)self._set_address(0)for i in range(16):self._byte(0x00)GPIO.output(self.stb,1)def write(self, data, pos0):Write to all 16 addresses from a given position.Order is left to right, 1st segment, 1st LED, 2nd segment, 2nd LED etc.if not 0 pos 15:raise ValueError(Position out of range)self._write_data_cmd()GPIO.output(self.stb,0)self._set_address(pos)for b in data:self._byte(b)GPIO.output(self.stb,1)def led(self, pos, val):Set the value of a single LEDself.write([val], (pos 1) 1)def leds(self, val):Set all LEDs at once. LSB is left most LED.Only writes to the LED positions (every 2nd starting from 1)self._write_data_cmd()pos 1for i in range(8):GPIO.output(self.stb,0)self._set_address(pos)self._byte((val i) 1)pos 2GPIO.output(self.stb,1)def segments(self, segments, pos0):Set one or more segments at a relative position.Only writes to the segment positions (every 2nd starting from 0)if not 0 pos 7:raise ValueError(Position out of range)self._write_data_cmd()for seg in segments:GPIO.output(self.stb,0)self._set_address(pos 1)self._byte(seg)pos 1GPIO.output(self.stb,1)def keys(self):Return a byte representing which keys are pressed. LSB is SW1keys 0GPIO.output(self.stb,0)self._byte(TM1638_CMD1 | TM1638_READ)for i in range(4):keys | self._scan_keys() iGPIO.output(self.stb,1)return keysdef encode_digit(self, digit):Convert a character 0-9, a-f to a segment.return _SEGMENTS[digit 0x0f]def encode_string(self, string):Convert an up to 8 character length string containing 0-9, a-z,space, dash, star to an array of segments, matching the length of thesource string excluding dots, which are merged with previous char.segments bytearray(len(string.replace(.,)))j 0for i in range(len(string)):if string[i] . and j 0:segments[j-1] | (1 7)continuesegments[j] self.encode_char(string[i])j 1return segmentsdef encode_char(self, char):Convert a character 0-9, a-z, space, dash or star to a segment.o ord(char)if o 32:return _SEGMENTS[36] # spaceif o 42:return _SEGMENTS[38] # star/degreesif o 45:return _SEGMENTS[37] # dashif o 65 and o 90:return _SEGMENTS[o-55] # uppercase A-Zif o 97 and o 122:return _SEGMENTS[o-87] # lowercase a-zif o 48 and o 57:return _SEGMENTS[o-48] # 0-9raise ValueError(Character out of range: {:d} {:s}.format(o, chr(o)))def show(self, string, pos0):Displays a stringsegments self.encode_string(string)self.segments(segments[:8], pos)
1这里的数码管定义SEGMENTS bytearray(b\x3F\x06\x5B\x4F\x66\x6D\x7D\x07\x7F\x6F\x77\x7C\x39\x5E\x79\x71\x3D\x76\x06\x1E\x76\x38\x55\x54\x3F\x73\x67\x50\x6D\x78\x3E\x1C\x2A\x76\x6E\x5B\x00\x40\x63)
可以看出0为3F是共阴极数码管的段码。bytearray() 是 Python 的一个内置函数用于创建一个可变字节序列。与 bytes 类型不同bytearray 对象的内容是可以修改的。它主要用于在需要字节级别的数据操作时提供一种更灵活、可变的存储方式。这个和C51的字符型变量用一个字节存储契合。
这样我们可以在文件中自己定义个列表。0-9的段码放进去
dispaly_list[b\x3F,b\x06,b\x5B,b\x4F,b\x66,b\x6D,b\x7D,b\x07,b\x7F,b\x6F]
我们就可以让单个数码管显示了。调用类的segments方法这个地方和C语言不同因为Python是面向对象而C是面向过程后面实验也会提到。如果让第0个数码管显示0那么则
tm.segments(dispaly_list[0],0)如果让第7个数码管显示3那么则tm.segments(dispaly_list[3],7)。 想显示哪个数码管就显示哪个数码管想关哪个就关哪个。有了这个方法然后我们就可以利用数码管一次显示8个字符、数字当然我们主要还是显示数字。其他的方法可以自行编写。
2LED灯可以点亮一个也可以点亮多个。注意看led和leds函数
tm.leds(0b01010101)同时给8个灯二进制数0-11为亮0为灭
tm.led(0,1)这是对单个LED控制第0个灯点亮
3tm.keys()获取键值按键1按下得到的键值为1第二个是2第三个是4第四个是8第5个是162**(n-1),因此要转成1、2、3、4需要数学的取对数函数才行。
4.实验代码与现象
实验就是按键按第几个数码管第一个显示按键的键值对应的LED灯亮
import TM1638
import time
import mathtmTM1638.TM1638(stb36,clk38,dio40) ##标号一致 板子有标记
tm.brightness(2)#循环读取按键值并更新数码管显示
while True:keys tm.keys()if keys:print(keys)key_num int(math.log(keys,2))print(key_num)# 读取到按键这里简单地显示第一个按下的键值tm.show(str(key_num))#tm.number(int(keys))tm.leds(2**key_num)time.sleep(0.15)
就这几行代码完全可以实现当然程序的问题关键仍然是time.sleep函数的休眠时间不能给的太长太长则按键不灵这里将sleep设置为0.15,显示和按键都没有问题。