基于树莓派PICO的带屏12指神探平台的多路PWM波形发生器设计
该项目使用了树莓派PICO的带屏12指神探平台,实现了多路PWM波形发生器设计的设计,它的主要功能为:生成多路最高12MHz的可调脉宽调制(PWM)信号,通过按键和拨轮调整参数。在LCD屏上展示当前信息。
标签
示波器
嵌入式系统
MicroPython
树莓派PICO
RP2040
屏幕显示
PWM波形
ARM Cortex-M0
amirror
更新2024-04-11
21

一、项目需求

生成最大12MHz的PWM信号,每路的频率和占空比都可调,且遵循重复频率越高,占空比分辨率越低

使用开发板上的按键和拨轮组合达到所有参数可调

在LCD屏幕上显示信息,当前使用引脚、及其PWM参数

 

二、需求分析

1、根据原理图,12Pin中有4路支持PWM输出的针脚,并且每路分别有2个通道,在实现时就需要使用这4路中的3路,每路使用其中一个引脚即可。

2、在实现按键和拨轮控制时,可以使用按键控制要修改的选项。可修改的选项分别为:引脚号、占空比、频率这三项,占空比调节精度则随频率的修改而变化,最小为1/1000。这里为了实现方便并且控制准确,按键设计为每按下一次数值发生一个单位的变化。

3、LCD上就分别用文字来显示这些信息即可,按照上述修改思路设计界面,大概示意图如下,在每一项的最前面,使用*号来指示当前正在修改的选项,使用拨轮左右按下来修改当前参数。使用两个按键来切换修改项。当修改项为引脚时,切换引脚,其他参数也会跟随切换为对应引脚上次调节后的参数(必须可以保存每个引脚上次调节后的状态,不能够切换引脚后就丢失参数,并且其他引脚的PWM还在同时输出),*号位置和选中修改pin可循环滚动。

* pin: 22
  duty: 40.0%
  f: 12000000Hz
  dutyacc: 10%

4、硬件框图

image.png


三、实现效果

第一路

3280/8337 = 39.3%

第二路

40/80 = 50%

第三路

590/842 = 70%

由于采样误差以及设置标记点位置问题,1%差距基本可以认为是误差导致。

具体动态效果演示见演示视频


四、实现方式

本项目使用官方所推荐的micropython进行编程实现。

4.1 构建三路PWM波

根据需求分析,需要同时保存3路PWM波并且输出,我想到了用类的方式来做具体实现,对参数进行保存与操作。下面是类的总体结构与包含参数,通过实例化时调用构造函数的方式绑定引脚,并且在后面通过调用类中的方法来实现对PWM参数的修改,并把这些参数进行输出与显示。

class PWMInfo:
def __init__(self, pin):
self.pin = pin
self.duty = 32332 # 占空比默认为49%
self.duty_accuracy = 10 # 占空比调节精度默认为10
self.frequency = 12000000 # 默认频率为12M
# =========================控制函数========================
def DutyAddFunc(self):
def DutySubFunc(self):
def FreqMulFunc(self):
def FreqDivFunc(self):
# =========================输出函数========================
def LCDDisplay(self):

把实例化后的3个对象保存在同一个列表中,方便调用:

pwm_list = (PWMInfo(20), PWMInfo(22), PWMInfo(24))


4.2 按键的控制思路与菜单切换思路

按键即为我们常见的按键,滚轮,通过分析电路图可以发现,其就是一个同时集成了三个按键的器件。我们只需要把他们分别看作3个按键即可。二者在代码的实现方式上并没有不同。

按键的初始化:通过设置引脚来实现。指定引脚号,设置输入输出方向,最后因为在电路中没有对应的上拉下拉电阻来给按键提供电平变化,所以需要设置为上拉,即按下按键时为低电平,未按下为高电平。

buttonM = Pin(5,Pin.IN, Pin.PULL_UP) #B

在进行按键控制的时候,一个很好的方法就是使用按键中断。在micropython中,按键中断十分简单,这里参考micropython官方文档中的使用方法。(以ButtonR,即滚轮的右侧按钮为例)

