Arduino Giga R1 WiFi¶
Arduino Giga R1 WiFi 是一块 101 × 53 mm 的 Mega 外形规格开发板,围绕意法半导体(STMicroelectronics)的 STM32H747XI 构建——这是一款双核 SoC,将主频 480 MHz 的 Cortex‑M7 与主频 240 MHz 的 Cortex‑M4 结合在一起。OpenMV 固件完全运行在 M7 核上。在标准 Arduino Mega 排针布局的基础上,Giga 还增加了一个 22 针 Arducam 摄像头柔性连接器、一个用于 Arduino Giga Display Shield 的 MIPI‑DSI 连接器,以及一个 3.5 mm 立体声音频插孔。
完整的数据手册、照片和尺寸信息请参阅 Arduino Giga R1 WiFi 产品页面。
亮点¶
意法半导体 STM32H747XI 双核 Cortex‑M7(480 MHz)+ Cortex‑M4(240 MHz)。OpenMV 固件仅运行在 M7 核上;M4 核通过 openamp 暴露出来,用于处理器间通信。
8 MB 外部 SDRAM,外加 2 MB 内部闪存 和 16 MB 外部 QSPI 闪存。
硬件 JPEG 编码器/解码器。
22 针 Arducam 兼容摄像头柔性连接器(
J6)——驱动支持 OV5640(5MP)、OV7670、GC2145、HM01B0 和 HM0360 传感器模块。MIPI‑DSI 显示连接器(
J5),用于 Arduino Giga Display Shield(480×800 电容式触摸屏),另有一个 LTDC RGB 显示引擎可用于高级载板。3.5 mm 音频插孔,带立体声线路输出和麦克风输入。
Wi‑Fi b/g/n(2.4 GHz)+ Bluetooth LE 5.1,通过 Murata 1DX(CYW4343W)模块实现——经由板载 U.FL 连接器 连接随附的天线。
USB‑C(全速),用于供电 / 串口 / 编程。
用户 I/O 位于 Mega 风格的排针上——
D0–D75(数字)、A0–A11(模拟)、DAC0/DAC1(DAC 输出)、CAN_RX/CAN_TX(FDCAN2),以及内排的SDA1/SCL1I²C 引脚对。开发板正面有一个独立的 6 针 SPI1 排针,引出CIPO/COPI/SCK(D89/D90/D91)。JTAG / SWD 引出至顶部的调试排针,供高级调试使用。
引脚分布¶
引脚参考¶
Arduino Mega 风格的排针提供 76 个数字引脚(D0–D75)、12 个模拟引脚(A0–A11)、两个 DAC 输出(DAC0/DAC1)、一个辅助 I²C 引脚对(SDA1/SCL1),以及一个 FDCAN2 引脚对(CAN_RX/CAN_TX)。开发板正面有一个独立的 6 针 SPI1 排针,引出 CIPO/COPI/SCK(D89/D90/D91)。
引脚名称 |
参考 |
功能 |
|---|---|---|
D0 |
3.3 V |
USART1 RX (Serial1) / TIM4 CH2 |
D1 |
3.3 V |
USART1 TX (Serial1) / TIM1 CH2 |
D2 |
3.3 V |
TIM2 CH4 / TIM5 CH4 / USART2 RX |
D3 |
3.3 V |
TIM2 CH3 / TIM5 CH3 / USART2 TX |
D4 |
3.3 V |
TIM8 CH1 / UART8 TX |
D5 |
3.3 V |
TIM3 CH2 / SPI1 MOSI / SPI6 MOSI |
D6 |
3.3 V |
TIM4 CH2 |
D7 |
3.3 V |
TIM3 CH1 / SPI1 MISO / SPI3 MISO / SPI6 MISO |
D8 |
3.3 V |
TIM4 CH3 / I2C1 SCL / I2C4 SCL / UART4 RX |
D9 |
3.3 V |
TIM4 CH4 / I2C1 SDA / I2C4 SDA / UART4 TX |
D10 |
3.3 V |
TIM1 CH1 / TIM8 CH3N |
D11 |
3.3 V |
TIM8 CH2 / SPI5 MOSI |
D12 |
3.3 V |
TIM8 CH2N / SPI5 MISO |
D13 |
3.3 V |
TIM12 CH1 / SPI5 SCK |
D14 |
3.3 V |
USART6 TX (Serial2) / SPI6 MOSI |
D15 |
3.3 V |
USART6 RX (Serial2) / TIM3 CH2 / TIM8 CH2 |
D16 |
3.3 V |
UART4 TX (Serial3) / TIM8 CH1N |
D17 |
3.3 V |
UART4 RX (Serial3) |
D18 |
3.3 V |
USART2 TX (Serial4) |
D19 |
3.3 V |
USART2 RX (Serial4) / SPI3 MOSI |
D20 |
3.3 V |
I2C2 SDA / TIM2 CH4 / USART3 RX |
D21 |
3.3 V |
I2C2 SCL |
D22 |
3.3 V |
GPIO |
D23 |
3.3 V |
GPIO / SPI6 SCK |
D24 |
3.3 V |
GPIO / SPI6 MISO |
D25 |
3.3 V |
GPIO |
D26 |
3.3 V |
GPIO |
D27 |
3.3 V |
GPIO |
D28 |
3.3 V |
GPIO |
D29 |
3.3 V |
GPIO |
D30 |
3.3 V |
GPIO |
D31 |
3.3 V |
GPIO |
D32 |
3.3 V |
GPIO |
D33 |
3.3 V |
GPIO |
D34 |
3.3 V |
GPIO |
D35 |
3.3 V |
GPIO |
D36 |
3.3 V |
GPIO |
D37 |
3.3 V |
TIM8 CH2 |
D38 |
3.3 V |
TIM8 CH2N |
D39 |
3.3 V |
GPIO |
D40 |
3.3 V |
TIM15 CH2 / SPI4 MOSI |
D41 |
3.3 V |
GPIO |
D42 |
3.3 V |
GPIO |
D43 |
3.3 V |
GPIO |
D44 |
3.3 V |
GPIO |
D45 |
3.3 V |
GPIO |
D46 |
3.3 V |
TIM8 CH3N |
D47 |
3.3 V |
SPI3 MOSI |
D48 |
3.3 V |
TIM8 CH3 / SPI5 SCK |
D49 |
3.3 V |
GPIO |
D50 |
3.3 V |
GPIO |
D51 |
3.3 V |
TIM15 CH1 / SPI4 MISO |
D52 |
3.3 V |
GPIO |
D53 |
3.3 V |
GPIO |
D54 |
3.3 V |
TIM8 CH1(摄像头 DCMI VSYNC) |
D55 |
3.3 V |
I2C3 SDA(摄像头 DCMI HSYNC) |
D56 |
3.3 V |
TIM3 CH1 / TIM13 CH1(摄像头 DCMI PXCLK) |
D57 |
3.3 V |
TIM8 CH1N / UART8 RX(摄像头主时钟——TIM1 CH3) |
D58 |
3.3 V |
TIM8 CH3(摄像头 DCMI D7) |
D59 |
3.3 V |
TIM8 CH2(摄像头 DCMI D6) |
D60 |
3.3 V |
GPIO(摄像头 DCMI D5) |
D61 |
3.3 V |
TIM8 CH2N / UART4 RX(摄像头 DCMI D4) |
D62 |
3.3 V |
SPI1 SCK(摄像头 DCMI D3) |
D63 |
3.3 V |
TIM5 CH2 / I2C4 SCL(显示屏 I²C) |
D64 |
3.3 V |
TIM5 CH1(摄像头 DCMI D1) |
D65 |
3.3 V |
TIM12 CH2(摄像头 DCMI D0) |
D66 |
3.3 V |
GPIO(摄像头复位——摄像头激活时被占用) |
D67 |
3.3 V |
GPIO(摄像头掉电——摄像头激活时被占用) |
D68 |
3.3 V |
TIM3 CH1 / TIM8 CH1 / USART6 TX(Display Shield DSI RESET) |
D69 |
3.3 V |
TIM5 CH4(Display Shield DSI TE) |
D70 |
3.3 V |
SPI2 SCK |
D71 |
3.3 V |
TIM8 CH4 / SPI2 MISO |
D72 |
3.3 V |
SPI2 MOSI |
D73 |
3.3 V |
ADC123 IN11(Display Shield DFSDM 麦克风数据) |
D74 |
3.3 V |
GPIO(显示屏背光——被 Giga Display Shield 占用) |
D75 |
3.3 V |
SPI2 SCK(Display Shield DFSDM 麦克风时钟) |
A0 / D76 |
3.3 V |
ADC12 IN4 |
A1 / D77 |
3.3 V |
ADC12 IN8 |
A2 / D78 |
3.3 V |
ADC12 IN9 / TIM3 CH3 / TIM8 CH2N |
A3 / D79 |
3.3 V |
ADC12 IN5 / TIM3 CH4 / TIM8 CH3N |
A4 / D80 |
3.3 V |
ADC12 IN13 / SPI2 MOSI |
A5 / D81 |
3.3 V |
ADC123 IN12 / SPI2 MISO |
A6 / D82 |
3.3 V |
ADC123 IN10 |
A7 / D83 |
3.3 V |
ADC1 IN16 / TIM2 CH1 / TIM5 CH1(音频插孔麦克风输入) |
A8 |
3.3 V |
ADC3 IN0(仅模拟) |
A9 |
3.3 V |
ADC3 IN1(仅模拟) |
A10 |
3.3 V |
ADC12 IN1(仅模拟) |
A11 |
3.3 V |
ADC12 IN0(仅模拟) |
DAC0 / A12 / D84 |
3.3 V |
DAC1 OUT1 / ADC12 IN18(音频插孔线路输出 L) |
DAC1 / A13 / D85 |
3.3 V |
DAC1 OUT2 / TIM2 CH1 / SPI1 SCK / ADC12 IN19(音频插孔线路输出 R) |
D89 |
3.3 V |
SPI1 MISO(正面 SPI 排针上的 |
D90 |
3.3 V |
SPI1 MOSI(正面 SPI 排针上的 |
D91 |
3.3 V |
SPI1 SCK(正面 SPI 排针上的 |
CAN_RX / D93 |
3.3 V |
FDCAN2 RX / TIM3 CH2 / UART5 RX |
CAN_TX / D94 |
3.3 V |
FDCAN2 TX / SPI2 SCK / UART5 TX |
SDA1 / D102 |
3.3 V |
I2C4 SDA(显示屏触摸 / 摄像头控制总线) |
SCL1 / D101 |
3.3 V |
I2C4 SCL(显示屏触摸 / 摄像头控制总线) |
RESET |
3.3 V |
按下板载 RESET 按钮或拉至 GND 以复位 |
LED_RED |
3.3 V |
RGB LED 红色通道(低电平有效) |
LED_GREEN |
3.3 V |
RGB LED 绿色通道(低电平有效) |
LED_BLUE |
3.3 V |
RGB LED 蓝色通道(低电平有效) |
备注
A8–A11 是 STM32H747 上 _C 引脚的 纯模拟 焊盘——它们没有 GPIO 功能,只能通过 ADC 读取。
电源引脚¶
Mega 排针引脚:
VIN —— 6–32 V 输入。通过板载降压稳压器为开发板供电。
+5V —— 由 USB 经二极管或板载降压稳压器供给的 5 V 电源轨。
+3V3 —— 主 3.3 V 电源轨。
IOREF —— 反映开发板的 I/O 电压(3.3 V)。
AREF —— ADC 引脚的模拟电压基准。默认为 3.3 V;可外部驱动以使用不同的基准。
OFF —— 拉至 GND 以关闭 +3.3 V 电源轨并使系统关机。
VRTC —— 3.0 V 纽扣电池输入(最高 3.3 V),在开发板其余部分断电时保持片上 RTC 运行。
GND —— 公共地。
Giga R1 可以通过以下任意路径供电:
USB‑C —— 为板载降压稳压器提供 5 V。
VIN 引脚 —— 直接接入经稳压的 6–32 V 电源。
小技巧
使用 电池续航估算器 来估算在给定的激活 / 深度睡眠占空比下,Giga R1 用电池可以运行多久。
恢复和调试引脚¶
RESET —— 既是电源排针上引出的一个引脚,也是开发板顶部的一个瞬动开关,连接到 SoC 的 NRST 线。拉至 GND 或按下按钮即可复位。
Giga R1 使用 Arduino 标准的 双击复位 进入 Arduino 引导加载程序。快速按两下 RESET 按钮——开发板会通过 USB 重新枚举为 DFU 设备,OpenMV IDE 即可刷写新的固件镜像。
如果引导加载程序完全缺失,请在按下 RESET 的同时按住 BOOT0 按钮,强制 SoC 进入 ROM 引导加载程序模式。
STM32 的 SWD 信号引出至开发板正面的 10 针 1.27 mm Cortex 调试排针。通过 SEGGER J‑Link、ST‑Link 或任何标准 ARM JTAG/SWD 探针接线即可使用。所有调试信号均为 3.3 V 基准。
板载外设¶
LED¶
Giga R1 有一个用户 RGB LED,可通过 machine.LED 用软件控制:
from machine import LED
LED("LED_RED").on()
LED("LED_GREEN").on()
LED("LED_BLUE").on()
开发板上另有一个独立的 电源 LED,只要 +3.3 V 电源轨上电它就会点亮,无法由用户控制。
摄像头连接器(J6)¶
J6 是一个 22 针 Arducam 兼容摄像头柔性连接器。插入任何受支持的传感器模块,固件就会通过 csi --- 摄像头传感器 模块自动探测它们:
import csi
cam = csi.CSI()
cam.reset()
cam.pixformat(csi.RGB565)
cam.framesize(csi.QVGA)
cam.snapshot(time=2000) # let auto‑exposure settle
while True:
img = cam.snapshot()
受支持的传感器:
OV5640 —— 5 MP 彩色,最高支持 QSXGA(2592 × 1944)。
OV7670 —— 0.3 MP 彩色,最高支持 VGA(640 × 480)。
GC2145 —— 2 MP 彩色,最高支持 UXGA(1600 × 1200)。
HM01B0 —— 320 × 320 单色。
HM0360 —— VGA(640 × 480)单色。
警告
在摄像头初始化期间,固件会占用以下 Mega 排针引脚,这些引脚 无法使用:
引脚 |
原因 |
|---|---|
|
摄像头柔性连接器上的 DCMI 数据 + 同步信号 |
|
TIM1 CH3 —— 摄像头主时钟 |
|
摄像头 复位 GPIO |
|
摄像头 掉电 GPIO |
|
I²C 4 —— 与摄像头共享;总线可用,但应避开传感器的 I²C 地址 |
机器学习¶
ml --- 机器学习 在 Cortex‑M7 上使用 CMSIS‑NN 内核运行量化的 TFLite 模型——速度足以让紧凑型检测器以每秒几帧的速率运行。位于只读 /rom 文件系统上的模型可直接从闪存加载,无需复制到 RAM。下面是一个 128×128 的 BlazeFace 检测器,它在每一帧上叠加检测到的人脸及其六个关键点:
import csi
import time
import ml
from ml.postprocessing.mediapipe import BlazeFace
# Initialize the sensor.
csi0 = csi.CSI()
csi0.reset()
csi0.pixformat(csi.RGB565)
csi0.framesize(csi.VGA)
csi0.window((400, 400))
# Load built-in face detection model
model = ml.Model("/rom/blazeface_front_128.tflite", postprocess=BlazeFace(threshold=0.4))
print(model)
clock = time.clock()
while True:
clock.tick()
img = csi0.snapshot()
for r, score, keypoints in model.predict([img]):
ml.utils.draw_predictions(img, [r], ("face",), ((0, 0, 255),), format=None)
ml.utils.draw_keypoints(img, keypoints, color=(255, 0, 0))
print(clock.fps(), "fps")
M4 核¶
Cortex‑M4 核通过 openamp 暴露出来,用于处理器间通信。OpenMV 固件仅运行在 M7 上;M4 自身没有 MicroPython 运行时,因此使用它意味着要构建一个单独的 C 固件镜像,并通过 openamp.RemoteProc 从文件系统加载。实现虚拟 UART 端点的预构建示例固件可在 openamp_vuart 仓库中获取——按照其 README 构建 vuart.elf:
import openamp
import time
def ept_recv_callback(src_addr, data):
print("Received:", data.decode())
ept = openamp.Endpoint("vuart-channel", callback=ept_recv_callback)
rproc = openamp.RemoteProc("vuart.elf")
rproc.start()
count = 0
while True:
if ept.is_ready():
ept.send("Hello World %d!" % count, timeout=1000)
count += 1
time.sleep_ms(1000)
在实际使用中,最好将这一支持视为对 openamp 接口的演示,而非一个可用的双核平台——M4 无法独立于 M7 复位,因此停止 M4 会强制整个系统重启。
显示屏(J5)¶
J5 是用于 Arduino Giga Display Shield 的 MIPI‑DSI 连接器——这是一块 480 × 800 电容式触摸屏,围绕 ST7701 屏幕驱动器和 GT911 触摸控制器构建。两个驱动均随固件以冻结形式提供。使用 display --- 显示驱动 推送帧缓冲区,使用 gt911.GT911 处理触摸输入。
下面的示例将摄像头画面镜像到一个纵向的 800 × 480 显示窗口中,并将每个触摸接触点叠加显示为一个彩色圆圈:
import csi
import time
import image
import display
from gt911 import GT911
from machine import I2C
IMG_OFFSET = 80
touch_detected = False
points_colors = ((255, 0, 0), (0, 255, 0), (0, 0, 255),
(0, 255, 255), (255, 255, 0))
csi0 = csi.CSI()
csi0.reset()
csi0.pixformat(csi.RGB565)
csi0.framesize(csi.VGA)
lcd = display.DSIDisplay(
framesize=display.FWVGA,
portrait=True,
refresh=60,
controller=display.ST7701(),
)
# Pass pin names (not Pin objects) so the driver can flip
# the reset pin's direction during start-up.
touch = GT911(
I2C(4, freq=400_000),
reset_pin="D71",
irq_pin="D70",
touch_points=5,
refresh_rate=240,
reverse_x=True,
touch_callback=lambda pin: globals().update(touch_detected=True),
)
clock = time.clock()
while True:
clock.tick()
img = csi0.snapshot()
if touch_detected:
n, points = touch.read_points()
for i in range(n):
img.draw_circle(
(points[i][0] - IMG_OFFSET,
points[i][1],
points[i][2] * 3),
color=points_colors[points[i][3]],
thickness=2,
)
touch_detected = False
lcd.write(img, y=IMG_OFFSET, hint=image.TRANSPOSE | image.VFLIP)
print(clock.fps())
警告
Giga Display Shield 使用与摄像头相同的 I²C 4 总线(SDA1/SCL1),使用 D74 控制 LCD 背光使能,使用 D70/D71 处理 GT911 触摸 IRQ 和复位,使用 D68/D69 处理 DSI 面板的 TE 和 RESET 信号。
麦克风(Display Shield)¶
Arduino Giga Display Shield 搭载一个数字麦克风,接线至 STM32H747 的 DFSDM 外设(麦克风时钟在 D75 上,麦克风数据在 D73 上)。该麦克风通过 audio --- 音频模块 进行采集。每个缓冲区以有符号 16 位 PCM bytearray 的形式到达,可直接送入 ulab/numpy 进行 DSP 处理:
import audio
from ulab import numpy as np
def loudness(pcmbuf):
samples = np.array(np.frombuffer(pcmbuf, dtype=np.int16), dtype=np.float)
rms = np.sqrt(np.mean(samples ** 2))
if rms > 10000:
print("Loud!", int(rms))
audio.init(channels=1, frequency=16000, gain_db=24)
audio.start_streaming(loudness)
while True:
pass
IMU(Display Shield)¶
Arduino Giga Display Shield 在同一条 I²C 4 总线上、地址为 0x68 处搭载了一颗博世(Bosch)BMI270 6 轴 IMU(3D 加速度计 + 3D 陀螺仪)。使用社区提供的 micropython_bmi270 驱动来读取它:
import time
from machine import I2C
from micropython_bmi270 import bmi270
sensor = bmi270.BMI270(I2C(4, freq=400_000))
sensor.load_config_file()
while True:
ax, ay, az = sensor.acceleration # m/s²
gx, gy, gz = sensor.gyro
print(ax, ay, az, gx, gy, gz)
time.sleep_ms(100)
完整的寄存器映射见 BMI270 数据手册。
RGB LED(Display Shield)¶
Arduino Giga Display Shield 在同一条 I²C 4 总线上搭载了一个板载 RGB LED,由 ISSI IS31FL3197 3 通道 LED 驱动器驱动。该驱动器的 AD 引脚接至 GND,因此其 I²C 地址为 0x50。使用社区提供的 IS31FL3197 驱动来控制该 LED:
from machine import I2C
from is31fl3197 import IS31FL3197
led = IS31FL3197(I2C(4, freq=400_000))
led.set_color(255, 0, 0) # full red
完整的寄存器映射见 IS31FL3197 数据手册。
Wi‑Fi¶
板载的 Murata 1DX(CYW4343W)通过 network --- 网络配置 以 station 接口形式暴露出来。在启动射频之前,请将随附的天线连接到板载的 U.FL 连接器:
import network, time
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect("ssid", "password")
while not wlan.isconnected():
time.sleep(1)
print("Wi‑Fi IP:", wlan.ipconfig("addr4")[0])
蓝牙¶
同一颗 Murata 1DX 还提供 Bluetooth LE 5.1。使用 aioble --- 异步 BLE 进行 asyncio 友好的 BLE 操作——例如,作为外设广播并等待中心设备连接:
import asyncio
import aioble
async def run():
while True:
conn = await aioble.advertise(250_000, name="Giga-R1")
print("Connected:", conn.device)
await conn.disconnected()
asyncio.run(run())
总线参考¶
GPIO¶
使用 machine.Pin 来读取或驱动任何丝印标注的引脚。输出为 3.3 V CMOS 电平,每个引脚可吸入/拉出最高 20 mA 电流(整个排针总计 140 mA)。
from machine import Pin
out = Pin("D2", Pin.OUT)
out.on()
out.off()
out.value(1)
inp = Pin("D3", Pin.IN, Pin.PULL_UP)
print(inp.value())
任何输入引脚也可以在边沿跳变时触发中断:
def handler(pin):
print("triggered:", pin)
Pin("D3", Pin.IN, Pin.PULL_UP).irq(
handler, Pin.IRQ_FALLING | Pin.IRQ_RISING,
)
UART¶
总线 |
TX |
RX |
Arduino 名称 |
|---|---|---|---|
UART1 |
D1 |
D0 |
Serial1 |
UART6 |
D14 |
D15 |
Serial2 |
UART4 |
D16 |
D17 |
Serial3 |
UART2 |
D18 |
D19 |
Serial4 |
from machine import UART
uart = UART(1, baudrate=115200)
uart.write("hello")
uart.read(5)
I²C¶
总线 |
SCL |
SDA |
|---|---|---|
I2C2 |
D21 |
D20 |
I2C1 |
D8 |
D9 |
I2C4 |
SCL1 |
SDA1 |
from machine import I2C
i2c = I2C(2, freq=400_000)
i2c.scan()
i2c.writeto(0x76, b"hi")
总线 2(D20/D21,即丝印标注的 SCL/SDA)是默认的 Arduino Wire 总线。总线 4(SCL1/SDA1)与摄像头以及 Giga Display Shield 的 GT911 触摸控制器共享——此总线上的用户设备必须避开以下地址(7 位):
0x3C—— OV5640 / GC21450x24—— HM01B0 / HM03600x21—— OV76700x5D—— GT911 触摸控制器(Giga Display Shield)
同一硬件也可以通过 machine.I2CTarget 以目标(从)模式使用,将一块内存区域暴露给另一个 I²C 控制器:
from machine import I2CTarget
buf = bytearray(32)
target = I2CTarget(2, addr=0x42, mem=buf)
SPI¶
总线 |
MOSI |
MISO |
SCK |
|---|---|---|---|
SPI1 |
D90 |
D89 |
D91 |
SPI5 |
D11 |
D12 |
D13 |
SPI1 引出至开发板正面一个专用的 6 针排针上。SPI5 引出至 D11/D12/D13 上丝印标注的 COPI/CIPO/SCK 标签处。
备注
正面 6 针 SPI1 排针(J7)的引脚分布:
引脚 |
信号 |
|---|---|
1 |
|
2 |
+5V |
3 |
|
4 |
|
5 |
NRST |
6 |
GND |
from machine import SPI
from machine import Pin
spi = SPI(5, baudrate=10_000_000)
cs = Pin("D10", Pin.OUT, value=1) # CS is not driven by the SPI peripheral
cs.value(0)
spi.write(b"hello")
cs.value(1)
CAN (FDCAN)¶
总线 |
TX |
RX |
|---|---|---|
FDCAN2 |
D94 |
D93 |
from machine import CAN
can = CAN(2, 500_000)
can.set_filters(None)
can.send(0x123, b"\xDE\xAD\xBE\xEF")
print(can.recv())
ADC¶
Giga R1 在 A0–A11 上暴露了 12 个 12 位 ADC 通道,全部为 3.3 V 基准——read_u16 在引脚 0–3.3 V 范围内返回 0–65535。A8–A11 是纯模拟的 _C 焊盘,没有 GPIO 外设:
from machine import ADC
import time
adc = ADC("A0")
while True:
voltage = adc.read_u16() * 3.3 / 65535
print(voltage)
time.sleep_ms(100)
备注
A7 还接到 3.5 mm TRRS 音频插孔上的 麦克风输入——当插入耳机时,ADC("A7") 会直接读取模拟麦克风信号。
DAC¶
通过 pyb.DAC 在 DAC0 和 DAC1 上暴露了两个 12 位 DAC 通道。两者都接到 3.5 mm TRRS 音频插孔,作为左右 线路输出 通道:
from pyb import DAC
left = DAC("DAC0")
right = DAC("DAC1")
left.write(int(0.5 * 255)) # 8‑bit, ~1.65 V
right.write(int(0.5 * 255))
PWM¶
引脚 |
定时器 / 通道 |
|---|---|
D0 |
TIM4 CH2 / TIM17 CH1N |
D1 |
TIM1 CH2 |
D2 |
TIM2 CH4 / TIM5 CH4 / TIM15 CH2 |
D3 |
TIM2 CH3 / TIM5 CH3 / TIM15 CH1 |
D4 |
TIM1 CH3N / TIM8 CH1 |
D5 |
TIM1 CH1N / TIM3 CH2 / TIM8 CH1N / TIM14 CH1 |
D6 |
TIM4 CH2 |
D7 |
TIM3 CH1 |
D8 |
TIM4 CH3 / TIM16 CH1 |
D9 |
TIM4 CH4 / TIM17 CH1 |
D10 |
TIM1 CH1 / TIM8 CH3N |
D11 |
TIM1 CH2N / TIM8 CH2 |
D12 |
TIM1 CH2 / TIM8 CH2N |
D13 |
TIM12 CH1 |
D15 |
TIM3 CH2 / TIM8 CH2 |
D16 |
TIM8 CH1N |
D20 |
TIM2 CH4 |
D37 |
TIM8 CH2 |
D38 |
TIM8 CH2N |
D40 |
TIM15 CH2 |
D46 |
TIM8 CH3N |
D48 |
TIM1 CH1N / TIM8 CH3 |
D51 |
TIM15 CH1 |
D54 |
TIM8 CH1 |
D56 |
TIM3 CH1 / TIM13 CH1 |
D57 |
TIM1 CH3 / TIM8 CH1N |
D58 |
TIM8 CH3 |
D59 |
TIM8 CH2 |
D61 |
TIM8 CH2N |
D63 |
TIM5 CH2 |
D64 |
TIM5 CH1 |
D65 |
TIM12 CH2 |
D68 |
TIM3 CH1 / TIM8 CH1 |
D69 |
TIM5 CH4 |
D71 |
TIM8 CH4 |
D78 / A2 |
TIM1 CH2N / TIM3 CH3 / TIM8 CH2N |
D79 / A3 |
TIM1 CH3N / TIM3 CH4 / TIM8 CH3N |
D83 / A7 |
TIM2 CH1 / TIM5 CH1 |
D85 / A13 |
TIM2 CH1 / TIM8 CH1N |
通过 machine.PWM 驱动其中任意一个:
from machine import Pin, PWM
pwm = PWM(Pin("D2"), freq=1_000, duty_u16=32768)
警告
当通过 csi --- 摄像头传感器 初始化摄像头时,TIM1 被保留用作 摄像头主时钟。那些唯一 PWM 功能在 TIM1 上的引脚——D1、D10、D11、D12——在摄像头激活时无法用作 PWM 输出。其他列出的引脚都有非 TIM1 的备选项。
备注
有几个引脚共用定时器通道:
TIM2 CH4 同时位于
D2和D20上。TIM2 CH1 同时位于
D83/A7和D85/A13上。TIM3 CH1 同时位于
D7、D56和D68上。TIM3 CH2 同时位于
D5和D15上。TIM4 CH2 同时位于
D0和D6上。TIM5 CH1 同时位于
D64和D83/A7上。TIM5 CH4 同时位于
D2和D69上。TIM8 CH1 同时位于
D4、D54和D68上。TIM8 CH1N 同时位于
D5、D16、D57和D85/A13上。TIM8 CH2 同时位于
D11、D15、D37和D59上。TIM8 CH2N 同时位于
D12、D38、D61和D78/A2上。TIM8 CH3 同时位于
D48和D58上。TIM8 CH3N 同时位于
D10、D46和D79/A3上。TIM15 CH1 同时位于
D3和D51上。TIM15 CH2 同时位于
D2和D40上。
每个定时器通道只能选一个使用方。
软件位操作(bit‑bang)总线¶
如果你需要额外的总线,machine.SoftI2C 和 machine.SoftSPI 可以在任何 GPIO 上工作。
热成像传感器(板外)¶
固件包含 fir --- 热成像传感器驱动(fir == 远红外) 驱动,用于外部接线的热成像仪:
MLX90621 —— 16 × 4 红外阵列
MLX90640 —— 32 × 24 红外阵列
MLX90641 —— 16 × 12 红外阵列
AMG8833 —— 8 × 8 红外阵列
将模块接到开发板的 I²C 总线,并用 fir.init() + fir.snapshot() 读取帧:
import time
import image
import fir
fir.init() # auto‑detects the sensor
clock = time.clock()
while True:
clock.tick()
try:
img = fir.snapshot(x_scale=5, y_scale=5,
color_palette=image.PALETTE_IRONBOW,
hint=image.BICUBIC,
copy_to_fb=True)
except OSError:
continue
print(clock.fps())
fir 驱动只通过 I²C 1 与传感器通信——请将模块接到 D8(SCL)和 D9(SDA)。
定时¶
time¶
time 模块涵盖阻塞延时、单调计时和经过时间测量:
import time
time.sleep(1) # seconds
time.sleep_ms(500)
time.sleep_us(10)
start = time.ticks_ms()
# ...do work...
elapsed = time.ticks_diff(time.ticks_ms(), start)
虚拟定时器¶
machine.Timer 在不占用硬件定时器槽位的情况下调度周期性或一次性回调。传入 -1 作为 id 即可使用虚拟(软件)定时器:
from machine import Timer
one_shot = Timer(-1)
one_shot.init(period=5_000, mode=Timer.ONE_SHOT,
callback=lambda t: print("once"))
periodic = Timer(-1)
periodic.init(period=2_000, mode=Timer.PERIODIC,
callback=lambda t: print("tick"))
周期值以毫秒为单位。调用 deinit() 以停止并释放槽位。
实时时钟¶
machine.RTC 在多次复位之间——以及在 VRTC 引脚连接了纽扣电池时跨完全断电——保持挂钟时间:
from machine import RTC
rtc = RTC()
rtc.datetime((2026, 4, 30, 4, 12, 0, 0, 0)) # Y, M, D, weekday, h, m, s, subsec
print(rtc.datetime())
看门狗¶
如果应用程序挂起,machine.WDT 会复位开发板。一旦启动,它就无法停止或重新配置——请在主循环中定期喂狗:
from machine import WDT
wdt = WDT(timeout=5_000) # 5 second window
while True:
# ...do work...
wdt.feed()
启动和运行时信息¶
固件更新(DFU)¶
Giga R1 使用 Arduino 标准的 双击复位 进入 Arduino 引导加载程序。快速按两下 RESET 按钮——开发板会通过 USB 重新枚举为 DFU 设备,OpenMV IDE 即可刷写新的固件镜像。如果引导加载程序完全缺失,请在按下 RESET 的同时按住 BOOT0 按钮,强制 SoC 进入 ROM 引导加载程序模式。
正在运行的脚本可以通过调用 machine.bootloader() 按需重新进入引导加载程序:
import machine
machine.bootloader()
文件系统和启动顺序¶
Giga R1 固件在启动时最多挂载两个文件系统:
内部闪存 —— 始终挂载在
/flash。默认存放main.py和README.txt;在首次启动时创建。ROMFS —— 只读、内存映射的文件系统,位于
/rom,由 MicroPython 在启动时自动挂载。
挂载完成后,工作目录被设置为 /flash。解释器随后从该目录运行脚本:
boot.py在 每次 软复位时执行(冷启动、从 REPL 按Ctrl‑D,或正在运行的脚本返回时)。main.py仅在冷启动时 执行,紧接在boot.py之后。后续的软复位会重新运行boot.py,但会直接跳到 REPL——要重新运行main.py,你必须完全复位开发板。
刚刷写完的开发板上随附的默认 main.py 只是将用户 RGB LED 的 蓝色 通道作为心跳灯闪烁(两次短脉冲,短暂间隔),这样在没有连接任何主机的情况下,你也能知道固件已干净地启动。
sys.path 被扩展为包含这两个文件系统及其 lib/ 子目录,因此可导入的模块可以放在 /flash/lib 或 /rom/lib 中。
通过 USB 连接时,/flash 还会在主机上枚举为一个 USB 大容量存储驱动器,让你可以直接编辑 boot.py、main.py 和任何其他文件。在复位开发板之前请先弹出该驱动器,以便主机刷新其缓存的写入。
备注
由于操作系统将该驱动器视为被动块设备,在摄像头上运行的代码创建或修改的文件,在主机重新挂载该驱动器之前不会显示出来。如果操作系统和摄像头同时写入同一个文件系统,操作系统会胜出并覆盖摄像头所做的更改。
备注
当主机正在从 USB 大容量存储驱动器读取或向其写入时,用户 RGB LED 的 红色 通道可能会短暂点亮——这是由固件驱动的活动指示,并非故障。
存储容量¶
Giga R1 出厂时配备:
/flash—— 11 MB FAT 文件系统,可读写。/rom—— 4 MB 只读内存映射 ROMFS,用于随固件提供脚本和能从零拷贝 mmap 访问中受益的 ML 模型。
硬件故障(hard fault)指示¶
如果用户 RGB LED 正在快速循环显示所有颜色——快到看起来更像是一个 闪烁的白色 LED 而不是各种分明的色调——说明固件遇到了不可恢复的硬件故障。重新刷写固件即可恢复;如果重新刷写也无济于事,则开发板可能已发生物理损坏。
软件库¶
完整的模块列表请参阅 库索引——其中也包括哪些模块是 Giga R1 构建所特有的。