在本教程中,我们将使用ESP32和MicroPython来驱动一个带小数点的单位数码管(7段显示器)。将详细讲解数码管的工作原理,并分步骤完成从基本的段位控制到完整的数字显示,最后封装成可重用的控制类。同时,本文将提供如何判断数码管是共阳极还是共阴极的方法,并为不同类型的数码管提供兼容代码。
数码管基础知识
数码管结构及显示原理
数码管通常包含7个段位(A-G)和一个小数点(DP)。不同的段位可以组合显示0-9的数字,或显示部分字母。数码管的两个主要分类是共阳极和共阴极:
- 共阳极数码管:数码管的阳极引脚连接到电源,单个段位点亮时接地。
- 共阴极数码管:数码管的阴极引脚接地,单个段位点亮时接电源。
判断数码管的类型
我们可以通过简单测试来判断数码管的类型。以下步骤有助于辨别:
- 准备电源:取一个3.3V或5V的电源。
- 连接任意段位引脚:将数码管的任一段位引脚连接到电源的正极。
- 测试公共引脚:依次将公共引脚(标记为COM或“+”“-”)接到电源的负极,观察数码管是否亮起。
- 若数码管亮起,则该数码管为共阳极。
- 若数码管未亮,再将公共引脚接到电源的正极,若此时数码管亮起,则该数码管为共阴极。
硬件连接
在测试完成后,我们将数码管连接到ESP32上。以下是连接方案示例:
公共引脚的接法取决于数码管的类型:
-
共阳极数码管:公共引脚连接到电源(VCC,3.3V或5V)。这种类型的数码管需要通过给各段位的引脚提供低电平(即接地)来点亮段位。
-
共阴极数码管:公共引脚连接到地(GND)。这种类型的数码管需要通过给各段位的引脚提供高电平(即接电源)来点亮段位。
假设以下引脚分配:
- A - GPIO 15
- B - GPIO 2
- C - GPIO 4
- D - GPIO 16
- E - GPIO 17
- F - GPIO 5
- G - GPIO 18
- DP(小数点) - GPIO 19
数码管显示逻辑
数码管每个数字所需的段位亮灭状态如下表:
数字 | A | B | C | D | E | F | G | DP |
---|---|---|---|---|---|---|---|---|
0 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 |
1 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 |
2 | 1 | 1 | 0 | 1 | 1 | 0 | 1 | 0 |
3 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | 0 |
4 | 0 | 1 | 1 | 0 | 0 | 1 | 1 | 0 |
5 | 1 | 0 | 1 | 1 | 0 | 1 | 1 | 0 |
6 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 0 |
7 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 |
8 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 |
9 | 1 | 1 | 1 | 1 | 0 | 1 | 1 | 0 |
在代码中将使用该段位状态表来控制数码管显示。
MicroPython代码实现
初始化GPIO引脚
首先,为ESP32上连接的每个段位定义一个GPIO引脚,并初始化为输出模式。
python">from machine import Pin
import time# 定义数码管段位引脚(A-G 和 DP分别连接GPIO引脚)
pins = {'A': Pin(15, Pin.OUT),'B': Pin(2, Pin.OUT),'C': Pin(4, Pin.OUT),'D': Pin(16, Pin.OUT),'E': Pin(17, Pin.OUT),'F': Pin(5, Pin.OUT),'G': Pin(18, Pin.OUT),'DP': Pin(19, Pin.OUT) # 小数点引脚
}# 判断数码管类型
is_common_anode = True # 设置为 True 表示共阳极,False 表示共阴极
数字显示字典
根据数码管类型,调整段位的高低电平。例如,共阳极数码管需要低电平点亮,而共阴极数码管需要高电平点亮。
python"># 数字的段位组合,1 表示点亮,0 表示熄灭
segments = {'0': [1, 1, 1, 1, 1, 1, 0, 0],'1': [0, 1, 1, 0, 0, 0, 0, 0],'2': [1, 1, 0, 1, 1, 0, 1, 0],'3': [1, 1, 1, 1, 0, 0, 1, 0],'4': [0, 1, 1, 0, 0, 1, 1, 0],'5': [1, 0, 1, 1, 0, 1, 1, 0],'6': [1, 0, 1, 1, 1, 1, 1, 0],'7': [1, 1, 1, 0, 0, 0, 0, 0],'8': [1, 1, 1, 1, 1, 1, 1, 0],'9': [1, 1, 1, 1, 0, 1, 1, 0]
}# 根据数码管类型调整段位的电平状态
def get_segment_state(state):return not state if is_common_anode else state
定义显示函数
编写一个函数,接受一个数字字符,根据数码管类型设置各段位的电平状态。
python">def display_digit(digit, dp=False):"""显示一个数字,并控制小数点"""if digit not in segments:print("无效数字")returnsegment_states = segments[digit]# 设置每个段位的状态for i, (seg, pin) in enumerate(pins.items()):state = segment_states[i] if i < 7 else dp # dp 为小数点控制pin.value(get_segment_state(state))
测试显示功能
依次循环显示0-9,并带小数点。
python">while True:for digit in '0123456789':display_digit(digit, dp=True) # 小数点显示time.sleep(1)display_digit(digit, dp=False) # 小数点熄灭time.sleep(0.5)
面向对象封装
将数码管显示功能封装为一个类,使其更具可复用性。
python">class SevenSegmentDisplay:def __init__(self, pin_map, is_common_anode=True):self.segments = {key: Pin(pin, Pin.OUT) for key, pin in pin_map.items()}self.is_common_anode = is_common_anodeself.numbers = {'0': [1, 1, 1, 1, 1, 1, 0, 0],'1': [0, 1, 1, 0, 0, 0, 0, 0],'2': [1, 1, 0, 1, 1, 0, 1, 0],'3': [1, 1, 1, 1, 0, 0, 1, 0],'4': [0, 1, 1, 0, 0, 1, 1, 0],'5': [1, 0, 1, 1, 0, 1, 1, 0],'6': [1, 0, 1, 1, 1, 1, 1, 0],'7': [1, 1, 1, 0, 0, 0, 0, 0],'8': [1, 1, 1, 1, 1, 1, 1, 0],'9': [1, 1, 1, 1, 0, 1, 1, 0]}def display(self, digit, dp=False):if digit not in self.numbers:print("Invalid digit")returnfor i, (seg, pin) in enumerate(self.segments.items()):state = self.numbers[digit][i] if i < 7 else dppin.value(not state if self.is_common_anode else state)
使用方式:
python">display = SevenSegmentDisplay(pins, is_common_anode=True)
while True:for digit in '0123456789':display.display(digit, dp=True)time.sleep(1)
总结
通过本教程,我们深入学习了单位数码管的控制原理,掌握了使用ESP32和MicroPython驱动数码管的完整流程。从判断数码管类型到封装类实现数码管显示,这一系列操作将为你提供坚实的硬件控制基础。