1.项目需求
- 利用拓展板上的电位计调节电压从0-3.3V之间变化
- 在OLED显示屏上显示电压值
2.完成的功能
读取电位计电压并显示在OLED显示屏上
- 设计平台:Thonny
- 编写语言:MicroPython
- 编写环境:Win10
- 硬件平台:基于STEP Pico的嵌入式系统学习平台
3.程序流程图
4.硬件介绍
(1)核心板介绍
微控制器RP2040的性能指标:
- 双核 Arm Cortex-M0+ @ 133MHz
- 264KB 片内RAM,内部6个独立的RAM块, 在总线中心进行交换,可以让内核和DMA并行运行而无冲突
- 通过专用的QSPI总线可以支持最高16MB的片外Flash存储器
- DMA控制器
- Interpolator and integer divider peripherals
- 30 GPIO管脚, 其中的4个可以用于模拟输入
- 2 × UARTs, 2 × SPI控制器, 和2 × I2C控制器
- 16 × PWM通道
- 1 × USB 1.1控制器和PHY,支持Host和Device
- 8 × 树莓派可编程I/O状态机
- USB存储启动模式并支持UF2, 可以通过拖拽进行编程
- 7*7 56管脚的QFN封装
STEP Pico完全兼容树莓派官方Pico的核心模块,并在其基础上增加了4个WS2812彩色灯,一个电源指示灯,以及一个复位按键,USB端口也改成了先进的Type C。
(2)拓展板介绍
- 2个按键输入
- 4个单色LED
- 12个WS2812B RGB三色灯
- 1个姿态传感器
- 1个128*64 OLED显示屏
- 1个蜂鸣器
- 1个可调电位计(用于电压表)
- 1路音频信号输入(用于示波器)
- 8位R-2R电阻网络构成的DAC(用于DDS信号发生器)
5.部分选用模块
LED:
只需控制对应引脚的电平即可进行控制,有GPIO13、GPIO14、GPIO15
OLED:
使用SPI进行连接。
串行外设接口(SPI)是微控制器和外围IC(如传感器、ADC、DAC、移位寄存器、SRAM等)之间使用较广泛的接口之一。SPI是一种同步、全双工、主从式接口。来自主机或从机的数据在时钟上升沿或下降沿同步。主机和从机可以同时传输数据,但本设备中OLED作为从设备使用。
使SPI作为串行通信接口脱颖而出的原因很多:
- 全双工串行通信;
- 高速数据传输速率。
- 简单的软件配置;
- 极其灵活的数据传输,不限于8位,它可以是任意大小的字;
- 非常简单的硬件结构。从机不需要唯一地址(与I2C不同)。从机使用主机时钟,不需要精密时钟振荡器/晶振(与UART不同)。不需要收发器(与CAN不同)。
4线SPI器件有四个信号:
- 时钟(SPI CLK, SCLK)
- 片选(CS)
- 主机输出、从机输入(MOSI)
- 主机输入、从机输出(MISO)
产生时钟信号的器件称为主机。主机和从机之间传输的数据与主机产生的时钟同步。同I2C接口相比,SPI器件支持更高的时钟频率。
SPI接口只能有一个主机,但可以有一个或多个从机。来自主机的片选信号用于选择从机。这通常是一个低电平有效信号,拉高时从机与SPI总线断开连接。当使用多个从机时,主机需要为每个从机提供单独的片选信号。
MOSI和MISO是数据线。MOSI将数据从主机发送到从机,MISO将数据从从机发送到主机。
因为我们的从机只有OLED屏,且OLED不需要向主机(rp2040)发送数据,所以我们没有CS和MISO信号。具体接线可看下图
电位计:
使用rp2040内部ADC进行读取电压并转换,该部分的操作很简单,只需几步函数调用即可,其对应的引脚是GPIO28
6.主函数代码
各行代码作用已经标注在注释中。
from machine import Pin, SPI, ADC
from ssd1306 import SSD1306_SPI
import framebuf
from time import sleep
from utime import sleep_ms
from board import pin_cfg
from oled import oled
spi = SPI(1, 100000, mosi=Pin(pin_cfg.spi1_mosi), sck=Pin(pin_cfg.spi1_sck))
oled = SSD1306_SPI(128, 64, spi, Pin(pin_cfg.spi1_dc),Pin(pin_cfg.spi1_rstn), Pin(pin_cfg.spi1_cs))
oled.rotate(1)
adc = ADC(Pin(28)) # create ADC object on ADC pin
#设置LED对应引脚输出
r = Pin(pin_cfg.red_led, Pin.OUT)
g = Pin(pin_cfg.green_led, Pin.OUT)
b = Pin(pin_cfg.blue_led, Pin.OUT)
while True:
r.off()#关闭红色LED
g.off()#关闭绿色LED
b.off()#关闭蓝色LED
oled.fill(0)
oled.show()#清空OLED显示
a=adc.read_u16() # read value, 0-65535 across voltage range 0.0v - 3.3v
value=a*3.3/65535#计算电压值
if value <= 1.1:#判断电压所处的范围,给使用者直观的感受
b.on()
elif value > 1.1 and value < 2.2:
g.on()
elif value >= 2.2:
r.on()
valuestr='%f' %value#将测得电压转换成字符串
oled.text("Value:",1,1)
oled.text(valuestr,50,1)
oled.show()#OLED显示测量的电压值
print(value)#串口输出电压值
sleep_ms(100)#延时
7.效果展示
8.未来计划
本次参加了多项活动,但只完成了这一个项目,不得不说micropython是真的好用(人生苦短,我用python!),仅用很短的代码就能实现所需要的功能,是一个很好的机会来入门嵌入式,但是我也发现了自己目前并未进一步深入的了解单片机,曾经想搭建C++环境来编写代码,奈何英语水平不够,搞半天搞不好,只能放弃。我也参加了其他项目,比如esp32、sipeed,但发现还有好多要学的新知识:虚拟机、linux、freertos……然后进展就很慢,没能顺利完成所有项目。这也算是一次开阔视野的机会了,单片机在手,可不能让他们吃灰了。希望我继续保持对嵌入式的热爱,学习更多新知识,做出更好的作品,也感谢电子森林给我们提供这样的机会,假期也能不断提升自己,让我有为自己热爱的事物努力的机会。我还会继续参加这样的活动,但不能再像这次太贪心了,参加两个项目也许就够我闲暇时间折腾了=v=