新一代微控制器:深入了解 Raspberry Pi RP2350

新一代微控制器:深入了解 Raspberry Pi RP2350

Raspberry Pi RP2350 是 Raspberry Pi 推出的新一代微控制器,它在上一代 RP2040 的基础上进行了重大改进。本文将深入探讨 RP2350 的功能特性、与 RP2040 的比较、A 和 B 型板的差异、开发选择和限制、GPIO 引脚特点以及应用案例,特别关注 USB 主机和设备模拟相关的例子。

1. RP2350 的功能特性

RP2350 是一款强大的微控制器,具有以下关键特性:

  • 双核架构:RP2350 搭载了双核 Arm Cortex-M33 处理器或 Hazard3 RISC-V 处理器,运行频率高达 150 MHz,性能远超 RP2040。

  • 丰富的内存:它拥有 520 kB 的片上 SRAM,分为 10 个独立的存储区,并支持通过专用 QSPI 总线连接高达 16 MB 的外部 QSPI 闪存/PSRAM,此外还可通过可选的第二个芯片选择连接额外的 16 MB 闪存/PSRAM。

  • 多功能外设:RP2350 集成了丰富的外设,包括 2 个 UART、2 个 SPI 控制器、2 个 I2C 控制器、24 个 PWM 通道、支持主机和设备模式的 USB 1.1 控制器和 PHY、12 个 PIO 状态机以及 1 个 HSTX 外设。

  • 片上电源管理:它内置了开关模式电源,可生成内核电压。

  • 灵活的封装选项:RP2350 提供 QFN-80 (10 × 10 mm) 和 QFN-60 (7 × 7 mm) 两种封装选择,并有带和不带封装内闪存的版本。

2. 与 RP2040 的比较

与上一代 RP2040 相比,RP2350 具有以下优势:

  • 更高的时钟频率:RP2350 的时钟频率为 150 MHz,而 RP2040 为 133 MHz。

  • 更多的引脚和 GPIO:RP2350 B 型号具有 80 个引脚和 48 个 GPIO,而 RP2040 只有 40 个引脚和 26 个 GPIO。

  • 更大的内存容量:RP2350 集成了 520 KB 的 SRAM,而 RP2040 只有 264 KB。 此外,RP2354 型号还内置了 2 MB 闪存,而 RP2040 则需要外部闪存芯片。

  • 更多的模拟输入:RP2350 B 型号具有 8 个模拟输入,而 RP2040 和 RP2350 A 型号只有 4 个。

  • 更强大的内核:RP2350 采用了 Arm Cortex-M33 内核,它基于 Armv8-M 架构,支持硬件除法和更多 32 位指令,性能和功耗都优于 RP2040 的 Arm Cortex-M0+ 内核。

  • 增强的安全性:Cortex-M33 内核增强了安全性,更适合物联网应用。

3. RP2350 A 和 B 型板的区别

RP2350 分为 A 和 B 两个型号,主要区别在于封装尺寸、引脚数量和 GPIO 数量:

  • RP2350A 采用 QFN-60 封装,具有 60 个引脚和 30 个 GPIO。

  • RP2350B 采用 QFN-80 封装,具有 80 个引脚和 48 个 GPIO。

此外,B 型号还具有 8 个模拟输入,而 A 型号只有 4 个。 选择哪种型号取决于项目的具体需求,如果需要更多的 GPIO 或模拟输入,则应选择 B 型号。

4. 开发选择和限制

RP2350 的开发工具和软件支持非常丰富,但也存在一些限制:

  • 官方 SDK:Raspberry Pi 提供了官方 SDK,支持使用 C/C++、MicroPython 和 CircuitPython 等语言进行开发。

  • VS Code 集成:推荐使用 Visual Studio Code 进行开发,它提供了 Raspberry Pi Pico 扩展,可以方便地创建、编译和调试项目。

  • 启动过程复杂:RP2350 的启动过程比 RP2040 复杂得多,需要仔细研究数据手册才能理解。

  • 工具链差异:RP2350 的工具链与 RP2040 不同,需要安装新的编译器和调试器。

  • 裸机编程挑战:由于启动过程和工具链的差异,进行裸机编程比较困难,需要深入了解芯片架构和启动流程。

