【雕爷学编程】MicroPython手册之 RP2040 特定端口库 rp2.StateMachine.restart()

在这里插入图片描述

MicroPython是为了在嵌入式系统中运行Python 3编程语言而设计的轻量级版本解释器。与常规Python相比,MicroPython解释器体积小(仅100KB左右),通过编译成二进制Executable文件运行,执行效率较高。它使用了轻量级的垃圾回收机制并移除了大部分Python标准库,以适应资源限制的微控制器。

MicroPython主要特点包括:
1、语法和功能与标准Python兼容,易学易用。支持Python大多数核心语法。
2、对硬件直接访问和控制,像Arduino一样控制GPIO、I2C、SPI等。
3、强大的模块系统,提供文件系统、网络、图形界面等功能。
4、支持交叉编译生成高效的原生代码,速度比解释器快10-100倍。
5、代码量少,内存占用小,适合运行在MCU和内存小的开发板上。
6、开源许可,免费使用。Shell交互环境为开发测试提供便利。
7、内置I/O驱动支持大量微控制器平台,如ESP8266、ESP32、STM32、micro:bit、掌控板和PyBoard等。有活跃的社区。

MicroPython的应用场景包括:
1、为嵌入式产品快速构建原型和用户交互。
2、制作一些小型的可 programmable 硬件项目。
3、作为教育工具,帮助初学者学习Python和物联网编程。
4、构建智能设备固件,实现高级控制和云连接。
5、各种微控制器应用如物联网、嵌入式智能、机器人等。

使用MicroPython需要注意:
1、内存和Flash空间有限。
2、解释执行效率不如C语言。
3、部分库函数与标准版有差异。
4、针对平台优化语法,订正与标准Python的差异。
5、合理使用内存资源,避免频繁分配大内存块。
6、利用原生代码提升速度关键部位的性能。
7、适当使用抽象来封装底层硬件操作。

总体来说,MicroPython让Python进入了微控制器领域,是一项重要的创新,既降低了编程门槛,又提供了良好的硬件控制能力。非常适合各类物联网和智能硬件的开发。
在这里插入图片描述

RP2040 是一款由树莓派公司设计的 32 位双核 ARM Cortex-M0+ 微控制器芯片,于 2021 年 1 月发布,作为树莓派 Pico 开发板的核心部件。RP2040 的特点是高性能、低成本、小封装、灵活的 I/O 和独特的可编程 I/O(PIO)子系统。RP2040 还支持 MicroPython、C/C++ 和 TensorFlow Lite 等编程语言和框架,适用于各种创意项目和机器学习应用。

MicroPython 的特定于 RP2040 的库包括以下模块:

rp2:包含特定于 RP2040 的函数和类,如 PIO 相关功能、Flash 类和 StateMachine 类。
machine:包含通用的硬件控制功能,如 Pin、Timer、UART、PWM、ADC 等。
utime:包含时间相关的函数,如 sleep、ticks_ms、ticks_diff 等。
uos:包含操作系统相关的函数,如 uname、mount、remove 等。

这些模块使得 MicroPython 可以充分利用 RP2040 的硬件特性,实现各种创意项目。

在这里插入图片描述
MicroPython 的 rp2.StateMachine.restart() 是一个用于重启状态机并跳转到程序的开始处的方法。状态机是 RP2040 芯片的一种特殊功能,它可以实现自定义的 I/O 行为,例如模拟 SPI、I2C、UART 等协议,或者实现位摇摆 (bit banging) 技术。状态机有两个实例,每个实例有四个编号为 0 到 3 的状态机,共计八个状态机。

rp2.StateMachine.restart() 的主要特点是:

它可以在任何时候调用,无论状态机是否已经初始化或启动。如果状态机未初始化,则该方法无效。
它可以通过 RP2040 的 SM_RESTART 寄存器来清除状态机的内部状态,包括:
输入和输出移位计数器
输入移位寄存器的内容
输出移位寄存器的内容
程序计数器
执行延迟
状态寄存器
它可以用于重新开始执行状态机的程序,或者恢复状态机的初始状态。

