1.前言
此次电子森林与硬禾学堂的2024寒假在家一起练活动意义非凡,不仅能让我们免费获得平日里价格不菲的板卡,而且让我们寒假在家就能学习到丰富的知识,感谢电子森林与硬禾学堂能够举办此次活动。
2.项目介绍
基于对自己水平的认识,此次活动我选择的项目是带显示屏的RP2040的多功能硬件调试平台任务一:可编程PWM发生器。
该项目旨在通过按键与拨轮调整RP2040输出的PWM波频率及占空比,且占空比有一定的精度要求,接着使用另一块RP2040作为逻辑分析仪检测验证输出的PWM波。
RP2040是Raspberry Pi的首款微控制器。它将我们的高性能、低成本和易用性的标志性价值观带入微控制器领域。 凭借大容量片上存储器、对称双核处理器复合体、确定性总线结构和丰富的外设集,以及独特的可编程 I/O (PIO) 子系统,它为专业用户提供了无与伦比的功能和灵活性。凭借详细的文档,完善的MicroPython端口和ROM中的UF2引导加载程序,对于初学者和业余爱好者用户来说,它具有尽可能低的入门门槛。 RP2040 是一款无状态设备,支持从外部 QSPI 存储器缓存就地执行。这种设计决策允许为我们的应用选择适当密度的非易失性存储,并从商品闪存器件的低价中受益。 RP2040 采用现代 40nm 工艺节点制造,提供高性能、低动态功耗和低泄漏,具有多种低功耗模式,支持电池供电长时间运行。
3.项目分析与设计思路
首先,该项目在完成时分为两大板块,其一是带屏的RP2040产生三股可用按键与拨轮调节占空比频率的独立PWM波,其二是用另一块RP2040检测验证PWM的产生。
首先我学习了MicroPython在RP2040上的配置与使用,
作为python初学者,我选择的python编译器是thonny,其作为初学者友好的pythonIDE,页面简洁,功能齐全,针对micropython有完善的编译环境。
接着我进行了PulseView的调试这是一款较为便捷的软件,帮助我们用RP2040实现逻辑分析仪的功能。
最后是程序的编写,我决定使用machine库pwm功能,按键控制频率,左右拨轮调节占空比,按住拨轮中键通过左右按键改变调试的通道。
功能框图如下:
4.代码说明
from machine import Pin, PWM
首先是库函数的引用,选择machine库的pin与pwm功能。
p1 = PWM(Pin(20), freq=120000, duty_u16=32768)
p2 = PWM(Pin(21), freq=120000, duty_u16=32768)
p3 = PWM(Pin(22), freq=120000, duty_u16=32768)
buttonValueM = Pin(5,Pin.IN, Pin.PULL_UP)
buttonValueS = Pin(6,Pin.IN, Pin.PULL_UP)
buttonValueR = Pin(9,Pin.IN, Pin.PULL_UP)
buttonValuePress = Pin(8,Pin.IN, Pin.PULL_UP)
buttonValueL = Pin(7,Pin.IN, Pin.PULL_UP)
接着定义pwm输出的引脚与按键的定义。将pin20,21,22作为输出的引脚,基础频率为120kHz,占空比为,将各个按键拨轮设置为输入上拉模式,当按键按下或者拨轮偏移时检测到低电平。
freq1 = 120000
freq2 = 120000
freq3 = 120000
duty1 = 32768
duty2 = 32768
duty3 = 32768
state = 1
i = 1
这里是一些参数的定义,freq123,duty123分别代表通道123的频率与占空比,state为通道的选择标志,i为防止按键接触时间较长导致的频率占空比迅速变化。
while True:
接下来是循环内容
i = i + 1
if i > 5000:
i = 1
计数位与清零
if buttonValuePress.value() == 0:
if i %5000 == 1:
if state > 1 and buttonValueM.value() == 0:
state = state - 1
if state < 3 and buttonValueS.value() == 0:
state = state + 1
按住拨轮中键,按左右按键即切换通道。
if state == 1:
if i %10 == 1:
if buttonValueR.value() == 0 and duty1 <= 65535:
duty1 = duty1 + 1
if buttonValueL.value() == 0 and duty1 >= 0:
duty1 = duty1 - 1
if i%5000 == 1:
if buttonValueM.value() == 0:
freq1 = int(freq1 / 10)
if buttonValueS.value() == 0:
freq1 = int(freq1 * 10)
if freq1 < 1200:
freq1 = 1200
if freq1 > 12000000:
freq1 = 12000000
p1.freq(freq1)
if freq1 < 1200000:
p1.duty_u16(duty1)
elif freq1 == 12000000:
duty_high1=int(duty1-(duty1%6553))
if duty1==65535:
duty_high1=65535
p1.duty_u16(duty_high1)
这是通道一的代码,三通道代码大致一样,只展示通道一。
首先根据需要采用不同的计数值判断按键的信号接受,在接受处理完信号后,通过p1.freq()函数改变输出pwm的频率,接着按照要求,1.2MHz以下的占空比分辨度为1/1000,1.2MHz为1/100,12MHz为1/10,我通过简单的数据处理解决了这个问题,接着通过p1.duty_u16()函数更新占空比。
5.遇到的难题与解决思路
首先,这次的项目采用的是micro python,python本就是我接触最少的常用编程语言,对于python语法的学习占据了我前期大量的时间。
其次我注意到大部分的machine库pwm教程都声明频率的上限低于题目要求,这让我最初忙于寻找其他方法输出pwm,最开始我选择delay函数从原理出发实现该功能,但是最低延迟us级仍然无法满足需求,因此我的进度陷入困境。最终我回到树莓派官方的演示文档中发现事实上最高频率是系统时钟频率,可满足需求,因此解决了这一问题。
再者是pulseview识别RP2040时出现的问题,扫描输出通道不知为何出现了24个channel
且只有20 21 22三个引脚能接受到信号,查了各种资料找不到原因,在做出程序主体后,发现其中21引脚对应的输出信号无法调制但是其与20引脚的信号频率相同,占空比却独立可调,寻找很久却找不到原因,遂未解决。
最后,未能完成lcd的显示。
6.未来计划
通过这次寒假实践的经历,我学会了很多东西,学会了使用RP2040芯片,并使用该芯片输出了规定的PWM波。在未来,我会继续研究关于该芯片的应用,在未来研究更多关于有关该芯片在生活中各个方面的应用,进一步加深对该芯片的认知。与此同时,我也会继续支持硬禾学堂的各项活动。非常感谢硬禾学堂给我提供的这次机会,让我学到了很多。