5. RP2350 GPIO 的引脚特点

RP2350 的 GPIO 引脚具有以下特点:

  • 多功能性:每个 GPIO 引脚都可以连接到多种内部外设,也可以通过软件直接控制。

  • 模拟输入功能:部分 GPIO 引脚具有模拟输入功能,可以连接到 ADC 进行电压采样。

  • 可配置性:GPIO 引脚的方向、输出电平和输入电平都可以通过 GPIO 控制寄存器进行配置。

  • 隔离寄存器:RP2350 新增了隔离寄存器,可以在低功耗状态下保存焊盘状态,由软件清除。

6. 应用案例

RP2350 适用于各种应用场景,以下是一些与 USB 主机和设备模拟相关的例子:

  • USB 主机:RP2350 可以作为 USB 主机,连接 USB 设备,例如键盘、鼠标、U 盘等。它可以通过 USB 控制器和 PHY 与这些设备通信,并通过软件控制数据传输。

例如,可以将 RP2350 连接到 U 盘,读取存储在 U 盘上的文件,并将文件内容显示在 LCD 屏幕上。

  • 还可以将 RP2350 连接到键盘,读取键盘输入,并将输入内容发送到另一个设备,例如电脑或手机。

USB 设备模拟:RP2350 可以模拟各种 USB 设备,例如 HID 设备、串口设备、大容量存储设备等。它可以通过 USB 控制器和 PHY 与主机通信,并通过软件模拟设备的行为。

  • 例如,可以将 RP2350 模拟成一个 HID 设备,例如鼠标,并将 RP2350 上的传感器数据发送到电脑,控制电脑上的鼠标指针。

  • 还可以将 RP2350 模拟成一个串口设备,将 RP2350 上的 UART 数据发送到电脑,实现与电脑的串口通信。

RP2350 是一款功能强大且灵活的微控制器,它为各种应用场景提供了无限的可能性。 相信随着 RP2350 生态系统的不断发展,我们将看到更多基于 RP2350 的创新应用。


开发环境搭建

使用Arduino IDE开发

安装步骤

  1. 添加开发板支持
Arduino IDE → 文件 → 首选项 → 附加开发板管理器网址
添加: https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json
  1. 安装开发板包
工具 → 开发板 → 开发板管理器
搜索 "RP2040" 或 "Raspberry Pi Pico"
安装 "Raspberry Pi Pico/RP2040"
  1. 选择开发板
工具 → 开发板 → Raspberry Pi Pico
工具 → 端口 → 选择正确的串口

基础示例代码

// LED闪烁
void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  Serial.begin(115200);
}

void loop() {
  digitalWrite(LED_BUILTIN, HIGH);
  delay(1000);
  digitalWrite(LED_BUILTIN, LOW);
  delay(1000);
  Serial.println("Hello RP2350!");
}

使用C/C++ SDK开发

环境准备

# 安装依赖(Ubuntu/Debian)
sudo apt update
sudo apt install cmake gcc-arm-none-eabi libnewlib-arm-none-eabi build-essential

# 克隆SDK
git clone https://github.com/raspberrypi/pico-sdk.git
cd pico-sdk
git checkout master

# 设置环境变量
export PICO_SDK_PATH=/path/to/pico-sdk

创建项目

mkdir my_project && cd my_project

cat > CMakeLists.txt << 'CMAKE'
cmake_minimum_required(VERSION 3.13)
include($ENV{PICO_SDK_PATH}/external/pico_sdk_import.cmake)
project(my_project C CXX ASM)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)
pico_sdk_init()
add_executable(my_project main.c)
pico_add_extra_outputs(my_project)
target_link_libraries(my_project pico_stdlib)
CMAKE

cat > main.c << 'C'
#include "pico/stdlib.h"

int main() {
    stdio_init_all();
    const uint LED_PIN = 25;
    gpio_init(LED_PIN);
    gpio_set_dir(LED_PIN, GPIO_OUT);
    
    while (true) {
        gpio_put(LED_PIN, 1);
        sleep_ms(1000);
        gpio_put(LED_PIN, 0);
        sleep_ms(1000);
    }
    return 0;
}
C

