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.PIO.IN_HIGH是一个常量,用于表示PIO程序中的输入或输出引脚的初始状态为高电平。
它的主要特点有:
它是一个整数,其值为1。
它可以用于asm_pio()函数或PIOProgram类的out_init, set_init, sideset_init参数中,用于配置PIO程序中的out(), set(), sideset()指令所使用的引脚的初始状态。
它可以用于StateMachine.init()方法的out_init, set_init, sideset_init参数中,用于覆盖PIO程序中的out(), set(), sideset()指令所使用的引脚的初始状态。
它的应用场景有:
当需要使用PIO实现一些特殊的协议或功能时,可以使用rp2.PIO.IN_HIGH常量来设置输入或输出引脚的初始状态为高电平。例如,如果需要使用PIO实现一个SPI协议,并在通信之前将输出引脚设置为高电平,可以使用rp2.PIO.IN_HIGH常量来配置out_init参数。
当需要动态生成或加载PIO程序时,可以使用rp2.PIO.IN_HIGH常量来设置输入或输出引脚的初始状态为高电平。例如,如果需要根据用户的输入或其他变量来生成或加载不同的PIO程序,并在运行之前将输出引脚设置为高电平,可以使用rp2.PIO.IN_HIGH常量来配置out_init参数。
当需要调试或分析PIO程序时,可以使用rp2.PIO.IN_HIGH常量来设置输入或输出引脚的初始状态为高电平。例如,如果需要检查或比较不同的PIO程序的运行结果或性能,并在运行之前将输出引脚设置为高电平,可以使用rp2.PIO.IN_HIGH常量来配置out_init参数。
它需要注意的事项有:
在使用rp2.PIO.IN_HIGH常量时,需要确保其与PIO程序中的out(), set(), sideset()指令所使用的引脚数量和顺序相匹配。如果不匹配,会导致引脚状态错误或异常。
在使用rp2.PIO.IN_HIGH常量时,需要确保其与StateMachine.init()方法中的out_base, set_base, sideset_base参数相协调。如果不协调,会导致引脚状态错误或异常。
在使用rp2.PIO.IN_HIGH常量时,需要注意与rp2.PIO.IN_LOW, rp2.PIO.OUT_LOW, rp2.PIO.OUT_HIGH等其他常量的区别和配合。这些常量分别表示输入或输出引脚的初始状态为低电平、输出模式下低电平、输出模式下高电平。
以下是MicroPython的rp2.PIO.IN_HIGH几个实际运用程序参考代码案例:
案例1:使用rp2.asm_pio()函数编写一个SPI发送功能的程序,并使用rp2.PIO.IN_HIGH常量将输出引脚设置为高电平
import rp2
import machine
# 使用rp2.asm_pio()函数编写一个SPI发送功能的程序
@rp2.asm_pio(out_shiftdir=rp2.PIO.SHIFT_LEFT)
def spi_tx():
pull()
out(pins, 8)
nop() [7]
out(x, 1) .side(0)
nop() [7]
out(x, 1) .side(1)
# 使用rp2.PIO.IN_HIGH常量将输出引脚设置为高电平
spi_tx_program = rp2.PIOProgram(spi_tx, out_init=rp2.PIO.IN_HIGH)
# 获取第0个PIO实例对象
pio = rp2.PIO(0)
# 使用rp2.PIO.state_machine()方法获取和初始化第0个PIO实例的第0个状态机对象,并将其关联到spi_tx_program对象
sm = pio.state_machine(0, spi_tx_program, freq=1000000, out_base=machine.Pin(0), sideset_base=machine.Pin(1))
# 启动状态机
sm.active(1)
案例2:使用rp2.PIOProgram类构造一个根据用户输入产生不同频率PWM信号的程序,并使用rp2.PIO.IN_HIGH常量将输出引脚设置为高电平
import rp2
import machine
# 定义一个根据用户输入产生不同频率PWM信号的函数
def generate_pwm(freq, duty):
# 计算y寄存器需要设置的值,以便产生所需频率
y_value = int(125000000 / freq - 1)
# 计算x寄存器需要设置的值,以便产生所需占空比
x_value = int(y_value * duty / 100)
# 使用rp2.asm_pio_encode()函数将y寄存器和x寄存器的值编码为机器码指令
set_y_code = rp2.asm_pio_encode(f"set (y, {y_value})", 0)
set_x_code = rp2.asm_pio_encode(f"set (x, {x_value})", 0)
# 使用rp2.asm_pio_encode()函数将其他固定的PIO指令编码为机器码指令
out_code = rp2.asm_pio_encode("out (pins, 1)", 0)
jmp_code = rp2.asm_pio_encode("jmp x_dec", 0)
# 将所有的机器码指令组合成一个字节数组
program = bytearray([set_y_code & 0xff, set_y_code >> 8, set_x_code & 0xff, set_x_code >> 8, out_code & 0xff, out_code >> 8, jmp_code & 0xff, jmp_code >> 8])
# 使用rp2.PIOProgram类构造一个PIO程序对象,并设置一些配置参数,其中使用rp2.PIO.IN_HIGH常量将输出引脚设置为高电平
pio_program = rp2.PIOProgram(program, freq=125000000, out_base=machine.Pin(0), out_init=rp2.PIO.IN_HIGH)
# 获取第0个PIO实例对象
pio = rp2.PIO(0)
# 使用rp2.PIO.state_machine()方法获取和初始化第0个PIO实例的第0个状态机对象,并将其关联到pio_program对象
sm = pio.state_machine(0, pio_program)
# 启动状态机
sm.active(1)
# 调用函数,生成一个频率为100Hz,占空比为50%的PWM信号
generate_pwm(100, 50)
案例3:使用rp2.PIO.IN_HIGH常量将输出引脚设置为高电平,并使用StateMachine.init()方法覆盖PIO程序中的out_init参数
import rp2
import machine
# 使用rp2.asm_pio()函数编写一个闪烁LED的程序,其中使用rp2.PIO.OUT_LOW常量将输出引脚设置为低电平
@rp2.asm_pio(set_init=rp2.PIO.OUT_LOW)
def blink_1hz():
irq(rel(0))
set(pins, 1)
set(x, 31) [5]
label("delay_high")
nop() [29]
jmp(x_dec, "delay_high")
nop()
set(pins, 0)
set(x, 31) [5]
label("delay_low")
nop() [29]
jmp(x_dec, "delay_low")
# 获取第0个PIO实例对象
pio = rp2.PIO(0)
# 使用rp2.PIO.state_machine()方法获取第0个PIO实例的第0个状态机对象,但不初始化它
sm = pio.state_machine(0)
# 使用StateMachine.init()方法初始化状态机对象,并将其关联到blink_1hz程序,其中使用rp2.PIO.IN_HIGH常量覆盖PIO程序中的out_init参数,将输出引脚设置为高电平
sm.init(blink_1hz, freq=2000000, set_base=machine.Pin(25), out_init=rp2.PIO.IN_HIGH)
# 启动状态机
sm.active(1)
案例4:高电平触发中断
import rp2
from machine import Pin
sm = rp2.PIO(0)
pin = Pin(15, mode=Pin.IN)
sm.irq(lambda: print('Interrupt!'), IN_HIGH)
while True:
# 高电平触发中断
pass
这个示例通过IN_HIGH设置高电平触发中断。
示例5:水位检测
import rp2
from machine import Pin
@rp2.asm_pio(set_init=rp2.PIO.OUT_LOW)
def water_level():
set(pins, 1)
in_(pins, 1)
jmp(pin, 'not_full')
sm = rp2.PIO()
sensor = Pin(4, Pin.IN)
sm.init(water_level, freq=100)
sm.irq(lambda: print('Water level high!'), IN_HIGH)
sm.put(sensor)
这个示例通过IN_HIGH实现水位高度触发中断。
示例6:特定边沿触发
import rp2
sm = rp2.PIO(0)
sm.irq(handler, IN_HIGH | rp2.IRQ_RISE)
这个示例通过与RISE相与实现上升沿触发中断。
这些示例展示了IN_HIGH可以用来设置引脚电平触发以及应用场景。