树莓派Pico引脚不够用?巧用GPIO复用与隐藏测试点(TP1-TP6)扩展你的项目
当你的树莓派Pico项目变得越来越复杂,26个GPIO引脚可能突然显得捉襟见肘。别急着换开发板——Pico内部其实隐藏着更多可能性。本文将带你探索如何通过GPIO复用和那些常被忽视的测试点(TP1-TP6)来突破引脚限制,为你的项目解锁新维度。
1. GPIO复用:让每个引脚发挥多重作用
RP2040芯片的每个GPIO引脚都不只是简单的输入输出接口。通过Alternate Function(复用功能)配置,你可以让同一个引脚在不同时间扮演不同角色。
1.1 理解GPIO复用机制
RP2040的GPIO复用系统允许每个引脚被动态重映射到不同的内部外设。这意味着:
- 一个引脚可以上午做UART通信,下午变成PWM输出
- 同一组物理引脚可以按需切换为SPI或I2C接口
- 数字引脚可以临时"变身"为模拟输入(仅限GPIO26-29)
复用配置主要通过gpio_set_function()函数实现。以下是C SDK中的典型设置流程:
#include "hardware/gpio.h" // 将GPIO0设置为SPI0 RX功能 gpio_set_function(0, GPIO_FUNC_SPI);在MicroPython中更简单:
import machine spi = machine.SPI(0, sck=machine.Pin(2), mosi=machine.Pin(3), miso=machine.Pin(4)) # 即使这些引脚之前被用作其他用途,现在也会自动切换为SPI功能1.2 复用实战:创建第二组SPI接口
虽然Pico官方文档只提到两组SPI(SPI0和SPI1),但通过复用我们可以"创造"出更多:
| 引脚 | 默认SPI0功能 | 复用为SPI1功能 |
|---|---|---|
| GP2 | SPI0 SCK | SPI1 SCK |
| GP3 | SPI0 TX | SPI1 TX |
| GP4 | SPI0 RX | SPI1 RX |
| GP5 | SPI0 CSn | SPI1 CSn |
注意:同时使用多组SPI时需注意时钟冲突问题,建议不同时激活
2. 隐藏的宝藏:测试点(TP1-TP6)深度解析
Pico底部那六个神秘的测试点(TP1-TP6)远不止用于工厂测试。它们提供了直接访问关键信号的途径,是硬件黑客的秘密武器。
2.1 测试点功能速查表
| 测试点 | 主要功能 | 安全使用建议 |
|---|---|---|
| TP1 | 专用USB地线 | 连接USB设备时必接 |
| TP2 | USB D- | 需与TP3配对使用 |
| TP3 | USB D+ | 需与TP2配对使用 |
| TP4 | SMPS控制 | 不建议外部使用 |
| TP5 | LED控制 | 输出电压受限 |
| TP6 | BOOTSEL | 无需按钮即可烧录 |
2.2 实战应用:通过测试点扩展USB功能
想连接额外的USB设备但不想占用宝贵的GPIO?TP2和TP3就是答案:
- 准备四线电缆(包含D+, D-, GND和5V)
- 将TP2连接至设备的D-
- 将TP3连接至设备的D+
- TP1连接至设备地线
- 从VBUS(引脚40)获取5V电源
C SDK示例代码配置USB端口:
#include "pico/stdlib.h" #include "hardware/gpio.h" #include "tusb.h" void usb_task() { tud_task(); // 处理USB事件 if(tud_cdc_connected()) { uint8_t buf[64]; uint32_t count = tud_cdc_read(buf, sizeof(buf)); // 处理接收到的数据 } }3. 高级技巧:不按按钮的固件烧录
厌倦了每次更新固件都要按住BOOTSEL按钮?TP6可以解放你的手指:
- 在电路中添加一个NPN三极管或MOSFET
- 将集电极/漏极连接至TP6
- 发射极/源极接地
- 通过任一GPIO控制基极/栅极
这样就能通过代码触发烧录模式了:
import machine import time boot_pin = machine.Pin(14, machine.Pin.OUT) # 假设GPIO14控制烧录电路 def enter_bootloader(): boot_pin.value(1) # 拉高触发三极管 time.sleep_ms(100) machine.reset() # 重启进入烧录模式4. 电源管理:榨取每一毫瓦的性能
当引脚紧张时,合理管理电源可以释放出被占用的电源相关引脚:
- GPIO23 (SMPS控制): 通常保持低电平(PFM模式)。设为高电平可强制PWM模式,降低纹波但增加功耗
- GPIO24 (VBUS检测): 可用于检测USB连接状态,无需额外电路
- GPIO29 (VSYS监测): 通过ADC读取系统电压,实现电池电量监测
电源模式优化示例:
// 切换电源模式 void set_power_mode(bool high_perf) { gpio_init(23); gpio_set_dir(23, GPIO_OUT); gpio_put(23, high_perf); // 高性能模式=1,省电模式=0 }5. 极限挑战:当所有GPIO都用完时
即使复用和测试点都用上,有时还是需要更多接口。这时可以考虑:
- 矩阵扫描技术: 用N个引脚控制N×M个按钮/LED
- 移位寄存器: 如74HC595,3个GPIO扩展出8+个输出
- I2C/SPI扩展芯片: MCP23017等GPIO扩展器
- PIO程序: 用RP2040独有的可编程I/O实现定制接口
PIO示例:用单个引脚模拟WS2812B控制信号
import rp2 from machine import Pin @rp2.asm_pio(sideset_init=rp2.PIO.OUT_LOW, out_shiftdir=rp2.PIO.SHIFT_LEFT, autopull=True) def ws2812(): T1 = 2 T2 = 5 T3 = 3 wrap_target() label("bitloop") out(x, 1) .side(0) [T3 - 1] jmp(not_x, "do_zero") .side(1) [T1 - 1] jmp("bitloop") .side(1) [T2 - 1] label("do_zero") nop() .side(0) [T2 - 1] wrap() sm = rp2.StateMachine(0, ws2812, freq=8_000_000, sideset_base=Pin(15)) sm.active(1)通过这些技巧,我的一个气象站项目成功在仅使用Pico的情况下,同时驱动了传感器阵列、OLED显示屏、SD卡存储和无线模块。关键是把UART1复用到了原本用于LED的GPIO25上,并通过TP6实现了无线固件更新。