编译和烧录

mkdir build && cd build
cmake ..
make

# 按住BOOTSEL按钮,连接USB,将.uf2文件拖拽到RPI-RP2磁盘

使用Python开发(MicroPython)

安装MicroPython固件

  1. 下载MicroPython UF2固件:https://micropython.org/download/RPI_PICO2/
  2. 按住BOOTSEL按钮,连接USB
  3. 将UF2文件拖拽到RPI-RP2磁盘

使用Thonny IDE

# 安装Thonny
sudo apt install thonny

MicroPython示例

# LED闪烁
from machine import Pin
import time

led = Pin(25, Pin.OUT)
while True:
    led.toggle()
    time.sleep(1)
# ADC读取
from machine import ADC, Pin
import time

adc = ADC(26)  # GP26
while True:
    value = adc.read_u16()
    voltage = value * 3.3 / 65535
    print(f"ADC: {value}, Voltage: {voltage:.2f}V")
    time.sleep(0.5)

高级功能应用

PIO(可编程IO)应用

PIO是RP2350的独特功能,允许用户自定义硬件状态机来处理IO操作。

应用案例

  1. WS2812 LED驱动
#include "hardware/pio.h"
#include "ws2812.pio.h"

#define LED_PIN 16
PIO pio = pio0;
uint sm = pio_claim_unused_sm(pio, true);
uint offset = pio_add_program(pio, &ws2812_program);
ws2812_program_init(pio, sm, offset, LED_PIN, 800000, false);

// 发送颜色数据
uint32_t color = 0xFF0000;  // 红色
pio_sm_put_blocking(pio, sm, color << 8);
  1. 自定义通信协议
.pio
.program custom_uart
.side_set 1

wrap_target
    set x, 7
    set pins, 0
    side 0
bitloop:
    out pins, 1
    side 1 [2]
    jmp x-- bitloop
    set pins, 1
    side 0 [2]
wrap

安全特性

Secure Boot配置

// 在CMakeLists.txt中启用
pico_set_binary_type(my_project copy_to_ram)

# 生成签名密钥
openssl genrsa -out private_key.pem 2048
openssl rsa -in private_key.pem -pubout -out public_key.pem

# 签名固件
python3 sign_firmware.py --key private_key.pem --input app.bin --output app_signed.bin

TrustZone应用

#include "hardware/structs/tz.h"

// 设置GPIO为非安全访问
tz_configure_gpio_nonsecure(15);

// 配置UART为非安全访问
tz_configure_peripheral_nonsecure(UART0_IRQn);

实战项目案例

项目1:USB HID键盘模拟器

功能:模拟USB键盘,实现自动输入

代码

#include "tusb.h"
#include "bsp/board_api.h"

typedef struct {
    uint8_t modifier;
    uint8_t reserved;
    uint8_t keycode[6];
} keyboard_report_t;

void send_key(uint8_t keycode) {
    keyboard_report_t report = {0};
    report.keycode[0] = keycode;
    tud_hid_keyboard_report(0, 0, report.keycode);
    sleep_ms(100);
    
    report.keycode[0] = 0;
    tud_hid_keyboard_report(0, 0, report.keycode);
}

int main() {
    board_init();
    tusb_init();
    
    while (true) {
        tud_task();
        // 检测按钮并发送按键
    }
    return 0;
}

项目2:多通道数据采集系统

功能:8通道模拟信号采集,USB传输到PC

硬件

  • RP2350开发板
  • CD4051模拟多路复用器
  • 8路模拟信号输入

代码框架

#include "hardware/adc.h"
#include "hardware/gpio.h"

#define MUX_PIN_0 16
#define MUX_PIN_1 17
#define MUX_PIN_2 18
#define ADC_PIN 26

void select_channel(uint8_t channel) {
    gpio_put(MUX_PIN_0, channel & 0x01);
    gpio_put(MUX_PIN_1, (channel >> 1) & 0x01);
    gpio_put(MUX_PIN_2, (channel >> 2) & 0x01);
    sleep_us(10);
}

