引言

本文将介绍如何使用MicroPython在Raspberry Pi Pico上控制74HC595移位存器驱动7段数码符,并络合I2C接口读取和写入24LC64 EEPROM数据,实现简单的随机数存储、校验以及错误显示功能。以下是详细的程序分析和实现细节。


硬件连接

74HC595与Raspberry Pi Pico的连接:

  • SCLK (时钟) -> GPIO16
  • RCLK (锁存) -> GPIO17
  • DATA (数据) -> GPIO18

EEPROM (24LC64) 与 I2C:

  • SCL -> GPIO3
  • SDA -> GPIO2

程序分析

1. 数码符段码映射

通过共阳极数码符的编码表(digits),定义了数字 0-9 的段码。额外定义了横板(dash)和错误(err)的显示段码:

digits = [0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90]
dash = 0xBF
err = [0x86, 0xAF, 0xAF, 0x7F]
2. EEPROM读写操作

程序初始化I2C接口并扫描设备,获取24LC64 EEPROM的地址:

i2c = I2C(1, scl=Pin(3), sda=Pin(2), freq=400000)
EEPROM_ADDR = scan_i2c()

通过以下函数实现16位地址数据的读写:

  • 写入数据:

    def write_eeprom(addr, value):
      addr_high = (addr >> 8) & 0xFF
      addr_low = addr & 0xFF
      value_high = (value >> 8) & 0xFF
      value_low = value & 0xFF
      i2c.writeto(EEPROM_ADDR, bytes([addr_high, addr_low, value_high, value_low]))
      time.sleep(0.01)
  • 读取数据:

    def read_eeprom(addr):
      addr_high = (addr >> 8) & 0xFF
      addr_low = addr & 0xFF
      i2c.writeto(EEPROM_ADDR, bytes([addr_high, addr_low]))
      data = i2c.readfrom(EEPROM_ADDR, 2)
      return (data[0] << 8) | data[1]
3. 74HC595移位存器控制

移位存器的控制通过模拟SPI接口实现,包括数据移位与显示锁存:

def shift_out(value):
    for i in range(8):
        data.value((value >> (7 - i)) & 1)
        sclk.value(0)
        sclk.value(1)

通过发送段选和位选信号控制数码符显示:

def display_digit(no, num):
    shift_out(digits[num])  # 发送段选信号
    shift_out(0x01 << (4 - no))  # 发送位选信号
    rclk.value(0)
    rclk.value(1)
4. 模式控制与定时器

程序设定了3种显示模式:

  • DISP_MODE_DIGIT:显示随机生成的4位数字;
  • DISP_MODE_DASH:显示横板,用于等待校验结果;
  • DISP_MODE_ERROR:显示错误信息。

定时器每1ms调用一次回调函数,用于切换模式和控制逻辑:

def time_tick_1ms(timer):
    global tt, dispMode, new_number
    tt += 1
    if dispMode == DISP_MODE_DIGIT or dispMode == DISP_MODE_ERROR:
        if tt > 1000:
            tt = 0
            new_number = random.randint(1000, 9999)
            write_eeprom(EEPROM_MEM_ADDR, new_number)
            dispMode = DISP_MODE_DASH
    elif dispMode == DISP_MODE_DASH:
        if tt > 500:
            tt = 0
            read_number = read_eeprom(EEPROM_MEM_ADDR)
            dispMode = DISP_MODE_DIGIT if read_number == new_number else DISP_MODE_ERROR
5. 主循环

主循环根据当前显示模式调用相应的显示函数:

def main():
    while True:
        if dispMode == DISP_MODE_DIGIT:
            display_digit(1, new_number // 1000)
            display_digit(2, (new_number % 1000) // 100)
            display_digit(3, (new_number % 100) // 10)
            display_digit(4, new_number % 10)
        elif dispMode == DISP_MODE_DASH:
            display_dash()
        elif dispMode == DISP_MODE_ERROR:
            display_err()
main()

程序运行效果

  1. 启动后扫描I2C设备,确认连接的EEPROM地址。
  2. 定期生成随机数并写入EEPROM。
  3. 验证读取数据是否与写入数据一致:

    • 一致时显示随机数;
    • 不一致时显示“Err”错误信息。

完整源码

74HC595 4-digits LED.zip

Last modification:January 19, 2025
If you think my article is useful to you, please feel free to appreciate