rp2.StateMachine.restart() 的应用场景是:

当需要在程序中重新开始执行某个状态机的程序时,例如根据某些条件或事件来重启状态机。
当需要在程序中恢复某个状态机的初始状态时,例如清除之前的数据或错误。
当需要在程序中切换不同的状态机程序时,例如根据不同的协议或模式来选择合适的程序。

rp2.StateMachine.restart() 的注意事项是:

使用 rp2.StateMachine.restart() 时,需要注意状态机的初始化和配置。如果状态机未正确地初始化或配置,可能会导致错误或异常。
使用 rp2.StateMachine.restart() 时,需要注意状态机的运行频率和时序。如果状态机的运行频率过高或过低,或者与其他设备的时序不匹配,可能会影响数据的传输或处理。
使用 rp2.StateMachine.restart() 时,需要注意状态机的资源占用和竞争。如果多个状态机同时运行,可能会消耗过多的系统资源,或者出现数据冲突或丢失。

以下是 MicroPython 的 rp2.StateMachine.restart() 的几个实际运用程序参考代码案例:

案例一:使用状态机 0 实现一个简单的 PWM (脉冲宽度调制) 信号,并在每次改变占空比时重启 PWM 状态机。

import time
from machine import Pin
import rp2

# 定义一个 PWM 程序
@rp2.asm_pio(set_init=rp2.PIO.OUT_LOW)
def pwm_prog():
    # 设置初始占空比为 50%
    set(y, 15) [31]
    # 设置初始周期为 32
    set(x, 31) [31]
    label("pwmloop")
    # 输出高电平
    set(pins, 1)
    # 等待 y 周期
    label("delayh")
    jmp(y_dec, "delayh")
    # 输出低电平
    set(pins, 0)
    # 等待 x-y 周期
    label("delayl")
    jmp(x_dec, "delayl")
    # 跳转到循环开始处
    jmp("pwmloop")

# 创建状态机 0,输出 PWM 信号到 Pin(25)
sm = rp2.StateMachine(0, pwm_prog, freq=1000, set_base=Pin(25))

# 启动状态机 0
sm.active(1)

# 循环改变 PWM 的占空比,并重启 PWM 状态机
for i in range(32):
    # 向 FIFO 中写入新的占空比
    sm.put(i)
    # 打印当前 PWM 状态机的占空比
    duty = sm.get() / 32
    print("PWM duty cycle changed to", duty)
    # 重启 PWM 状态机
    sm.restart()
    # 等待一秒
    time.sleep(1)

案例二:使用状态机 1 实现一个简单的 UART (通用异步收发器) 发送器,并在每次发送一个字节前重启 UART 状态机。

from machine import Pin
import rp2

# 定义一个 UART 发送程序
@rp2.asm_pio(set_init=rp2.PIO.OUT_LOW, sideset_init=(rp2.PIO.OUT_LOW,))
def uart_tx_prog():
    # 设置初始波特率为 9600
    set(x, 103) [31]
    # 设置初始数据位为 8
    set(y, 7) [31]
    label("uartloop")
    # 判断是否有数据要发送(从 TX FIFO 中读取数据)
    pull(block)
    mov(isr, osr)
    # 输出起始位(低电平,side set)
    out(x, 0) .side(0)
    # 等待一个周期
    nop() [31]
    label("outbit")
    # 输出一位数据到输出引脚(side set)
    out(x, 1) .side(isr)
    # 等待一个周期
    mov(x, isr)
    label("waitbit")
    jmp(x_dec, "waitbit")
    # 判断是否输出完所有数据位
    jmp(y_dec, "outbit")
    # 输出停止位(高电平,side set)
    out(x, 0) .side(1)
    # 等待一个周期
    nop() [31]
    # 跳转到循环开始处
    jmp("uartloop")

# 创建状态机 1,从 Pin(17) 发送 UART 数据
sm = rp2.StateMachine(1, uart_tx_prog, freq=1000000, out_base=Pin(17))

