TobudOS 上的 MicroPython pyb.SPI 外设编程指南:从总线初始化到全双工收发

发布时间:2026/10/12 2:11:25
TobudOS 上的 MicroPython pyb.SPI 外设编程指南:从总线初始化到全双工收发 【免费下载链接】TobudOSTobudOS 是面向物联网领域开发的实时操作系统早期版本基于腾讯自研的物联网操作系统TencentOS Tiny2020年由腾讯捐赠到开放原子开源基金会进行孵化2023年正式更名为TobudOSTobudOS具有低功耗低资源占用模块化安全可靠等特点可有效提升物联网终端产品开发效率提供精简的 RTOS 内核内核组件可裁剪可配置可快速移植到多种主流 MCU (如 STM32 全系列) 及模组芯片上。而且基于 RTOS 内核提供了丰富的物联网组件内部集成主流物联网协议栈如 CoAP/MQTT/TLS/DTLS/LoRaWAN/NB-IoT 等可助力物联网终端设备及业务快速接入物联网云平台。项目地址https://gitcode.com/openatomfoundation/TobudOS点击查看免费下载导读本文以 pyb.SPI 模块文档 为核心系统讲解在 TobudOS 物联网实时操作系统上使用 MicroPython 驱动 SPI 总线的完整方法如何构造 SPI 对象、如何通过init()配置时钟速率、极性、相位、位宽、字节序与 CRC如何用send/recv/send_recv完成单工与全双工数据传输并深入 TobudOS 移植层源码揭示machine.SPI与内核 HAL 之间的底层调用关系。读完本文你将能够在 TobudOS 的 MicroPython 环境中独立编写驱动 SPI 外设如 Flash、LCD、传感器的脚本并理解从 Python API 到硬件寄存器的完整数据通路。SPI 协议与 pyb.SPI 类概览SPISerial Peripheral Interface是一种由控制器Controller驱动的串行通信协议。在物理层面它至少需要 3 根信号线SCK串行时钟线由控制器产生MOSI控制器输出、外设输入的数据线MISO外设输出、控制器输入的数据线。与 I2C 类似SPI 也是设备间通信的总线协议二者的使用模型非常接近——先创建总线对象再初始化然后收发数据。主要区别在于初始化参数SPI 需要配置模式、时钟速率、极性与相位等参数而这些参数直接决定了时序协议是否与外设匹配。在 TobudOS 的 MicroPython 移植中SPI 硬件类以machine.SPI形式注册见 modmachine.c 中的MP_QSTR_SPI其 API 与 pyb.SPI 文档描述保持同源。文档给出了最简洁的初始化示例from pyb import SPI spi SPI(1, SPI.CONTROLLER, baudrate600000, polarity1, phase0, crc0x7)其中唯一必需的位置参数是mode即SPI.CONTROLLER控制器或SPI.PERIPHERAL外设其余参数均可选并在创建对象时完成总线初始化。构造 SPI 对象总线编号与物理引脚通过pyb.SPI(bus, ...)可在指定总线上构造 SPI 对象。bus可以是整数1或2也可以是位置别名X或Y不带额外参数时对象仅被创建而不执行初始化——它保留该总线上一次初始化如果存在的设置带额外参数时创建的同时会调用init()完成初始化参数含义与init()完全一致。以 Pyboard 为例两条 SPI 总线的物理引脚映射如下总线位置NSSSCKMISOMOSI对应 STM32 引脚SPI(1)XX5X6X7X8PA4 / PA5 / PA6 / PA7SPI(2)YY5Y6Y7Y8PB12 / PB13 / PB14 / PB15文档特别说明当前 SPI 驱动并未使用 NSS 引脚因此该引脚空闲可留作其他用途例如用普通 GPIO 手动控制片选。这一设计在驱动外设时非常实用——你可以自行决定片选信号的拉低/拉高时机。在 TobudOS 的板级移植中SPI 总线的数量由板级配置文件决定。例如 BearPi 开发板的 mpconfigboard.h 中定义了MICROPY_HW_SPI_NUM 4表示该板可用的 SPI 硬件实例数为 4对应地machine_hw_spi.c 中通过machine_hard_spi_obj_all[MICROPY_HW_SPI_NUM]静态分配对象池。因此在不同开发板上可用的总线编号以该板的mpconfigboard.h为准。init()SPI 总线初始化参数详解init()是 SPI 配置的核心入口完整签名如下SPI.init(mode, baudrate328125, *, prescaler-1, polarity1, phase0, bits8, firstbitSPI.MSB, tiFalse, crcNone)各参数含义与取值范围如下表参数取值说明modeSPI.CONTROLLER/SPI.PERIPHERAL总线工作模式必选参数baudrate整数SCK 时钟频率仅对控制器模式有意义默认 328125prescaler-1 或 2/4/8/16/32/64/128/256由 APB 总线频率推导 SCK 的分频系数一旦指定将覆盖baudratepolarity0 或 1空闲时钟线的电平0 为低电平空闲1 为高电平空闲phase0 或 1数据采样边沿0 在第一个时钟沿采样1 在第二个时钟沿采样bits8 或 16每个传输字的位数firstbitSPI.MSB/SPI.LSB先发送最高有效位还是最低有效位tiTrue/False为True时使用 TI德州仪器信号约定否则使用 Motorola 约定crcNone或多项式None表示不启用 CRC否则传入多项式指定符其中polarity与phase的组合即 SPI 模式 03决定了控制器与外设之间的时序握手方式是驱动能否正常通信的关键。crc用于需要校验的链路普通场景传None即可。关于时钟频率的重要说明文档强调SPI 实际时钟频率不一定会等于请求的baudrate。原因在于硬件只支持APB 总线频率除以分频系数的离散频率集合可用的分频系数为 2、4、8、16、32、64、128、256。在 Pyboard 上SPI(1)挂载于 AHB2SPI(2)挂载于 AHB1两者 APB 时钟源不同可参考pyb.freq查询。因此当需要对 SPI 时钟频率进行精确控制时应直接指定prescaler而不是baudrate。打印 SPI 对象时会显示计算得到的实际波特率与选中的分频系数可用于核对配置是否符合预期 print(spi) SPI(1, SPI.CONTROLLER, baudrate600000, polarity1, phase0, bits8)数据收发send、recv 与 send_recvSPI 是同步全双工协议时钟由控制器产生因此收发天然可以同时进行。pyb.SPI 提供三个基本方法SPI.send(send, *, timeout5000)向总线发送数据。send可以是单个整数发送 1 个字节或缓冲区对象如bytes、bytearray。timeout为等待发送完成的超时时间毫秒。返回值恒为Nonespi.send(0xA5) # 发送单个字节 spi.send(b\x01\x02\x03) # 发送 3 个字节SPI.recv(recv, *, timeout5000)从总线接收数据。recv可以是整数表示要接收的字节数或可变缓冲区接收到的字节将写入其中。返回规则若recv是整数则返回一个包含所收字节的新缓冲区若recv是缓冲区则返回传入的同一个缓冲区原地填充。data spi.recv(4) # 接收 4 字节返回新 bytes 对象 buf bytearray(4) spi.recv(buf) # 接收 4 字节写入 buf返回 bufSPI.send_recv(send, recvNone, *, timeout5000)同时发送与接收这是 SPI 全双工能力的直接体现。send为待发送数据整数或缓冲区recv为接收缓冲区可以省略此时自动新建缓冲区也可以与send是同一个缓冲区原地收发。返回值是包含接收字节的缓冲区data spi.send_recv(b1234) # 发送 4 字节并接收 4 字节 buf bytearray(4) spi.send_recv(b1234, buf) # 发送 4 字节接收结果写入 buf spi.send_recv(buf, buf) # 以 buf 为源同时收发 4 字节这种发送即接收的写法在读写 Flash、LCD 等外设时非常常见向从设备写入命令字节的同时读回状态或数据。常量模式与位序pyb.SPI 提供四个类常量常量用途SPI.CONTROLLER初始化总线为控制器模式SPI.PERIPHERAL初始化总线为外设模式SPI.MSB先传输最高有效位默认SPI.LSB先传输最低有效位mode与firstbit参数直接引用这些常量避免手写魔法数字。总线关闭与对象生命周期SPI.deinit()用于关闭 SPI 总线释放硬件资源。在 TobudOS 移植实现中deinit对应调用tos_hal_spi_deinit并复位初始化标记见 machine_hw_spi.c而init()在已初始化状态下重复调用会抛出OSError(SPI(%u) has been initialized)tos_hal_spi_init返回非 0 时则抛出ValueError(SPI(%u) doesnt exist)——这解释了 测试用例 中创建非法总线编号如 -1、0会捕获ValueError的原因。底层实现从 machine.SPI 到 TobudOS HALpyb.SPI 文档描述的是类 API 契约而 TobudOS 仓库中的实际移植位于 machine_hw_spi.c它揭示了一条清晰的调用链使能开关该文件整体受#if MICROPY_PY_MACHINE_SPI保护第 28 行。在 mpconfigport.h 中MP_USING_MACHINE_SPI宏会展开为MICROPY_PY_MACHINE_SPI (1)与MICROPY_PY_MACHINE_SOFTSPI (1)即硬件 SPI 与软件 SPI 同时启用。对象模型machine_hard_spi_obj_t内嵌了 HAL 层句柄hal_spi_t spi与端口号hal_spi_port_t port第 41-48 行并将所有 SPI 实例静态分配到machine_hard_spi_obj_all[MICROPY_HW_SPI_NUM]对象池中。初始化init()内部调用tos_hal_spi_init(self-spi, self-port)把 Python 层的总线编号直接映射为 HAL 端口第 108 行。数据传输核心的machine_hard_spi_transfer调用tos_hal_spi_transfer(self-spi, src, dest, len, timeout)完成一次全双工传输超时按timeout len * timeout_char随长度动态计算第 134-137 行。模块注册machine_hard_spi_type以MP_QSTR_SPI名字挂入 machine 模块全局表modmachine.c并通过mp_machine_spi_locals_dict复用标准 MicroPython SPI 方法表定义于 extmod/machine_spi.c。也就是说pyb.SPI文档中的init / deinit / send / recv / send_recv语义在 TobudOS 移植中由machine.SPI通过tos_hal_spi_*系列接口落到各芯片厂商驱动如 STM32 HAL、GD32 标准库等之上最终驱动硬件寄存器。测试用例API 行为验证仓库自带的测试 tests/pyb/spi.py 覆盖了 SPI 对象的主要行为可当作入门参考按编号创建与非法编号校验对 -1、0、1、2 逐个尝试SPI(bus)非法的抛出ValueError多种初始化方式SPI(1, SPI.CONTROLLER)、带baudrate的初始化、以及全参数形式SPI(1, SPI.CONTROLLER, 500000, polarity1, phase0, bits8, firstbitSPI.MSB, tiFalse, crcNone)模式切换spi.init(SPI.PERIPHERAL, phase1)后打印对象可观察到模式、极性、相位的变化外设模式接收错误外设模式下recv()会因总线无数据而抛OSError测试通过循环接收捕获该异常基本收发send(1)、recv(1)、send_recv(1)均指定timeout100执行资源释放最后调用deinit()。对应期望输出见 spi.py.exp例如SPI(1, SPI.CONTROLLER, baudrate , polarity1, phase0, bits8)。在 TobudOS 工程中启用 MicroPython SPI要在具体开发板上使用 SPI需要满足两个条件工程配置在板级mpconfigboard.h中定义MICROPY_HW_SPI_NUM如 BearPi 的 4并在编译宏中定义MP_USING_MACHINE_SPI使 mpconfigport.h 生效运行时接入MicroPython 解释器在 TobudOS 中以一个内核任务的形式运行。参考 micropython_demo.capplication_entry中通过tos_task_create创建名为micropython的任务优先级 3、栈 4KB任务内循环调用mp_main()执行用户脚本。启动后在 MicroPython REPL 或脚本中即可按文档所述方式操作 SPI例如驱动一块基于 SPI 的 Flash/LCD 芯片from machine import SPI, Pin cs Pin(PA0, Pin.OUT) # 用普通 GPIO 手动控制片选NSS 空闲 spi SPI(1, SPI.CONTROLLER, baudrate1000000, polarity0, phase0, bits8, firstbitSPI.MSB) cs.value(0) # 拉低片选选中从设备 spi.send(b\x90\x00\x00\x00) # 发送读 ID 命令 buf bytearray(4) spi.send_recv(b\x00\x00\x00\x00, buf) # 全双工读回 4 字节 cs.value(1) # 释放片选 print(hex(buf[0]), hex(buf[1]), hex(buf[2]))小结SPI 是物联网终端中最常用的高速外设总线之一。pyb.SPI文档给出了完整、可复用的 API 契约init()负责模式、时钟、极性/相位、位宽、位序与 CRC 的配置send/recv/send_recv覆盖单工与全双工收发场景deinit()负责资源释放。结合 TobudOS 仓库的 machine_hw_spi.c 与 mpconfigport.h 可以确认该 API 在 TobudOS 移植中通过tos_hal_spi_init/tos_hal_spi_transfer/tos_hal_spi_deinit逐级映射到芯片 HAL真正做到了Python 一行配置硬件即刻响应。编写 SPI 驱动脚本时的三个关键检查点极性/相位polarity phase是否与外设数据手册一致、时钟频率是否落在硬件分频集合内必要时用 prescaler 精调、片选时序是否由你的 GPIO 逻辑正确控制。把握这三点即可在 TobudOS MicroPython 环境下快速打通各类 SPI 外设。赞分享【免费下载链接】TobudOSTobudOS 是面向物联网领域开发的实时操作系统早期版本基于腾讯自研的物联网操作系统TencentOS Tiny2020年由腾讯捐赠到开放原子开源基金会进行孵化2023年正式更名为TobudOSTobudOS具有低功耗低资源占用模块化安全可靠等特点可有效提升物联网终端产品开发效率提供精简的 RTOS 内核内核组件可裁剪可配置可快速移植到多种主流 MCU (如 STM32 全系列) 及模组芯片上。而且基于 RTOS 内核提供了丰富的物联网组件内部集成主流物联网协议栈如 CoAP/MQTT/TLS/DTLS/LoRaWAN/NB-IoT 等可助力物联网终端设备及业务快速接入物联网云平台。项目地址https://gitcode.com/openatomfoundation/TobudOS点击查看免费下载相关推荐MicroPython pyb.SPI 完全指南pyboard 硬件 SPI 总线的初始化、引脚映射与数据收发实战MicroPython pyb.SPI 完全指南pyboard 硬件 SPI 总线的初始化、引脚映射与数据收发实战 本篇技术指南围绕 MicroPython嵌入式语言运行时编程语言解释器编译器物联网系统编程TobudOS MicroPython 外设编程pyb.I2C 双线串行协议接口完整指南TobudOS MicroPython 外设编程pyb.I2C 双线串行协议接口完整指南 TobudOS 在 components/language/micrTobudOS 上的 MicroPython machine.SPI 指南硬件 SPI 与 SoftSPI 的构造、初始化与读写实战TobudOS 上的 MicroPython machine.SPI 指南硬件 SPI 与 SoftSPI 的构造、初始化与读写实战 本文基于 compone上一篇一个.cmd文件能同时搞定Windows激活和Office激活吗下一篇BlockNote 表格 Markdown 导出与列宽处理从 columnWidths 到快照文件的完整链路解析创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询