OpenMV Cam M7¶
OpenMV Cam M7 是一款基于 Cortex‑M7 的机器视觉开发板,核心采用主频 216 MHz 的 STMicroelectronics STM32F765,内置 512 KB 片内 SRAM 和 2 MB 片内闪存。随附的 OV7725 传感器能以最高 150 FPS 的速度捕获 640×480 灰度帧或 320×240 RGB565 帧,10 针用户排针引出了 UART、I²C、SPI、CAN、ADC/DAC 和 PWM 等外设。
完整的数据手册、照片和尺寸信息请参阅 OpenMV Cam M7 产品页面。
亮点¶
STMicroelectronics STM32F765 Cortex‑M7,主频 216 MHz。
512 KB 片内 SRAM —— 无外部 SDRAM。
2 MB 片内闪存(无外部 QSPI 闪存)。
OV7725 传感器 —— 640×480 灰度或 320×240 RGB565,最高 150 FPS。
全速 USB(12 Mb/s)—— 对主机呈现为 VCP + USB 大容量存储设备。
microSD 插槽 —— SD 最大 2 GB,SDHC 最大 32 GB,SDXC 最大 2 TB。
10 个 I/O 引脚,兼容 5 V,3.3 V 输出,每个引脚 25 mA(整个排针总计 120 mA),支持中断。当 P6 用于 ADC 或 DAC 模式时不兼容 5 V。
用户 RGB LED 以及两颗大功率 850 nm 红外 LED,可在弱光视觉场景下进行主动补光。
备注
M7 没有板载电源管理芯片:没有电池接口、没有电池充电器、没有电池电压 ADC、没有充电/电源状态 LED,也没有硬件电源按钮。请通过 USB 或 VIN 为开发板供电。
引脚定义¶
引脚参考¶
引脚名称 |
功能 |
|---|---|
P0 |
UART1 RX / SPI2 MOSI |
P1 |
UART1 TX / SPI2 MISO |
P2 |
SPI2 SCK / CAN2 TX |
P3 |
SPI2 NSS (CS) / CAN2 RX |
P4 |
I2C2 SCL / UART3 TX / TIM2 CH3 |
P5 |
I2C2 SDA / UART3 RX / TIM2 CH4 |
P6 |
ADC / DAC / TIM2 CH1 |
P7 |
I2C4 SCL / TIM4 CH1 |
P8 |
I2C4 SDA / TIM4 CH2 |
P9 |
TIM4 CH3 |
RESET |
拉至 GND 以复位开发板 |
SYN |
帧同步焊盘 —— 仅连接到摄像头传感器 |
BOOT0 |
上电时拉至 3.3 V 以进入 DFU / ROM 引导加载程序 |
LED_RED |
RGB LED 红色通道(低电平有效) |
LED_GREEN |
RGB LED 绿色通道(低电平有效) |
LED_BLUE |
RGB LED 蓝色通道(低电平有效) |
LED_IR |
大功率红外 LED(两个通道一同驱动) |
备注
排针上的 SYN 焊盘直接连接到摄像头传感器的触发/曝光线 —— 在 M7 上它不连接到 MCU。请在外部驱动或读取它;无法从 MicroPython 切换它。
电源引脚¶
3.3V —— 稳压后的 3.3 V 电源轨。最多可为扩展板提供 250 mA(若正在使用 microSD 卡则会更少)。与较新的摄像头不同,此引脚是双向的 —— 请参阅下方的警告。
VIN —— 3.6 – 5 V 输入。通过板载稳压器为开发板供电。
GND —— 公共地。
备注
当 USB 和 VIN 同时接入时,由电压较高的一方为开发板供电 —— 板载二极管会直接选择电压较强的电源轨。
警告
如果你不想经过板载稳压器,你可以将 3.3 V 直接馈入 3.3V 引脚来为 M7 供电。在这种情况下,切勿同时再施加 VIN 或 USB 电源 —— 在另一路电源处于活动状态时反向驱动稳压器可能会永久损坏并毁坏摄像头。
小技巧
可使用 电池续航估算器 来估算 M7 在给定的活动/深度睡眠占空比下能依靠电池运行多长时间。
恢复与调试引脚¶
RESET —— 拉至 GND 以复位开发板。释放后 MCU 即可正常启动。
BOOT0 —— 在为开发板供电时拉至 3.3 V,即可进入 STM32 ROM 引导加载程序(DFU 模式)。OpenMV IDE 使用此模式来重新刷写板载引导加载程序。
开发板在 GPIO 排针旁边引出了 SWD 调试排针(RST / SWCLK / SWDIO),兼容 ST‑LINK 和 SEGGER J‑Link 适配器。
板载外设¶
LED¶
M7 配有一颗用户 RGB LED 以及一对大功率 850 nm 红外 LED:
用户 RGB LED —— 可由软件控制,引出为
LED_RED、LED_GREEN和LED_BLUE:from machine import LED LED("LED_RED").on() LED("LED_GREEN").on() LED("LED_BLUE").on()
红外 LED —— 两颗 LED 通过
LED_IR引脚一同驱动。LED_IR在硬件上接成高电平有效,而固件将其他所有板载 LED 都视为低电平有效,因此请使用low()/high()而非on()/off()(后者会使电平含义反转):from machine import LED ir = LED("LED_IR") ir.low() # turn IR illumination ON ir.high() # turn IR illumination OFF
摄像头传感器¶
OV7725 通过 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()
M7 上的传感器是焊接在板上的 —— 它并非位于可更换的模块上。
microSD 卡¶
插入卡后,它会自动挂载到 /sdcard,并可通过常规文件系统使用:
import os
for entry in os.listdir("/sdcard"):
print(entry)
总线参考¶
GPIO¶
使用 machine.Pin 来读取或驱动任意丝印标注的引脚。输出为 3.3 V CMOS 电平,输入侧兼容 5 V,每个引脚可灌入/拉出最多 25 mA(整个排针总计 120 mA)。
from machine import Pin
out = Pin("P0", Pin.OUT)
out.on()
out.off()
out.value(1)
inp = Pin("P1", Pin.IN, Pin.PULL_UP)
print(inp.value())
任意输入引脚也可在边沿跳变时触发中断:
def handler(pin):
print("triggered:", pin)
Pin("P1", Pin.IN, Pin.PULL_UP).irq(
handler, Pin.IRQ_FALLING | Pin.IRQ_RISING,
)
UART¶
总线 |
TX |
RX |
|---|---|---|
UART1 |
P1 |
P0 |
UART3 |
P4 |
P5 |
from machine import UART
uart = UART(3, baudrate=115200)
uart.write("hello")
uart.read(5)
I²C¶
总线 |
SCL |
SDA |
|---|---|---|
I2C2 |
P4 |
P5 |
I2C4 |
P7 |
P8 |
from machine import I2C
i2c = I2C(2, freq=400_000)
i2c.scan()
i2c.writeto(0x76, b"hi")
同一硬件也可通过 machine.I2CTarget 用作目标(从机)模式,向另一个 I²C 控制器暴露一段内存区域:
from machine import I2CTarget
buf = bytearray(32)
target = I2CTarget(2, addr=0x42, mem=buf)
SPI¶
总线 |
MOSI |
MISO |
SCK |
CS |
|---|---|---|---|---|
SPI2 |
P0 |
P1 |
P2 |
P3 |
from machine import SPI
from machine import Pin
spi = SPI(2, baudrate=10_000_000)
cs = Pin("P3", Pin.OUT, value=1) # CS is not driven by the SPI peripheral
cs.value(0)
spi.write(b"hello")
cs.value(1)
CAN¶
总线 |
TX |
RX |
|---|---|---|
CAN2 |
P2 |
P3 |
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 与 DAC¶
P6 是唯一的用户模拟引脚。它既可用作 12 位 ADC 输入,也可用作 DAC 输出。
ADC —— 引脚处满量程为 3.3 V:
from machine import ADC import time adc = ADC("P6") while True: voltage = adc.read_u16() * 3.3 / 65535 print(voltage) time.sleep_ms(100)
DAC —— 通过
pyb.DAC。8 位值覆盖 0–3.3 V:from pyb import DAC dac = DAC("P6") voltage = 1.65 dac.write(int(voltage / 3.3 * 255))
在 ADC 或 DAC 模式下,P6 仅兼容 3.3 V —— 切勿向其馈入 5 V。
PWM¶
引脚 |
定时器/通道 |
|---|---|
P4 |
TIM2 CH3 |
P5 |
TIM2 CH4 |
P6 |
TIM2 CH1 |
P7 |
TIM4 CH1 |
P8 |
TIM4 CH2 |
P9 |
TIM4 CH3 |
备注
TIM1 已被固件保留用于生成摄像头传感器的像素时钟,因此物理上位于 P0/P1/P2 上的 TIM1 通道无法用于用户 PWM,否则会导致摄像头无法工作。
TIM4 与 pyb.Servo 共用 —— 实例化一个舵机会将整个定时器重新配置为 50 Hz 工作,因此请勿在同一脚本中将 P7/P8/P9 上的 machine.PWM 与 pyb.Servo 混用。
可通过 machine.PWM 驱动其中任意一个:
from machine import Pin, PWM
pwm = PWM(Pin("P7"), freq=1_000, duty_u16=32768)
软件位拨(bit‑banged)总线¶
如果你需要额外的总线,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 2 与传感器通信 —— 请将模块接到 P4(SCL)和 P5(SDA)。
计时¶
time¶
time 模块涵盖阻塞延时、单调计时(ticks)以及经过时间测量:
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 可在不占用硬件定时器槽位的情况下调度周期性或单次回调。将 id 传入 -1 即可使用虚拟(软件)定时器:
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 可在复位后保持挂钟时间:
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()
启动与运行时信息¶
USB 引导加载程序窗口¶
每次上电时,摄像头都会运行一个短暂的引导加载程序(几秒钟),让 OpenMV IDE 无需用户手动进入 DFU 模式即可更新固件。该窗口期结束后,引导加载程序会将控制权移交给 boot.py,随后再移交给 main.py。
正在运行的脚本可通过调用 machine.bootloader() 按需重新进入引导加载程序:
import machine
machine.bootloader()
文件系统与启动顺序¶
M7 固件在启动时最多会挂载三个文件系统:
片内闪存 —— 始终挂载于
/flash。默认存放main.py和README.txt;在首次启动时创建。microSD 卡 —— 若插入了卡,则会挂载于
/sdcard。ROMFS —— 位于
/rom的只读、内存映射文件系统,用于发布受益于零拷贝访问的大型数据资源(例如 AI 模型)。由 MicroPython 在启动时、任何用户 Python 代码运行之前自动挂载。
挂载完成后,当存在卡时工作目录会设为 /sdcard,否则设为 /flash。解释器随后从该目录运行脚本:
boot.py在每次软复位时执行(冷启动、从 REPL 按Ctrl‑D,或正在运行的脚本返回时)。main.py仅在冷启动时执行,紧随boot.py之后。后续的软复位会重新运行boot.py但会直接进入 REPL —— 要重新运行main.py,你必须彻底复位开发板。
将 boot.py 或 main.py 放到 SD 卡上会覆盖闪存中的副本而不会改动它 —— 这两个文件都会在启动目录中查找(挂载了卡时为 /sdcard,否则为 /flash)。
刚刷写好的开发板上随附的默认 main.py 只是将用户 RGB LED 的蓝色通道作为心跳进行闪烁(两次短脉冲,短暂间隔),这样你无需连接任何主机即可判断固件是否干净启动。
sys.path 已扩展为包含全部三个文件系统及其各自的 lib/ 子目录,因此可导入的模块可以放在 /flash/lib、/sdcard/lib 或 /rom/lib 中。
若要强制系统忽略已插入的 SD 卡(例如即使插着卡也要运行闪存中的 main.py),请在 /flash 根目录下创建一个名为 SKIPSD 的空文件。
通过 USB 连接时,启动文件系统(若存在卡则为 /sdcard,否则为 /flash)也会在主机上枚举为一个 USB 大容量存储驱动器,让你可以直接编辑 boot.py、main.py 以及任何其他文件。复位摄像头之前请先弹出该驱动器,以便主机刷新其缓存的写入。
备注
由于操作系统将该驱动器视为被动的块设备,由 OpenMV Cam 上运行的代码创建或修改的文件在主机重新挂载驱动器之前不会显示出来。如果操作系统与 OpenMV Cam 同时写入同一文件系统,操作系统会胜出并覆盖摄像头所做的更改。请将脚本写回的任何数据存到 SD 卡,并在从主机读取这些文件之前重新挂载。
备注
当主机正在从 USB 大容量存储驱动器读取或向其写入时,用户 RGB LED 的红色通道可能会短暂点亮 —— 这是固件驱动的活动指示,而非故障。
存储容量¶
M7 出厂时配备:
/flash—— 96 KB FAT 文件系统,可读写。/rom—— 256 KB 只读、内存映射的 ROMFS。/sdcard—— 所插入的 microSD 卡的全部容量(存在时),可读写。
硬故障指示¶
如果用户 RGB LED 正在快速循环切换所有颜色 —— 快到看起来更像是闪烁的白色 LED 而非各种分明的色调 —— 则说明固件遇到了无法恢复的硬故障。请重新刷写固件以恢复;如果重刷无济于事,开发板可能已发生物理损坏。
软件库¶
完整的模块列表(包括哪些模块为 M7 构建版本所独有)请参阅 库索引。