# 启动状态机 1
sm.active(1)

# 循环发送字节数据,并重启 UART 状态机
for i in range(256):
    # 重启 UART 状态机
    sm.restart()
    # 向 TX FIFO 中写入一个字节数据
    sm.put(i)
    # 打印发送的字节数据
    print("UART sent:", i)

案例三:使用状态机 2 和状态机 3 实现一个简单的 SPI (串行外设接口) 主从模式,并在每次切换主从模式时重启状态机。

from machine import Pin
import rp2

# 定义一个 SPI 主机程序
@rp2.asm_pio(set_init=rp2.PIO.OUT_LOW, sideset_init=(rp2.PIO.OUT_LOW,))
def spi_master_prog():
    # 设置初始时钟分频为 250(4 MHz)
    set(x, 249) [31]
    # 设置初始数据位为 8
    set(y, 7) [31]

案例四:重新启动状态机:

import rp2

# 创建 PIO 对象
pio = rp2.PIO(0)

# 设置 PIO 引脚 0 和 1 为输出引脚
pio.set_pins(0, 1 << 0)
pio.set_pins(1, 1 << 1)

# 创建 PIO 状态机
sm = rp2.StateMachine(0, pio, freq=1000000, out_base=pio.base)

# 启动状态机
sm.active(1)

# 在这里执行一些操作

# 重新启动状态机
sm.restart()

这个示例创建了一个 PIO 对象,并使用 pio.set_pins() 方法将 PIO 引脚 0 和 1 配置为输出引脚。然后,使用 rp2.StateMachine() 创建了一个 PIO 状态机对象 sm,并通过 sm.active(1) 启动了状态机。在某些操作之后,通过调用 sm.restart() 方法重新启动状态机。

案例五:使用循环重新启动状态机:

import rp2
import time

# 创建 PIO 对象
pio = rp2.PIO(0)

# 设置 PIO 引脚 0 和 1 为输出引脚
pio.set_pins(0, 1 << 0)
pio.set_pins(1, 1 << 1)

# 创建 PIO 状态机
sm = rp2.StateMachine(0, pio, freq=1000000, out_base=pio.base)

while True:
    # 启动状态机
    sm.active(1)

    # 在这里执行一些操作

    # 重新启动状态机
    sm.restart()

    time.sleep(1)

这个示例创建了一个 PIO 对象,并使用 pio.set_pins() 方法将 PIO 引脚 0 和 1 配置为输出引脚。然后,在主循环中,通过调用 sm.active(1) 启动状态机。在某些操作之后,通过调用 sm.restart() 方法重新启动状态机,并在每次循环结束前等待 1 秒。

案例六:使用条件语句和循环重新启动状态机:

import rp2
import time

# 创建 PIO 对象
pio = rp2.PIO(0)

# 设置 PIO 引脚 0 和 1 为输出引脚
pio.set_pins(0, 1 << 0)
pio.set_pins(1, 1 << 1)

# 创建 PIO 状态机
sm = rp2.StateMachine(0, pio, freq=1000000, out_base=pio.base)

while True:
    # 启动状态机
    sm.active(1)

    # 在这里执行一些操作

    # 检查是否需要重新启动状态机
    if some_condition:
        # 重新启动状态机
        sm.restart()

    time.sleep(1)

这个示例创建了一个 PIO 对象,并使用 pio.set_pins() 方法将 PIO 引脚 0 和 1 配置为输出引脚。然后,在主循环中,通过调用 sm.active(1) 启动状态机。在某些操作之后,通过检查条件 some_condition 决定是否需要重新启动状态机,并在需要时调用 sm.restart() 方法。在每次循环结束前等待 1 秒。请根据实际需求和条件来调整条件语句的逻辑。

请注意,以上示例仅供参考,具体的使用方法可能因不同的硬件平台和MicroPython版本而有所差异。在实际编程中,你需要根据你所使用的硬件和具体需求进行适当的调整。

在这里插入图片描述

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

驴友花雕

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值