03-一位数码管、四位数码管
·
一位数码管、四位数码管
一、1位数码管的显示
1位数码管的引脚定义如下:-

将esp32引脚,按照下图的形式连接。直接驱动电流较大,中间注意串联电阻


其实数码管的本质就是一些按照规律排列组合的LED灯。数码管显示数字,实际上就是按照顺序让LED点亮。
结合第一节-点亮LED的内容,定义好管脚信息。
import machine
import time
# 按照连接方式定义管脚
a = machine.Pin(13, machine.Pin.OUT)
b = machine.Pin(12, machine.Pin.OUT)
c = machine.Pin(14, machine.Pin.OUT)
d = machine.Pin(27, machine.Pin.OUT)
e = machine.Pin(26, machine.Pin.OUT)
f = machine.Pin(25, machine.Pin.OUT)
g = machine.Pin(33, machine.Pin.OUT)
h = machine.Pin(32, machine.Pin.OUT)
# 以list的形式收录管脚信息
led_list = [a, b, c, d, e, f, g, h]
led_map = {
0: "11111100", # 按照a-h的形式排列,1亮灯 0灭灯
1: "01100000",
2: "11011010",
3: "11110010",
4: "01100110",
5: "10110110",
6: "10111110",
7: "11100000",
8: "11111110",
9: "11110110",
}
def show_one_num(num): # 定义显示数字方法,处理每一个管脚
if num < 0 or num > 9:
print("out of range") # 异常拦截
return
count = 0
for bit in led_map.get(num):
if bit == "1" :
led_list[count].value(bit)
else:
led_list[count].value(0)
count += 1
for i in range(0, 12):
show_one_num(i)
time.sleep_ms(500)
这里的管脚定义也可以使用PWM的形式,可以通过设置duty值来控制数码管的亮度
from machine import Pin, PWM
import time
a = PWM(Pin(13), freq = 10000)
# ......
led_list = [a, b, c, d, e, f, g, h]
led_map = {
# 与上一节中定义一致
}
def show_one_num(num):
if num < 0 or num > 9:
print("out of range")
count = 0
for bit in led_map.get(num):
if bit == "1" :
led_list[count].duty(10) # 通过duty设置亮度
else:
led_list[count].duty(0)
count += 1
for i in range(0, 100):
# ......
二、四位数码管的显示
四位数码管的引脚定义,有一些变化,多出了led1-led4的控制引脚:

按照图示连接面包板电路:

