在microPython开发系统下,使用file是可以存数据至单片机板上flash,不过我还没找到直接用USB可访问这些数据的办法(也就是设置成一个板载U盘),只能在Thonny窗口里面去open看flash上的数据,不让arduino IDE下设置成U盘方便
用RP2040单片机一段时间了,最近测试了一下PIO,专门测试了一段简单代码,适合入门避坑,使用microPython(Thonny)编程开发。
首先拿到一个RP2040 Zero板,用USB线插电脑上,然后下载一个Thonny.exe,安装到电脑上。运行Thonny可以在编辑窗口或下方命令行写简单的Python代码如print并运行,这与单片机还没有关系,只是确认这个编辑器是正常的。然后需要向单片机boot状态下(按住boot键插USB,插好后释放boot键)的U盘中,拷入一个RPI_PICO-20260406-v1.28.0uf2这样的文件。等一会儿就可以在<运行><设置编辑器>里面,选RP2040,及相应的com连接,这样就搭建好了microPython开发系统。
可以测试一个简单的microPython代码,验证此开发系统正常,比如一个数字输出程序:
from machine import Pin
p5 = Pin(5, Pin)
p5.value(1)
运行此程序,可以测到5脚有高电平(可以直接插个LED在5脚和GND之间),把value值改成0,再运行就变成了低电平。
然后就可以测试PIO,一个简单的方波发生器:
from machine import Pin
from rp2 import PIO, asm_pio
machine.freq(280000000)
@asm_pio(set_init=rp2.PIO.OUT_LOW)
def blink():
set(pins, 1)
set(pins, 0)
sm = rp2.StateMachine(0, blink, freq=280000000, set_base=Pin(5))
sm1.active(1) #启动PIO
运行后在5脚能测到140MH方波。
from machine import Pin
from rp2 import PIO, asm_pio, StateMachine
machine.freq(100000000) #这句挺重要,网上很多例程没有这个设置,会导致信号上升或下降沿有+/-7ns的跳动,因为默认的CPU的freq与PIO的freq有可能不成整数比例关系
p2 = Pin(2, XXXXXX) #可用于外部输入触发,在wait()中用到
p4 = Pin(4, Pin.OUT) #用于同步软启动多通道
@rp2.asm_pio(set_init=rp2.PIO.OUT_LOW)
def pulse_gen():
wait(0, gpio, 4) # 等待4上升沿
wait(1, gpio, 4) # 出现4上升沿
mov(x, osr) # 加载延迟参数
label("delay_loop")
jmp(x_dec, "delay_loop") # 延时循环
wrap_target() #周期脉冲循环
set(pins, 1) [10] # 输出脉宽ON
set(pins, 0) [10] # OFF
wrap()
# 初始化4个状态机,对应5-8脚输出
for i in range(4):
sm = rp2.StateMachine(i, pulse_gen, freq=100000000, set_base=Pin(i+5))
sm.put(i*2) #设置信号间延迟
sm.active(1) #启动
p4.value(0)
p4.value(1) #4个状态机虽然已经启动,但是会处于等待wait(…,4),直到这里第4脚出现上升沿,因此这里提供了一个软启动用于同步。如果在wait(…,2)中等待的是2脚,那就是硬触发同步
通过这个例程,测试了几个基本功能,如多通道工作、信号延迟、软触发同步或硬触发同步,实现起来还比较容易。PIO还有很多其他功能,入门以后再深入研究就比较容易了。
在microPython开发系统下,使用file是可以存数据至单片机板上flash,不过我还没找到直接用USB可访问这些数据的办法(也就是设置成一个板载U盘),只能在Thonny窗口里面去open看flash上的数据,不让arduino IDE下设置成U盘方便
可以的,下面是我写的MP3播放器
import board
import audiopwmio
import audiomp3
import time
import microcontroller
import digitalio
import os
# ==================== 硬件配置 ====================
AUDIO_PIN = board.GP13 # 音频输出引脚
BUTTON_PIN = board.GP24 # 切歌按键(短接 GND 触发)
OVERCLOCK_FREQ_HZ = 150000000 # 超频以获得更流畅的解码
# ==================== 初始化按键(内置上拉,短接时为低电平) ====================
button = digitalio.DigitalInOut(BUTTON_PIN)
button.switch_to_input(pull=digitalio.Pull.UP)
# ==================== 扫描根目录下的 MP3 文件 ====================
def get_mp3_files():
files = []
for file in os.listdir("/"):
if file.lower().endswith(".mp3"):
files.append(file)
files.sort()
return files
playlist = get_mp3_files()
if not playlist:
# 没有歌曲时闪灯或仅保持静默,这里简单进入死循环
while True:
time.sleep(1)
current_index = 0
def next_song():
global current_index
current_index = (current_index + 1) % len(playlist)
# ==================== 主播放逻辑 ====================
microcontroller.cpu.frequency = OVERCLOCK_FREQ_HZ
audio_out = None
try:
audio_out = audiopwmio.PWMAudioOut(AUDIO_PIN)
while True:
mp3_file_name = playlist[current_index]
try:
with open(mp3_file_name, "rb") as mp3_file:
decoder = audiomp3.MP3Decoder(mp3_file)
audio_XXXXXXXXXXXXXXX(decoder)
button_last = button.value
while audio_out.playing:
# 检测按键下降沿(按下)
current_button = button.value
if button_last and not current_button:
audio_out.stop()
next_song()
# 等待按键释放,避免连续触发
while not button.value:
time.sleep(0.01)
time.sleep(0.2)
break # 退出内层循环,开始播放新歌
button_last = current_button
time.sleep(0.05) # 短延时,保证按键响应灵敏
else:
# 歌曲自然播放完毕,自动切下一首
next_song()
time.sleep(0.5)
except Exception as e:
# 单曲播放异常,等待 2 秒后尝试下一首
time.sleep(2)
next_song()
except Exception as e:
# 音频输出初始化失败,陷入死循环
while True:
time.sleep(1)
finally:
if audio_out:
audio_out.stop()
audio_out.deinit()