void acquire_data(void) {
    adc_init();
    adc_gpio_init(ADC_PIN);
    adc_select_input(0);
    
    for (int ch = 0; ch < 8; ch++) {
        select_channel(ch);
        uint16_t value = adc_read();
        printf("Channel %d: %d\n", ch, value);
    }
}

int main() {
    stdio_init_all();
    
    // 初始化GPIO
    gpio_init(MUX_PIN_0);
    gpio_init(MUX_PIN_1);
    gpio_init(MUX_PIN_2);
    gpio_set_dir(MUX_PIN_0, GPIO_OUT);
    gpio_set_dir(MUX_PIN_1, GPIO_OUT);
    gpio_set_dir(MUX_PIN_2, GPIO_OUT);
    
    while (true) {
        acquire_data();
        sleep_ms(1000);
    }
    return 0;
}

性能优化技巧

内存优化

  1. 使用XIP(Execute In Place)
// 将常量数据放在Flash中
const uint8_t lookup_table[256] __attribute__((section(".rodata"))) = {
    // 数据...
};
  1. 动态内存管理
// 使用内存池而非malloc
#define POOL_SIZE 4096
static uint8_t memory_pool[POOL_SIZE];
static size_t pool_offset = 0;

void* pool_alloc(size_t size) {
    if (pool_offset + size > POOL_SIZE) return NULL;
    void* ptr = &memory_pool[pool_offset];
    pool_offset += size;
    return ptr;
}

功耗优化

  1. 使用睡眠模式
#include "hardware/structs/scb.h"

void enter_sleep(void) {
    // 配置唤醒源
    // ...
    
    // 进入睡眠
    __wfi();  // Wait For Interrupt
}
  1. 动态调整时钟频率
#include "hardware/clocks.h"

// 降低系统时钟以节省功耗
set_sys_clock_khz(48000, true);  // 48MHz

常见问题解答

Q1:RP2350与RP2040代码兼容吗?

A:大部分代码兼容,但需要注意:

  • PIO指令集有差异
  • 新增的安全特性需要额外配置
  • 部分寄存器地址不同
  • 建议使用新版SDK

Q2:如何选择ARM Cortex-M33还是RISC-V?

A

  • ARM Cortex-M33:生态成熟,工具链完善,适合大多数应用
  • RISC-V:开源架构,未来潜力大,适合研究和特定场景

Q3:如何调试PIO程序?

A

  • 使用PIOASM编译器预编译
  • 通过调试器查看PIO状态机
  • 使用逻辑分析仪观察IO波形
  • 添加调试输出到UART

Q4:RP2350适合做音频处理吗?

A

  • 适合简单音频应用(I2S、PWM输出)
  • 不适合复杂DSP(算力有限)
  • 可以使用外部DAC提高音质
  • 建议采样率不超过48kHz

学习资源推荐

官方资源

社区资源

教程和视频

  • YouTube:搜索 “RP2350 tutorial”
  • B站:搜索 “树莓派Pico”
  • GitHub:搜索 “rp2350-examples”

书籍推荐

  • 《Raspberry Pi Pico for Beginners》
  • 《Getting Started with MicroPython on Raspberry Pi Pico》
  • 《Embedded Systems with RP2040》

总结

RP2350是一款功能强大的微控制器,相比RP2040有显著提升:

核心优势

  • ✅ 更强的CPU性能(Cortex-M33 vs M0+)
  • ✅ 翻倍的SRAM(520KB vs 264KB)
  • ✅ 增强的安全特性(TrustZone、Secure Boot)
  • ✅ 更多的PIO状态机(12个 vs 8个)
  • ✅ AI加速能力(DSP扩展)

适用场景

  • 需要更高性能的应用
  • 安全性要求高的场景
  • 复杂IO控制需求
  • 边缘AI推理
  • USB设备和主机应用

开发建议

  1. 从官方示例开始,熟悉基础功能
  2. 充分利用PIO进行创新IO设计
  3. 利用安全特性保护产品
  4. 参与社区,分享和学习经验

RP2350为嵌入式开发带来了更多可能性,相信随着生态系统的完善,会有更多创新应用涌现。开始你的RP2350之旅吧!


相关资源: