使用 MicroPython 控制 74HC595 和 EEPROM 的项目解析
引言本文将介绍如何使用MicroPython在Raspberry Pi Pico上控制74HC595移位存器驱动7段数码符，并络合I2C接口读取和写入24LC64 EEPROM数据，实现简单的随机数存储、校验以及错误显示功能。以下是详细的程序分析和实现细节。硬件连接74HC595与Raspberry Pi Pico的连接：SCLK (时钟) -> GPIO16RCLK (锁存) -> GPIO17DATA (数据) -> GPIO18EEPROM (24LC64) 与 I2C：SCL -> GPIO3SDA -> 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_ERROR5. 主循环主循环根据当前显示模式调用相应的显示函数：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()程序运行效果启动后扫描I2C设备，确认连接的EEPROM地址。定期生成随机数并写入EEPROM。验证读取数据是否与写入数据一致：一致时显示随机数；不一致时显示“Err”错误信息。完整源码74HC595 4-digits LED.zip系列文章用Raspberry Pi Pico驱动MAX7219 8x8 LED点阵并实现呼吸灯效果使用MicroPython控制Raspberry Pi Pico与MAX7219和EEPROM的应用使用 MicroPython 控制 74HC595 和 EEPROM 的项目解析【当前文章】
使用MicroPython控制Raspberry Pi Pico与MAX7219和EEPROM的应用
本文将介绍一个在Raspberry Pi Pico上运行的MicroPython程序，该程序控制一个8x8 LED矩阵（MAX7219），并通过I2C与EEPROM进行数据交互。程序会随机生成一个数字，将其存储到EEPROM中，并在LED矩阵上显示相应的数字。如果从EEPROM读取的值与存储的值匹配，则显示数字；如果不匹配，则显示叉号。效果完整源码eeprom_24LC64_pico.zip使用的组件：Raspberry Pi Pico：一款基于RP2040芯片的小型微控制器开发板。MAX7219 8x8 LED矩阵：一种常见的显示模块，用于显示数字或字符。24LC64 EEPROM：一种通过I2C通信的串行EEPROM，用于数据存储。关键功能：使用SPI协议与MAX7219通信：MAX7219 LED矩阵通过SPI协议进行控制。通过I2C与EEPROM交互：程序使用I2C协议与24LC64 EEPROM进行读写操作。随机生成数字并存储：程序会生成一个随机数字并将其写入EEPROM。显示效果：根据读取的EEPROM值来决定LED矩阵显示数字或叉号。程序分析from machine import Pin, SPI, I2C from max7219 import max7219 import time import random # SPI接口设置 spi = SPI(1, baudrate=10000000, polarity=0, phase=0) cs = Pin(0, Pin.OUT) # I2C接口设置 (修改为I2C1，SDA=GPIO2, SCL=GPIO3) i2c = I2C(1, scl=Pin(3), sda=Pin(2), freq=400000)首先，程序初始化了SPI接口（用于与MAX7219进行通信）和I2C接口（用于与EEPROM进行通信）。SPI接口使用的是SPI(1)，波特率设定为10MHz，极性和相位均为0。I2C接口设置为I2C1，使用GPIO2作为SDA，GPIO3作为SCL。def scan_i2c(): devices = i2c.scan() if len(devices) == 0: print("没有检测到I2C设备。") return None elif len(devices) == 1: print(f"检测到1个设备，地址: 0x{devices[0]:02X}") return devices[0] else: print("检测到多个I2C设备:") for i, device in enumerate(devices): print(f"{i + 1}: 0x{device:02X}") while True: try: choice = int(input("请选择设备 (输入序号): ")) - 1 if 0 <= choice < len(devices): return devices[choice] else: print("无效选择，请重试。") except ValueError: print("请输入有效数字。")scan_i2c函数用于扫描I2C总线上连接的设备。该函数会返回设备的地址，如果未检测到设备或检测到多个设备，程序会给出提示让用户自行选择一个设备。如果只检测到一个设备那么程序会直接使用。EEPROM_ADDR = scan_i2c() if EEPROM_ADDR is None: raise Exception("未检测到EEPROM设备，程序终止。")通过调用scan_i2c函数来确定连接的EEPROM设备。如果未找到设备，程序会抛出异常并终止。# 初始化MAX7219 matrix = max7219.Matrix8x8(spi, cs, 1) matrix.brightness(0) # 显示方向（1=0°，2=90°，3=180°，4=270°） display_direction = 2 # 默认顺时针旋转90度在此部分，程序初始化了MAX7219模块并设置亮度为最低。display_direction变量决定显示的旋转方向，默认值为2，表示旋转90度。# 定义数字0-9、问号和叉的图案 digits = [ [0x3E, 0x63, 0x67, 0x6F, 0x7B, 0x73, 0x63, 0x3E], # 0 [0x0C, 0x1C, 0x3C, 0x0C, 0x0C, 0x0C, 0x0C, 0x3F], # 1 [0x3E, 0x63, 0x03, 0x0E, 0x3C, 0x70, 0x63, 0x7F], # 2 [0x3E, 0x63, 0x03, 0x1E, 0x03, 0x03, 0x63, 0x3E], # 3 [0x06, 0x0E, 0x1E, 0x36, 0x66, 0x7F, 0x06, 0x06], # 4 [0x7F, 0x60, 0x7E, 0x03, 0x03, 0x03, 0x63, 0x3E], # 5 [0x1E, 0x30, 0x60, 0x7E, 0x63, 0x63, 0x63, 0x3E], # 6 [0x7F, 0x63, 0x06, 0x0C, 0x18, 0x18, 0x18, 0x18], # 7 [0x3E, 0x63, 0x63, 0x3E, 0x63, 0x63, 0x63, 0x3E], # 8 [0x3E, 0x63, 0x63, 0x63, 0x3F, 0x03, 0x06, 0x3C] # 9 ] question_mark = [0x3E, 0x63, 0x03, 0x0E, 0x1C, 0x00, 0x1C, 0x1C] # ? cross_mark = [0x63, 0x36, 0x1C, 0x08, 0x1C, 0x36, 0x63, 0x00] # X在这部分代码中，定义了数字0-9、问号和叉号的图案。这些图案将以字节的形式存储，每个数字或符号由8行数据表示。def rotate_pattern(pattern, direction): rotated = [[0] * 8 for _ in range(8)] for y in range(8): for x in range(8): bit = (pattern[y] >> (7 - x)) & 1 if direction == 1: rotated[y][x] = bit elif direction == 2: rotated[x][7 - y] = bit elif direction == 3: rotated[7 - y][7 - x] = bit elif direction == 4: rotated[7 - x][y] = bit return [int("".join(str(bit) for bit in row), 2) for row in rotated]rotate_pattern函数将数字或符号图案根据direction参数的值进行旋转。旋转方向包括：0°（不旋转）、90°、180°和270°。def display_pattern(pattern): rotated = rotate_pattern(pattern, display_direction) matrix.fill(0) for y in range(8): matrix.buffer[y] = rotated[y] matrix.show()display_pattern函数用于在LED矩阵上显示旋转后的图案。def write_eeprom(addr, value): addr_high = (addr >> 8) & 0xFF addr_low = addr & 0xFF i2c.writeto(EEPROM_ADDR, bytes([addr_high, addr_low, value])) 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])) return int.from_bytes(i2c.readfrom(EEPROM_ADDR, 1), 'big')write_eeprom和read_eeprom函数分别用于向EEPROM写入数据和从EEPROM读取数据。last_number = -1 while True: new_number = random.choice([i for i in range(10) if i != last_number]) last_number = new_number write_eeprom(EEPROM_MEM_ADDR, new_number) display_pattern(question_mark) time.sleep(0.5) read_number = read_eeprom(EEPROM_MEM_ADDR) if read_number == new_number: display_pattern(digits[read_number]) else: display_pattern(cross_mark) time.sleep(1)主循环中，程序生成一个新的随机数字（不等于上一个数字），将其写入EEPROM。然后显示一个问号，等待0.5秒后从EEPROM读取数据并与存储的数字进行比较。如果相同，则显示对应的数字；否则，显示叉号。整个过程每秒执行一次。总结该程序展示了如何使用MicroPython与Raspberry Pi Pico进行硬件编程，实现了与MAX7219 LED矩阵和24LC64 EEPROM的交互。通过SPI控制LED矩阵显示数字，通过I2C与EEPROM进行数据读写，能够实现数字存储和显示的功能，适用于数字展示、测试等应用场景。系列文章用Raspberry Pi Pico驱动MAX7219 8x8 LED点阵并实现呼吸灯效果使用MicroPython控制Raspberry Pi Pico与MAX7219和EEPROM的应用【当前文章】使用 MicroPython 控制 74HC595 和 EEPROM 的项目解析
用Raspberry Pi Pico驱动MAX7219 8x8 LED点阵并实现呼吸灯效果
前言Raspberry Pi Pico是一款功能强大的微型开发板，搭配MicroPython能够轻松实现各种硬件控制。本篇博客将介绍如何使用Pico驱动MAX7219 8x8 LED点阵屏，依次循环显示数字0-9，并加入亮度呼吸效果和可调显示方向。效果完整源码max7219-By-ChatGPT.zip硬件准备Raspberry Pi PicoMAX7219 8x8 LED点阵模块杜邦线若干Pico引脚定义图接线说明Pico引脚MAX7219引脚GPIO11 (SPI1 MOSI) (SPI1 TX) (Pin15)DINGPIO10 (SPI1 SCK) (Pin14)CLKGPIO0 (Pin1)CSGNDGND3.3VVCC软件准备安装MicroPython固件至Pico（官方默认固件就可以）使用Thonny或其他支持MicroPython的IDE下载max7219库并上传到Pico模拟驱动器的根目录：max7219.py功能实现主要功能：循环显示数字0-9，每个数字停顿1秒。呼吸灯亮度效果（最大亮度可调）。通过变量设置显示方向（0°/90°/180°/270°）。代码实现将以下代码保存为main.py文件并上传或覆盖根目录原来的main.py文件。上电时会自动寻找并执行根目录下的main.pyfrom machine import Pin, SPI from max7219 import max7219 import time # SPI接口设置 spi = SPI(1, baudrate=10000000, polarity=0, phase=0) cs = Pin(0, Pin.OUT) # 初始化MAX7219 matrix = max7219.Matrix8x8(spi, cs, 1) matrix.brightness(0) # 定义数字0-9的图案 digits = [ [0x3E, 0x63, 0x67, 0x6F, 0x7B, 0x73, 0x63, 0x3E], # 0 [0x0C, 0x1C, 0x3C, 0x0C, 0x0C, 0x0C, 0x0C, 0x3F], # 1 [0x3E, 0x63, 0x03, 0x0E, 0x3C, 0x70, 0x63, 0x7F], # 2 [0x3E, 0x63, 0x03, 0x1E, 0x03, 0x03, 0x63, 0x3E], # 3 [0x06, 0x0E, 0x1E, 0x36, 0x66, 0x7F, 0x06, 0x06], # 4 [0x7F, 0x60, 0x7E, 0x03, 0x03, 0x03, 0x63, 0x3E], # 5 [0x1E, 0x30, 0x60, 0x7E, 0x63, 0x63, 0x63, 0x3E], # 6 [0x7F, 0x63, 0x06, 0x0C, 0x18, 0x18, 0x18, 0x18], # 7 [0x3E, 0x63, 0x63, 0x3E, 0x63, 0x63, 0x63, 0x3E], # 8 [0x3E, 0x63, 0x63, 0x63, 0x3F, 0x03, 0x06, 0x3C] # 9 ] # 显示方向（1=0°，2=90°，3=180°，4=270°） display_direction = 1 # 最大亮度（0-15） max_brightness = 10 # 呼吸灯效果 def breathing_effect(): for b in range(0, max_brightness + 1): matrix.brightness(b) time.sleep(0.05) for b in range(max_brightness, -1, -1): matrix.brightness(b) time.sleep(0.05) # 循环显示数字0-9 while True: for digit in digits: matrix.fill(0) matrix.show() start_time = time.ticks_ms() while time.ticks_diff(time.ticks_ms(), start_time) < 1000: breathing_effect()系列文章用Raspberry Pi Pico驱动MAX7219 8x8 LED点阵并实现呼吸灯效果【当前文章】使用MicroPython控制Raspberry Pi Pico与MAX7219和EEPROM的应用使用 MicroPython 控制 74HC595 和 EEPROM 的项目解析