这个芯片确实非常棒。架构非常简洁,例如IO口根本不像其它MCU还分什么ABCD...port,而是统一操作,一个32bit ulong数按位操作就可以随意操作所有IO,对于有些场合(例如高位宽并行)就非常合适。另外它的双核编程也是不错,特别适合略复杂的分工合作。它最大的硬件亮点是PIO,通过微码以200M(典型超频时钟频率)节拍级精确度控制引脚,可以当做简单FPGA来用,玩法花样很多。更好的是它的开源生态很好。我去年发现了这个芯片,现在已经很喜欢它了,我觉得比STM32好玩得多。
之前主要使用Arduino Pro Micro单片机,几年前遇到过arduino单片机性能不够用的情况,当时就是换了teensy4.0单片机,完全兼容arduino,主频高达600MHz,各方面都好就是贵啊,得200多元一片。最近逛淘宝,发现一款很便宜的单片机RP2040,自称是可以兼容arduino。这个板子体积超小,主频高达133MHz还可以超频,内存也大,才十多块钱一片。抱着试试看的心态,买了一个回来测试,发现确实不错,经过一些简单设置可以兼容arduino,个别函数如定时中断有改变,实际是变得更简单了。这样以相同甚至更低的价格,极小的设置代价,就可以获得性能远超标准arduino板(32U4或328P)的单片机。
我做的试车台推力计使用这个板子替代Pro Micro,主频足够支持1000Hz以上采样率,内部闪存1MB以上,足够保存几百次试车数据,OLED显示刷新率也大为提高,特此推荐给大家。
1,器件
我购买的是无名科技的RP2040,另一个牌子SeeedStudio的XIAO RP2040我也试过,不大对劲,暂不细说。
通常情况下选2M(flash闪存)的就足够用了,这个板子性能方面就不用吹了,就看这长达600多页的说明书,你就知道这东西不简单。再看这十多块钱的价格,是不是很感人呢。
所以性能是不用担心的,主要看能不能直接用起来了。
2,Arduino IDE下的基本运行
同标准arduino板子一样,要用USB线将RP2040插到电脑USB口,然后按以下3个步骤操作,这里为了逻辑清晰使用倒序,实际应该按3、2、1操作:
2.1,同标准arduino单片机首次使用,总是需要在arduino开发软件IDE工具Tools菜单下,找到板子Board对应类型,2M flash的小板子选DFRobot Beetle RP2040就可以,如果是16M的,选Arduino Nano RP2040 Connect。
2.2,可是你会发现,根本找不到这个板子型号,它不在现有的菜单里。嗯,应该在Tools下面的Board里点Board Manager去搜索一下这个板子的驱动看看。得在弹窗里搜索到RP2040板子的驱动Arduino Raspberry Pi Pico/RP2040… by Earle F. … ,点安装,然后才能在Tools下Board里找到这种板子。
2.3,可是你又会发现Board Manager里搜索不到这个板子程序,因为你还需要在IDE界面的File下,点开Preferences,然后把板子管理程序的地址XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX Manager里搜索并安装这种RP2040板子的驱动,然后才能在Tools下Board里找到这种板子。
经过这三步,后面就简单了,下面一项Tools下的Port也要选对USB口,通常新板子或板子重启再插入的情况下,是UF2_Board,后来会变成一长串COM12(…RP2040…)。
连上板子以后,在IDE界面的File下Example里找个最简单的程序试一试,比如01. Basics的AnalogReadSerial,上传运行就可以了。打开工具Tools下串口绘图Serial Plotter,可以看到波形,用手触碰A0脚,波形为50Hz正弦波,表明单片机能运行arduino基本程序了。
3,扩展应用
简单的应用到上述2就足够了,这里再补充一些稍复杂一点的应用。
3.1 首先可以#include各种h文件,反正这个板子内存够大。有一些RP2040的特有函数是放在这些h文件里的。
#include <Arduino.h>
#include <stdio.h>
#include <pico/stdlib.h>
#include <hardware/uart.h>
#include <hardware/gpio.h>
#include <hardware/divider.h>
#include <hardware/timer.h>
#include <hardware/clocks.h>
#include <EEPROM.h>
比如定时中断函数就放在timer.h里,然后超频设置函数就放在clock.h里。具体说明可以百度RP2040 C/C++ SDK,有好几百页,各种功能设置相当复杂,这里只举例说两个常用的功能。
3.2 数据存储及模拟EEPROM
这个板子没有EEPROM,但是flash大,可以在Tools下的菜单里选择flash分1MB容量出来做数据存储。上述3.1中include的EEPROM.h,里面有模拟的EEPROM读写函数,可以直接访问部分flash存储空间。在include了EEPROM.h的情况下,在void setup()中开启EEPROM
EEPROM.begin(1024);
然后用for循环顺序写入多个数据点进EEPROM映射的缓存上(此时还没真正写入)
EEPROM.write(j*2+1,F0[j]/2/255);
然后用flash写入命令固定数据到EEPROM定义的flash上,就可以掉电保存了
EEPROM.commit();
读出也是用循环逐点读出数据,每个数据是8位二进制也就是0-255,如果大于255或小于0的数,就得占用2个或以上的存储单元了。
uint8_t FL = EEPROM.read(i*2+0);
更复杂的数据存储办法是直接把数据存成文件,这个板子甚至可以把flash设置成U盘来使用,就是说你可以把数据存到板子上成为一个文本文件,然后插上USB线在电脑就能看见这个文件,直接能拷走文件。比如下例简单代码就能在电脑上看到一个新的U盘,里面有一个数据文件。在16M板子的情况下,可以得到一个15MB的U盘,可以存储数百次试车数据。
#include <Arduino.h> // 引入 Arduino 核心头文件
#include <stdio.h>
#include <pico/stdlib.h>
#include <FatFS.h>
#include <FatFSUSB.h>
void setup() {
Serial.begin(115200);
char buff[32];
int cnt = 1;
sprintf(buff, "%d\n%d\n%d\n", cnt+2, 190, 5000);
sprintf(buff+strlen(buff), "%d\n%d\n%d\n", cnt+5, 333, 422);
FatFS.begin();
File f = XXXXXXXXXXXXXXXXX("counts.txt", "w");
f.write(buff, strlen(buff));
f.close();
FatFS.end();
// Start FatFS USB drive mode
FatFSUSB.begin();
}
void loop()
{
}
3.3 定时中断
以我写的推力测量代码为例,使用定时中断,会精确地每20ms采集一次数据,这样计算比冲的时候会比较准确。RP2040不能直接使用TimerOne.h或Timer2.h这两个库,不过它有更简单的定时中断函数:
struct repeating_timer timer;
然后在void setup(){}里,添加1行代码add_repeating_timer_ms(-20, F_Smp, NULL, &timer); 就可以启动定时中断,第一个参数-20就表示每20ms会中断,强制跳到函数F_Smp里去执行一次(推力测量)。
bool F_Smp(struct repeating_timer *t)
{
……
}
一个完整的定时中断例程如下,会每20ms在串口上输出数字,以及在数字口2输出一个50Hz方波,定时间隔最高可以设置-2也就是2us,能产生500kHz方波,不过这个时候串口输出就得注释掉,中间有个for循环20次是用来延时的,调整占空比便于观测
#include <Arduino.h>
#include <stdio.h>
#include <pico/stdlib.h>
#include <hardware/uart.h>
#include <hardware/gpio.h>
#include <hardware/divider.h>
#include <hardware/timer.h>
#include <hardware/clocks.h>
#define BUILTIN_LED 2
struct repeating_timer timer;
int i;
float x1=1;
int j;
bool repeating_timer_callback(struct repeating_timer *t)
{
gpio_put(BUILTIN_LED, 1);
Serial.println(i);
for(j=0;j<20;j++)
{
i=i*1;
}
gpio_put(BUILTIN_LED, 0);
return true;
}
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
set_sys_clock_khz(266000, true);
gpio_init(BUILTIN_LED);
gpio_set_dir(BUILTIN_LED, 1);
gpio_pull_up(BUILTIN_LED);
delay(100);
add_repeating_timer_us(-20000, repeating_timer_callback, NULL, &timer);
}
void loop(){
delay(25000);
Serial.println("XXXXXX...............Timer %d fired!");//, (int)id);
bool cancelled = cancel_repeating_timer(&timer);
}
这里只展示了RP2040如何替代Ardunio的方面,这当然只是RP2040强大性能的冰山一角,爱学习的朋友们可以查阅其C/C++ SDK说明书,比如定时器timer在第297页,有例程演示如何设置定时中断。
值得注意的是,说明书中的C/C++例程一般是主函数int main(){}方式,要把那里面语句放到arduino的void setup(){}和void loop(){}板子才认,厉害一点的也可以直接在arduino IDE下用C编程,略微麻烦一些。还有两个连接,有arduino IDE下对树莓派Pico编程的代码说明:
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
总之,使用RP2040板替代标准arduino板,简单易行,可以在不增加成本的情况下,获得极大的性能升级,值得推广。
这个芯片确实非常棒。架构非常简洁,例如IO口根本不像其它MCU还分什么ABCD...port,而是统一操作,一个32bit ulong数按位操作就可以随意操作所有IO,对于有些场合(例如高位宽并行)就非常合适。另外它的双核编程也是不错,特别适合略复杂的分工合作。它最大的硬件亮点是PIO,通过微码以200M(典型超频时钟频率)节拍级精确度控制引脚,可以当做简单FPGA来用,玩法花样很多。更好的是它的开源生态很好。我去年发现了这个芯片,现在已经很喜欢它了,我觉得比STM32好玩得多。
RP2040开发板我也有一片 但是我觉得这个是要慎重选择的 选择这个 不如把学习方向换为传统STM32或者RISC-V
它本身也是也是cortex M0+的 和低端STM32内核一样 虽然有PIO 可以模拟一些简单或者特殊外设 但是在外设方面 还是弱于传统STM32的 尤其在定时器方面
产品线也比较少 应用上比较受限 开发环境较其他的STM32 选择也少
如果不是用开发板 需要自己设计硬件 得使用片外flash 有点麻烦 也没有什么集成好的模组可选择
不过在用micropython的时候 因为较大的flash和RAM 比其他STM32有较大的性价比 可以当成Arm+micropython的最具性价比选择
至于用flash当U盘或EEPROM的想法 实验性或者DIY玩玩可以 但正式的应用要谨慎考虑flash的寿命 采用磨损均衡的算法
对于非专业的爱好者,STM32学习成本会不会比较高?我现在教理科学生arduino三个学时就学完大部分内容了。
这篇文章主要想说RP2040确实可以兼容arduino,很小代价获得性能大幅提升。要说arduino、树莓派、STM32学哪个好,这得看专门讨论了,网上有不少帖子说这个问题。
爱好者级别的应用中flash擦除寿命也不是问题,本身就有10万次,加上它容量大,文件写满才会擦除覆盖。像我另一个帖子做的推力采集,5000段数据才会满,估计多数人一辈子也不会试那么多次车
网上有不少探讨Ardunio、树莓派、STM32的适用范围,是可以分得比较清楚的。首先,对于非电专业的爱好者来说,arduino应该是很好的选择,最容易上手。其次,很多个性化研究中的小任务、小装置,使用Ardunio也足以胜任,很灵活高效,比如我们在的大型仪器上增加外围组件、增加辅助功能,都使用arduino。而专业开发、量产的工业品,肯定都是直接用芯片、画PCB,即使用STM32也不会用开发板来搭。
网上有不少探讨Ardunio、树莓派、STM32的适用范围,是可以分得比较清楚的。首先,对于非电专业的爱好者来说,arduino应该是很好的选择,最容易上手。其次,很多个性化研究中的小任务、小装置,使...
看来楼主是学校里的老师。那么楼主的选择没错,arduino或树莓派是首选。搞研究和教学的人搭实验环境,MCU环境首先考虑的就是性能够用下的开发友好。这个需求和我的需求是一致的。我同事用STM32,我经常帮他debug,做过比较,我觉得STM32的程序远远不如树莓派的清晰。以数据搬运为例,SPI-DMA-以太网或SPI,做个程序打通这条搬运路径,树莓派的程序组织清晰模块隔离严谨,而STM32的就互相纠缠,DMA的结束中断回调函数和SPI还能扯到一起,结构上挺垃圾的,当然适应了就好。我不以嵌入式MCU谋生,所以只要树莓派够用我就继续蜷缩在树莓派之中。相对于学STM32的低性价比(高代价:浪费生命的顺从性学习内容过多;低性能:会STN32的满大街都是,再怎么学也是和月薪仅一两万的工程师竞争),把我省出来的时间用来做电子娱乐和电子进阶明显更划算。
在arduino生态里, tenny4.x确实是无敌的存在, 甚至在传统mcu的里rt106x也有一席之地。
平民芯片pico这个确实性能够好,相比之下avr就没啥玩头。
再几个好玩的就是esp32的wifi,nordic的蓝牙.