buttonR.irq(ButtonRISRHandler, Pin.IRQ_FALLING)

使用上述语句注册中断,第一个参数传入一个函数,用于写需要实现的方法(注意按键消抖),第二个参数时中断的触发方式,这里是下降沿触发即当按键按下触发。

按键消抖函数实现方式:

debounce_time = 0
def KeyDisstableFunc(pin):
global debounce_time
if (pin.value() is 0) and (time.ticks_ms()-debounce_time > 100):
debounce_time=time.ticks_ms()
while pin.value() is 0:
if pin.value() is 1:
return 1
else:
return 0

在刚才提到的中断的方法函数中,会默认传入一个参数Pin,再把这个参数传递给按键消抖函数即可实现代码的复用(而不是复制)。具体的实现思路是,判断当按键按下时(pin的值为0),并且稳定处于这个状态的时间大于100ms,就认为此时按键已经处于稳定状态,则进入按键松开状态的判定(为了实现按一次按键数值变化一单位)。以上条件全部满足则返回1。否则如果是不稳定的状态则会返回0。返回值配合方法函数实现功能的控制。

按键控制菜单:

定义一个全局变量用于指示当前星号所处的位置即当前拨动拨轮发生修改的参数,当按键按下,位置值改变,可修改参数也发生改变。变动后,重新绘制用于指示的星号到对应行,刷新针脚显示(该函数逻辑较为简单,文中不再赘述,可自行查看代码)。这里函数的开头也可以看到在上文中所提到的按键消抖函数。

star_location = 0
def ButtonMISRHandler(Pin):
global star_location # star_location 作为全局变量来指示当前状态
interrupt_flag = KeyDisstableFunc(Pin)
if interrupt_flag is 1:
if star_location == 0:
star_location = 2
else:
star_location -= 1
MenuDisplayFunc()
else:
pass

当星号移动到对应位置,下面就是对特定值的修改,通过拨轮的左右两个按钮触发:

curr_pin = 0
def ButtonRISRHandler(Pin):
global curr_pin
pin_use = pwm_list[curr_pin]
interrupt_flag = KeyDisstableFunc(Pin)
if interrupt_flag is 1:
if star_location == 0:
if curr_pin == 2: # pwm引脚列表最大元素数
curr_pin = 0
else:
curr_pin += 1
elif star_location == 1:
pin_use.DutyAddFunc()
elif star_location == 2:
pin_use.FreqMulFunc()
pwm_list[curr_pin].LCDDisplay()
else:
pass

这里再声明一个全局变量用于指示当前的引脚,(代码中如此频繁的使用两次全局变量的理由是:这两个变量一次仅在一个函数中被修改,但是在整个代码中有多次需要读取,他们的性质是用来指示状态,才会放心的使用全局变量,否则请慎用全局变量。)通过判断*号位置来决定需要调用的方法,以实现修改。最后,当只有按键被按下时,才会发生数值的变化,此时才需要刷新屏幕,如果没有按下则保持,可以节约CPU的功耗。

具体的占空比、频率修改的函数都在PWM类中,逻辑也比较简单,在此不过多赘述。可自行参看代码文件


4.3 屏幕显示

屏幕显示驱动在拿到开发板的时候官方已经内置了,甚至还附带了一个使用demo,主要需要关注的是显示文本的这个方法

text(self, font, text, x0, y0, color=WHITE, background=BLACK)

我们只需要直接把我们需要显示的内容转换为字符串类型直接传给text参数即可。

display.text(font2, "pin:" + pin_str + "  ", 30, 10)


五、感想与心得

使用micropython来编写嵌入式设备确实十分简单易上手,但相应的由于其语言特性,远远没有C语言编译执行效率高,我认为可以用来做一些快速简单的开发。但是对于本身性能就不是很强的嵌入式设备来说,对于CPU的资源利用率和执行效率还是十分重要的,最终还是需要回归到C语言上面。


六、参考资料

本项目详情页

micropython官方手册

附件下载
task1_v2.zip
把main.py,st7789.py,test文件夹全部上传到开发板的/路径下
团队介绍
团队成员
amirror
评论
0 / 100
查看更多
目录
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2023 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号