注意

这是最新开发分支配套的文档,可能包含已发布版本中尚未提供的功能。如果您要查看特定版本的文档,请使用左侧的下拉菜单并选择所需要的版本。

SPI 使用教程#

什么是 SPI?#

SPI(Serial Peripheral Interface) 是一种高速全双工串行通信协议,常用于与外设(如 Flash、LCD、传感器、DAC/ADC 芯片等)通信。其典型结构包括:

  • 主设备(Master):控制通信(K230 为主)

  • 从设备(Slave):响应主机命令

  • 信号线

    • MOSI:主机输出 / 从机输入

    • MISO:主机输入 / 从机输出

    • SCLK:时钟

    • CS/SS:片选信号

K230 SPI 模块特点#

  • 内置 3 个 SPI 控制器

  • 支持配置:

    • 通信速率(如 5 MHz)

    • 时钟极性 polarity

    • 时钟相位 phase

    • 数据位宽(默认为 8 位)

  • 可通过 FPIOA 灵活映射引脚

应用示例:读取 SPI Flash 的 JEDEC ID#

此示例展示 K230 使用 SPI 读取外接 Flash 存储器的 ID,同时进行擦除、写入和读取验证。

示例代码#

from machine import FPIOA, Pin, SPI
import time

# ========== 引脚绑定 ========== #
fpioa = FPIOA()
fpioa.set_function(14, FPIOA.GPIO14)      # CS 引脚
fpioa.set_function(15, FPIOA.QSPI0_CLK)   # SPI 时钟
fpioa.set_function(16, FPIOA.QSPI0_D0)    # MOSI
fpioa.set_function(17, FPIOA.QSPI0_D1)    # MISO

# ========== 初始化引脚 ========== #
cs = Pin(14, Pin.OUT, pull=Pin.PULL_NONE, drive=15)
cs.value(1)  # 默认拉高(不选中)

# ========== 初始化 SPI ========== #
spi = SPI(1, baudrate=1_000_000, polarity=0, phase=0, bits=8)

发送指令与读取 ID#

def read_id():
    cs.value(0)
    spi.write_readinto(bytearray([0x9F, 0xFF, 0xFF, 0xFF]), read_buf := bytearray(4))
    cs.value(1)
    print("JEDEC ID:", [hex(b) for b in read_buf])

写入/擦除操作(以 4KB Sector 为单位)#

def write_enable():
    cs.value(0)
    spi.write(bytearray([0x06]))  # 写使能命令
    cs.value(1)

def wait_busy():
    while True:
        cs.value(0)
        spi.write(bytearray([0x05]))  # 读取状态寄存器
        busy = spi.read(1)[0] & 0x01
        cs.value(1)
        if not busy:
            break
        time.sleep(0.05)

def erase_sector(addr):
    write_enable()
    cs.value(0)
    spi.write(bytearray([0x20, (addr >> 16) & 0xFF, (addr >> 8) & 0xFF, addr & 0xFF]))
    cs.value(1)
    wait_busy()

写入数据 + 读取验证#

def page_program(addr, data):
    assert len(data) <= 256  # 写入最大 256 字节
    write_enable()
    cs.value(0)
    cmd = bytearray([0x02, (addr >> 16) & 0xFF, (addr >> 8) & 0xFF, addr & 0xFF])
    spi.write(cmd + data)
    cs.value(1)
    wait_busy()

def read_data(addr, length):
    cs.value(0)
    cmd = bytearray([0x03, (addr >> 16) & 0xFF, (addr >> 8) & 0xFF, addr & 0xFF])
    spi.write(cmd)
    data = spi.read(length)
    cs.value(1)
    return data

测试流程:完整 Flash 操作流程#

test_addr = 0x000000
test_data = bytearray(b"1234567890")

read_id()  # 读取 JEDEC ID

print("擦除 4KB 扇区...")
erase_sector(test_addr)

print("写入数据...")
page_program(test_addr, test_data)

print("读取验证...")
read_back = read_data(test_addr, len(test_data))
print("READ_BACK:", read_back.decode())

SPI 关键配置说明#

参数

说明

baudrate

通信速率(单位 Hz),如 1_000_000 表示 1 MHz

polarity

时钟极性:0 = 空闲时为低电平,1 = 空闲时为高电平

phase

时钟相位:0 = 第一个边沿采样,1 = 第二个边沿采样

bits

每帧数据位数,常用为 8 位

cs

片选信号由用户手动控制(Pin 对象)

应用场景#

  • Flash、EEPROM 存储器读写

  • OLED、TFT 等显示驱动

  • 传感器通信(如陀螺仪、温湿度、加速度等)

  • ADC/DAC 数模转换器控制

  • 多设备总线管理(通过多个 CS 控制多从机)

注意事项#

事项

说明

引脚映射

使用 FPIOA 进行 SPI 相关引脚的映射,确保与外设连接正确

通信协议匹配

注意 SPI 设备的 CPOL/CPHA 配置必须匹配(极性、相位)

写入限制

Flash 写入通常需 4KB 对齐擦除,最多每次写入 256 字节页数据

读取指令不同

有些 SPI 设备使用不同的命令(如 0x9F / 0x90 读取 JEDEC ID)

多片设备管理

多个 SPI 从设备需使用不同的 CS 引脚进行片选

延伸阅读#

评论列表
条评论
登录