在一位数码管的基础上,单独控制led1-led4引脚,可以直接让他们显示某一个数字
from machine import Pin, PWM
import time
import machine
a = PWM(Pin(13), freq = 10000)
# ...参考一位数码管实现
# 将四位数码管特有的控制引脚赋值
led1 = machine.Pin(5, machine.Pin.OUT)
led2 = machine.Pin(18, machine.Pin.OUT)
led3 = machine.Pin(19, machine.Pin.OUT)
led4 = machine.Pin(21, machine.Pin.OUT)
led_list = [a, b, c, d, e, f, g, h]
led_map = {# ...参考一位数码管实现
def show_one_num(num): # ...参考一位数码管实现
# 通过将ledx引脚激活/关闭,可以实现数码管按需同时亮灭
led1.value(0)
led2.value(0)
led3.value(1)
led4.value(0)
for i in range(0, 9):
show_one_num(i)
time.sleep_ms(500)
练习:依次让数码管显示0-9999的数字
参考前文一位数码管的逻辑,补充使能LED位数的代码
注意需要确保显示质量的话,注释中显示质量1 2中的实现比较重要
from machine import Pin, PWM
import time
import machine
a = PWM(Pin(13), freq = 10000)
# ...参考一位数码管实现
# 将四位数码管特有的控制引脚赋值
led1 = machine.Pin(5, machine.Pin.OUT)
led2 = machine.Pin(18, machine.Pin.OUT)
led3 = machine.Pin(19, machine.Pin.OUT)
led4 = machine.Pin(21, machine.Pin.OUT)
led_enable_list = [led1, led2, led3, led4]
led_list = [a, b, c, d, e, f, g, h]
led_map = {# ...参考一位数码管实现
def show_one_num(num): # ...参考一位数码管实现
def show_four_num(index, num):
for ledx in led_enable_list: # 先将所有的使能位置为不显示,防止快速刷新时留下残影
ledx.value(1) # <---显示质量1
if num != -1: show_one_num(num) # 不为-1显示对应的一位数
# 显示第几位数字
for ledx in range(0, 4):
if ledx == index and num != -1:
led_enable_list[ledx].value(0) # 操作需要显示第几位数
for i in range(0, 10000): # 显示0-9999的数字
num_index = [-1, -1, -1, -1] # 个位 十位 百位 千位的列表,之后会对数字取余
num_index[3] = i % 10
if i >= 10: num_index[2] = int(i / 10 % 10) # 初值为-1 方便后续判断,未初始化的位数不亮灯
if i >= 100: num_index[1] = int(i / 100 % 10)
if i >= 1000: num_index[0] = int(i / 1000)
print(num_index)
for delay1 in range(150): # 确保显示质量,单个数字多次刷新 <---显示质量2
for numx in range(0, 4): # 依次遍历数位
show_four_num(numx, num_index[numx])
以上实现都在主线程里运行,不方便调节显示速率与显示内容的关系,
使用线程,可以很好的解决这个问题,显示数字与更新数字的线程分开,可以对不同的功能做针对性的操作
from machine import Pin, PWM
import time
import machine
import _thread
a = PWM(Pin(13), freq = 10000)
b = PWM(Pin(12), freq = 10000)
c = PWM(Pin(14), freq = 10000)
d = PWM(Pin(27), freq = 10000)
e = PWM(Pin(26), freq = 10000)
f = PWM(Pin(25), freq = 10000)
g = PWM(Pin(33), freq = 10000)
h = PWM(Pin(32), freq = 10000)
# 将四位数码管特有的控制引脚赋值
led1 = machine.Pin(5, machine.Pin.OUT)
led2 = machine.Pin(18, machine.Pin.OUT)
led3 = machine.Pin(19, machine.Pin.OUT)
led4 = machine.Pin(21, machine.Pin.OUT)
led_enable_list = [led1, led2, led3, led4]
led_list = [a, b, c, d, e, f, g, h]
led_map = {
0: "11111100",
1: "01100000",
2: "11011010",
3: "11110010",
4: "01100110",
5: "10110110",
6: "10111110",
7: "11100000",
8: "11111110",
9: "11110110",
}
def show_one_num(num):
if num < 0 or num > 9:
print("out of range")
count = 0
for bit in led_map.get(num):
if bit == "1" :
led_list[count].duty(1000)
else:
led_list[count].duty(0)
count += 1
def clean():
for ledx in led_enable_list: # 先将所有的使能位置为不显示,防止快速刷新时留下残影
ledx.value(1)
time.sleep_us(1)
def show_four_num(index, num):
clean()
if num != -1: show_one_num(num) # 不为-1显示对应的一位数
clean()
# 显示第几位数字
for ledx in range(0, 4):
if ledx == index and num != -1:
led_enable_list[ledx].value(0) # 操作需要显示第几位数
show_num_list = [-1, -1, -1, -1]
def show_num():
while True:
for numx in range(4): # 依次遍历数位
show_four_num(numx, show_num_list[numx])
time.sleep_us(10)
def split_num():
for i in range(0, 10000): # 显示0-9999的数字
current_list = [-1, -1, -1, -1] # 个位 十位 百位 千位的列表,之后会对数字取余
current_list[3] = i % 10
if i >= 10: current_list[2] = int(i / 10 % 10) # 初值为-1 方便后续判断,未初始化的位数不亮灯
if i >= 100: current_list[1] = int(i / 100 % 10)
if i >= 1000: current_list[0] = int(i / 1000)
# 更新显示数字
global show_num_list
show_num_list = current_list
time.sleep_ms(500)
# 启动多个线程
_thread.start_new_thread(show_num, ()) # 显示线程,循环显示,不受迭代时间影响
_thread.start_new_thread(split_num, ()) # 数字拆分线程,拆分完成更新全局变量,保证显示的稳定
至此,数码管的显示就告一段落。
更多推荐
所有评论(0)