18 19 SPI接口的74HC595驱动数码管实验

本文详细介绍了如何利用74HC595串行移位寄存器实现串转并,级联应用,以及如何通过Verilog编程驱动数码管,包括时序控制和具体代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 串行移位寄存器原理(以四个移位寄存器为例)

1. 通过移位寄存器实现串转并:一个数据输入端口可得到四位并行数据。

通过给data输送0101数据,那么在经过四个时钟周期后,与data相连的四个寄存器的输出端口得到了0101这样的数据,然后我们将latch信号拉高,在下一个时钟周期,D0, D1, D2, D3同时分别获得了这四个数据1010。(其中DFF指D触发器,LATCH信号也可连接锁存器来控制输出)

2. 级联

级联:数据输出端口作为另外的移位寄存器数据端的输入。

2.使用74HC595驱动数码管

1. ACX720上不是直接用fpga的管脚驱动数码管的,而是用74HC595这样的一种串转并的串行移位寄存器来驱动的

2.1 74HC595端口图:

2.2 74HC595时序图

 2.3 74HC595时钟工作频率

取工作频率为12.5MHz。

3. 使用74HC595芯片驱动数码管的verilog代码实现

1.要完成的模块为hc595_driver,实现将16位并行数据转为串行数据发送至74HC595中,实现三线制控制数码管。因此我们的输入需遵循74HC595时序图。

3.1 设

### 使用ESP32驱动数码管的实现方法 #### 方法一:直接连接数码管至ESP32 GPIO引脚 当使用共阴极数码管时,可以将其各段(a, b, c, d, e, f, g 和 dp)分别连接到 ESP32 的 GPIO 引脚上。为了保护数码管并防止电流过大,通常会在每条数据线上串联一个约 220 欧姆的电阻[^2]。 以下是基于 MicroPython 实现的代码示例: ```python from machine import Pin import time # 定义数码管各段对应的GPIO引脚 segments = { 'a': Pin(18, Pin.OUT), 'b': Pin(19, Pin.OUT), 'c': Pin(21, Pin.OUT), 'd': Pin(5, Pin.OUT), 'e': Pin=Pin(17, Pin.OUT), 'f': Pin(16, Pin.OUT), 'g': Pin(4, Pin.OUT) } digit_pins = [ Pin(2, Pin.OUT), # 数码管第1位选通 Pin(15, Pin.OUT) # 数码管第2位选通 ] def display_digit(digit_index, number): """ 显示指定位置上的数字 """ segment_map = { 0: ['a', 'b', 'c', 'd', 'e', 'f'], 1: ['b', 'c'], 2: ['a', 'b', 'd', 'e', 'g'], 3: ['a', 'b', 'c', 'd', 'g'], 4: ['b', 'c', 'f', 'g'], 5: ['a', 'c', 'd', 'f', 'g'], 6: ['a', 'c', 'd', 'e', 'f', 'g'], 7: ['a', 'b', 'c'], 8: ['a', 'b', 'c', 'd', 'e', 'f', 'g'], 9: ['a', 'b', 'c', 'd', 'f', 'g'] } digit_pins[digit_index].on() # 启用当前数码管的位置 for seg in segments.keys(): if seg in segment_map[number]: segments[seg].on() else: segments[seg].off() while True: for i in range(len(digit_pins)): display_digit(i, (i + 1)) # 循环显示不同数字 time.sleep_ms(500) for pin in digit_pins: pin.off() # 关闭所有数码管 ``` 此代码实现了在两个数码管之间切换显示不同的数字,并通过 `time.sleep` 控制刷新频率[^1]。 --- #### 方法二:利用移位寄存器 HC595 驱动多位数码管 对于多于两位以上的数码管或者更复杂的场景下,推荐采用移位寄存器(如 HC595)。这种方法能够显著减少所需的 GPIO 引脚数量[^3]。 下面是具体的 Python 示例代码片段用于配置和控制 HC595 芯片来点亮多个七段数码管: ```python from machine import Pin import time class ShiftRegisterSevenSegment: def __init__(self, data_pin, clock_pin, latch_pin): self.data_pin = Pin(data_pin, Pin.OUT) self.clock_pin = Pin(clock_pin, Pin.OUT) self.latch_pin = Pin(latch_pin, Pin.OUT) def shift_out(self, value): self.latch_pin.low() bit_mask = 1 << 7 while(bit_mask != 0): self.clock_pin.low() if(value & bit_mask): self.data_pin.high() else: self.data_pin.low() self.clock_pin.high() bit_mask >>= 1 self.latch_pin.high() sr_seven_seg = ShiftRegisterSevenSegment(data_pin=13, clock_pin=14, latch_pin=12) try: while True: sr_seven_seg.shift_out(int('0x3F', base=16)) # Displaying the character '0' time.sleep(1) except KeyboardInterrupt: pass finally: sr_seven_seg.shift_out(0x00) # Clear all outputs when done. ``` 上述程序展示了如何设置一个类对象以简化向 HC595 发送命令的过程,从而轻松更新所连结之数码管的内容。 --- #### 方法三:封装函数提高可读性和复用率 如果希望进一步优化代码结构,则可以通过创建自定义库文件或将逻辑抽象成独立模块的形式完成。这种方式不仅便于维护还利于移植到其他项目当中去[^4]。 例如,在单独的一个 `.py` 文件里编写如下内容作为工具集的一部分供调用者导入即可: ```python # seven_segment_utils.py def get_segments_for_number(number): mapping = { ... } # Similar to previous examples' mappings but expanded here as needed. result = [] for char in str(number).zfill(4): try: result.append(mapping[int(char)]) except KeyError: raise ValueError(f"Unsupported character '{char}' encountered.") return tuple(result[::-1]) # Reverse order so LSB is first sent out by SPI/shift register logic later on... ``` 随后主应用程序只需简单地引入该实用程序包中的辅助功能即可快速构建起完整的解决方案框架体系。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值