资讯详情

资讯详情

TobudOS 集成 MicroPython RP2 快速参考:Raspberry Pi Pico 外设编程实战指南

【免费下载链接】TobudOSTobudOS 是面向物联网领域开发的实时操作系统早期版本基于腾讯自研的物联网操作系统TencentOS Tiny2020年由腾讯捐赠到开放原子开源基金会进行孵化2023年正式更名为TobudOSTobudOS具有低功耗低资源占用模块化安全可靠等特点可有效提升物联网终端产品开发效率提供精简的 RTOS 内核内核组件可裁剪可配置可快速移植到多种主流 MCU (如 STM32 全系列) 及模组芯片上。而且基于 RTOS 内核提供了丰富的物联网组件内部集成主流物联网协议栈如 CoAP/MQTT/TLS/DTLS/LoRaWAN/NB-IoT 等可助力物联网终端设备及业务快速接入物联网云平台。项目地址https://gitcode.com/openatomfoundation/TobudOS点击查看免费下载本文基于 components/language/micropython/docs/rp2/quickref.rst 编写。TobudOS 仓库以组件形式内置了 MicroPython 语言实现components/language/micropython其文档体系完整收录了 RP2xxx 移植版的快速参考、芯片说明与 PIO 教程。本文以该快速参考文档为骨架面向在 Raspberry Pi PicoRP2040上使用 MicroPython 的开发者系统讲解 REPL 使用、GPIO、PIO、UART、PWM、ADC、SPI/I2C、I2S、RTC、WDT、OneWire 与 NeoPixel 等全部外设的调用方法并结合仓库内的 PIO 示例与源码级 API 文档做纵深剖析帮助读者快速上手并深入理解 RP2 移植版的编程模型。Raspberry Pi Pico 开发板图片来源Raspberry Pi Foundation1. 板级概览与前置准备RP2xxx 移植版面向 Raspberry Pi 基金会 RP2xxx 系列微控制器最典型的代表就是采用 RP2040 的 Raspberry Pi Pico。其芯片级要点详见 components/language/micropython/docs/rp2/general.rst包括双核 ARM Cortex-M0标准主频 133 MHz文档注明可超频至 400 MHz 以上264 KB SRAM分为 6 个独立 bank无片内 Flash/EEPROM复位后由 bootloader 从外部 Flash 或 USB 总线将固件加载进 SRAMQSPI 总线控制器最高支持 16 MB 外部 Flash片上可编程 LDO 生成内核电压、2 个片内 PLL 分别生成 USB 与内核时钟30 个 GPIO其中 4 个可复用为模拟输入外设资源2 个 UART、2 个 SPI 控制器、2 个 I2C 控制器、16 路 PWM 通道、USB 1.1 控制器、8 个 PIO 状态机。安装 MicroPython 固件首次接触该板时建议先阅读 tutorial/intro.rst其中包含安装步骤与故障排除小节按官方流程将 MicroPython 固件烧录到板子后即可进入交互式开发。2. 通用板级控制REPL、machine 与 rp2 模块MicroPython REPL 通过 USB 串口访问。两个实用技巧Tab 补全在 REPL 中输入对象名后按 Tab可查看该对象拥有哪些方法粘贴模式Ctrl-E将大段 Python 代码粘贴进 REPL 时使用避免逐行解释的缩进错误。通用控制代码import machine machine.freq() # 获取当前 CPU 频率 machine.freq(240000000) # 将 CPU 频率设置为 240 MHzRP2 专属功能由rp2模块提供PIO 相关 API 详见后文import rp23. 延时与定时3.1 time 模块sleep 与 ticks 计时import time time.sleep(1) # 睡眠 1 秒 time.sleep_ms(500) # 睡眠 500 毫秒 time.sleep_us(10) # 睡眠 10 微秒 start time.ticks_ms() # 获取毫秒计数器 delta time.ticks_diff(time.ticks_ms(), start) # 计算时间差注意ticks_diff()用于处理计数器回绕wrap-around问题是嵌入式计时推荐的差值计算方式不要直接用减法。3.2 machine.Timer软件定时器RP2040 的系统定时器外设提供全局微秒时间基准并产生中断。当前移植版提供软件定时器数量理论上无限受内存限制无需指定定时器 id当前支持id-1并默认使用from machine import Timer tim Timer(period5000, modeTimer.ONE_SHOT, callbacklambda t:print(1)) tim.init(period2000, modeTimer.PERIODIC, callbacklambda t:print(2))mode支持Timer.ONE_SHOT单次触发与Timer.PERIODIC周期触发回调函数接收定时器对象作为参数。4. 引脚与 GPIOmachine.PinGPIO 操作是外设编程的基础完整 API 见 machine.Pin.rstfrom machine import Pin p0 Pin(0, Pin.OUT) # 在 GPIO0 上创建输出引脚 p0.on() # 置高电平 p0.off() # 置低电平 p0.value(1) # 置高value(0) 置低 p2 Pin(2, Pin.IN) # 在 GPIO2 上创建输入引脚 print(p2.value()) # 读取电平返回 0 或 1 p4 Pin(4, Pin.IN, Pin.PULL_UP) # 使能内部上拉电阻 p5 Pin(5, Pin.OUT, value1) # 创建时即置高Pin构造函数支持Pin.IN、Pin.OUT、Pin.OPEN_DRAIN、Pin.ALT、Pin.ANALOG等模式pull参数可指定Pin.PULL_UP/Pin.PULL_DOWN还可通过init()重配置、irq()注册中断回调。在 RP2 移植版中引脚标识即为 GPIO 编号0~29。5. 可编程 IOPIORP2040 的灵魂特性PIOProgrammable Input/Output是 RP2040 最具特色的外设用于从零构建底层 IO 接口——尤其适合硬件没有原生支持、或需要自定义 IO 行为的协议。相比在 CPU 上位拆弹bit banging占用主核执行时间PIO 状态机可以在后台完成位级操作CPU 专注执行主逻辑。5.1 硬件结构2 个 PIO 块 × 4 个状态机RP2040 拥有 2 个 PIO 块每块 4 个独立状态机共 8 个状态机编号 0~7。状态机通过 FIFO 与主处理器交换数据每个 FIFO 4 个字每字 32 位可联动 DMA 传输更大批量数据实现状态机与 CPU 的并行与同步。5.2 汇编指令体系所有 PIO 指令遵循统一模式.side(...)与[...]均为可选修饰instruction .side(side_set_value) [delay_value]九条核心指令jmp()跳转到代码其他位置wait()等待某个特定事件发生in_()将数据scratch 寄存器或一组引脚移入输入移位寄存器ISRout()将输出移位寄存器OSR数据移出到目标push()将 ISR 数据送入 RX FIFOpull()从 TX FIFO 取数据到 OSRmov()在源与目标之间搬移数据irq()置位或清除 IRQ 标志set()向目标写入立即数。修饰符与指令directive.side(value)在指令开始时设置 side-set 引脚电平[value]/.delay(value)指令执行后延时若干周期0~31wrap_target()指定程序回绕后继续执行的位置默认程序开头wrap()指定程序结束回绕的位置默认自动加在例程末尾回绕不消耗周期label(name)定义标签供jmp()使用word(instr)向汇编产物中插入一条原始 16 位指令。更完整的参数如jmp的条件not_x/x_dec/y_dec/x_not_y/pin/not_osre、in_/out的源与目标、mov的invert()/reverse()修饰等可在 rp2.rst 与 rp2.PIO.rst 中查阅。5.3 asm_pio 装饰器关键参数PIO 汇编例程在 MicroPython 中以rp2.asm_pio(...)装饰的 Python 函数书写可声明以下初始化参数out_init/set_init/sideset_init分别配置out()、set()、side-set 指令所用引脚的初始状态PIO.IN_LOW、PIO.IN_HIGH、PIO.OUT_LOW或PIO.OUT_HIGH多用脚可传元组如out_init(PIO.OUT_LOW, PIO.OUT_LOW)。set_init与sideset_init最多各 5 个引脚in_shiftdir/out_shiftdirISR/OSR 移位方向PIO.SHIFT_LEFT或PIO.SHIFT_RIGHTpush_thresh/pull_thresh触发自动 push/pull 的位数阈值默认 32autopush/autopull是否启用自动 push/pullfifo_join将 4 字 TX 与 RX FIFO 合并为单向 8 字 FIFOPIO.JOIN_NONE/PIO.JOIN_RX/PIO.JOIN_TX。上述参数除初始化外也均可在StateMachine.init()中覆盖。5.4 StateMachine 类 APIrp2.StateMachine(id, program, ...)按编号获取状态机并可选装载程序常用方法init(program, freq-1, *, in_baseNone, out_baseNone, set_baseNone, jmp_pinNone, sideset_baseNone, in_shiftdirNone, out_shiftdirNone, push_threshNone, pull_threshNone)装载并配置程序。freq为状态机运行频率分频器按system clock / freq计算存在取整误差默认系统时钟 125 MHz 时freq最小为1908 Hz若需更慢需先用machine.freq()降低系统时钟active([value])查询/设置状态机运行状态restart()复位状态机内部状态移位计数、ISR、延时计数器、等待 IRQ 状态、停滞指令等exec(instr)单条执行一条 PIO 指令经asm_pio_encode编码get(bufNone, shift0)从 RX FIFO 取一个 32 位字空则阻塞返回值右移shift位put(value, shift0)向 TX FIFO 推入一个字满则阻塞数值先左移shift位rx_fifo()/tx_fifo()查询 RX/TX FIFO 中字数irq(handlerNone, trigger0|1, hardFalse)获取或配置状态机 IRQ。5.5 实战示例一1Hz LED 闪烁附 IRQ仓库在 examples/rp2/pio_1hz.py 提供完整可运行示例并在 tutorial/pio.rst 中逐行注释import time from machine import Pin import rp2 rp2.asm_pio(set_initrp2.PIO.OUT_LOW) def blink_1hz(): # Cycles: 1 1 6 32 * (30 1) 1000 irq(rel(0)) set(pins, 1) set(x, 31) [5] label(delay_high) nop() [29] jmp(x_dec, delay_high) # Cycles: 1 7 32 * (30 1) 1000 set(pins, 0) set(x, 31) [6] label(delay_low) nop() [29] jmp(x_dec, delay_low) # 创建状态机运行 blink_1hz 程序、2000Hz、输出到 Pin(25) sm rp2.StateMachine(0, blink_1hz, freq2000, set_basePin(25)) # 设置 IRQ 回调LED 点亮瞬间打印毫秒时间戳 sm.irq(lambda p: print(time.ticks_ms())) # 启动状态机 sm.active(1)执行过程拆解irq(rel(0))触发与状态机关联的 IRQset(pins, 1)点亮 LEDX 寄存器载入 31 并延时 5 周期nop() [29]等待 30 周期jmp(x_dec, delay_high)在 X 非零时循环回标签并后递减 X——共执行 32 次nop() [29]含 32 次jmp指令周期。随后set(pins, 0)熄灭 LED再经历一轮 32 次延时循环。因未显式声明wrap_target()/wrap()程序默认从底部回绕到顶部回绕不消耗周期。整个例程恰为 2000 个状态机周期设置状态机频率 2000 Hz 即实现 1 Hz 闪烁。5.6 实战示例二PIO 实现 PWM 呼吸灯仓库还提供了用 PIO 生成 PWM 并实现 LED 呼吸效果的示例 examples/rp2/pio_pwm.pyfrom machine import Pin from rp2 import PIO, StateMachine, asm_pio from time import sleep asm_pio(sideset_initPIO.OUT_LOW) def pwm_prog(): pull(noblock) .side(0) mov(x, osr) # 将最近 pull 的数据暂存到 X供 noblock 循环复用 mov(y, isr) # ISR 需预载 PWM 计数最大值 label(pwmloop) jmp(x_not_y, skip) nop() .side(1) label(skip) jmp(y_dec, pwmloop) class PIOPWM: def __init__(self, sm_id, pin, max_count, count_freq): self._sm StateMachine(sm_id, pwm_prog, freq2 * count_freq, sideset_basePin(pin)) # 用 exec() 将最大值载入 ISR self._sm.put(max_count) self._sm.exec(pull()) self._sm.exec(mov(isr, osr)) self._sm.active(1) self._max_count max_count def set(self, value): value max(value, -1) # 最小 -1 完全关闭0 实际仍输出窄脉冲 value min(value, self._max_count) self._sm.put(value) # Pin 25 是 Pico 板载 LED pwm PIOPWM(0, 25, max_count(1 16) - 1, count_freq10_000_000) while True: for i in range(256): pwm.set(i**2) sleep(0.01)该示例展示了sideset_init、StateMachine.put()、exec()动态装载寄存器、jmp(x_not_y, ...)比较跳转等进阶用法可作为自定义协议实现的参考模板。6. UART串口RP2 移植版提供UART0 与 UART1两个串口。引脚映射UART0 可映射到 GPIO 0/1、12/13、16/17UART1 可映射到 GPIO 4/5、8/9。from machine import UART, Pin uart1 UART(1, baudrate9600, txPin(4), rxPin(5)) uart1.write(hello) # 写入 5 字节 uart1.read(5) # 读取至多 5 字节注意默认情况下 REPL-over-UART 是禁用的。如需在串口上启用 REPL请参考 tutorial/intro.rst 中的说明。7. PWM脉冲宽度调制RP2040 提供8 个独立通道每通道 2 路输出共 16 路 PWM可配置时钟频率范围约7 Hz ~ 125 MHz。from machine import Pin, PWM pwm0 PWM(Pin(0)) # 从引脚创建 PWM 对象 pwm0.freq() # 获取当前频率 pwm0.freq(1000) # 设置频率 pwm0.duty_u16() # 获取当前占空比范围 0-65535 pwm0.duty_u16(200) # 设置占空比范围 0-65535 pwm0.deinit() # 关闭该引脚上的 PWMduty_u16()以 16 位精度0~65535表示占空比等效百分比为duty / 65535 * 100。8. ADC模数转换RP2040 共5 路 ADC 通道其中 4 路为 12 位 SAR 型GP26、GP27、GP28、GP29 分别对应 ADC0~ADC3Pico 板上 GP29 连接 VSYS标准量程0~3.3 V第 5 路连接片内温度传感器可用于测温。from machine import ADC, Pin adc ADC(Pin(26)) # 在 ADC 引脚上创建 ADC 对象 adc.read_u16() # 读取数值0-65535 对应 0.0V - 3.3Vread_u16()将 12 位采样结果归一化到 16 位范围0~65535便于跨平台统一处理。9. SPI 总线9.1 软件 SPISoftSPI位拆弹软件 SPI 可工作在所有引脚上from machine import Pin, SoftSPI # 在指定引脚上构造 SoftSPI 总线 # polarity 为 SCK 空闲电平 # phase0 表示在 SCK 第一个边沿采样phase1 表示第二个边沿 spi SoftSPI(baudrate100_000, polarity1, phase0, sckPin(0), mosiPin(2), misoPin(4)) spi.init(baudrate200000) # 修改波特率 spi.read(10) # 在 MISO 上读取 10 字节 spi.read(10, 0xff) # 读取 10 字节同时在 MOSI 输出 0xff buf bytearray(50) spi.readinto(buf) # 读入给定缓冲区此处读 50 字节 spi.readinto(buf, 0xff) # 读入缓冲区同时在 MOSI 输出 0xff spi.write(b12345) # 在 MOSI 上写 5 字节 buf bytearray(4) spi.write_readinto(b1234, buf) # 写 MOSI 并从 MISO 读入缓冲区 spi.write_readinto(buf, buf) # 将 buf 写到 MOSI并将 MISO 读回 buf警告初始化软件 SPI 时sck、mosi、miso三者必须全部指定。9.2 硬件 SPIRP2040 有 2 个硬件 SPI 控制器API 与软件 SPI 相同详见 machine.SPI.rstfrom machine import Pin, SPI spi SPI(1, 10_000_000) # 默认分配sckPin(10), mosiPin(11), misoPin(8) spi SPI(1, 10_000_000, sckPin(14), mosiPin(15), misoPin(12)) spi SPI(0, baudrate80_000_000, polarity0, phase0, bits8, sckPin(6), mosiPin(7), misoPin(4))10. I2C 总线10.1 软件 I2CSoftI2C软件 I2C 可工作在所有支持输出的引脚上from machine import Pin, SoftI2C i2c SoftI2C(sclPin(5), sdaPin(4), freq100_000) i2c.scan() # 扫描总线上的设备 i2c.readfrom(0x3a, 4) # 从地址 0x3a 的设备读取 4 字节 i2c.writeto(0x3a, 12) # 向地址 0x3a 写入 12 buf bytearray(10) i2c.writeto(0x3a, buf) # 向外设写入缓冲区内容10.2 硬件 I2Cfrom machine import Pin, I2C i2c I2C(0) # 默认分配sclPin(9), sdaPin(8) i2c I2C(1, sclPin(3), sdaPin(2), freq400_000)API 与软件 I2C 相同。freq指定总线时钟频率常用 100 kHz 标准模式 / 400 kHz 快速模式。11. I2S 音频总线I2S 支持两个总线id0、id1当前以Technical Preview技术预览状态提供API 与实现可能根据用户反馈调整from machine import I2S, Pin # 发送模式16 位立体声、44.1 kHz 采样率 i2s I2S(0, sckPin(16), wsPin(17), sdPin(18), modeI2S.TX, bits16, formatI2S.STEREO, rate44100, ibuf40000) i2s.write(buf) # 将音频采样缓冲区写入 I2S 设备 # 接收模式16 位单声道、22.05 kHz 采样率 i2s I2S(1, sckPin(0), wsPin(1), sdPin(2), modeI2S.RX, bits16, formatI2S.MONO, rate22050, ibuf40000) i2s.readinto(buf) # 从 I2S 设备填充采样缓冲区约束ws引脚号必须比sck引脚号大 1即ws sck 1。12. RTC实时时钟from machine import RTC rtc RTC() rtc.datetime((2017, 8, 23, 2, 12, 48, 0, 0)) # 设置日期时间如 2017/8/23 1:12:48 rtc.datetime() # 读取日期时间datetime()元组格式为(year, month, day, weekday, hour, minute, second, subsecond)。13. WDT看门狗定时器RP2040 的看门狗是一个倒计时定时器计数归零时可重启芯片部分电路from machine import WDT # 启用 WDT超时 5 秒最小 1 秒 wdt WDT(timeout5000) wdt.feed()timeout单位为毫秒最小值为 10001 秒feed()用于喂狗复位倒计时。14. OneWire 驱动与 DS18x20 温度传感器OneWire 驱动以软件实现可工作在所有引脚上from machine import Pin import onewire ow onewire.OneWire(Pin(12)) # 在 GPIO12 上创建 OneWire 总线 ow.scan() # 返回总线上的设备列表 ow.reset() # 复位总线 ow.readbyte() # 读取一个字节 ow.writebyte(0x12) # 写入一个字节 ow.write(123) # 写入多个字节 ow.select_rom(b12345678) # 按 ROM 码选择特定设备DS18S20 / DS18B20 专用驱动import time, ds18x20 ds ds18x20.DS18X20(ow) roms ds.scan() ds.convert_temp() time.sleep_ms(750) for rom in roms: print(ds.read_temp(rom))硬件注意数据线上必须接4.7k 上拉电阻每次采样温度前都必须调用convert_temp()转换需要约 750 ms。15. NeoPixel 与 APA106 彩灯驱动from machine import Pin from neopixel import NeoPixel pin Pin(0, Pin.OUT) # GPIO0 设为输出以驱动 NeoPixel np NeoPixel(pin, 8) # 在 GPIO0 上创建 8 颗像素的驱动 np[0] (255, 255, 255) # 将第 1 颗像素设为白色 np.write() # 将数据写入所有像素 r, g, b np[0] # 读取第 1 颗像素颜色APA106 驱动继承 NeoPixel但内部使用不同的颜色顺序from apa106 import APA106 ap APA106(pin, 8) r, g, b ap[0]APA102DotStar由于额外带时钟引脚使用不同的驱动不在此列。16. 在 TobudOS 中运行 MicroPython 的工程视角TobudOS 将 MicroPython 作为语言组件集成在 components/language/micropython包含完整的py/Python 解释器核心、extmod/扩展模块、docs/Sphinx 文档与examples/。其中面向 TobudOS 的移植位于 components/language/micropython/port提供machine模块适配引脚、定时器、UART、硬件 SPI、VFS 等见 port/modules。演示入口见 examples/micropython_demo/micropython_demo.c它以 RTOS 任务形式承载 MicroPython——application_entry()中创建micropython任务优先级 3、默认 4 KB 栈任务内先挂载 VFS/文件系统如/dev/sd上的 FATFS随后循环调用mp_main()启动 REPL 与脚本执行。可选的 QSPI Flash 支持MP_USING_QSPI_FLASH宏可在执行前初始化 W25Qxx 并切换为内存映射模式。RP2 相关的脚本示例集中在 examples/rp2除上文展开的pio_1hz.py、pio_pwm.py外还有pio_uart_rx.py/pio_uart_tx.pyPIO 模拟 UART、pio_ws2812.pyPIO 驱动 WS2812、pio_pinchange.py引脚变化检测、pio_exec.py动态执行指令以及pwm_fade.pyPWM 渐变适合作为 PIO 协议实现的进阶参考资料。17. 相关文档索引在 TobudOS 仓库内继续深挖 RP2 移植版推荐以下文档均以仓库根目录为起点的相对路径芯片与板级总览docs/rp2/general.rst上手教程安装、REPL、故障排除docs/rp2/tutorial/intro.rstPIO 汇编教程含逐指令注释docs/rp2/tutorial/pio.rstrp2模块与asm_pio完整参数docs/library/rp2.rstrp2.StateMachine类 APIdocs/library/rp2.StateMachine.rst各machine外设类文档docs/library含machine.Pin.rst、machine.UART.rst、machine.PWM.rst、machine.ADC.rst、machine.I2C.rst、machine.SPI.rst、machine.I2S.rst、machine.RTC.rst、machine.WDT.rst、machine.Timer.rst等以上文档与示例配合本文快速参考即可在 Raspberry Pi PicoRP2040上完成从点亮 LED 到自定义 PIO 协议的完整开发链路。赞分享【免费下载链接】TobudOSTobudOS 是面向物联网领域开发的实时操作系统早期版本基于腾讯自研的物联网操作系统TencentOS Tiny2020年由腾讯捐赠到开放原子开源基金会进行孵化2023年正式更名为TobudOSTobudOS具有低功耗低资源占用模块化安全可靠等特点可有效提升物联网终端产品开发效率提供精简的 RTOS 内核内核组件可裁剪可配置可快速移植到多种主流 MCU (如 STM32 全系列) 及模组芯片上。而且基于 RTOS 内核提供了丰富的物联网组件内部集成主流物联网协议栈如 CoAP/MQTT/TLS/DTLS/LoRaWAN/NB-IoT 等可助力物联网终端设备及业务快速接入物联网云平台。项目地址https://gitcode.com/openatomfoundation/TobudOS点击查看免费下载相关推荐MicroPython RP2 端口快速参考Raspberry Pi PicoRP2040/RP2350外设编程速查手册MicroPython RP2 端口快速参考Raspberry Pi PicoRP2040/RP2350外设编程速查手册 本篇技术指南以 MicroPyt嵌入式语言运行时编程语言解释器编译器物联网系统编程TobudOS 中的 MicroPython i.MXRT 快速参考NXP 跨界 MCU 外设编程实战指南TobudOS 中的 MicroPython i.MXRT 快速参考NXP 跨界 MCU 外设编程实战指南 本文是面向 NXP i.MXRT 系列 MCUMTobudOS 集成 MicroPython 的 rp2 模块完全指南RP2040 PIO 可编程 IO 与 StateMachine 实战TobudOS 集成 MicroPython 的 rp2 模块完全指南RP2040 PIO 可编程 IO 与 StateMachine 实战 rp2 是 Mi上一篇BilibiliDown 哔哩哔哩视频下载教程5分钟三步把视频和收藏存到本地下一篇AVA 共享 Worker 执行崩溃时的行为验证快照报告、错误传播与插件 API 影响创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →