# STM32F103C8T6：OLED 屏幕点亮与接线

目标：用 STM32F103C8T6、四针 I²C 屏幕和 ST-Link 完成第一次屏幕点亮。先只连接这些硬件，用 USB 给开发板供电，暂不连接三节电池组和其他模块。

屏幕引脚为 GND、VCC、SCL、SDA，真实驱动型号未确认。看到的“0x7A”可能是 8 位 I²C 写地址，对应 7 位地址 0x3D，不能据此确定控制器型号。本测试按常见 3.3V OLED 尝试。

## 1. 屏幕连线

先断电，按引脚名称接线。下图是连接关系图，不表示实物排针顺序。

```tikz
\begin{tikzpicture}[x=1cm,y=1cm,thick,font=\small]
\definecolor{boardblue}{RGB}{32,77,120}
\definecolor{powerred}{RGB}{190,45,55}
\definecolor{clockblue}{RGB}{35,100,200}
\definecolor{datagreen}{RGB}{20,135,100}
\draw[rounded corners,fill=blue!5,draw=boardblue] (0,0) rectangle (4,5);
\node[font=\bfseries,text=boardblue] at (2,4.5) {STM32F103C8T6};
\node at (2,3.95) {开发板};
\draw[rounded corners,fill=gray!8] (9,0) rectangle (12.5,5);
\node[font=\bfseries] at (10.75,4.5) {I2C OLED};
\node at (10.75,3.95) {四针屏幕};
\foreach \y/\left/\right/\col in {3.2/GND/GND/black,2.35/3.3V/VCC/powerred,1.5/PB6/SCL/clockblue,0.65/PB7/SDA/datagreen} {
  \node[anchor=east] at (3.8,\y) {\left};
  \node[anchor=west] at (9.2,\y) {\right};
  \draw[\col,line width=1.3pt] (4,\y) -- (9,\y);
  \fill[\col] (4,\y) circle (2pt);
  \fill[\col] (9,\y) circle (2pt);
}
\node[fill=white,text=powerred] at (6.5,2.35) {3.3V 电源};
\node[fill=white,text=clockblue] at (6.5,1.5) {时钟};
\node[fill=white,text=datagreen] at (6.5,0.65) {数据};
\draw[rounded corners,fill=gray!10] (0,6) rectangle (4,6.8);
\node at (2,6.4) {USB 供电};
\draw[->,line width=1.3pt] (2,6) -- (2,5);
\node[align=center] at (6.25,-0.75) {按引脚文字连接，图中位置不代表实物排针顺序。};
\node[align=center] at (6.25,-1.3) {断电接线；本次先不接电池、舵机和其他模块。};
\end{tikzpicture}

```

| 屏幕 | STM32 开发板 | 作用 |
|---|---|---|
| GND | GND | 共地 |
| VCC | 3.3V | 屏幕供电 |
| SCL | PB6 | I²C 时钟 |
| SDA | PB7 | I²C 数据 |

SCL、SDA 使用开漏输出，需要上拉电阻。常见 OLED 模块自带上拉；若确认没有，则两根信号线各通过约 4.7kΩ 电阻接到 3.3V。不要把信号线上拉到 5V。

## 2. ST-Link 连线

```tikz
\begin{tikzpicture}[x=1cm,y=1cm,thick,font=\small]
\draw[rounded corners,fill=blue!5] (0,0) rectangle (4,4.8);
\node[font=\bfseries] at (2,4.3) {ST-Link 下载器};
\draw[rounded corners,fill=blue!5] (9,0) rectangle (13,4.8);
\node[font=\bfseries] at (11,4.3) {STM32 开发板};
\foreach \y/\left/\right/\col in {3.5/GND/GND/black,2.65/SWDIO/PA13/blue,1.8/SWCLK/PA14/orange} {
  \node[anchor=east] at (3.8,\y) {\left};
  \node[anchor=west] at (9.2,\y) {\right};
  \draw[\col,line width=1.3pt] (4,\y) -- (9,\y);
  \fill[\col] (4,\y) circle (2pt);
  \fill[\col] (9,\y) circle (2pt);
}
\node[anchor=east] at (3.8,0.85) {NRST};
\node[anchor=west] at (9.2,0.85) {RST / NRST};
\draw[dashed,gray] (4,0.85) -- (9,0.85);
\node[fill=white] at (6.5,0.85) {可选复位线};
\node[align=center] at (6.5,-0.7) {开发板由 USB 供电，双方必须共地；BOOT0 = 0。};
\node[align=center,text=red!70!black] at (6.5,-1.3) {不要再接下载器的 3.3V / 5V 电源输出。};
\node[align=center] at (6.5,-1.9) {若探针有 VTref 电压检测输入：接开发板 3.3V。};
\end{tikzpicture}

```

| ST-Link | 开发板 |
|---|---|
| GND | GND |
| SWDIO / SWIO | PA13 / SWDIO |
| SWCLK | PA14 / SWCLK |
| NRST（可选） | NRST / RST |

BOOT0 保持 0。开发板已经由 USB 供电时，不再连接 ST-Link 的 3.3V/5V 电源输出。如果探针有 Vref/VTref **电压检测输入**，应接开发板 3.3V；检测输入与电源输出是两回事，按下载器标识区分。

## 3. Keil 编译与下载

使用已生成的 `OLED_Test.uvprojx` 工程。工程文件和 HEX 位于本次电脑工作目录；这篇笔记没有上传工程附件。

1. 双击 `OLED_Test.uvprojx`，按 F7 编译。
2. 打开 `Options for Target → Debug`，选择 `ST-Link Debugger`。
3. 点击 `Settings`，确认探针可见，Port 选择 **SW**，初次连接可选 1 MHz。
4. 在 `Flash Download` 中确认算法为 `STM32F10x Medium-density Flash`，起始地址为 `0x08000000`。不要选择 Option Bytes 算法。可勾选 `Reset and Run`。
5. 按 F8 下载，成功后按开发板 RESET，观察至少 15 秒。

如果曾出现 `Cannot read project file`：当前工程已修复 XML 编码和空标签格式，重新打开修复后的同名文件。

## 4. 应看到什么

测试程序自动探测 7 位地址 `0x3C`、`0x3D`，约每 4 秒轮换配置。正常画面包含 `OLED OK`、配置编号、地址以及底部棋盘条纹。

| 第二行文字 | 配置 |
|---|---|
| SSD 0 | SSD1306，128×64 |
| SH 1 | SH1106，128×64，列偏移 2 |
| SSD 2 | SSD1306，128×32 |

第三行 `03C` / `03D` 表示探测地址，分别对应 8 位写地址 `0x78` / `0x7A`。地址应答只说明有设备回应，不能自动识别控制器。

轮换时部分配置可能乱码、缺行或偏移。记下显示完整的编号，再将 `main.c` 中的配置固定：

```c
// -1：自动轮换；0：SSD1306 64行；1：SH1106；2：SSD1306 32行
#define OLED_PROFILE (-1)
```

把 `(-1)` 改为正确编号后，重新编译下载。

## 5. 黑屏排查

先检查供电、共地、SCL/SDA 是否接反、BOOT0 是否为 0，以及下载后是否复位运行。

若仍全黑，进入 Keil 调试，运行几秒后暂停，在 Watch 中查看：

| 变量 | 含义 |
|---|---|
| oled_address | 7 位地址；0 表示两个候选地址均未找到 |
| oled_status = 1 | 命令和数据传输获得 ACK；不保证面板已显示 |
| oled_status = 2 | 没有地址应答，优先排查接线、供电、上拉 |
| oled_status = 3 | 总线被拉低或传输失败 |
| oled_profile | 当前尝试的配置编号 |
| oled_frames | 成功提交画面的次数 |

如果板载 LED 接在 PC13 且低电平点亮：正常传输时约每秒闪一次，无地址应答时快闪。不同开发板 LED 接法可能不同，以 Watch 为准。

状态为 1 但始终黑屏，仍需排查屏幕控制器、面板配置和供电，不能据此认定屏幕已点亮。

## 6. 已完成的验证与边界

- 已参考本地 `t1/t2` 工程的 STM32F103C8、DFP 2.4.1 和 ST-Link 配置。
- Keil ARM Compiler 6.22 实际编译通过：**0 错误、0 警告**。
- 编译大小：Code 2118 字节，RO 166 字节，RW 0 字节，ZI 1040 字节。
- 已生成 `OLED_Test.axf` 和 `OLED_Test.hex`。
- **尚未确认实物显示效果。**完成下载后，以实际屏幕为准。

本测试使用复位默认 HSI 8 MHz、DWT 延时和 PB6/PB7 软件 I²C，无 HAL 依赖。以后改变系统时钟时需同步修改延时换算；扩展中断功能时需补齐启动结构。

参考：[STM32F103C8 数据手册](https://www.st.com/resource/en/datasheet/stm32f103c8.pdf)、[SSD1306 数据手册](https://cdn-shop.adafruit.com/datasheets/SSD1306.pdf)、[SH1106 初始化参考](https://github.com/adafruit/Adafruit_SH110x/blob/master/Adafruit_SH1106G.cpp)。


---

## 7. 下一阶段：ESP8266 手机中文留言屏（设计方案）

### 已确认硬件与当前状态

- 已通过 esptool 读出 **ESP8266EX、1 MB Flash**，USB 转串口为 **CH340 / COM5**，下载通信成功。8 针模块外形符合 ESP-01/ESP-01S，具体子型号尚未确认。
- STM32 与 OLED 已烧录并运行中文水族箱。当前采用 **SSD1306 128×64、配置 0**；水草和横线就是画面底部，不是下半部分丢失。
- 下文是待实施的联网方案，尚未给 ESP 写入新固件，也未完成 ESP—STM32 联调。本文前面的 SH/SSD 编号轮换属于首次点亮测试历史。

### 用户怎样使用

1. ESP8266 启动一个带密码的 2.4 GHz Wi-Fi 热点，例如 `OLED-Message`，无需接入家里路由器。
2. 手机连接热点，手动打开 `http://192.168.4.1`。手机提示“无互联网”时保持连接；第一版不依赖自动弹出的门户页面。
3. 页面提供文本输入、字号、换行、黑白反转、简单涂鸦和 128×64 实时预览。
4. 点击“发送”，屏幕显示手机预览内容。页面区分“发送中、屏幕已更新、发送失败”，避免只收到 HTTP 请求就显示成功。
5. 点击“恢复水族箱”，回到原来的中文小鱼动画。新留言成功接收后进入留言模式，保留到下一条消息或重启；第一版不频繁写 Flash 保存留言。

热点名和密码随固件明确给出，至少使用 8 位密码；第一版为近距离局域网访问，不连接公网服务，不需要提交家庭 Wi-Fi 密码。

### 为什么能显示更多中文

数据路径：**手机浏览器 Canvas 绘制 → 黑白点阵 → Wi-Fi → ESP8266 → UART → STM32 → OLED**。

中文由手机已安装的字体绘制，再转换成像素，不要求 STM32 或 ESP 内置完整汉字库。常用中文可直接使用，罕见字、特殊符号和 emoji 是否能显示取决于手机字体及单色转换。等待 `document.fonts.ready` 后再生成点阵，按实际宽度换行，超出 64 行的部分在网页预览中提示。

一帧只有 `128 × 64 ÷ 8 = 1024` 字节。手机预览与 OLED 使用同一份二值化像素，减少抗锯齿导致的细笔画丢失；16 像素汉字通常一行约 8 个、最多 4 行，实际以预览为准。

### 运行接线图

**先断电接线。图中是引脚功能关系，不是模块正反面或排针位置图；未确认板型前不要按图的位置数针脚。**

```tikz
\begin{tikzpicture}[x=0.85cm,y=0.85cm,thick,font=\small]
\draw[rounded corners,fill=orange!8] (0,0) rectangle (4,4.6);
\node[font=\bfseries] at (2,4.15) {ESP-01 / ESP-01S};
\node at (2,3.6) {ESP8266EX};
\draw[rounded corners,fill=blue!6] (8,0) rectangle (12.5,4.6);
\node[font=\bfseries] at (10.25,4.15) {STM32F103C8T6};
\draw[rounded corners,fill=green!6] (16,0) rectangle (19,4.6);
\node[font=\bfseries] at (17.5,4.15) {OLED};
\node at (17.5,3.6) {128 x 64};
\node[anchor=east] at (3.8,2.9) {TX / GPIO1};
\node[anchor=west] at (8.2,2.9) {PA10 / RX};
\draw[->,blue,line width=1.2pt] (4,2.9) -- (8,2.9);
\node[anchor=east] at (3.8,1.9) {RX / GPIO3};
\node[anchor=west] at (8.2,1.9) {PA9 / TX};
\draw[<-,orange!80!black,line width=1.2pt] (4,1.9) -- (8,1.9);
\node[align=center] at (6,0.9) {UART1\\3.3V 电平};
\foreach \y/\left/\right/\col in {2.9/PB6/SCL/blue,1.9/PB7/SDA/green!60!black,0.9/3.3V/VCC/red!70!black} {
\node[anchor=east] at (12.3,\y) {\left};
\node[anchor=west] at (16.2,\y) {\right};
\draw[\col] (12.5,\y) -- (16,\y);
}
\foreach \x in {2,10.25,17.5} {
\node at (\x,0.35) {GND};
\draw (\x,0) -- (\x,-1);
\fill (\x,-1) circle (2pt);
}
\draw (2,-1) -- (17.5,-1);
\node[fill=white] at (10,-1) {所有 GND 共地};
\draw[rounded corners,fill=red!5] (0,5.8) rectangle (5,7.2);
\node[align=center] at (2.5,6.5) {独立稳压 3.3V 电源\\输出能力至少 500 mA};
\draw[->,red!70!black] (2,5.8) -- (2,4.6);
\node[anchor=west,text=red!70!black] at (2.1,5.2) {接 ESP VCC};
\draw[rounded corners,fill=gray!8] (8.5,5.8) rectangle (12,6.8);
\node at (10.25,6.3) {开发板 USB 供电};
\draw[->] (10.25,5.8) -- (10.25,4.6);
\node[align=center] at (9.5,-1.9) {稳压电源 GND 也接共地；两路 3.3V 输出不要并联。};
\node[align=center] at (9.5,-2.6) {运行时 ESP 移出 USB 烧写器；启动脚接法见下图。};
\end{tikzpicture}

```

| ESP 模块引脚 | 接到哪里 | 说明 |
|---|---|---|
| TX / TXD / GPIO1 | STM32 PA10（USART1 RX） | ESP 发送图片数据 |
| RX / RXD / GPIO3 | STM32 PA9（USART1 TX） | STM32 返回确认 |
| GND | STM32 GND、稳压电源 GND | 必须共地 |
| VCC / 3V3 | 独立稳压 3.3V 输出 | 不能接 5V 或电池组直出 |
| EN / CH_PD | 上拉到 ESP 的 3.3V | 芯片使能 |
| RST | 上拉到 ESP 的 3.3V | 低电平复位，正常保持高 |
| GPIO0 | 正常运行时上拉 | 进入下载时才拉低并复位 |
| GPIO2 | 上拉到 ESP 的 3.3V | 保持正常启动条件 |

STM32 与 ESP 都使用 3.3V 串口逻辑，正常情况下无需电平转换，**TX 接对方 RX**。不要用 RS-232 电平接口，也不要接 5V TTL。

OLED 原接线不动：`GND→GND，VCC→STM32 3.3V，SCL→PB6，SDA→PB7`。ST-Link 原接线也不动：`SWDIO→PA13，SWCLK→PA14，GND→GND`，与 UART1 不冲突。STM32 的 BOOT0 继续保持 0。

### ESP 供电与启动脚

```tikz
\begin{tikzpicture}[x=1cm,y=1cm,thick,font=\small]
\draw[red!70!black] (0,4) -- (12,4);
\node[anchor=west,text=red!70!black] at (0,4.45) {ESP 独立 3.3V 电源正极};
\foreach \x/\label in {1/EN (CH\_PD),4/RST,7/GPIO0,10/GPIO2} {
\fill[red!70!black] (\x,4) circle (2pt);
\draw (\x,4) -- (\x,3.2);
\draw[fill=white] (\x-0.3,2.2) rectangle (\x+0.3,3.2);
\node[anchor=west] at (\x+0.35,2.7) {10k};
\draw (\x,2.2) -- (\x,1.4);
\node[align=center] at (\x,0.95) {\label};
}
\node[align=center] at (6,0) {正常运行：EN、RST、GPIO0、GPIO2 保持高电平。};
\node[align=center] at (6,-0.65) {若模块已有这些上拉，无需重复加装；以实物板型为准。};
\node[align=center] at (6,-1.3) {下载时才将 GPIO0 拉低后复位；运行时解除下载状态。};
\node[align=center] at (6,-1.95) {ESP VCC 与 GND 附近放置 0.1uF + 10uF 去耦电容。};
\end{tikzpicture}

```

ESP8266 的 Wi-Fi 发射会带来较高的瞬时电流，电源按 **稳定 3.3V、至少 500 mA 输出能力**配置；500 mA 是电源能力要求，不是持续耗电量。开发板 3.3V 稳压器的型号和余量未知，本方案不默认让它同时供 ESP。ESP 附近放置 0.1µF 与 10µF 去耦，电源线尽量短，电容不能替代足够的稳压能力。

建议准备带 2×4 插座和明确引脚标识的 ESP-01 转接板，以及有足够输出能力的 3.3V 稳压供电。裸模块若未自带启动上拉，则 EN、RST、GPIO0、GPIO2 各用约 10kΩ 上拉；ESP-01S 等板型可能已经带上拉，以实物或对应原理图为准。GPIO15 在此类模块内部处理，8 针接口不引出，不自行改动模块。

三节电池的串并联关系和电压尚未确认，此阶段仍用 USB 输入及合适的稳压电源，不直接接电池组。

### USB 烧写器什么时候连接

- **给 ESP 下载程序时**：ESP 插回现有 CH340 烧写器，通过 COM5 下载，断开它与 STM32 的 TX/RX 连线。
- **与 STM32 联机运行时**：ESP 移出烧写器，插在转接座上，按运行图供电和接串口。
- 若希望让 USB 烧写器仅供电，必须先确认能断开 CH340 TX/RX 以及下载/自动复位控制线，并让 GPIO0 处于运行状态。当前烧写器电路尚未确认，因此这不是默认接法。

原因：烧写器 CH340 的 TX 通常已经连到 ESP RX；再把 STM32 TX 接入同一点会形成两个输出驱动同一根线，可能冲突。仅关闭电脑串口软件不能保证 CH340 TX 已电气断开。

### 软件分工与通信约定

| 部分 | 计划职责 |
|---|---|
| 手机网页 | 中文排版、黑白阈值转换、像素预览、发送按钮 |
| ESP8266 | 热点与 HTTP 服务、检查帧长、UART 转发、等待屏幕确认 |
| STM32 | UART 接收、长度和 CRC 校验、完整帧切换、OLED 刷新、留言/动画模式切换 |

ESP 计划使用 ESP8266 Arduino Core 的通用 ESP8266 目标，按检测到的 1 MB Flash 配置；网页资源嵌入固件，第一版不加 OTA 或大型文件系统。编译后检查固件大小，写入前先备份现有 ESP Flash。STM32 继续使用当前 Keil 工程。

串口初始约定为 **115200、8N1、无硬件流控**。一帧原始数据传输约需 90 ms，再加 OLED 刷新时间，因此第一版以手动发送为主，不追求视频帧率。

拟定图片帧格式：

| 字段 | 长度 | 规则 |
|---|---|---|
| Magic | 4 字节 | ASCII `OLED`，用于同步 |
| Seq | 2 字节 | 递增序号，小端 |
| Length | 2 字节 | 固定 1024，小端 |
| Pixels | 1024 字节 | `index = x + (y / 8) * 128`，位 `y % 8`；1=亮 |
| CRC | 2 字节 | CRC-16/CCITT-FALSE，初值 0xFFFF、多项式 0x1021；覆盖 Seq、Length、Pixels，结果小端 |

STM32 只在完整帧校验通过并完成 OLED 写入后回复 `ACK <序号>\n`；ESP 收到对应 ACK 后才给网页成功响应。超时约 2 秒，最多重试 2 次，同序号重复帧按幂等方式处理。ESP 启动串口杂音由同步头和长度/CRC 过滤，不作为命令执行。模式切换使用单独的控制帧，在实施时与图片帧统一定义。

为避免现有软件 I²C 刷新期间漏掉 UART 数据，STM32 需要补齐 UART 接收中断或 DMA 和对应向量表，使用接收缓冲与显示缓冲；发送端一次只等待一帧完成，不连续灌入图片。正常刷新不发送关屏命令，传输失败保留最后一张完整画面。

### 分阶段实施与验收

1. 备份 ESP 固件，烧录最小热点网页，手机能打开页面。
2. 按图连接独立供电、启动脚和 UART，先验证往返确认，暂不改屏幕内容。
3. 发送棋盘格、四角标记和底边，验证 128×64 的方向、页顺序及边界。
4. 发送常用中文、长句换行、涂鸦；网页预览与屏幕内容一致。
5. 验证恢复水族箱、重启、断开再连、CRC 错误与超时处理；失败不破坏原画面。

**实施前仍需确认的硬件条件：**独立 3.3V 供电或合格的稳压转接板、可用的引脚转接方式；当前烧写器是否能隔离串口尚不清楚。这里只完成设计与接线说明，不把未验证的供电路径当成现成可用方案。

依据：[ESP8266 官方硬件设计指南](https://documentation.espressif.com/esp8266_hardware_design_guidelines_en.html)、[乐鑫供电要求](https://docs.espressif.com/projects/esp-techpedia/en/latest/esp-friends/get-started/try-firmware/try-firmware-hardware/esp8266.html)、[官方启动模式说明](https://docs.espressif.com/projects/esptool/en/latest/esp8266/advanced-topics/boot-mode-selection.html)、[Ai-Thinker ESP-01 系列手册](https://docs.ai-thinker.com/_media/esp8266/esp8266_series_modules_user_manual_en.pdf)、[STM32F103C8 数据手册](https://www.st.com/resource/en/datasheet/stm32f103c8.pdf)。

---

## 8. OV7670 实验总结、调焦与当前接线（2026-09-12）

**当前运行：STM32F103C8T6 + 无FIFO OV7670，640×480 RGB565；电脑原生USB彩色预览 + SSD1306 OLED黑白预览。Bayer颜色还原失败，已经回退。以下接线取代旧PB5/PA8/SCL-PB10方案。**

### 当前接线与可编辑画板

摄像头所有数据/同步/控制信号集中到用户基础板同侧；OLED与USB仍使用另一侧各自的引脚。按丝印接线，不把映射表当作STM32实际排针顺序。

| 摄像头丝印 | STM32连接 | 作用 |
|---|---|---|
| 3.3V | 3.3V | 摄像头电源，不接5V |
| DGND | GND | 共地 |
| D0～D7 | PA0～PA7，逐位对应 | 并行输入；不能同时接电机控制等输出 |
| PLK / PCLK | PB0 | TIM3_CH3触发DMA采样 |
| HS / HREF | PB1 | 行有效 |
| VS / VSYNC | **PC14 / C14** | 帧同步，EXTI14；原PB5已释放 |
| XLK / XCLK | **PB10** | TIM2_CH3重映射输出12MHz；原PA8已释放 |
| SCL | **PC15 / C15** | SCCB配置时钟；原PB10已改为XCLK |
| SDA | PB11 | SCCB配置数据 |
| RET / RESET | 3.3V | 保持非复位 |
| PWDN | GND | 保持工作 |

PC14/PC15作为GPIO，不启用32.768kHz LSE；PC13设输入，PC13～PC15中只让PC15作低速输出。PC15不能用来输出12MHz时钟，故移动PA8需要同时移动SCL。

- OLED：VCC→3.3V、GND→GND、SCL→PB6、SDA→PB7；SSD1306 128×64，实测地址0x3C。
- 原生USB：D−→PA11、D+→PA12、VBUS 5V→板5V、GND→GND。当前为USB-A数据线引出接线；只有两根电源线的线缆不能传图。不能依靠线色猜D+/D−。
- ST-Link：SWDIO→PA13、SWCLK→PA14、GND共地；板由USB供电时不并接ST-Link供电线。ST-Link用于烧录调试，当前图像经STM32原生USB传输。
- 换线先断电；摄像头数据口与TB6612/测距等旧实验线不能并接。ESP不参与当前图传。

画板名称沿用“OV7670重启实验｜实物针序与F103接线”，内容已更新为当前方案，深色底配浅色文字，可继续编辑。

```tikz
\begin{tikzpicture}[scale=1.18, line cap=round, line join=round]
  \color{white}
  \filldraw[draw={rgb,255:red,16;green,24;blue,32}, line width=0.742857pt, fill={rgb,255:red,16;green,24;blue,32}] (-11.8,7.4) -- (12.6,7.4) -- (12.6,-12) -- (-11.8,-12) -- cycle;
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (0.4,6.72) {OV7670 → STM32F103C8T6｜当前同侧接线};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text={rgb,255:red,143;green,236;blue,179}] at (0.4,5.96) {640×480 RGB565 · 原生USB彩色 + OLED黑白预览};
  \filldraw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.742857pt, fill={rgb,255:red,22;green,51;blue,72}] (-9,4.6) -- (-2.5,4.6) -- (-2.5,-5.6) -- (-9,-5.6) -- cycle;
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (-5.8,5.1) {摄像头排针：按丝印面观察};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (-5.8,3.84) {OV7670 · 无外置 FIFO};
  \filldraw[draw={rgb,255:red,255;green,184;blue,77}, line width=0.742857pt, fill={rgb,255:red,16;green,24;blue,32}] (-7.56,3.02) -- (-7.24,3.02) -- (-7.24,2.7) -- (-7.56,2.7) -- cycle;
  \node[anchor=east, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,184;blue,77}] at (-7.8,2.86) {3.3V};
  \filldraw[draw={rgb,255:red,255;green,227;blue,107}, line width=0.742857pt, fill={rgb,255:red,16;green,24;blue,32}] (-4.26,3.02) -- (-3.94,3.02) -- (-3.94,2.7) -- (-4.26,2.7) -- cycle;
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,227;blue,107}] at (-3.7,2.86) {DGND};
  \filldraw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.742857pt, fill={rgb,255:red,16;green,24;blue,32}] (-7.56,2.1) -- (-7.24,2.1) -- (-7.24,1.78) -- (-7.56,1.78) -- cycle;
  \node[anchor=east, inner sep=0pt, outer sep=0pt, text={rgb,255:red,40;green,215;blue,236}] at (-7.8,1.94) {SCL};
  \filldraw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.742857pt, fill={rgb,255:red,16;green,24;blue,32}] (-4.26,2.1) -- (-3.94,2.1) -- (-3.94,1.78) -- (-4.26,1.78) -- cycle;
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,40;green,215;blue,236}] at (-3.7,1.94) {SDA};
  \filldraw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.742857pt, fill={rgb,255:red,16;green,24;blue,32}] (-7.56,1.18) -- (-7.24,1.18) -- (-7.24,0.86) -- (-7.56,0.86) -- cycle;
  \node[anchor=east, inner sep=0pt, outer sep=0pt, text={rgb,255:red,40;green,215;blue,236}] at (-7.8,1.02) {VS};
  \filldraw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.742857pt, fill={rgb,255:red,16;green,24;blue,32}] (-4.26,1.18) -- (-3.94,1.18) -- (-3.94,0.86) -- (-4.26,0.86) -- cycle;
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,40;green,215;blue,236}] at (-3.7,1.02) {HS};
  \filldraw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.742857pt, fill={rgb,255:red,16;green,24;blue,32}] (-7.56,0.26) -- (-7.24,0.26) -- (-7.24,-0.06) -- (-7.56,-0.06) -- cycle;
  \node[anchor=east, inner sep=0pt, outer sep=0pt, text={rgb,255:red,40;green,215;blue,236}] at (-7.8,0.1) {PLK};
  \filldraw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.742857pt, fill={rgb,255:red,16;green,24;blue,32}] (-4.26,0.26) -- (-3.94,0.26) -- (-3.94,-0.06) -- (-4.26,-0.06) -- cycle;
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,40;green,215;blue,236}] at (-3.7,0.1) {XLK};
  \filldraw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.742857pt, fill={rgb,255:red,16;green,24;blue,32}] (-7.56,-0.66) -- (-7.24,-0.66) -- (-7.24,-0.98) -- (-7.56,-0.98) -- cycle;
  \node[anchor=east, inner sep=0pt, outer sep=0pt, text={rgb,255:red,40;green,215;blue,236}] at (-7.8,-0.82) {D7};
  \filldraw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.742857pt, fill={rgb,255:red,16;green,24;blue,32}] (-4.26,-0.66) -- (-3.94,-0.66) -- (-3.94,-0.98) -- (-4.26,-0.98) -- cycle;
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,40;green,215;blue,236}] at (-3.7,-0.82) {D6};
  \filldraw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.742857pt, fill={rgb,255:red,16;green,24;blue,32}] (-7.56,-1.58) -- (-7.24,-1.58) -- (-7.24,-1.9) -- (-7.56,-1.9) -- cycle;
  \node[anchor=east, inner sep=0pt, outer sep=0pt, text={rgb,255:red,40;green,215;blue,236}] at (-7.8,-1.74) {D5};
  \filldraw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.742857pt, fill={rgb,255:red,16;green,24;blue,32}] (-4.26,-1.58) -- (-3.94,-1.58) -- (-3.94,-1.9) -- (-4.26,-1.9) -- cycle;
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,40;green,215;blue,236}] at (-3.7,-1.74) {D4};
  \filldraw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.742857pt, fill={rgb,255:red,16;green,24;blue,32}] (-7.56,-2.5) -- (-7.24,-2.5) -- (-7.24,-2.82) -- (-7.56,-2.82) -- cycle;
  \node[anchor=east, inner sep=0pt, outer sep=0pt, text={rgb,255:red,40;green,215;blue,236}] at (-7.8,-2.66) {D3};
  \filldraw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.742857pt, fill={rgb,255:red,16;green,24;blue,32}] (-4.26,-2.5) -- (-3.94,-2.5) -- (-3.94,-2.82) -- (-4.26,-2.82) -- cycle;
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,40;green,215;blue,236}] at (-3.7,-2.66) {D2};
  \filldraw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.742857pt, fill={rgb,255:red,16;green,24;blue,32}] (-7.56,-3.42) -- (-7.24,-3.42) -- (-7.24,-3.74) -- (-7.56,-3.74) -- cycle;
  \node[anchor=east, inner sep=0pt, outer sep=0pt, text={rgb,255:red,40;green,215;blue,236}] at (-7.8,-3.58) {D1};
  \filldraw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.742857pt, fill={rgb,255:red,16;green,24;blue,32}] (-4.26,-3.42) -- (-3.94,-3.42) -- (-3.94,-3.74) -- (-4.26,-3.74) -- cycle;
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,40;green,215;blue,236}] at (-3.7,-3.58) {D0};
  \filldraw[draw={rgb,255:red,255;green,184;blue,77}, line width=0.742857pt, fill={rgb,255:red,16;green,24;blue,32}] (-7.56,-4.34) -- (-7.24,-4.34) -- (-7.24,-4.66) -- (-7.56,-4.66) -- cycle;
  \node[anchor=east, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,184;blue,77}] at (-7.8,-4.5) {RET};
  \filldraw[draw={rgb,255:red,255;green,227;blue,107}, line width=0.742857pt, fill={rgb,255:red,16;green,24;blue,32}] (-4.26,-4.34) -- (-3.94,-4.34) -- (-3.94,-4.66) -- (-4.26,-4.66) -- cycle;
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,227;blue,107}] at (-3.7,-4.5) {PWDN};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (-5.8,-6.4) {3.3V / DGND 在上，RET / PWDN 在下};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,227;blue,107}] at (-5.8,-7.1) {若模块翻面或旋转，以丝印名称为准。};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (-5.8,-7.8) {PLK=PCLK · XLK=XCLK};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (-5.8,-8.46) {HS=HREF · VS=VSYNC · RET=RESET};
  \filldraw[draw={rgb,255:red,52;green,71;blue,89}, line width=0.742857pt, fill={rgb,255:red,20;green,34;blue,47}] (-0.8,5.1) -- (12.1,5.1) -- (12.1,-8.48) -- (-0.8,-8.48) -- cycle;
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (5.64,4.52) {信号对应表（不是 STM32 实物针序）};
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,184;blue,77}] at (-0.2,3.7) {3.3V};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,184;blue,77}] at (2,3.7) {→};
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,184;blue,77}] at (2.9,3.7) {3.3V 电源};
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,227;blue,107}] at (-0.2,3.06) {DGND};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,227;blue,107}] at (2,3.06) {→};
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,227;blue,107}] at (2.9,3.06) {GND 共地};
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,40;green,215;blue,236}] at (-0.2,2.42) {SCL};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text={rgb,255:red,40;green,215;blue,236}] at (2,2.42) {→};
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,40;green,215;blue,236}] at (2.9,2.42) {PC15 / C15 · SCCB 时钟};
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,40;green,215;blue,236}] at (-0.2,1.78) {SDA};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text={rgb,255:red,40;green,215;blue,236}] at (2,1.78) {→};
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,40;green,215;blue,236}] at (2.9,1.78) {PB11 · SCCB 数据};
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,40;green,215;blue,236}] at (-0.2,1.14) {XLK};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text={rgb,255:red,40;green,215;blue,236}] at (2,1.14) {→};
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,40;green,215;blue,236}] at (2.9,1.14) {PB10 · TIM2 CH3 / 12MHz};
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,184;blue,77}] at (-0.2,0.5) {RET};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,184;blue,77}] at (2,0.5) {→};
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,184;blue,77}] at (2.9,0.5) {3.3V · 非复位};
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,227;blue,107}] at (-0.2,-0.14) {PWDN};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,227;blue,107}] at (2,-0.14) {→};
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,227;blue,107}] at (2.9,-0.14) {GND · 工作模式};
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,40;green,215;blue,236}] at (-0.2,-0.78) {D0};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text={rgb,255:red,40;green,215;blue,236}] at (2,-0.78) {→};
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,40;green,215;blue,236}] at (2.9,-0.78) {PA0 · 摄像头数据输入};
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,40;green,215;blue,236}] at (-0.2,-1.42) {D1};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text={rgb,255:red,40;green,215;blue,236}] at (2,-1.42) {→};
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,40;green,215;blue,236}] at (2.9,-1.42) {PA1 · 摄像头数据输入};
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,40;green,215;blue,236}] at (-0.2,-2.06) {D2};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text={rgb,255:red,40;green,215;blue,236}] at (2,-2.06) {→};
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,40;green,215;blue,236}] at (2.9,-2.06) {PA2 · 摄像头数据输入};
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,40;green,215;blue,236}] at (-0.2,-2.7) {D3};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text={rgb,255:red,40;green,215;blue,236}] at (2,-2.7) {→};
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,40;green,215;blue,236}] at (2.9,-2.7) {PA3 · 摄像头数据输入};
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,40;green,215;blue,236}] at (-0.2,-3.34) {D4};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text={rgb,255:red,40;green,215;blue,236}] at (2,-3.34) {→};
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,40;green,215;blue,236}] at (2.9,-3.34) {PA4 · 摄像头数据输入};
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,40;green,215;blue,236}] at (-0.2,-3.98) {D5};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text={rgb,255:red,40;green,215;blue,236}] at (2,-3.98) {→};
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,40;green,215;blue,236}] at (2.9,-3.98) {PA5 · 摄像头数据输入};
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,40;green,215;blue,236}] at (-0.2,-4.62) {D6};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text={rgb,255:red,40;green,215;blue,236}] at (2,-4.62) {→};
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,40;green,215;blue,236}] at (2.9,-4.62) {PA6 · 摄像头数据输入};
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,40;green,215;blue,236}] at (-0.2,-5.26) {D7};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text={rgb,255:red,40;green,215;blue,236}] at (2,-5.26) {→};
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,40;green,215;blue,236}] at (2.9,-5.26) {PA7 · 摄像头数据输入};
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,40;green,215;blue,236}] at (-0.2,-5.9) {PLK};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text={rgb,255:red,40;green,215;blue,236}] at (2,-5.9) {→};
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,40;green,215;blue,236}] at (2.9,-5.9) {PB0 · TIM3 CH3};
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,40;green,215;blue,236}] at (-0.2,-6.54) {HS};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text={rgb,255:red,40;green,215;blue,236}] at (2,-6.54) {→};
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,40;green,215;blue,236}] at (2.9,-6.54) {PB1 · 行有效};
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,40;green,215;blue,236}] at (-0.2,-7.18) {VS};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text={rgb,255:red,40;green,215;blue,236}] at (2,-7.18) {→};
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,40;green,215;blue,236}] at (2.9,-7.18) {PC14 / C14 · 帧同步};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,184;blue,77}] at (0.4,-9.34) {换线先断电：VS→C14；XLK→B10；SCL→C15。旧PB5 / PA8不再使用。};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,184;blue,77}] at (0.4,-10.04) {OLED：VCC→3.3V，GND→GND，SCL→PB6，SDA→PB7。};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (0.4,-10.74) {USB：D−→PA11，D+→PA12，5V→板5V，GND共地；必须是数据线。};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text={rgb,255:red,143;green,236;blue,179}] at (0.4,-11.44) {ST-Link：SWDIO→PA13，SWCLK→PA14，GND共地；USB供电时不接下载器供电线。};
\end{tikzpicture}
```

### 摄像头调焦：先分清模糊来源

OV7670模块通常没有自动对焦；可调螺纹镜头需要手动改变镜头位置。具体锁紧结构依模块而异，不保证每块都能直接旋转。[Adafruit调焦说明](https://learn.adafruit.com/adafruit-ov7670-camera-library-samd51/other-hardware-notes)

1. 固定摄像头，拍摄正常照明下约30～50cm外的印刷文字、黑白边缘或纹理，避开灯泡和窗户直射。保持拍摄距离、光照不变。
2. 用电脑端640×480彩色图判断细节，不用85×64黑白OLED判断最佳焦点。确认帧号持续增加；旧画面不更新时不能凭旋转前后判断。
3. 如有侧面锁紧螺钉，先略松；如有固定胶，不强拧。固定镜头座，仅小幅旋转可调镜筒，每次转几度，等待至少两张新画面后比较。越调越糊就反方向小幅回调；不要一次转很多圈或把镜头拧脱。
4. 以文字边缘最清楚为准，轻轻锁紧后再检查。换拍摄距离后可能需要重新调焦。调焦不会修复错色、错行、过曝或低帧率。

**本次记录的是建议的调焦方法，未测量或标定这颗镜头的最佳位置。** 用户曾确认RGB565实景成像正常；仍不能把所有后续模糊都归为焦距。

| 现象 | 优先检查 |
|---|---|
| 轮廓完整但普遍模糊 | 镜头焦点、拍摄距离、运动、曝光时间 |
| 大片白色、亮部细节消失 | 光照、曝光/增益、寄存器是否复位；不是靠锐化补救 |
| 颜色乱、条纹或像素错位 | RGB565字节次序、采样边沿、行首位置、数据线 |
| 画面不更新或漏行 | 最新帧时间、行计数、CRC、USB积压与采样调度 |

### 带宽与采样限制

OV7670的640×480/最高30fps是传感器输出能力，不等于当前主控到电脑的帧率。F103C8T6只有20KiB SRAM、72MHz CPU，没有专用DCMI；一帧RGB565要614400字节，无法整帧放在RAM中，必须按行采样、分块发送。硬件资料：[ST F103C8](https://www.st.com/en/microcontrollers-microprocessors/stm32f103c8)、[OV7670手册](https://www-ug.eecg.toronto.edu/msl/manuals/OV7670Datasheet.pdf)。

- F103内置USB为Full Speed，12Mbit/s，即1.5MB/s原始总线比特率换算，实际图像负载还要扣除协议与调度开销。换USB3端口、Type-C插头或提高CPU时钟，不能把它变成480Mbit/s高速USB。
- VGA RGB565：640×480×2＝614400字节；30fps需18.432MB/s，远超USB FS。相机8位数据总线不代表每个彩色像素只有1字节，RGB565需要两个字节。
- 曾测得USB测试程序约574KiB/s；USB彩色视频稳定窗口约576KB/s图像有效数据。两者为实现实测，不是USB硬件的绝对天花板；KiB按1024、KB按1000计算。
- 提速不能只改相机分频：采样、行间处理、缓存、USB发送、电脑持续读取、PNG生成都可能限速。实测更快档会漏行，不能把所有瓶颈归为USB带宽。
- ESP8266八针模块不适合直接接完整OV7670并行口；经串口转Wi-Fi会增加传输限制。例如921600波特率、8N1理论有效约92KB/s，一张RGB565约需6.7秒，未含协议开销。

### 本次实测演进与结果

| 配置 | 结果 | 当前是否采用 |
|---|---|---|
| USB VGA RGB565初版 | 约4.26秒/帧 | 历史 |
| CPU72MHz、HREF边界采样、硬件CRC、分线程接收 | 逐步约2.13～1.87秒/帧 | 优化经验保留 |
| USB应用传输缓冲512B、电脑64KiB连续读取，CLKRC7 | 约1.066秒/帧；曾55秒50完整帧、0错误，后续也观察过偶发丢帧 | 无OLED时的已验证基线；非永不丢帧保证 |
| Bayer RAW，每像素1字节，CLKRC4 | 307200字节/帧、约0.666秒/帧；传输完整，但用户确认颜色还原失败 | **撤回，不作为成功方案** |
| 当前RGB565 + OLED，CLKRC11 | 传感器周期1.599秒；OLED写入约103ms，错过下一次帧起点，实际约3.2秒更新一次；USB约0.31fps | **当前运行版本** |

当前OLED把640×480按比例缩至85×64居中，用4×4有序抖动表现灰度，屏幕本身仍只有黑白。曾关闭电脑接收程序验证OLED继续刷新；物理断开USB改用独立供电未专门测试。最近最终窗口OLED7→12次刷新，漏行/CRC/采集错误均为0；这只证明该观察窗口，不代表长期保证。实物屏幕显示效果仍以用户观察为准。

### 值得保留的调试经验

- 先做SCCB寄存器读回、数字测试图、逐位walking-one，再检查实景。数字链路通过不等于镜头/曝光/颜色通过。
- 遮住镜头会明显变黑、移开恢复，只能证明光响应，不证明焦点正确。
- HREF有效窗口实测有1280个RGB565字节及一个额外尾时钟；保留行首1280字节。曾因尾对齐导致RGB字节错位和异常颜色，不能盲目丢首字节。
- 曾观察到摄像头寄存器回到上电默认，需排查供电、RET/PWDN与接触；软件配置成功一次不代表以后未复位。
- 相机时钟降得很低时，默认防闪烁参数可能不适用。当前COM8=C7保留自动曝光/增益/白平衡、关闭防闪烁约束；不是所有场景都应照抄该值。
- USB端点物理包仍64字节，512字节是应用缓冲批次；电脑64KiB读取和PNG独立线程减少了接收阻塞。
- OLED缩图计算占用行间时间，过重会漏行；I2C刷屏也会影响下一帧同步。加OLED并非免费，不应沿用USB单独运行的帧率宣传。
- CRC与合成去马赛克测试通过不证明实际Bayer颜色正确。该实验仅证实减小了数据量，未完成实际颜色还原，已回退。
- Keil与命令行构建使用独立对象目录，避免ABI/编译选项不同导致混用旧对象。每次换引脚同步改固件、启动中断向量、接线表和画板。

工程：`D:\down\Mod\stm32\camera-usb`，Keil工程`Camera_USB.uvprojx`；页面`http://127.0.0.1:8770/`。本地证据：`batch-result.json`、`bayer-result.json`、`oled-final.json`；可回退备份在`backup`目录。第9节继续保留历史恢复鱼缸记录，不代表当前状态。

### 原作者参考（保留）



| 原作者项目 | 源码已证明的实现 | 对当前硬件的适用范围 |
|---|---|---|
| [sqlxx/stm32-workshop · ov7670分支](https://github.com/sqlxx/stm32-workshop/tree/ov7670) | F103R系列，320×240 RGB565，GPIO读并行口，640字节行缓存经SPI送ILI9341 | 最接近现有F103；PC0～PC7应适配为PA0～PA7，电脑显示替代其彩屏，不能直接照抄引脚 |
| [iwatake2222/DigitalCamera_STM32](https://github.com/iwatake2222/DigitalCamera_STM32) | F407 Discovery＋无外置FIFO OV7670，DCMI＋DMA送并口LCD | 有完整成像展示；作者报告QVGA预览约20fps，非本板实测。DCMI/FSMC路径不能直接迁移到F103C8T6 |
| [ComputerNerd/ov7670-no-ram-arduino-uno](https://github.com/ComputerNerd/ov7670-no-ram-arduino-uno) | 小内存直接传电脑；默认VGA Bayer，QVGA/QQVGA使用YUV422和行缓冲 | 可参考行缓存与消隐期传输；不是VGA RGB565高帧率方案，Bayer还需要电脑去马赛克 |

[F407原作者演示](https://www.youtube.com/watch?v=MqtJbraAlOU)。本轮核查了源码路径，未在这些参考硬件上运行，也未独立测得其宣称的帧率。

版本与入口：sqlxx `78f3d9f`，`Core/Src/main.c` → `User/Src/ov7670.c` → GPIO逐行读取 → `HAL_SPI_Transmit`；F407 `e3ca40f0`，`Src/app/liveviewCtrl.c` → `Src/hal/camera.c` → `Src/driver/ov7670/ov7670.c` → `HAL_DCMI_Start_DMA`；Uno `d64dcf0a`，`main.c` → `camInit/setRes/setColorSpace` → `captureImg` → UART。



## 9. 摄像头实验总结与恢复测距鱼缸（2026-09-10）

本节为2026-09-10的历史实测与恢复鱼缸记录，保留用于回顾，不代表当前烧录状态。2026-09-12已完成摄像头原生USB与OLED预览，最新接线、调焦及实测总结见第8节；本节恢复鱼缸记录仅为历史。

### 实际做到了什么

- OV7670 识别成功：PID/VER=0x7673，厂商 ID=0x7FA2。
- STM32F103C8T6 通过 TIM3_CH3 触发 DMA 读取并行数据，完成逐行采集、亮度提取和 OLED 80×60 黑白显示。
- 电脑先实现 80×60 灰度预览，再实现 160×120 分块扫描。早期 160×120 的四个条带来自不同传感器帧，有运动拼接错位的限制。
- 后续实现 640×480 VGA 同帧分块传输：两个 4800 字节缓冲轮换发布，电脑校验序列锁、帧号、行位置及结束标记，缺块不跨帧补齐。
- VGA 4 位量化灰度档实测连续 8 帧无缺块、无采集错误，约 0.19 fps。4 位代表最多 16 级灰度，空间尺寸仍为 640×480；PNG 映射到 8 位显示不会恢复丢失的灰度精度。
- ST-Link 持久连接读取 4848 字节约 46.7ms，约 103KB/s。提高传感器时钟后出现缓冲覆盖，不能只以摄像头输出速度衡量有效刷新率。
- VGA 8 位及各预览档的最终速度未完成验证；每四帧刷新一次 OLED 的优化只编译通过，未完成烧录验证。不能把这些候选方案称为已经达到的性能。

### 经验与边界

1. F103C8T6 的 20KiB RAM 和无 DCMI 接口决定了它更适合控制、测距和小屏动画。VGA 灰度需要 300KiB，RGB565 彩色需要 600KiB；分块解决缓存容量，不能凭空增加吞吐。
2. 分别测量传感器采集、同步等待、OLED 刷新、电脑传输和完整帧到达率。ST-Link 可用于诊断，电脑图传仍受其带宽约束。
3. 先读芯片 ID，再用测试条纹检查字节顺序、行长和稳定性，最后看真实镜头。识别成功只证明当时 SCCB 通信正常，不等于全部连线可靠。
4. 本次曾有 ID、厂商 ID、行长异常和 USB 失联；不能单凭一次 0 错误断言接线长期稳定，也不能把全部问题归因于驱动。
5. 灰度原图已有明暗轮廓，用户确认可辨，但仍偏模糊。增加像素、对比度拉伸和抖动不能恢复光学细节；对焦、光线及信号质量需要分开检查。
6. OLED 上看到的黑白块可能来自二值化。保留电脑未增强灰度视图有助于区别采集问题与显示处理问题。
7. 做更完整的图像项目，应选带摄像头接口、DMA 和足够图像内存的平台，例如带 SDRAM 的 STM32F429/F7/H7 开发板；无线图传可考虑带 PSRAM 的 ESP32-S3。具体型号还要核对引脚、驱动和传输链路，不能仅看主频。

参考：[ST DCMI 应用说明](https://www.st.com/resource/en/application_note/an5020-digital-camera-interface-dcmi-on-stm32-mcus-stmicroelectronics.pdf)、[Espressif 摄像头驱动](https://github.com/espressif/esp32-camera)。以上实测速率只代表这套板卡、连线和当时的光照条件。

### 恢复后的接线与功能

先断电拔下摄像头，尤其不能让摄像头 D0 与恢复为输出的 PA0 同时连接。用户已确认摄像头拔下。

| 模块 | 引脚 | STM32 / 电源 |
|---|---|---|
| OLED | VCC / GND | 3.3V / GND |
| OLED | SCL / SDA | PB6 / PB7 |
| HC-SR04 | VCC / GND | 5V / GND |
| HC-SR04 | TRIG | PA0 |
| HC-SR04 | ECHO | PB8 |
| ST-Link | SWDIO / SWCLK / GND | PA13 / PA14 / GND |

本项目沿用此前无电阻方案：PB8 为支持 5V 容限的数字输入，配置为浮空输入，禁用内部上下拉；MCU 必须正常供电并共地，不允许模块在 MCU 断电时继续向它送信号。此前 PA1 直接接 ECHO 的方案不适用。

恢复版本使用默认 8MHz 时钟、12µs TRIG、回波等待总超时 30ms，测量结束后等待至少 80ms；顶部显示距离，鱼缸动画与 ESP 串口留言功能保留。超时显示无有效距离，不把异常值冒充测量结果。超过约 3m 的可靠性仍受目标大小、角度和环境影响，不承诺量程标称值以内都准确。

### 保存与恢复记录

- 原 Clip 正文和插图完整保留，本节仅追加。
- 摄像头源码、Keil 工程及当时编译产物保存在本地 `backup/camera-experiment-20260910`；`camera-viewer`、原尺寸 PNG 与性能采样记录继续保留。备份中的最后一次 OLED 节流改动属于未上板验证版本。
- 停止本地摄像头读取服务，避免继续占用 ST-Link 或对恢复后的固件写入旧控制地址。
- 主工程恢复 `backup/before-camera/main.c`；Keil 全量编译 0 错误、0 警告，Code=5478、RO=1158、ZI=5228 字节。ST-Link 下载读回 `Verification...OK`，已复位运行。
- 软件和下载验证不等于测距标定；当前有效回波与显示运行读回结果见后续记录。

运行读回：鱼缸模式 display_mode=0，OLED 地址 0x3C、状态1，2秒内帧数545→565；测量次数545→565，UART错误0。当前 range_status=2、距离0，表示没有有效回波；用户仅确认摄像头已拔下，HC-SR04重新接好后的有效测距仍待确认。


## 10. ESP8266 → STM32 网页无线烧录方案（设计，尚未实施）

本节仅设计并保存接线。当前测距鱼缸、绿灯常灭和 ESP 留言固件不做修改、不执行烧录。目标为同一局域网或 ESP 热点内上传 STM32 固件；不涉及云端编译、公网服务或 ESP 自身 OTA。

### 首版选择：网页上传，手动进入下载模式

电脑 Keil 编译 STM32 工程并导出 BIN → 浏览器上传 ESP → ESP 暂存并检查文件 → 用户切 STM32 BOOT0 并复位 → ESP 使用 ROM USART Bootloader 擦除、写入、读回校验 → 用户恢复 BOOT0 并复位 → 鱼缸重新运行。

采用 STM32 芯片自带的 ROM Bootloader，不额外安装占用应用 Flash 的自定义引导程序。ESP 初次增加烧录功能仍需使用现有 USB 烧写器更新一次。首版不需要新增 BOOT0/NRST 自动控制电路，适合手头 8 针 ESP 模块和暂无电阻的情况。

### 接线表：首版可按此准备

按丝印名称接线，图中位置不是实物排针顺序。调整接线前断电。ESP 的 TX/RX 是 3.3V TTL，不能接 RS-232 电平。

| ESP8266 模块 / 操作 | STM32F103C8T6 | 说明 |
|---|---|---|
| TX / TXD / GPIO1 | PA10 / RX1 | ESP 发命令，STM32 接收 |
| RX / RXD / GPIO3 | PA9 / TX1 | STM32 返回 ACK 和读回数据 |
| GND | GND | 必须共地 |
| VCC | 独立稳定的 3.3V 电源 | ESP 裸模块不能接 5V；沿用已验证供电，不能默认 ST-Link 能供电 |
| EN / CH_PD、RST、GPIO0、GPIO2 | 不接 STM32 | 保留 ESP 自身正常启动配置；使用适配座时保持运行档 |
| STM32 BOOT1 / PB2 跳帽 | 保持 0 | 系统存储器启动条件之一；不要改成高电平 |
| STM32 BOOT0 跳帽 | 下载前 1，正常运行 0 | 只用跳帽选择板上高/低，不增加一条与跳帽对顶的外部驱动线 |
| STM32 RESET 按键 | 手动按下并松开 | 进入下载模式或返回应用 |

**USB 烧写器串口冲突：**如果 ESP 仍插在 USB 烧写适配器中，先确认适配器 TX 已与 ESP RX 断开；不能让适配器 TX 和 STM32 PA9 同时驱动 ESP RX。仅“关闭串口软件”不等于电气断开。若适配座不能隔离串口，就把 ESP 移到合适的供电/转接座后再接 STM32。不要并联多个电源输出。

OLED 继续 PB6/PB7；HC-SR04 继续 TRIG=PA0、ECHO=PB8，不占用 USART1。摄像头保持撤线。ST-Link 的 PA13/PA14/GND 可保留作救援，但无线烧录期间退出 Keil 调试并停止其他下载/内存读取工具。

```tikz
\begin{tikzpicture}[x=1cm,y=1cm,thick,font=\small]
\draw[rounded corners,fill=blue!5] (0,0) rectangle (4,4.5);
\node[font=\bfseries] at (2,4) {ESP8266};
\draw[rounded corners,fill=green!5] (9,0) rectangle (13,4.5);
\node[font=\bfseries] at (11,4) {STM32F103C8T6};
\foreach \y/\left/\right/\col in {3/TX GPIO1/PA10 RX1/blue,2/RX GPIO3/PA9 TX1/orange,1/GND/GND/black} {
\node[anchor=east] at (3.8,\y) {\left};
\node[anchor=west] at (9.2,\y) {\right};
\draw[\col] (4,\y)--(9,\y);
}
\node[fill=white] at (6.5,3) {commands / BIN};
\node[fill=white] at (6.5,2) {ACK / readback};
\draw[rounded corners,fill=gray!8] (0,5.5) rectangle (4,6.6);
\node[align=center] at (2,6.05) {Browser upload\\Wi-Fi AP / LAN};
\draw[->] (2,5.5)--(2,4.5);
\draw[rounded corners,fill=yellow!10] (8.5,5.5) rectangle (13.5,7.4);
\node[align=center] at (11,6.45) {Manual STM32 controls\\BOOT1 = 0\\BOOT0 = 1: reset to loader\\BOOT0 = 0: reset to app};
\draw[->] (11,5.5)--(11,4.5);
\node[align=center] at (6.5,-0.8) {ESP VCC: regulated 3.3V. Common ground.\\Disconnect USB-UART TX before connecting STM32 TX.};
\end{tikzpicture}
```

### 网页与操作流程

拟在现有 ESP 网页增加“STM32 固件升级”入口，保留配网和留言页。以下功能均为待实现设计：

1. 选择本项目生成的 `.bin`。显示文件大小、SHA-256、目标 F103C8 和写入地址 0x08000000；不开放任意地址输入。
2. 完整上传并暂存成功后，才允许下一步。网页显示“请将 STM32 BOOT0 设为 1、BOOT1 保持 0，按 RESET”。ESP 正常运行，不能把 ESP 的 GPIO0 拉低当作此操作。
3. 用户点击“连接并检查”。ESP 暂停留言发送和串口日志，切换为 115200、8E1，发送 0x7F 同步，检查 ACK、芯片 ID、支持命令与容量。失败时只提示重试，不擦除。
4. 显示匹配结果后点击“开始烧录”。更新期间停止留言，鱼缸和测距暂停；依次显示擦除、写入、校验进度。
5. 校验成功后提示“BOOT0 恢复 0，再按 RESET”。ESP 恢复 115200、8N1 的留言协议。写入成功与应用运行成功分别显示；本次绿灯已关闭，不以 LED 闪烁作为运行凭据。

首版由用户手动复位，不以 GO 命令代替完整复位，以便外设和中断状态从已知状态启动。

### 文件、存储和协议设计

- BIN 是 STM32 应用的原始二进制，不是 ESP 固件、HEX 文本或 AXF 文件。Keil 链接起点保持 0x08000000；本机可用 fromelf `--bin --output Objects/OLED_Test.bin Objects/OLED_Test.axf` 导出，实施时验证产物布局。
- F103C8 按标称 64KiB Flash 限制，拒绝空文件和超过 65536 字节的镜像。检查向量表：初始栈指针对齐且位于本机 SRAM 合法范围，复位向量带 Thumb 位并位于已上传镜像范围。文件检查不能保证其逻辑正确，仍需匹配具体板型。
- 现有 ESP 1MB Flash 配置没有文件系统，不能直接假定能存完整镜像。实施时先备份 ESP，再调整分区，给 LittleFS 暂存区预留至少 128KiB，并确认编译后的程序、SDK 配置区和暂存区不重叠；不同时承诺 ESP 自身 OTA。
- 不把 64KiB 镜像全部塞进 ESP RAM。上传流式写临时文件，完成后核对长度和摘要并原子提交；上传未完成、空间不足或校验失败时禁止擦除 STM32。
- 按 AN3155 实现 GET、GET ID、READ MEMORY、WRITE MEMORY 和设备声明支持的 ERASE / EXTENDED ERASE。分块不超过 256 字节，地址按要求对齐，末尾使用 0xFF 补齐；记录每阶段 ACK/NACK 和超时，给擦除留足时间。
- 只允许应用 Flash 范围，按镜像覆盖的页擦除；不执行解除读保护、修改 Option Bytes 或任意内存写入。写完逐块读回比对全部镜像及补齐字节；普通串口透传不等于实现烧录协议。
- 每次只能有一个升级任务，状态机为：空闲→上传→文件有效→等待手动启动→设备匹配→擦除→写入→读回校验→等待复位→完成/失败。刷新网页可查询当前状态，不重复触发擦除。
- 本地维护入口使用设备端管理凭据、同源检查和明确的开始操作；不在公开 Clip 里保存密码。SHA-256 校验用于完整性检测，不等同于签名认证。公网升级、签名和安全回滚不属于首版。

### 失败恢复与限制

擦除前失败不修改 STM32。擦除或写入中断后，旧程序可能不完整，不存在双镜像自动回滚；保留暂存镜像，重新进入 ROM Bootloader，执行整次擦写和校验。芯片 ROM 引导程序不在应用 Flash 中；仍保留 ST-Link 作为接线、启动模式或串口恢复失败时的救援工具。不要承诺断电升级后仍能自动运行旧程序。

### 后续全自动版本：暂不按此接线

全自动需要 ESP 经合适的电路控制 STM32 BOOT0 和 NRST，同时 BOOT1 保持低。时序为：保持 STM32 复位→设置 BOOT0=1→释放复位→烧录校验→保持复位→BOOT0=0→释放复位。

8 针模块可用的 GPIO0/GPIO2 同时参与 ESP 启动采样；它们直接连接 STM32 跳帽、下拉或复位电路，可能让 ESP 启动失败或使 STM32 意外进入下载模式。因此本阶段不指定 GPIO0/GPIO2 直连接法。后续取得适配座与核心板原理图、补齐电阻/隔离驱动器件后，再给出具体电路及阻值；也可换用引出非启动 GPIO 的 ESP 开发板。自动电路需要验证 ESP 上电、复位、下载、掉电时 STM32 均能处于可恢复状态。

### 实施清单与验收

- [ ] 备份 ESP 和 STM32 固件，确认适配器串口隔离、3.3V 供电及 BOOT 跳帽。
- [ ] 为 ESP 增加暂存区、上传与状态页面，验证异常文件不会触发擦除。
- [ ] 手动启动模式下只读握手，确认设备和 8E1 通信，尚不擦写。
- [ ] 上传当前绿灯常灭的测距鱼缸 BIN，擦写并全量读回校验。
- [ ] BOOT0=0 复位，验证 OLED 鱼缸、有效测距和留言恢复。
- [ ] 验证上传中断、断网、重复点击、错误镜像和重新烧录；阶段结果据实记录。

依据：[ST AN2606 系统存储器启动模式](https://www.st.com/resource/en/application_note/an2606-introduction-to-system-memory-boot-mode-on-stm32-mcus-stmicroelectronics.pdf)、[ST AN3155 USART 烧录协议](https://www.st.com/resource/en/application_note/an3155-how-to-use-usart-protocol-in-bootloader-on-stm32-mcus-stmicroelectronics.pdf)、[Espressif ESP8266 启动电平说明](https://docs.espressif.com/projects/esptool/en/latest/esp8266/advanced-topics/boot-mode-selection.html)。本节是设计，未增加 ESP 网页或改变任何板卡固件。


## 11. SG90 舵机实验总结：定点切换正常（2026-09-10）

**最终实物反馈：改成两个固定位置之间切换后，用户确认“正常了”。** 当前保留直接周期测试，不受超声波距离控制。此前摄像头、无线烧录等设计与插图保留为历史记录；本节更新实际接线和舵机运行结论。

### 当前接线与运行参数

按“每个模块的信号线尽量同侧、相邻”的偏好安排；常见 F103 小板上，以下信号集中在 PB5～PB9，实物位置以丝印为准。

| 模块 | 信号 | 当前接线 |
|---|---|---|
| SG90 | 橙／黄色信号线 | PB5，TIM3_CH2 部分重映射 |
| SG90 | 棕／黑线 | GND，与 STM32 共地 |
| HC-SR04 | TRIG | PB9，原 PA0 接法已作废 |
| HC-SR04 | ECHO | PB8，FT 浮空数字输入，禁用内部上下拉 |
| OLED | SCL / SDA | PB6 / PB7 |

HC-SR04 保持 5V 供电，OLED 保持 3.3V。摄像头已经撤线。**舵机红线：用户明确表示本次用 3.3V 测试，之后没有明确确认已换电源。** 因此记录为“最后已知供电为3.3V”，不能把最后成功默认为改接5V的结果，也不能据此认定3.3V符合SG90额定工作条件。正式使用仍应按具体舵机规格使用约4.8～5V且电流充足的电源，并共地。

| 参数 | 最终值 |
|---|---|
| 当前模式 | servo_test_mode=3，定点周期测试 |
| PWM 载波 | 50Hz，20ms 一帧，持续输出 |
| 目标一 | 500µs，保持1秒 |
| 目标二 | 2500µs，保持1秒 |
| 循环周期 | 2秒，连续重复，无自动停止 |
| 位置转换 | 直接切换目标，不发送逐步插值的中间位置 |
| 实际轴角 | 用户观察约180°，未用量角器精确标定 |
| 其他功能 | 鱼缸、测距显示和留言代码保留，板载绿灯常灭 |

这里的“保持1秒”是持续发送该目标的PWM，包含舵机转过去所用的时间，不是检测到到位后再计时。没有轴角反馈，不能保证任何供电或负载下都能按时到位。

核心行为等价于：

```c
// 20ms更新一次，硬件定时器持续产生50Hz PWM。
pulse_us = phase_ms < 1000 ? 500 : 2500;
phase_ms = (phase_ms + 20) % 2000;
```

### 从旧工程找到的参考

用户提供目录 → `t1/t2/t2.uvprojx` → `t1/t2/main.c` → `SystemClock_Config_ex3()` → `ServoMotor_Init()` → `ServoMotor_SetAngle()` → HAL TIM3 PWM。

- `C:\Users\vine\Documents\keil\t1\t2\servo_motor.c` 使用 PB1 / TIM3_CH4，PSC=71、ARR=19999，脉宽公式为 `500 + angle / 180 * 2000`。
- `t1/t2/port.c` 配置72MHz系统时钟，APB1分频2；定时器时钟仍为72MHz，除以72得到1MHz计数，即每计数1µs。
- 当前工程使用8MHz时钟，所以PSC=7；同样得到1MHz计数。保留20ms周期与角度映射，适配到PB5 / TIM3_CH2，不直接照抄分频值或旧引脚。
- 旧 `main.c` 调用了初始化和 `SetAngle(0)`，但循环中的扫描调用被注释；旧文件本身不能证明当时完整扫描已经稳定运行。
- 另一个 `t1/sor/servo_motor.c` 把PB6配置成TIM3_CH1，与F103引脚映射不符，不作为直接移植依据。`t1/t2/pwm.c` 中还存在按84MHz假设写的另一个舵机初始化，实际入口没有调用它。
- 没有找到能确认旧实验舵机供电电压的记录。此次只读原工程，没有修改它。

迁移对应：旧程序500～2500µs映射 → 当前定点脉宽；旧72MHz/72计数 → 当前8MHz/8计数；旧PB1/CH4 → 当前PB5/CH2部分重映射；旧阻塞扫描 → 当前SysTick调度、定时器硬件输出。原代码的10°步进和测距等待并未机械照搬。

### 排查过程与有效结论

1. **先分离测距与舵机。** 初始“距离取模”方案对最近有效值滤波，目标为 `30 + (厘米 % 120)`，加入限速；无回波时暂停，持续1秒后停PWM。运行曾观察到回波间歇、目标改变后又停止，故不能把不转直接认定为舵机损坏。当前测试已绕过测距，联动代码仍保留但没有启用。
2. **验证硬件PWM，而不只看寄存器。** 配置TIM3的20ms周期，比较寄存器预装载；缓动由SysTick独立调度。PB5输入路径曾测得约19998～20001µs周期，以及约1195/1495/1796µs高电平、检查错误0。该结果支持当时MCU引脚有脉冲，但不证明舵机插头端信号、供电或机械动作正常。
3. **小幅试验不能代表最大行程。** 1400～1600µs按旧公式仅约81～99°；当时转得少主要是软件刻意限制幅度。不能据此说SG90只能小角度转动。
4. **扩大脉宽不能突破机械限位。** 曾依用户要求试500～2500、450～2550、0～3000µs。用户观察仍只有约180°，随后恢复500～2500µs。0µs表示无脉冲，不是0°；超出常用脉宽不是“解锁角度”的方法。0～3000µs试验不作为推荐工作范围。
5. **过慢的中间指令可能表现为分段动作。** 先以5µs/20ms缓动，再提高到20µs/20ms，用户表示更正常；之后测试40、80µs/20ms。小步进可能与舵机死区、摩擦和内部控制响应共同造成“积累几步才动”，但本次没有测量死区或电流，不能认定这是唯一根因。
6. **最终采用固定目标切换。** 用户要求“不使用连续变化”，于是改为500/2500µs各保持1秒，去掉软件位置插值，用户确认正常。这说明对这次位置切换实验，直接给目标比当前慢速插值方案更合适；不等于所有舵机都不适合平滑轨迹。
7. **不要过早把问题全归因于供电。** 3.3V低于普通SG90常见额定电压，可能影响力矩和稳定性；但用户没有确认更换供电，定点切换后却确认正常，所以当前证据不足以说“供电就是唯一原因”。正式负载测试仍需合规电源，不能把空载能动等同于可靠工作。
8. **区分声音。** 运动中的电机、齿轮声可能正常；顶住端点、持续吃力嗡鸣、明显发热或打齿不应继续硬试。最终“正常”是用户对动作的反馈，不是完全静音的证明。保持固定位置时仍持续输出PWM，舵机可能为保持力矩而发声。

### 电源与可复现边界

ST-Link 的5V脚能否供电要看具体版本、额定电流和保护，不能把VAPP/VTref检测脚当输出，也不能假定下载器适合驱动舵机。常见Blue Pill的5V引脚与USB 5V直连，可能既用于取电也用于外部输入；具体板型须核对，外部5V与电脑USB不能直接并联。以上是接线边界，不是本次已经改线的记录。

最终编译：Keil 0错误、0警告，Code=7074、RO=1238、RW=20、ZI=5312字节。ST-Link下载并读回 `Verification...OK`。用户随后确认定点周期动作正常。当前信号仍在PB5、无需迁回旧PB1。

本地文件：`servo_pwm.h`（硬件PWM与测试模式）、`servo_control.h`（未启用的测距控制）、`test_servo.c`（取模/滤波/限速/超时等主机测试）、`servo-discrete-flash.log`（最终下载记录）。主机算法测试和早期引脚读回是各自阶段的证据，不替代最终负载、角度、温升或长期稳定性验收。

后续若重新做测距联动，优先从“距离分区 → 少量固定目标角度”开始，加稳定确认和无回波处理，再按需要增加插值。先确认负载与供电，不为追求大角度继续扩大到机械限位之外。

依据：[ST RM0008 定时器与引脚重映射](https://www.st.com/resource/en/reference_manual/cd00171190.pdf)、[TowerPro SG90 参数](https://towerpro.com.tw/product/sg90-7/)、[Pololu 舵机控制与端点说明](https://www.pololu.com/blog/18/simple-hardware-approach-to-controlling-a-servo)、[Adafruit 舵机供电排查](https://learn.adafruit.com/adafruit-arduino-lesson-14-servo-motors/if-the-servo-misbehaves)。旧实现来源为用户本机文件，没有公开仓库链接；实际动作结论来自用户本次反馈。


## 12. 蜂鸣器与麦克风：先识别模块，再选择驱动方式

本节及后续章节补充第11节之后的实验。当前固件已进入“五区手势＋声控鱼缸”；第11节的舵机周期是历史成功实验，当前已暂停，不代表仍在来回转动。

### MH-FMD 三针有源蜂鸣器

用户提供丝印 `VCC、GND、I/O`，型号标记 MH-FMD，并亲自确认低电平触发。接线：VCC→3.3V、GND→GND、I/O→PA8。

测试程序上电先将PA8输出寄存器置高，再配置推挽输出；静音1.8秒、低电平鸣叫0.2秒，每2秒循环一次。节拍由1ms SysTick维护，不依赖OLED刷新或超声波阻塞等待。低电平有效的有源模块只需控制开关，不需要用音频PWM持续驱动。

验证：Keil编译0错误0警告，ST-Link烧录校验OK；SWD回读确认PA8高低交替，相邻低电平起点约隔2004ms，符合设计。该轮询不是示波器精密测量；实际鸣叫效果未收到单独确认。当前为了麦克风实验，`buzzer_enabled=0`，PA8保持高电平静音。

### 五针模块是麦克风放大板，不是第二只蜂鸣器

`GND、VDD、GAIN、OUT、AR` 的组合与MAX9814麦克风放大模块相符；芯片型号尚未通过清晰照片或芯片丝印独立核验。测试按MAX9814配置：

| 麦克风引脚 | 连接 | 作用 |
|---|---|---|
| VDD | 3.3V | 模块供电 |
| GND | GND | 共地 |
| OUT | PA0 / ADC1_IN0 | 模拟声音信号，STM32作为输入 |
| GAIN | 3.3V | 对标准MAX9814选择40dB最大增益 |
| AR | 悬空 | 使用模块对应的默认攻放比配置 |

MAX9814带自动增益，输出含直流偏置；标准参考板输出约以1.25V为中心、最大约2V峰峰值。不能把“静音时ADC不为零”当故障，也不能将OUT作为蜂鸣器控制输入。不同成品板仍以实际电路为准。

参考：[Adafruit MAX9814说明](https://learn.adafruit.com/adafruit-agc-electret-microphone-amplifier-max9814/overview)、[接线与测试](https://learn.adafruit.com/adafruit-agc-electret-microphone-amplifier-max9814/wiring-and-test)。

## 13. 麦克风音量条与声控鱼缸

### 实现与玩法

STM32当前运行HSI 8MHz，ADC1时钟4MHz，PA0配置模拟输入。软件以约8kHz在25ms窗口采200点，计算最大值、最小值、平均值和峰峰值。OLED约每100ms刷新一次，因此这是间歇声音强度采样，并非连续录音。

最初顶部显示MIC、强度历史及音量条；加入红外后顶部由五路状态替代，声音控制仍保留。麦克风试验时暂停了SG90 PWM和蜂鸣器，减少实验装置本身的声学干扰。

声控逻辑：

- 开机前20个采样窗口学习环境底噪，约2秒；此时尽量安静。
- 峰峰值超过“底噪×2＋180个ADC计数”，且经过安静复位，触发约2秒鱼群加速和额外气泡。
- 触发冷却1.2秒；持续大声不直接重复触发，需先回落到安静条件。
- 相对底噪的声音强度驱动水面振幅；鱼的位置在后续手势版本中连续更新，避免改速度时瞬移。

### 验证与经验

各版本Keil编译和烧录校验通过，运行回读ADC状态1、采样窗口和OLED帧数持续增长。`test_sound_aquarium.c`验证了预热、突增、冷却、不重复触发、到期恢复及计时回绕。真实拍手效果未收到单独明确验收反馈，不能用ADC变化替代收音成功的证明。

主要限制：浮空PA0也会乱跳；MAX9814自动增益会改变声音幅值，音量条不是校准分贝值；25ms窗口之间有空隙，很短的拍手可能被漏掉。若以后需要可靠拍手计数或录音，应优先升级定时器触发ADC＋DMA连续采样，而不是只调低阈值。

记录：`microphone.h`、`sound_aquarium.h`、`test_sound_aquarium.c`、`microphone-runtime.json`、`sound-aquarium-runtime.json`及对应flash日志。

## 14. 五路红外：输入测试成功，扩展为五区手势鱼缸

### 接线与第一步验证

用户确认模块接口为VCC、GND、OUT1～OUT5，已按下表接线，之后对五路输入测试反馈“正常”。模块的具体型号、额定探测距离，以及属于避障还是循迹结构，尚未独立确定。

| 模块 | STM32 |
|---|---|
| VCC | 3.3V |
| GND | GND |
| OUT1 | PA1 |
| OUT2 | PA2 |
| OUT3 | PA3 |
| OUT4 | PA4 |
| OUT5 | PA5 |

PA1～PA5连续排列，保留PA0给麦克风；配置为数字输入弱上拉，绝不驱动模块输出。早期测试画面“实心=低电平、空心=高电平”，回读曾为五路全低。单次全低无法判断障碍状态，有效极性也不能只从接口名称推断。用户随后逐路测试反馈正常。

本次供电方案为3.3V。PA1～PA5不可直接接5V输出；未核对模块电气规格前，不将其供电随意改为5V。

### 当前玩法与校准

上电移开手，保持探头前环境稳定约2秒。程序对20次采样逐路取多数电平作为无遮挡基准，因此可以适配高或低有效。预热时方框闪烁，之后**实心表示相对开机基准已触发**，与早期“实心=低电平”的测试图例不同。

| 触发区域 | 当前行为 |
|---|---|
| OUT1或OUT2 | 两条鱼向左加速 |
| OUT4或OUT5 | 两条鱼向右加速 |
| 左右同时 | 保持已有方向，避免来回抖动 |
| OUT3从未触发变为触发 | 额外冒泡约2秒 |
| 一直遮挡OUT3 | 不重复触发；移开再遮挡可再次冒泡 |
| 松手 | 恢复慢游，保持最后方向 |
| 声音突增 | 原声控加速与气泡仍可叠加 |

输入掩码连续两帧一致才生效，主要过滤单帧毛刺；响应约一个到两个显示周期。逻辑左右按OUT编号定义，如果实物探头排列相反，需要交换接线或修改映射。若开机时手挡住导致基准错误，移开手后按Reset重新学习。

验证：`test_ir_gesture.c`覆盖32种无遮挡基准、单帧毛刺、左右选择、左右冲突、中心持续遮挡仅触发一次、气泡到期及鱼位置边界。Keil0错误0警告，`ir-gesture-flash.log`为Verification...OK；`ir-gesture-runtime.json`显示校准完成、OLED与ADC正常，并记录到一次中心触发计数。该计数不证明实际动作符合用户预期：用户确认的是此前五路输入测试，最终手势视觉效果尚待单独确认。

## 15. 当前接线总览、恢复点与后续方向

以下以当前“五区手势＋声控鱼缸”固件为准，覆盖历史章节里已变更的引脚分配；不表示所有历史模块当前仍物理接着。

| 设备 | 信号连接 | 电源／当前状态 |
|---|---|---|
| OLED | SCL PB6；SDA PB7 | 3.3V，128×64，OLED_PROFILE=0 |
| 麦克风 | OUT PA0；GAIN 3.3V；AR悬空 | VDD 3.3V，采样与声控启用 |
| 红外五路 | OUT1～5依次PA1～PA5 | VCC 3.3V，手势启用 |
| MH-FMD | I/O PA8 | VCC 3.3V，当前高电平静音 |
| ESP8266 | TX→PA10；RX←PA9 | 保留原供电及UART留言功能配置 |
| HC-SR04 | TRIG PB9；ECHO PB8 | VCC 5V，测距代码仍运行，顶部距离读数已被红外覆盖 |
| SG90 | 信号PB5 | 当前servo_test_mode=2，PWM关闭；此前最后明确供电为3.3V，未确认改线 |
| ST-Link | SWDIO PA13；SWCLK PA14；GND | 保留下载调试，PC13绿灯保持关闭 |

所有模块共地。摄像头已退出当前实验，不可把原OV7670连线接回PA0～PA8后与上述设备同时使用。

信号分组示意：

```text
麦克风 OUT ───────── PA0
红外 OUT1 ────────── PA1
红外 OUT2 ────────── PA2
红外 OUT3 ────────── PA3      STM32F103C8T6
红外 OUT4 ────────── PA4
红外 OUT5 ────────── PA5
蜂鸣器 I/O ───────── PA8

舵机信号 ─────────── PB5
OLED SCL / SDA ───── PB6 / PB7
超声波 ECHO / TRIG ─ PB8 / PB9
模块 GND ─────────── 公共 GND
```

本地工程：`D:\down\Mod\stm32\OLED_Test.uvprojx`。当前核心文件：`main.c`、`aquarium.h`、`microphone.h`、`sound_aquarium.h`、`infrared5.h`、`ir_gesture.h`。最新编译记录Code=9682、RO=1266、RW=24、ZI=5620字节。

恢复点均在项目的backup目录：`before-buzzer`（蜂鸣器前）、`before-microphone`（麦克风前）、`before-sound-aquarium`（声控前）、`before-ir5`（红外输入前）、`before-ir-gesture`（手势前）。这些是相关文件和当时HEX/AXF的阶段备份，不是每份都含完整独立工程；直接复现可使用对应HEX，回退源码须同时核对相关头文件。

经验归纳：先识别模块输出性质，再决定GPIO输入、ADC还是输出；先展示原始信号并让用户观察，再绑定互动；自动校准不能替代正确的无遮挡启动环境；源码测试、引脚回读、真实动作反馈分别记录，不能互相替代。

后续只讨论、尚未购买确认或实施：六轴模块可做体感鱼缸／水平仪；GPS用于室外位置、速度、时间，不等于静止朝向传感器。用户询问陀螺仪运动补偿后选择暂不继续，未新增云台或电子防抖代码。此前建议的测距、音频播放器、摄像头开发板也只是选型方向，不是当前已接入设备。本次仅补齐笔记，不修改或重新烧录固件。


## 16. NE555双电位器方波模块：按用户提供原理图解析

用户确认持有NE555模块，并提供实物商品图及本节原理图。实物图可见NE555P、DIP-8芯片座、两个标记W103的电位器、跳帽、LED及三位螺丝端子。以下连接与计算以所提供电路图为依据，尚未给模块通电测频；原理图编号不直接等于实物端子的左右顺序。

### 原理图留存

![用户提供的NE555模块原理图](/public/uploads/l8uzNRWj6SUzqxrLSL-CIRgM.png)

### 电路连接与外部端子

这是标准NE555无稳态振荡电路，持续输出矩形脉冲，不是单次延时继电器板，也不保证50%占空比。

| 原理图编号 | 连接／意义 |
|---|---|
| J5-1 | VCC，连NE555的8脚与电源滤波电容C6上端 |
| J5-2 | GND，连公共地 |
| J5-3 | OUT，连NE555的3脚 |
| NE555 1脚 | GND |
| 2脚TRIG、6脚THRES | 并接到定时电容上端 |
| 3脚OUT | 方波输出，同时接板载LED支路 |
| 4脚RESET、8脚VCC | 接VCC，复位保持非有效状态 |
| 5脚CONT | 经C1“104”到地，即100nF控制端旁路电容 |
| 7脚DISCH | 接两个电位器之间的节点，内部放电开关由此泄放定时电容 |
| C6“100µF” | VCC与GND之间的滤波电容，不参与档位切换 |

接线前仍要用实物丝印／断电通断测量对应J5三端。照片中的三位螺丝端子不能凭观察角度直接指定“左正中负右信号”。建议首次以5V供电方案核对，模块上所有元件额定值仍以实物为准；普通NE555不是保证3.3V工作的CMOS 555替代品。

### 两个10kΩ电位器与四档电容

把J6对应的有效电阻记作RA，J7对应的有效电阻记作RB：

```text
VCC ── RA（J6，10k电位器）──●── RB（J7，10k电位器）──●
                            │                         │
                         7脚DISCH                  2脚＋6脚
                                                      │
                                                选中的定时电容 C
                                                      │
                                                     GND
```

图中每个电位器的滑动端与一端相连，按可变电阻使用；W103表示标称10kΩ。RA位于VCC与7脚之间，RB位于7脚与定时电容节点之间。不能只根据实物照片中“左旋钮／右旋钮”来认定RA、RB，应按PCB或实测确认。

| 跳帽编号 | 定时电容 | 容量解码 | RA=RB=10kΩ时的理论频率 |
|---|---|---|---|
| J1 | C3“102” | 1000pF＝1nF | 约48.1kHz |
| J2 | C2“104” | 100000pF＝100nF＝0.1µF | 约481Hz |
| J3 | C4“1µF” | 1µF | 约48.1Hz |
| J4 | C5“100µF” | 100µF | 约0.481Hz，周期约2.08秒 |

以上是指定电阻值下的理论计算，不是该板实测档位范围或保证精度。实际电阻、公差、电解电容漏电及芯片延迟会改变结果，尤其小电容／小电阻时偏差更明显。

图中跳帽把对应电容接到同一个定时节点。一次只选一档便于复现；若同时闭合多个跳帽，电容会并联，容量相加、频率降低，并不是新增独立输出。不插任何跳帽则缺少明确的定时电容，不能期待稳定的预定频率。调整跳帽前先断电。

### 频率、占空比和LED亮灭

在标准近似条件下，R以Ω、C以F计：

```text
高电平时间 tH ≈ 0.693 × (RA + RB) × C
低电平时间 tL ≈ 0.693 × RB × C
周期 T ≈ 0.693 × (RA + 2RB) × C
频率 f ≈ 1.443 / [(RA + 2RB) × C]
输出高电平占空比 D ≈ (RA + RB) / (RA + 2RB)
```

- 增大RA：高电平时间变长，低电平时间近似不变；频率下降，高电平占空比上升。
- 增大RB：高、低电平时间都变长；频率下降，高电平占空比趋近50%。
- 增大C：高、低电平按比例变长；理想占空比不变，频率降低。
- RA、RB均为正值时，此电路的高电平占空比大于50%，不能独立覆盖任意0～100%占空比。两个旋钮的效果相互关联，不能简单看作互不影响的“频率旋钮”和“占空比旋钮”。

原理图的LED支路为 `VCC → R3 1.5kΩ → D1 LED → OUT`。因此输出低电平时LED点亮，高电平时通常熄灭或明显变暗；LED亮的时间对应tL，不是tH。RA=RB时，输出高电平占约2/3，LED点亮约1/3周期。

图中R3只为LED限流，不是定时电路的保护电阻。所给图未画出RA/RB串联的固定最小电阻，不能把电位器拧到接近零欧来追求极限频率：RA过小会使7脚放电时的电流过大。实际板是否另有保护电阻需检查；初次测试先在断电状态将RA、RB设到较大电阻，再缓慢调整。

### 和现有STM32实验如何衔接

可先仅用模块板载LED，在J4大电容档观察低频闪烁；后续可让STM32显示频率、周期、高电平时间与占空比。需先确认模块输出幅度，再做合适的电平接口。NE555输出不保证是3.3V，也不保证高电平等于电源电压；不要将较高电压OUT直接接入当前PA口。

本次仅归档电路与玩法，没有给NE555分配新的STM32引脚，没有修改或烧录当前手势鱼缸固件，也没有测得模块实际频率。不把模块直接接SG90：舵机需要明确的脉宽和周期，此模块不能仅靠旋钮位置保证控制范围。

原始依据：用户本次提供的电路图；NE555引脚、供电与无稳态原理参考[TI NE555数据手册](https://www.ti.com/lit/ds/symlink/ne555.pdf)。本节元件编号、档位表及LED极性来自用户图，不能套用于所有外观相似的NE555模块。

---

## STM32 + TB6612FNG：双电机正反转与调速实验

### TB6612FNG实物模块针脚图

按用户提供照片这一面绘制，PWMA/VM在上，底部两侧为GND。左列自上而下：PWMA、AIN2、AIN1、STBY、BIN1、BIN2、PWMB、GND。右列自上而下：VM、VCC、GND、AO1、AO2、BO2、BO1、GND。**BO2在BO1上方，AIN2在AIN1上方，不能按名称数字递增猜位置。**

画板：**TB6612FNG模块｜实物针序与双电机接线**，可继续编辑。图中线1/线2仅作接线编号，实际旋转方向由接线与控制电平共同决定。

```tikz
\begin{tikzpicture}[scale=1.18, line cap=round, line join=round]
  \color{white}
  \filldraw[draw={rgb,255:red,16;green,24;blue,32}, line width=0.742857pt, fill={rgb,255:red,16;green,24;blue,32}] (-11.8,7.4) -- (11.8,7.4) -- (11.8,-7.4) -- (-11.8,-7.4) -- cycle;
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (0,6.76) {TB6612FNG模块｜实物针序与双电机接线};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (0,6) {按照片这一面观察：PWMA / VM在上，GND在下；翻面后左右会反转。};
  \filldraw[draw={rgb,255:red,255;green,105;blue,105}, line width=0.742857pt, fill={rgb,255:red,107;green,36;blue,42}] (-3.9,5.16) -- (3.7,5.16) -- (3.7,-4.5) -- (-3.9,-4.5) -- cycle;
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (-0.1,4) {TB6612FNG};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (-0.1,2.1) {控制输入在左};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (-0.1,1.2) {电源 / 电机输出在右};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (-0.1,-0.6) {按丝印接线};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (-0.1,-1.42) {不按芯片脚号接线};
  \filldraw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.742857pt, fill={rgb,255:red,16;green,24;blue,32}] (-3.64,4.8) -- (-3.2,4.8) -- (-3.2,4.36) -- (-3.64,4.36) -- cycle;
  \node[anchor=east, inner sep=0pt, outer sep=0pt, text={rgb,255:red,40;green,215;blue,236}] at (-4.16,4.58) {PWMA → PA6};
  \filldraw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.742857pt, fill={rgb,255:red,16;green,24;blue,32}] (-3.64,3.6) -- (-3.2,3.6) -- (-3.2,3.16) -- (-3.64,3.16) -- cycle;
  \node[anchor=east, inner sep=0pt, outer sep=0pt, text={rgb,255:red,40;green,215;blue,236}] at (-4.16,3.38) {AIN2 → PA5};
  \filldraw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.742857pt, fill={rgb,255:red,16;green,24;blue,32}] (-3.64,2.4) -- (-3.2,2.4) -- (-3.2,1.96) -- (-3.64,1.96) -- cycle;
  \node[anchor=east, inner sep=0pt, outer sep=0pt, text={rgb,255:red,40;green,215;blue,236}] at (-4.16,2.18) {AIN1 → PA4};
  \filldraw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.742857pt, fill={rgb,255:red,16;green,24;blue,32}] (-3.64,1.2) -- (-3.2,1.2) -- (-3.2,0.76) -- (-3.64,0.76) -- cycle;
  \node[anchor=east, inner sep=0pt, outer sep=0pt, text={rgb,255:red,40;green,215;blue,236}] at (-4.16,0.98) {STBY → PA7};
  \filldraw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.742857pt, fill={rgb,255:red,16;green,24;blue,32}] (-3.64,0) -- (-3.2,0) -- (-3.2,-0.44) -- (-3.64,-0.44) -- cycle;
  \node[anchor=east, inner sep=0pt, outer sep=0pt, text={rgb,255:red,40;green,215;blue,236}] at (-4.16,-0.22) {BIN1 → PA1};
  \filldraw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.742857pt, fill={rgb,255:red,16;green,24;blue,32}] (-3.64,-1.2) -- (-3.2,-1.2) -- (-3.2,-1.64) -- (-3.64,-1.64) -- cycle;
  \node[anchor=east, inner sep=0pt, outer sep=0pt, text={rgb,255:red,40;green,215;blue,236}] at (-4.16,-1.42) {BIN2 → PA2};
  \filldraw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.742857pt, fill={rgb,255:red,16;green,24;blue,32}] (-3.64,-2.4) -- (-3.2,-2.4) -- (-3.2,-2.84) -- (-3.64,-2.84) -- cycle;
  \node[anchor=east, inner sep=0pt, outer sep=0pt, text={rgb,255:red,40;green,215;blue,236}] at (-4.16,-2.62) {PWMB → PA0};
  \filldraw[draw={rgb,255:red,255;green,227;blue,107}, line width=0.742857pt, fill={rgb,255:red,16;green,24;blue,32}] (-3.64,-3.6) -- (-3.2,-3.6) -- (-3.2,-4.04) -- (-3.64,-4.04) -- cycle;
  \node[anchor=east, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,227;blue,107}] at (-4.16,-3.82) {GND → 共同GND};
  \filldraw[draw={rgb,255:red,255;green,184;blue,77}, line width=0.742857pt, fill={rgb,255:red,16;green,24;blue,32}] (3,4.8) -- (3.44,4.8) -- (3.44,4.36) -- (3,4.36) -- cycle;
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,184;blue,77}] at (3.96,4.58) {VM → 电机电源正极};
  \filldraw[draw={rgb,255:red,255;green,184;blue,77}, line width=0.742857pt, fill={rgb,255:red,16;green,24;blue,32}] (3,3.6) -- (3.44,3.6) -- (3.44,3.16) -- (3,3.16) -- cycle;
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,184;blue,77}] at (3.96,3.38) {VCC → STM32 3.3V};
  \filldraw[draw={rgb,255:red,255;green,227;blue,107}, line width=0.742857pt, fill={rgb,255:red,16;green,24;blue,32}] (3,2.4) -- (3.44,2.4) -- (3.44,1.96) -- (3,1.96) -- cycle;
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,227;blue,107}] at (3.96,2.18) {GND → 共同GND};
  \filldraw[draw={rgb,255:red,143;green,236;blue,179}, line width=0.742857pt, fill={rgb,255:red,16;green,24;blue,32}] (3,1.2) -- (3.44,1.2) -- (3.44,0.76) -- (3,0.76) -- cycle;
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,143;green,236;blue,179}] at (3.96,0.98) {AO1 → A电机线1};
  \filldraw[draw={rgb,255:red,143;green,236;blue,179}, line width=0.742857pt, fill={rgb,255:red,16;green,24;blue,32}] (3,0) -- (3.44,0) -- (3.44,-0.44) -- (3,-0.44) -- cycle;
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,143;green,236;blue,179}] at (3.96,-0.22) {AO2 → A电机线2};
  \filldraw[draw={rgb,255:red,143;green,236;blue,179}, line width=0.742857pt, fill={rgb,255:red,16;green,24;blue,32}] (3,-1.2) -- (3.44,-1.2) -- (3.44,-1.64) -- (3,-1.64) -- cycle;
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,143;green,236;blue,179}] at (3.96,-1.42) {BO2 → B电机线2};
  \filldraw[draw={rgb,255:red,143;green,236;blue,179}, line width=0.742857pt, fill={rgb,255:red,16;green,24;blue,32}] (3,-2.4) -- (3.44,-2.4) -- (3.44,-2.84) -- (3,-2.84) -- cycle;
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,143;green,236;blue,179}] at (3.96,-2.62) {BO1 → B电机线1};
  \filldraw[draw={rgb,255:red,255;green,227;blue,107}, line width=0.742857pt, fill={rgb,255:red,16;green,24;blue,32}] (3,-3.6) -- (3.44,-3.6) -- (3.44,-4.04) -- (3,-4.04) -- cycle;
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,227;blue,107}] at (3.96,-3.82) {GND → 共同GND};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text={rgb,255:red,143;green,236;blue,179}] at (0,-5.24) {注意：右侧电机输出顺序是 AO1、AO2、BO2、BO1。};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,227;blue,107}] at (0,-5.94) {多个GND为地连接点：STM32、驱动模块和电机电源负极共地。};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,184;blue,77}] at (0,-6.64) {VM与VCC不可混接；电机电源电压仍需按两台电机参数确认。};
\end{tikzpicture}
```


### 基础板实物排针图（USB朝下）

按用户照片绘制，两侧各20针；青色标出双电机实验使用的7根控制线。顶部SWD针序未在照片中确认，因此未推测各针定义。5V只标丝印，不据此断言该脚的供电方向。画板名称：**STM32基础板｜排针与双电机接线**，可在Geometry中继续编辑。

```tikz
\begin{tikzpicture}[scale=1.18, line cap=round, line join=round]
  \color{white}
  \filldraw[draw={rgb,255:red,16;green,24;blue,32}, line width=0.742857pt, fill={rgb,255:red,16;green,24;blue,32}] (-11.8,7.4) -- (11.8,7.4) -- (11.8,-7.4) -- (-11.8,-7.4) -- cycle;
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (0,6.8) {STM32基础板｜实物排针与双电机接线};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (0,6.14) {正面朝向自己 · USB口朝下 · 按用户照片丝印逐项标注};
  \filldraw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.742857pt, fill={rgb,255:red,22;green,51;blue,72}] (-3.5,5.5) -- (3.5,5.5) -- (3.5,-6.6) -- (-3.5,-6.6) -- cycle;
  \filldraw[draw=white, line width=0.742857pt, fill={rgb,255:red,70;green,86;blue,106}] (-0.94,-5.14) -- (0.94,-5.14) -- (0.94,-6.74) -- (-0.94,-6.74) -- cycle;
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (0,-5.9) {USB};
  \filldraw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.742857pt, fill={rgb,255:red,16;green,24;blue,32}] (-1.4,1.36) -- (1.4,1.36) -- (1.4,-1.36) -- (-1.4,-1.36) -- cycle;
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (0,0.24) {STM32};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (0,-0.3) {F103C8T6};
  \draw[draw={rgb,255:red,215;green,221;blue,229}, line width=0.742857pt] (-1,3.7) -- (1,3.7) -- (1,2.82) -- (-1,2.82) -- cycle;
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (0,3.26) {8 MHz};
  \draw[draw={rgb,255:red,215;green,221;blue,229}, line width=0.742857pt] (-1.04,5.22) -- (1.04,5.22) -- (1.04,4.54) -- (-1.04,4.54) -- cycle;
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (0,4.2) {SWD接口};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (0,-2.38) {BOOT跳帽};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (0,-3.16) {RESET按键};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (0,-4.08) {图为接线示意};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (0,-4.58) {不按实物比例};
  \filldraw[draw={rgb,255:red,255;green,184;blue,77}, line width=0.742857pt, fill={rgb,255:red,16;green,24;blue,32}] (-3.24,5.22) -- (-2.92,5.22) -- (-2.92,4.9) -- (-3.24,4.9) -- cycle;
  \node[anchor=east, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,184;blue,77}] at (-3.78,5.06) {VB = VBAT};
  \filldraw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.742857pt, fill={rgb,255:red,16;green,24;blue,32}] (-3.24,4.7) -- (-2.92,4.7) -- (-2.92,4.38) -- (-3.24,4.38) -- cycle;
  \node[anchor=east, inner sep=0pt, outer sep=0pt, text={rgb,255:red,189;green,203;blue,216}] at (-3.78,4.54) {C13 = PC13};
  \filldraw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.742857pt, fill={rgb,255:red,16;green,24;blue,32}] (-3.24,4.18) -- (-2.92,4.18) -- (-2.92,3.86) -- (-3.24,3.86) -- cycle;
  \node[anchor=east, inner sep=0pt, outer sep=0pt, text={rgb,255:red,189;green,203;blue,216}] at (-3.78,4.02) {C14 = PC14};
  \filldraw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.742857pt, fill={rgb,255:red,16;green,24;blue,32}] (-3.24,3.66) -- (-2.92,3.66) -- (-2.92,3.34) -- (-3.24,3.34) -- cycle;
  \node[anchor=east, inner sep=0pt, outer sep=0pt, text={rgb,255:red,189;green,203;blue,216}] at (-3.78,3.5) {C15 = PC15};
  \filldraw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.742857pt, fill={rgb,255:red,16;green,24;blue,32}] (-3.24,3.14) -- (-2.92,3.14) -- (-2.92,2.82) -- (-3.24,2.82) -- cycle;
  \node[anchor=east, inner sep=0pt, outer sep=0pt, text={rgb,255:red,40;green,215;blue,236}] at (-3.78,2.98) {A0 = PA0 → PWMB};
  \filldraw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.742857pt, fill={rgb,255:red,16;green,24;blue,32}] (-3.24,2.62) -- (-2.92,2.62) -- (-2.92,2.3) -- (-3.24,2.3) -- cycle;
  \node[anchor=east, inner sep=0pt, outer sep=0pt, text={rgb,255:red,40;green,215;blue,236}] at (-3.78,2.46) {A1 = PA1 → BIN1};
  \filldraw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.742857pt, fill={rgb,255:red,16;green,24;blue,32}] (-3.24,2.1) -- (-2.92,2.1) -- (-2.92,1.78) -- (-3.24,1.78) -- cycle;
  \node[anchor=east, inner sep=0pt, outer sep=0pt, text={rgb,255:red,40;green,215;blue,236}] at (-3.78,1.94) {A2 = PA2 → BIN2};
  \filldraw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.742857pt, fill={rgb,255:red,16;green,24;blue,32}] (-3.24,1.58) -- (-2.92,1.58) -- (-2.92,1.26) -- (-3.24,1.26) -- cycle;
  \node[anchor=east, inner sep=0pt, outer sep=0pt, text={rgb,255:red,189;green,203;blue,216}] at (-3.78,1.42) {A3 = PA3（留空）};
  \filldraw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.742857pt, fill={rgb,255:red,16;green,24;blue,32}] (-3.24,1.06) -- (-2.92,1.06) -- (-2.92,0.74) -- (-3.24,0.74) -- cycle;
  \node[anchor=east, inner sep=0pt, outer sep=0pt, text={rgb,255:red,40;green,215;blue,236}] at (-3.78,0.9) {A4 = PA4 → AIN1};
  \filldraw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.742857pt, fill={rgb,255:red,16;green,24;blue,32}] (-3.24,0.54) -- (-2.92,0.54) -- (-2.92,0.22) -- (-3.24,0.22) -- cycle;
  \node[anchor=east, inner sep=0pt, outer sep=0pt, text={rgb,255:red,40;green,215;blue,236}] at (-3.78,0.38) {A5 = PA5 → AIN2};
  \filldraw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.742857pt, fill={rgb,255:red,16;green,24;blue,32}] (-3.24,0.02) -- (-2.92,0.02) -- (-2.92,-0.3) -- (-3.24,-0.3) -- cycle;
  \node[anchor=east, inner sep=0pt, outer sep=0pt, text={rgb,255:red,40;green,215;blue,236}] at (-3.78,-0.14) {A6 = PA6 → PWMA};
  \filldraw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.742857pt, fill={rgb,255:red,16;green,24;blue,32}] (-3.24,-0.5) -- (-2.92,-0.5) -- (-2.92,-0.82) -- (-3.24,-0.82) -- cycle;
  \node[anchor=east, inner sep=0pt, outer sep=0pt, text={rgb,255:red,40;green,215;blue,236}] at (-3.78,-0.66) {A7 = PA7 → STBY};
  \filldraw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.742857pt, fill={rgb,255:red,16;green,24;blue,32}] (-3.24,-1.02) -- (-2.92,-1.02) -- (-2.92,-1.34) -- (-3.24,-1.34) -- cycle;
  \node[anchor=east, inner sep=0pt, outer sep=0pt, text={rgb,255:red,189;green,203;blue,216}] at (-3.78,-1.18) {B0 = PB0};
  \filldraw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.742857pt, fill={rgb,255:red,16;green,24;blue,32}] (-3.24,-1.54) -- (-2.92,-1.54) -- (-2.92,-1.86) -- (-3.24,-1.86) -- cycle;
  \node[anchor=east, inner sep=0pt, outer sep=0pt, text={rgb,255:red,189;green,203;blue,216}] at (-3.78,-1.7) {B1 = PB1};
  \filldraw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.742857pt, fill={rgb,255:red,16;green,24;blue,32}] (-3.24,-2.06) -- (-2.92,-2.06) -- (-2.92,-2.38) -- (-3.24,-2.38) -- cycle;
  \node[anchor=east, inner sep=0pt, outer sep=0pt, text={rgb,255:red,189;green,203;blue,216}] at (-3.78,-2.22) {B10 = PB10};
  \filldraw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.742857pt, fill={rgb,255:red,16;green,24;blue,32}] (-3.24,-2.58) -- (-2.92,-2.58) -- (-2.92,-2.9) -- (-3.24,-2.9) -- cycle;
  \node[anchor=east, inner sep=0pt, outer sep=0pt, text={rgb,255:red,189;green,203;blue,216}] at (-3.78,-2.74) {B11 = PB11};
  \filldraw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.742857pt, fill={rgb,255:red,16;green,24;blue,32}] (-3.24,-3.1) -- (-2.92,-3.1) -- (-2.92,-3.42) -- (-3.24,-3.42) -- cycle;
  \node[anchor=east, inner sep=0pt, outer sep=0pt, text={rgb,255:red,189;green,203;blue,216}] at (-3.78,-3.26) {R = NRST};
  \filldraw[draw={rgb,255:red,255;green,184;blue,77}, line width=0.742857pt, fill={rgb,255:red,16;green,24;blue,32}] (-3.24,-3.62) -- (-2.92,-3.62) -- (-2.92,-3.94) -- (-3.24,-3.94) -- cycle;
  \node[anchor=east, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,184;blue,77}] at (-3.78,-3.78) {3.3 = 3.3V};
  \filldraw[draw={rgb,255:red,255;green,227;blue,107}, line width=0.742857pt, fill={rgb,255:red,16;green,24;blue,32}] (-3.24,-4.14) -- (-2.92,-4.14) -- (-2.92,-4.46) -- (-3.24,-4.46) -- cycle;
  \node[anchor=east, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,227;blue,107}] at (-3.78,-4.3) {G = GND};
  \filldraw[draw={rgb,255:red,255;green,227;blue,107}, line width=0.742857pt, fill={rgb,255:red,16;green,24;blue,32}] (-3.24,-4.66) -- (-2.92,-4.66) -- (-2.92,-4.98) -- (-3.24,-4.98) -- cycle;
  \node[anchor=east, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,227;blue,107}] at (-3.78,-4.82) {G = GND};
  \filldraw[draw={rgb,255:red,255;green,184;blue,77}, line width=0.742857pt, fill={rgb,255:red,16;green,24;blue,32}] (2.92,5.22) -- (3.24,5.22) -- (3.24,4.9) -- (2.92,4.9) -- cycle;
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,184;blue,77}] at (3.78,5.06) {3.3 = 3.3V};
  \filldraw[draw={rgb,255:red,255;green,227;blue,107}, line width=0.742857pt, fill={rgb,255:red,16;green,24;blue,32}] (2.92,4.7) -- (3.24,4.7) -- (3.24,4.38) -- (2.92,4.38) -- cycle;
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,227;blue,107}] at (3.78,4.54) {G = GND};
  \filldraw[draw={rgb,255:red,255;green,184;blue,77}, line width=0.742857pt, fill={rgb,255:red,16;green,24;blue,32}] (2.92,4.18) -- (3.24,4.18) -- (3.24,3.86) -- (2.92,3.86) -- cycle;
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,184;blue,77}] at (3.78,4.02) {5V};
  \filldraw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.742857pt, fill={rgb,255:red,16;green,24;blue,32}] (2.92,3.66) -- (3.24,3.66) -- (3.24,3.34) -- (2.92,3.34) -- cycle;
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,189;green,203;blue,216}] at (3.78,3.5) {B9 = PB9};
  \filldraw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.742857pt, fill={rgb,255:red,16;green,24;blue,32}] (2.92,3.14) -- (3.24,3.14) -- (3.24,2.82) -- (2.92,2.82) -- cycle;
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,189;green,203;blue,216}] at (3.78,2.98) {B8 = PB8};
  \filldraw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.742857pt, fill={rgb,255:red,16;green,24;blue,32}] (2.92,2.62) -- (3.24,2.62) -- (3.24,2.3) -- (2.92,2.3) -- cycle;
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,189;green,203;blue,216}] at (3.78,2.46) {B7 = PB7};
  \filldraw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.742857pt, fill={rgb,255:red,16;green,24;blue,32}] (2.92,2.1) -- (3.24,2.1) -- (3.24,1.78) -- (2.92,1.78) -- cycle;
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,189;green,203;blue,216}] at (3.78,1.94) {B6 = PB6};
  \filldraw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.742857pt, fill={rgb,255:red,16;green,24;blue,32}] (2.92,1.58) -- (3.24,1.58) -- (3.24,1.26) -- (2.92,1.26) -- cycle;
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,189;green,203;blue,216}] at (3.78,1.42) {B5 = PB5};
  \filldraw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.742857pt, fill={rgb,255:red,16;green,24;blue,32}] (2.92,1.06) -- (3.24,1.06) -- (3.24,0.74) -- (2.92,0.74) -- cycle;
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,189;green,203;blue,216}] at (3.78,0.9) {B4 = PB4};
  \filldraw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.742857pt, fill={rgb,255:red,16;green,24;blue,32}] (2.92,0.54) -- (3.24,0.54) -- (3.24,0.22) -- (2.92,0.22) -- cycle;
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,189;green,203;blue,216}] at (3.78,0.38) {B3 = PB3};
  \filldraw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.742857pt, fill={rgb,255:red,16;green,24;blue,32}] (2.92,0.02) -- (3.24,0.02) -- (3.24,-0.3) -- (2.92,-0.3) -- cycle;
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,189;green,203;blue,216}] at (3.78,-0.14) {A15 = PA15};
  \filldraw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.742857pt, fill={rgb,255:red,16;green,24;blue,32}] (2.92,-0.5) -- (3.24,-0.5) -- (3.24,-0.82) -- (2.92,-0.82) -- cycle;
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,189;green,203;blue,216}] at (3.78,-0.66) {A12 = PA12};
  \filldraw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.742857pt, fill={rgb,255:red,16;green,24;blue,32}] (2.92,-1.02) -- (3.24,-1.02) -- (3.24,-1.34) -- (2.92,-1.34) -- cycle;
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,189;green,203;blue,216}] at (3.78,-1.18) {A11 = PA11};
  \filldraw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.742857pt, fill={rgb,255:red,16;green,24;blue,32}] (2.92,-1.54) -- (3.24,-1.54) -- (3.24,-1.86) -- (2.92,-1.86) -- cycle;
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,189;green,203;blue,216}] at (3.78,-1.7) {A10 = PA10};
  \filldraw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.742857pt, fill={rgb,255:red,16;green,24;blue,32}] (2.92,-2.06) -- (3.24,-2.06) -- (3.24,-2.38) -- (2.92,-2.38) -- cycle;
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,189;green,203;blue,216}] at (3.78,-2.22) {A9 = PA9};
  \filldraw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.742857pt, fill={rgb,255:red,16;green,24;blue,32}] (2.92,-2.58) -- (3.24,-2.58) -- (3.24,-2.9) -- (2.92,-2.9) -- cycle;
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,189;green,203;blue,216}] at (3.78,-2.74) {A8 = PA8};
  \filldraw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.742857pt, fill={rgb,255:red,16;green,24;blue,32}] (2.92,-3.1) -- (3.24,-3.1) -- (3.24,-3.42) -- (2.92,-3.42) -- cycle;
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,189;green,203;blue,216}] at (3.78,-3.26) {B15 = PB15};
  \filldraw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.742857pt, fill={rgb,255:red,16;green,24;blue,32}] (2.92,-3.62) -- (3.24,-3.62) -- (3.24,-3.94) -- (2.92,-3.94) -- cycle;
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,189;green,203;blue,216}] at (3.78,-3.78) {B14 = PB14};
  \filldraw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.742857pt, fill={rgb,255:red,16;green,24;blue,32}] (2.92,-4.14) -- (3.24,-4.14) -- (3.24,-4.46) -- (2.92,-4.46) -- cycle;
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,189;green,203;blue,216}] at (3.78,-4.3) {B13 = PB13};
  \filldraw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.742857pt, fill={rgb,255:red,16;green,24;blue,32}] (2.92,-4.66) -- (3.24,-4.66) -- (3.24,-4.98) -- (2.92,-4.98) -- cycle;
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,189;green,203;blue,216}] at (3.78,-4.82) {B12 = PB12};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (0,-7.14) {青色：7根电机控制线全部在左侧；VCC接3.3V，VM接电机电源，三者共地。};
\end{tikzpicture}
```


```tikz
\begin{tikzpicture}[x=0.8cm,y=0.8cm]
\fill[black!90] (-0.5,-1.3) rectangle (18,16);
\draw[cyan,rounded corners,line width=1pt] (0,1) rectangle (4,13);
\draw[cyan,rounded corners,line width=1pt] (8,1) rectangle (12,13);
\node[text=white,font=\small] at (2,12.3) {STM32F103C8T6};
\node[text=white] at (10,12.3) {TB6612FNG};
\draw[orange,->,line width=1pt] (4,11)--(8,11);
\node[text=white,anchor=east] at (3.9,11) {3.3V};
\node[text=white,anchor=west] at (8.1,11) {VCC};
\draw[cyan,->,line width=1pt] (4,10)--(8,10);
\node[text=white,anchor=east] at (3.9,10) {PA4};
\node[text=white,anchor=west] at (8.1,10) {AIN1};
\draw[cyan,->,line width=1pt] (4,9)--(8,9);
\node[text=white,anchor=east] at (3.9,9) {PA5};
\node[text=white,anchor=west] at (8.1,9) {AIN2};
\draw[cyan,->,line width=1pt] (4,8)--(8,8);
\node[text=white,anchor=east] at (3.9,8) {PA6};
\node[text=white,anchor=west] at (8.1,8) {PWMA};
\draw[green!70!white,->,line width=1pt] (4,7)--(8,7);
\node[text=white,anchor=east] at (3.9,7) {PA1};
\node[text=white,anchor=west] at (8.1,7) {BIN1};
\draw[green!70!white,->,line width=1pt] (4,6)--(8,6);
\node[text=white,anchor=east] at (3.9,6) {PA2};
\node[text=white,anchor=west] at (8.1,6) {BIN2};
\draw[green!70!white,->,line width=1pt] (4,5)--(8,5);
\node[text=white,anchor=east] at (3.9,5) {PA0};
\node[text=white,anchor=west] at (8.1,5) {PWMB};
\draw[cyan,->,line width=1pt] (4,3)--(8,3);
\node[text=white,anchor=east] at (3.9,3) {PA7};
\node[text=white,anchor=west] at (8.1,3) {STBY};
\node[text=white] at (2,2) {USB供电};
\node[text=cyan] at (6,3.6) {共用待机控制};
\draw[yellow,line width=1.8pt] (2,1)--(2,0)--(10,0)--(10,1);
\node[text=yellow,anchor=south] at (2,1) {GND};
\node[text=yellow,anchor=south] at (10,1) {GND};
\fill[yellow] (10,0) circle (0.09);
\node[text=yellow] at (8,-0.7) {STM32、驱动模块、电机电源负极共地};
\draw[orange,rounded corners,line width=1pt] (13.5,13.5) rectangle (17.5,15.5);
\node[text=white] at (15.5,14.9) {独立电机电源};
\node[text=white,font=\small] at (15.5,14.3) {电压匹配两台电机};
\node[text=orange] at (14,13.8) {$+$};
\node[text=yellow] at (17,13.8) {$-$};
\draw[orange,line width=1.8pt] (14,13.5)--(14,11.5)--(12,11.5);
\node[text=orange,anchor=east] at (11.9,11.5) {VM};
\draw[yellow,line width=1.8pt] (17,13.5)--(17,0)--(10,0);
\node[text=yellow,rotate=90] at (17.5,7) {电机电流直接返回电源负极};
\draw[white,line width=1pt] (14.6,9) circle (0.7);
\node[text=white] at (14.6,9) {MA};
\draw[green!70!white,line width=1.5pt] (12,10)--(14.6,10)--(14.6,9.7);
\draw[green!70!white,line width=1.5pt] (12,8)--(14.6,8)--(14.6,8.3);
\node[text=white,anchor=east] at (11.9,10) {AO1};
\node[text=white,anchor=east] at (11.9,8) {AO2};
\draw[white,line width=1pt] (14.6,5) circle (0.7);
\node[text=white] at (14.6,5) {MB};
\draw[green!70!white,line width=1.5pt] (12,6)--(14.6,6)--(14.6,5.7);
\draw[green!70!white,line width=1.5pt] (12,4)--(14.6,4)--(14.6,4.3);
\node[text=white,anchor=east] at (11.9,6) {BO1};
\node[text=white,anchor=east] at (11.9,4) {BO2};
\node[text=white] at (6,14.6) {双电机接线关系图};
\node[text=white,font=\small] at (6,14) {按引脚名称接线，非排针顺序};
\end{tikzpicture}
```

状态：接线与程序行为设计；尚未改固件、烧录或通电测试。待确认电机类型、额定电压、堵转电流及电机电源。仅适用两线有刷直流电机，不用于SG90三线舵机或两线无刷风扇。

### 接线
先断电。PA0、PA1、PA2、PA4、PA5、PA6、PA7上的旧模块信号线移除（包括占用PA0的旧超声波接线）；按用户提供的实物照片，USB口朝下时，PA0～PA7位于左侧。从上往下依次为PA0、PA1、PA2、PA3、PA4、PA5、PA6、PA7；七根控制线全部接左侧，PA3留空。按实物丝印接线，不根据开发板商品名称推断排针。OLED PB6/PB7和SWD可保留，但首次测试不运行旧传感器/舵机固件。

| TB6612模块 | 接到 |
|---|---|
| VCC | STM32 3.3V |
| GND | STM32 GND及电机电源负极，全部共地 |
| VM | 与电机额定电压匹配的独立电机电源正极，待确认 |
| AIN1 | PA4 |
| AIN2 | PA5 |
| PWMA | PA6 / TIM3_CH1，默认映射 |
| STBY | PA7 |
| AO1、AO2 | A电机两根线 |
| BIN1 | PA1 |
| BIN2 | PA2 |
| PWMB | PA0 / TIM2_CH1，默认映射 |
| BO1、BO2 | B电机两根线 |

电机电源负极直接返回驱动模块，不让电机电流经过STM32板。VCC与VM不可混接；电机不从STM32的3.3V或ST-Link供电。模块如有STBY固定上拉/跳帽，先核对才能由PA7控制。三节锂电池串联满电12.6V不能直接用于普通3～6V电机。

确认模块VM和VCC附近已有去耦；厂家典型应用两组电源各有10uF和0.1uF，靠近驱动器。补充电容须核对耐压及极性。

### 实验步骤与控制
1. 固定两台空载有刷电机。先拆除原B路BIN1、BIN2、PWMB接地线，再改接GPIO，避免GPIO输出短路到地。
2. 启动保持STBY=0，两台均不转；接线完成并烧录配套固件后才能运行。
3. 分别测试A、B电机：50%占空比转2秒，再滑行停止，确认两路引脚及方向。另一通道保持IN1=IN2=0、PWM=1（高阻停止）。
4. 两台同时正转50%，再同时停止；观察供电是否掉压、STM32是否重启、驱动是否发热。逐步再比较不同占空比，100%仅用于供电电压已匹配电机的情况。
5. 确认两轴完全停止后，再测试两台反转；不要带转速直接换向。先不安装车轮或机械负载。

A/B两路均：IN1=1、IN2=0为一个方向，交换电平则反向。两台接线方向可能相反，实际正反方向需实测确认。
STBY=0会让两路同时高阻停止，不能单独停一路。独立滑行停止使用对应IN1=IN2=0、PWM=1；独立短刹车可使用IN1=IN2=1、STBY=1。PWM=0不等于滑行停止。

两路各用20kHz硬件PWM：A=PA6/TIM3_CH1，B=PA0/TIM2_CH1，均默认映射。若TIM2与TIM3输入时钟均72MHz，则PSC=0、ARR=3599，CCR=1800为50%，2700为75%，3600为100%。这些是新固件设计参数，旧程序不能直接沿用。

无编码器时仅显示各路方向与占空比，不声称测得RPM。两台电机共用VM，需兼容同一供电电压；电源需承受两台的启动电流，驱动总发热也需重新评估。

### 适配判断
VCC工作范围2.7～5.5V，VM工作范围2.5～13.5V。芯片规格中的3.2A是10ms单次峰值条件，不能当持续输出能力。按电机启动/堵转电流、实际模块散热和数据手册工作范围选型，未确认前不指定电源电压或宣布电机适配。

依据：东芝TB6612FNG数据手册，工作范围、H桥控制表与典型应用。
https://toshiba.semicon-storage.com/info/TB6612FNG_datasheet_en_20141001.pdf?did=10660&prodName=TB6612FNG



## OV7670 FIFO扩展板设计草案（2026-09-12）

**状态：设计记录，尚未画正式原理图/PCB、采购或上板验证。当前相机仍使用无FIFO的STM32 USB＋OLED固件；本节不是立即换线指令。**

### 目标与容量选择

在OV7670与STM32之间增加硬件FIFO：相机用PCLK连续写入，MCU用自己的读取时钟取出，使采集不必等待USB和OLED。优先实现“抓一帧、冻结、读完再抓”，不承诺连续无丢帧视频。

| 格式 | 单帧字节 | AL422B单颗384 KiB是否足够 |
|---|---:|---|
| 320×240 RGB565 | 153600（150 KiB） | 足够，第一版建议 |
| 640×480 8位单字节格式 | 307200（300 KiB） | 容量足够，颜色处理另验证 |
| 640×480 RGB565 | 614400（600 KiB） | **不足** |

第一版采用AL422B类专用FIFO验证QVGA彩色，降低控制复杂度。如果必须保留当前VGA RGB565，则直接按至少600 KiB有效缓存设计；宜留余量，不能拿“支持VGA”的宣传替代实际字节数计算。Bayer虽能减半，本项目实际颜色还原失败，不作为容量不足的默认补救。

### 结构图（可编辑画板）

```tikz
\begin{tikzpicture}[scale=1.18, line cap=round, line join=round]
  \color{white}
  \filldraw[draw={rgb,255:red,16;green,24;blue,32}, line width=0.742857pt, fill={rgb,255:red,16;green,24;blue,32}] (-11.8,7.4) -- (12.2,7.4) -- (12.2,-6.2) -- (-11.8,-6.2) -- cycle;
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (0.2,6.7) {OV7670 FIFO扩展板｜设计草案};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text={rgb,255:red,143;green,236;blue,179}] at (0.2,6) {第一版：QVGA RGB565 + 单颗AL422B；尚未制板、接线或烧录};
  \filldraw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.742857pt, fill={rgb,255:red,22;green,51;blue,72}] (-11.1,4.6) -- (-6.4,4.6) -- (-6.4,1.6) -- (-11.1,1.6) -- cycle;
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (-8.75,3.76) {OV7670};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (-8.75,2.9) {320×240 RGB565};
  \filldraw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.742857pt, fill={rgb,255:red,22;green,51;blue,72}] (-2.6,4.6) -- (2.6,4.6) -- (2.6,1.6) -- (-2.6,1.6) -- cycle;
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (0,3.76) {AL422B FIFO};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (0,2.9) {384 KiB / 8位};
  \filldraw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.742857pt, fill={rgb,255:red,22;green,51;blue,72}] (6.6,4.6) -- (11.5,4.6) -- (11.5,1.6) -- (6.6,1.6) -- cycle;
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (9.05,3.76) {STM32F103};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (9.05,2.9) {分块读取 / USB / OLED};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text={rgb,255:red,40;green,215;blue,236}] at (-4.5,3.9) {D[7:0] →};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text={rgb,255:red,40;green,215;blue,236}] at (-4.5,2.96) {PCLK → WCK};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text={rgb,255:red,40;green,215;blue,236}] at (4.54,3.9) {DO[7:0] →};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text={rgb,255:red,40;green,215;blue,236}] at (4.54,2.96) {← RCK / 读控制};
  \filldraw[draw={rgb,255:red,255;green,227;blue,107}, line width=0.742857pt, fill={rgb,255:red,20;green,34;blue,47}] (-5,0.4) -- (5.2,0.4) -- (5.2,-2.2) -- (-5,-2.2) -- cycle;
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,227;blue,107}] at (0.1,-0.3) {写入控制逻辑（门电路 / 可编程逻辑）};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,227;blue,107}] at (0.1,-1.1) {VSYNC定帧 · HREF限定有效数据 · /WE与/WRST};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (0.1,-1.76) {按数据手册同步控制；不随意组合门控PCLK};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text={rgb,255:red,143;green,236;blue,179}] at (-8.4,0.6) {HREF / VSYNC →};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text={rgb,255:red,143;green,236;blue,179}] at (0.1,1.06) {↑ 写使能 / 写指针复位};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text={rgb,255:red,143;green,236;blue,179}] at (8.3,0.5) {MCU发起抓帧};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (0.2,-3.14) {流程：准备 → 等帧边界 → 只写一帧 → 停写 → MCU读出 → 再抓下一帧};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,184;blue,77}] at (0.2,-3.94) {384 KiB能存QVGA彩色；VGA RGB565需600 KiB，单颗不足。};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,184;blue,77}] at (0.2,-4.66) {VGA扩展：≥600 KiB有效缓存 + 相应控制器；双FIFO还需字节分流/复用逻辑。};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (0.2,-5.46) {FIFO缓解实时采样压力，不提高F103 USB的12 Mbit/s上限，也不修复失焦/错色。};
\end{tikzpicture}
```

### 第一版逻辑连接与器件

| 网络 | 连接关系 | 设计要点 |
|---|---|---|
| 像素数据 | OV7670 D0～D7 → FIFO DI0～DI7 | 不再直接依赖MCU按PCLK抓每个像素 |
| 写时钟 | OV7670 PCLK → FIFO WCK | 核对边沿、建立保持时间和时钟连续性 |
| 行/帧控制 | HREF、VSYNC → 写控制逻辑 | 只保存有效行数据，按帧启动/停止 |
| 写控制 | 控制逻辑 → /WE、/WRST | 低有效及复位需满足WCK同步要求；不直接凭信号名称连接 |
| 读取数据 | FIFO DO0～DO7 → MCU连续8位GPIO | 候选仍为PA0～PA7；正式原理图再定 |
| 读取控制 | MCU → RCK、/RE、/RRST、/OE | 按手册规定的读复位和首字节时序读取 |
| 相机配置 | MCU → XCLK、SCL、SDA | 候选保留当前PB10、PC15、PB11；不等于所有控制脚已分配 |
| 电源 | 稳定3.3V、共地 | 芯片去耦、内部稳压/DEC等按完整手册连接 |

主要物料：FIFO芯片、3.3V逻辑门或小型CPLD（器件数量待时序设计）、去耦/储能电容、必要上拉和可选源端串联电阻、相机/MCU连接器。第一版不指定未核实的逻辑门型号或阻值。

AL422B是带DRAM结构的专用FIFO，不应当作可无限停钟保留数据的普通SRAM。**写/读时钟最低频率、刷新条件、数据保持、复位脉冲、首字节延迟、写满回绕及使能极性，都需用完整数据手册核定。** 停写应控制使能，是否允许停时钟另行核对；不能用普通组合门随意切断PCLK产生毛刺。关闭HREF外的PCLK配置也要重新评估与FIFO时钟要求的兼容性。

### 抓帧流程

1. 禁止写入，准备/复位FIFO写指针，确认相机格式和窗口为320×240 RGB565。
2. 在确定的VSYNC帧边界启动一次抓取；根据HREF，仅在有效像素期间写入。
3. 帧结束后停止写入、锁定该帧，记录有效字节数；不得让下一帧覆盖尚未读出的内容。
4. MCU按规定时序复位读指针并读取153600字节，分块送USB；同时计算OLED小图。
5. 检查长度、行边界、测试图及CRC，读完再允许下一次抓取。若读端慢，降低抓帧频率或明确丢帧策略。

### VGA彩色扩展

- 方案A：两颗384 KiB FIFO分别保存RGB565的高/低字节，每颗需要300 KiB。相机仍只有8位输出，必须增加逐字节相位控制，把交替字节分送两颗FIFO；读取时再重组。
- 两颗不能靠简单并联把容量相加。需要处理帧首相位复位、相同写计数、读同步以及输出总线复用；共享读总线时必须确保只有一颗/OE有效，或使用外部复用器。还要核对DRAM刷新与时钟要求。
- 方案B：CPLD/FPGA＋足够容量RAM，用控制器完成采集、地址计数和读写仲裁。不能把普通SPI RAM直接连相机DVP口就当作FIFO。
- 双帧乒乓缓存还需要至少1200 KiB图像存储，且持续输出速率仍必须跟得上；只有大容量不能消除长期带宽差。

### 预期收益与边界

FIFO可以缓解F103实时采样压力，使OLED/USB处理与抓取解耦；但它不改变USB FS的12 Mbit/s上限，不修复镜头失焦、曝光或颜色解码。它可能改善实际帧率与完整性，幅度必须上板测量，**当前没有FIFO实测帧率**。高帧率相机的瞬时写入速率大于主机平均读取速率时，只能通过等待、丢帧或更快输出处理。

### PCB与验收

相机到FIFO的8位数据与PCLK短而直接；时钟保留连续回流路径，避免长飞线和大分支。优先双面板，按本项目居家蚀刻规则安排可手焊过孔：孔≥0.5mm、默认盘1.2mm、双面开窗且可接近。逻辑和连接器尽量同侧排布；线宽与间距在满足高速信号完整性前提下加宽，不机械套用普通慢速GPIO规则。

- [ ] 获取完整芯片手册、确认供货封装与刷新限制；公开模块仅作参考。
- [ ] 核对写入/读出状态机、复位及首字节时序，确定逻辑芯片与MCU引脚。
- [ ] 完成原理图与布局，检查电源/去耦/DEC、时钟回流、数据总线方向、ERC/DRC。
- [ ] 用数字测试图/固定序列核对位序、长度、首字节与读写冻结，再拍文字和色卡。
- [ ] 比较无FIFO/有FIFO完整帧率、错误率、USB吞吐和OLED并行开销；不只看“亮屏”。

### 参考及公开范围

- [AverLogic AL422B简介（原厂文档镜像）](https://akizukidenshi.com/goodsaffix/AL422B_Flyer.pdf)：384 KiB×8位、独立读写时钟等能力；简介不能替代完整时序手册。
- [Haoyu OV7670＋AL422B参考资料目录](https://www.haoyuelectronics.com/Attachment/OV7670%20%2B%20AL422B%28FIFO%29%20Camera%20Module%28V2.0%29/)：提供模块原理图、引脚资料及OV7670文档，证明存在相机＋FIFO的硬件参考；本节尚未逐网等价迁移，也未验证其固件与本板兼容性。
- 本地草案：`fifo-design-append.md`；画板：“OV7670 FIFO扩展板｜设计草案”。下一步若实施，先完成完整手册与参考原理图的时序核对，再确定最终电路。


## FIFO R1 完整电路图（2026-09-12）

本节补充前面的架构草案，现已明确器件与引脚。采用单颗AL422B、两个LVC门，外部稳压3.3V；信号通过实际连线连接；实心方点表示接点，交叉无点不连接。连接器为便于阅读分组展开，编号仍对应同一物理接口。n表示低有效。可在画板中编辑，PCB由用户自行布线，尚未上板验证。

```tikz
\begin{tikzpicture}[scale=1.18, line cap=round, line join=round]
  \color{white}
  \filldraw[draw={rgb,255:red,16;green,24;blue,32}, line width=0.742857pt, fill={rgb,255:red,16;green,24;blue,32}] (-12,7.6) -- (36,7.6) -- (36,-33.6) -- (-12,-33.6) -- cycle;
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (12,6.84) {OV7670 FIFO R1｜实际连线电路图};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,227;blue,107}] at (12,6.08) {实线为连接；实心方点为接点，交叉无点不连接。连接器分组展开，编号仍对应同一个物理接口。};
  \filldraw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.742857pt, fill={rgb,255:red,22;green,51;blue,72}] (-10.2,4.7) -- (-5,4.7) -- (-5,-5.7) -- (-10.2,-5.7) -- cycle;
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (-7.6,4.16) {J1 相机：数据 / 时钟};
  \filldraw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.742857pt, fill={rgb,255:red,22;green,51;blue,72}] (7,4.7) -- (13.6,4.7) -- (13.6,-13) -- (7,-13) -- cycle;
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (10.3,4.06) {U1 AL422B · 384 KiB};
  \filldraw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.742857pt, fill={rgb,255:red,22;green,51;blue,72}] (29,4.7) -- (33.8,4.7) -- (33.8,-4.7) -- (29,-4.7) -- cycle;
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (31.4,4.16) {J2 → MCU PA0～PA7};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (31.4,3.6) {GPIO映射为候选};
  \node[anchor=east, inner sep=0pt, outer sep=0pt, text=white] at (-5.24,2.8) {16 D0};
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text=white] at (7.24,2.8) {1 DI0};
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (-5,2.8) -- (7,2.8);
  \node[anchor=east, inner sep=0pt, outer sep=0pt, text=white] at (13.36,2.8) {28 DO0};
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text=white] at (29.24,2.8) {2 D0};
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (13.6,2.8) -- (29,2.8);
  \node[anchor=east, inner sep=0pt, outer sep=0pt, text=white] at (-5.24,1.94) {15 D1};
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text=white] at (7.24,1.94) {2 DI1};
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (-5,1.94) -- (7,1.94);
  \node[anchor=east, inner sep=0pt, outer sep=0pt, text=white] at (13.36,1.94) {27 DO1};
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text=white] at (29.24,1.94) {3 D1};
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (13.6,1.94) -- (29,1.94);
  \node[anchor=east, inner sep=0pt, outer sep=0pt, text=white] at (-5.24,1.08) {14 D2};
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text=white] at (7.24,1.08) {3 DI2};
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (-5,1.08) -- (7,1.08);
  \node[anchor=east, inner sep=0pt, outer sep=0pt, text=white] at (13.36,1.08) {26 DO2};
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text=white] at (29.24,1.08) {4 D2};
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (13.6,1.08) -- (29,1.08);
  \node[anchor=east, inner sep=0pt, outer sep=0pt, text=white] at (-5.24,0.22) {13 D3};
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text=white] at (7.24,0.22) {4 DI3};
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (-5,0.22) -- (7,0.22);
  \node[anchor=east, inner sep=0pt, outer sep=0pt, text=white] at (13.36,0.22) {25 DO3};
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text=white] at (29.24,0.22) {5 D3};
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (13.6,0.22) -- (29,0.22);
  \node[anchor=east, inner sep=0pt, outer sep=0pt, text=white] at (-5.24,-0.64) {12 D4};
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text=white] at (7.24,-0.64) {11 DI4};
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (-5,-0.64) -- (7,-0.64);
  \node[anchor=east, inner sep=0pt, outer sep=0pt, text=white] at (13.36,-0.64) {18 DO4};
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text=white] at (29.24,-0.64) {6 D4};
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (13.6,-0.64) -- (29,-0.64);
  \node[anchor=east, inner sep=0pt, outer sep=0pt, text=white] at (-5.24,-1.5) {11 D5};
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text=white] at (7.24,-1.5) {12 DI5};
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (-5,-1.5) -- (7,-1.5);
  \node[anchor=east, inner sep=0pt, outer sep=0pt, text=white] at (13.36,-1.5) {17 DO5};
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text=white] at (29.24,-1.5) {7 D5};
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (13.6,-1.5) -- (29,-1.5);
  \node[anchor=east, inner sep=0pt, outer sep=0pt, text=white] at (-5.24,-2.36) {10 D6};
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text=white] at (7.24,-2.36) {13 DI6};
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (-5,-2.36) -- (7,-2.36);
  \node[anchor=east, inner sep=0pt, outer sep=0pt, text=white] at (13.36,-2.36) {16 DO6};
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text=white] at (29.24,-2.36) {8 D6};
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (13.6,-2.36) -- (29,-2.36);
  \node[anchor=east, inner sep=0pt, outer sep=0pt, text=white] at (-5.24,-3.22) {9 D7};
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text=white] at (7.24,-3.22) {14 DI7};
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (-5,-3.22) -- (7,-3.22);
  \node[anchor=east, inner sep=0pt, outer sep=0pt, text=white] at (13.36,-3.22) {15 DO7};
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text=white] at (29.24,-3.22) {9 D7};
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (13.6,-3.22) -- (29,-3.22);
  \node[anchor=east, inner sep=0pt, outer sep=0pt, text=white] at (-5.24,-4.8) {7 PCLK};
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text=white] at (7.24,-4.8) {9 WCK};
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (-0.4,-4.8) -- (0.04,-4.8);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.742857pt] (0.04,-4.64) -- (0.76,-4.64) -- (0.76,-4.96) -- (0.04,-4.96) -- cycle;
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (0.76,-4.8) -- (1.2,-4.8);
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,227;blue,107}] at (0.4,-4.36) {R1 33R};
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (-5,-4.8) -- (-0.4,-4.8);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (1.2,-4.8) -- (7,-4.8);
  \filldraw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.742857pt, fill={rgb,255:red,22;green,51;blue,72}] (29,-5.3) -- (33.8,-5.3) -- (33.8,-13.8) -- (29,-13.8) -- cycle;
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (31.4,-5.9) {J3 MCU：FIFO控制};
  \node[anchor=east, inner sep=0pt, outer sep=0pt, text=white] at (13.36,-7.1) {20 RCK};
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text=white] at (29.24,-7.1) {2 RCLK};
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (19.8,-7.1) -- (20.24,-7.1);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.742857pt] (20.24,-6.94) -- (20.96,-6.94) -- (20.96,-7.26) -- (20.24,-7.26) -- cycle;
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (20.96,-7.1) -- (21.4,-7.1);
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,227;blue,107}] at (20.6,-6.66) {R2 33R};
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (29,-7.1) -- (21.4,-7.1);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (19.8,-7.1) -- (13.6,-7.1);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (25.6,-7.5) -- (25.6,-7.9);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.742857pt] (25.44,-7.9) -- (25.76,-7.9) -- (25.76,-8.5) -- (25.44,-8.5) -- cycle;
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (25.6,-8.5) -- (25.6,-8.9);
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,227;blue,107}] at (25.92,-8.2) {R11 10k};
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (29,-7.1) -- (25.6,-7.1) -- (25.6,-7.5);
  \filldraw[draw={rgb,255:red,143;green,236;blue,179}, line width=0.742857pt, fill={rgb,255:red,143;green,236;blue,179}] (25.54,-7.04) -- (25.66,-7.04) -- (25.66,-7.16) -- (25.54,-7.16) -- cycle;
  \draw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.914286pt] (25.6,-8.9) -- (25.6,-9.26);
  \draw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.914286pt] (25.36,-9.26) -- (25.84,-9.26);
  \draw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.914286pt] (25.44,-9.36) -- (25.76,-9.36);
  \draw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.914286pt] (25.52,-9.46) -- (25.68,-9.46);
  \node[anchor=east, inner sep=0pt, outer sep=0pt, text=white] at (13.36,-8.9) {24 nRE};
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text=white] at (29.24,-8.9) {3 nRE};
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (13.6,-8.9) -- (29,-8.9);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (18.2,-7.3) -- (18.2,-7.7);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.742857pt] (18.04,-7.7) -- (18.36,-7.7) -- (18.36,-8.3) -- (18.04,-8.3) -- cycle;
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (18.2,-8.3) -- (18.2,-8.7);
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,227;blue,107}] at (18.52,-8) {R7 10k};
  \draw[draw={rgb,255:red,255;green,184;blue,77}, line width=0.914286pt] (18.2,-7.3) -- (18.2,-6.9);
  \draw[draw={rgb,255:red,255;green,184;blue,77}, line width=0.914286pt] (18.06,-7.02) -- (18.2,-6.9) -- (18.34,-7.02);
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,184;blue,77}] at (18.2,-6.62) {3.3V};
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (13.6,-8.9) -- (18.2,-8.9) -- (18.2,-8.7);
  \filldraw[draw={rgb,255:red,143;green,236;blue,179}, line width=0.742857pt, fill={rgb,255:red,143;green,236;blue,179}] (18.14,-8.84) -- (18.26,-8.84) -- (18.26,-8.96) -- (18.14,-8.96) -- cycle;
  \node[anchor=east, inner sep=0pt, outer sep=0pt, text=white] at (13.36,-10.7) {21 nRRST};
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text=white] at (29.24,-10.7) {4 nRRST};
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (13.6,-10.7) -- (29,-10.7);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (21.7,-9.1) -- (21.7,-9.5);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.742857pt] (21.54,-9.5) -- (21.86,-9.5) -- (21.86,-10.1) -- (21.54,-10.1) -- cycle;
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (21.7,-10.1) -- (21.7,-10.5);
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,227;blue,107}] at (22.02,-9.8) {R6 10k};
  \draw[draw={rgb,255:red,255;green,184;blue,77}, line width=0.914286pt] (21.7,-9.1) -- (21.7,-8.7);
  \draw[draw={rgb,255:red,255;green,184;blue,77}, line width=0.914286pt] (21.56,-8.82) -- (21.7,-8.7) -- (21.84,-8.82);
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,184;blue,77}] at (21.7,-8.42) {3.3V};
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (13.6,-10.7) -- (21.7,-10.7) -- (21.7,-10.5);
  \filldraw[draw={rgb,255:red,143;green,236;blue,179}, line width=0.742857pt, fill={rgb,255:red,143;green,236;blue,179}] (21.64,-10.64) -- (21.76,-10.64) -- (21.76,-10.76) -- (21.64,-10.76) -- cycle;
  \node[anchor=east, inner sep=0pt, outer sep=0pt, text=white] at (13.36,-12.5) {22 nOE};
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text=white] at (29.24,-12.5) {5 nOE};
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (13.6,-12.5) -- (29,-12.5);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (25.2,-10.9) -- (25.2,-11.3);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.742857pt] (25.04,-11.3) -- (25.36,-11.3) -- (25.36,-11.9) -- (25.04,-11.9) -- cycle;
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (25.2,-11.9) -- (25.2,-12.3);
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,227;blue,107}] at (25.52,-11.6) {R8 10k};
  \draw[draw={rgb,255:red,255;green,184;blue,77}, line width=0.914286pt] (25.2,-10.9) -- (25.2,-10.5);
  \draw[draw={rgb,255:red,255;green,184;blue,77}, line width=0.914286pt] (25.06,-10.62) -- (25.2,-10.5) -- (25.34,-10.62);
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,184;blue,77}] at (25.2,-10.22) {3.3V};
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (13.6,-12.5) -- (25.2,-12.5) -- (25.2,-12.3);
  \filldraw[draw={rgb,255:red,143;green,236;blue,179}, line width=0.742857pt, fill={rgb,255:red,143;green,236;blue,179}] (25.14,-12.44) -- (25.26,-12.44) -- (25.26,-12.56) -- (25.14,-12.56) -- cycle;
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text=white] at (7.24,-6.8) {5 nWE};
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text=white] at (7.24,-8.9) {8 nWRST};
  \filldraw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.742857pt, fill={rgb,255:red,22;green,51;blue,72}] (-8.6,-7.1) -- (-3.6,-7.1) -- (-3.6,-10.5) -- (-8.6,-10.5) -- cycle;
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (-6.1,-7.6) {U2 NAND · 1G00};
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text=white] at (-8.36,-8.4) {1 A HREF};
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text=white] at (-8.36,-9.6) {2 B CAPTURE};
  \node[anchor=east, inner sep=0pt, outer sep=0pt, text=white] at (-3.84,-8.4) {4 Y};
  \filldraw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.742857pt, fill={rgb,255:red,22;green,51;blue,72}] (-0.6,-6.6) -- (3.9,-6.6) -- (3.9,-10.6) -- (-0.6,-10.6) -- cycle;
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (1.64,-7.24) {U3 AND · 1G08};
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text=white] at (-0.36,-8.4) {1 A};
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text=white] at (-0.36,-9.5) {2 B};
  \node[anchor=east, inner sep=0pt, outer sep=0pt, text=white] at (3.66,-7.9) {4 Y};
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (-3.6,-8.4) -- (-0.6,-8.4);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (3.9,-7.9) -- (5.3,-7.9) -- (5.3,-6.8) -- (7,-6.8);
  \filldraw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.742857pt, fill={rgb,255:red,22;green,51;blue,72}] (-10.2,-14) -- (-5,-14) -- (-5,-17.4) -- (-10.2,-17.4) -- cycle;
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (-7.6,-14.5) {J3 MCU：写控制};
  \node[anchor=east, inner sep=0pt, outer sep=0pt, text=white] at (-5.24,-15.3) {6 nWRST};
  \node[anchor=east, inner sep=0pt, outer sep=0pt, text=white] at (-5.24,-16.6) {7 CAPTURE};
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (-5,-15.3) -- (-1.8,-15.3) -- (-1.8,-9.5) -- (-0.6,-9.5);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (-1.8,-15.3) -- (5,-15.3) -- (5,-8.9) -- (7,-8.9);
  \filldraw[draw={rgb,255:red,143;green,236;blue,179}, line width=0.742857pt, fill={rgb,255:red,143;green,236;blue,179}] (-1.86,-15.24) -- (-1.74,-15.24) -- (-1.74,-15.36) -- (-1.86,-15.36) -- cycle;
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (2.9,-12.9) -- (2.9,-13.3);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.742857pt] (2.74,-13.3) -- (3.06,-13.3) -- (3.06,-13.9) -- (2.74,-13.9) -- cycle;
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (2.9,-13.9) -- (2.9,-14.3);
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,227;blue,107}] at (3.22,-13.6) {R5 10k};
  \draw[draw={rgb,255:red,255;green,184;blue,77}, line width=0.914286pt] (2.9,-12.9) -- (2.9,-12.5);
  \draw[draw={rgb,255:red,255;green,184;blue,77}, line width=0.914286pt] (2.76,-12.62) -- (2.9,-12.5) -- (3.04,-12.62);
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,184;blue,77}] at (2.9,-12.22) {3.3V};
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (2.9,-14.3) -- (2.9,-15.3) -- (-5,-15.3);
  \filldraw[draw={rgb,255:red,143;green,236;blue,179}, line width=0.742857pt, fill={rgb,255:red,143;green,236;blue,179}] (2.84,-15.24) -- (2.96,-15.24) -- (2.96,-15.36) -- (2.84,-15.36) -- cycle;
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (-5,-16.6) -- (-4.2,-16.6) -- (-4.2,-12.5) -- (-10.7,-12.5) -- (-10.7,-9.6) -- (-8.6,-9.6);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (-3.4,-16.8) -- (-3.4,-17.2);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.742857pt] (-3.56,-17.2) -- (-3.24,-17.2) -- (-3.24,-17.8) -- (-3.56,-17.8) -- cycle;
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (-3.4,-17.8) -- (-3.4,-18.2);
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,227;blue,107}] at (-3.08,-17.5) {R4 10k};
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (-5,-16.6) -- (-3.4,-16.6) -- (-3.4,-16.8);
  \filldraw[draw={rgb,255:red,143;green,236;blue,179}, line width=0.742857pt, fill={rgb,255:red,143;green,236;blue,179}] (-4.26,-16.54) -- (-4.14,-16.54) -- (-4.14,-16.66) -- (-4.26,-16.66) -- cycle;
  \draw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.914286pt] (-3.4,-18.2) -- (-3.4,-18.56);
  \draw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.914286pt] (-3.64,-18.56) -- (-3.16,-18.56);
  \draw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.914286pt] (-3.56,-18.66) -- (-3.24,-18.66);
  \draw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.914286pt] (-3.48,-18.76) -- (-3.32,-18.76);
  \filldraw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.742857pt, fill={rgb,255:red,22;green,51;blue,72}] (-10.2,-20) -- (-5,-20) -- (-5,-27.8) -- (-10.2,-27.8) -- cycle;
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (-7.6,-20.6) {J1 相机：配置 / 同步};
  \filldraw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.742857pt, fill={rgb,255:red,22;green,51;blue,72}] (29,-20) -- (33.8,-20) -- (33.8,-27.8) -- (29,-27.8) -- cycle;
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (31.4,-20.6) {J3 MCU：配置 / 同步};
  \node[anchor=east, inner sep=0pt, outer sep=0pt, text=white] at (-5.24,-21.6) {8 XCLK};
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text=white] at (29.24,-21.6) {10 XCLK};
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (12.2,-21.6) -- (12.64,-21.6);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.742857pt] (12.64,-21.44) -- (13.36,-21.44) -- (13.36,-21.76) -- (12.64,-21.76) -- cycle;
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (13.36,-21.6) -- (13.8,-21.6);
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,227;blue,107}] at (13,-21.16) {R3 33R};
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (29,-21.6) -- (13.8,-21.6);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (12.2,-21.6) -- (-5,-21.6);
  \node[anchor=east, inner sep=0pt, outer sep=0pt, text=white] at (-5.24,-23) {3 SCL};
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text=white] at (29.24,-23) {11 SCL};
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (-5,-23) -- (29,-23);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (19,-21.42) -- (19,-21.82);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.742857pt] (18.84,-21.82) -- (19.16,-21.82) -- (19.16,-22.42) -- (18.84,-22.42) -- cycle;
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (19,-22.42) -- (19,-22.82);
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,227;blue,107}] at (19.32,-22.12) {R9 4.7k};
  \draw[draw={rgb,255:red,255;green,184;blue,77}, line width=0.914286pt] (19,-21.42) -- (19,-21.02);
  \draw[draw={rgb,255:red,255;green,184;blue,77}, line width=0.914286pt] (18.86,-21.14) -- (19,-21.02) -- (19.14,-21.14);
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,184;blue,77}] at (19,-20.74) {3.3V};
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (19,-22.82) -- (19,-23) -- (-5,-23);
  \filldraw[draw={rgb,255:red,143;green,236;blue,179}, line width=0.742857pt, fill={rgb,255:red,143;green,236;blue,179}] (18.94,-22.94) -- (19.06,-22.94) -- (19.06,-23.06) -- (18.94,-23.06) -- cycle;
  \node[anchor=east, inner sep=0pt, outer sep=0pt, text=white] at (-5.24,-24.4) {4 SDA};
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text=white] at (29.24,-24.4) {12 SDA};
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (-5,-24.4) -- (29,-24.4);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (24,-22.82) -- (24,-23.22);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.742857pt] (23.84,-23.22) -- (24.16,-23.22) -- (24.16,-23.82) -- (23.84,-23.82) -- cycle;
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (24,-23.82) -- (24,-24.22);
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,227;blue,107}] at (24.32,-23.52) {R10 4.7k};
  \draw[draw={rgb,255:red,255;green,184;blue,77}, line width=0.914286pt] (24,-22.82) -- (24,-22.42);
  \draw[draw={rgb,255:red,255;green,184;blue,77}, line width=0.914286pt] (23.86,-22.54) -- (24,-22.42) -- (24.14,-22.54);
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,184;blue,77}] at (24,-22.14) {3.3V};
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (24,-24.22) -- (24,-24.4) -- (-5,-24.4);
  \filldraw[draw={rgb,255:red,143;green,236;blue,179}, line width=0.742857pt, fill={rgb,255:red,143;green,236;blue,179}] (23.94,-24.34) -- (24.06,-24.34) -- (24.06,-24.46) -- (23.94,-24.46) -- cycle;
  \node[anchor=east, inner sep=0pt, outer sep=0pt, text=white] at (-5.24,-25.8) {5 VSYNC};
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text=white] at (29.24,-25.8) {8 VSYNC};
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (-5,-25.8) -- (29,-25.8);
  \node[anchor=east, inner sep=0pt, outer sep=0pt, text=white] at (-5.24,-27.2) {6 HREF};
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text=white] at (29.24,-27.2) {9 HREF};
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (-5,-27.2) -- (29,-27.2);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (-3.6,-27.2) -- (-3.6,-28.4) -- (-11.5,-28.4) -- (-11.5,-8.4) -- (-8.6,-8.4);
  \filldraw[draw={rgb,255:red,143;green,236;blue,179}, line width=0.742857pt, fill={rgb,255:red,143;green,236;blue,179}] (-3.66,-27.14) -- (-3.54,-27.14) -- (-3.54,-27.26) -- (-3.66,-27.26) -- cycle;
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,227;blue,107}] at (11.8,-29.4) {电源 / 去耦：下列电源符号共网。只接稳压3.3V，禁止5V。U1 DEC在3.3V模式接3.3V。};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (-2,-30.2) {U1 电源脚};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (-4.32,-31.4) {10};
  \draw[draw={rgb,255:red,255;green,184;blue,77}, line width=0.914286pt] (-4.32,-31.4) -- (-4.32,-31);
  \draw[draw={rgb,255:red,255;green,184;blue,77}, line width=0.914286pt] (-4.46,-31.12) -- (-4.32,-31) -- (-4.18,-31.12);
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,184;blue,77}] at (-4.32,-30.72) {3.3V};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (-3.16,-31.4) {19};
  \draw[draw={rgb,255:red,255;green,184;blue,77}, line width=0.914286pt] (-3.16,-31.4) -- (-3.16,-31);
  \draw[draw={rgb,255:red,255;green,184;blue,77}, line width=0.914286pt] (-3.3,-31.12) -- (-3.16,-31) -- (-3.02,-31.12);
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,184;blue,77}] at (-3.16,-30.72) {3.3V};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (-2,-31.4) {7};
  \draw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.914286pt] (-2,-31.4) -- (-2,-31.76);
  \draw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.914286pt] (-2.24,-31.76) -- (-1.76,-31.76);
  \draw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.914286pt] (-2.16,-31.86) -- (-1.84,-31.86);
  \draw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.914286pt] (-2.08,-31.96) -- (-1.92,-31.96);
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (-0.84,-31.4) {6};
  \draw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.914286pt] (-0.84,-31.4) -- (-0.84,-31.76);
  \draw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.914286pt] (-1.08,-31.76) -- (-0.6,-31.76);
  \draw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.914286pt] (-1,-31.86) -- (-0.68,-31.86);
  \draw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.914286pt] (-0.92,-31.96) -- (-0.76,-31.96);
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (0.32,-31.4) {23};
  \draw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.914286pt] (0.32,-31.4) -- (0.32,-31.76);
  \draw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.914286pt] (0.08,-31.76) -- (0.56,-31.76);
  \draw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.914286pt] (0.16,-31.86) -- (0.48,-31.86);
  \draw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.914286pt] (0.24,-31.96) -- (0.4,-31.96);
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (4.8,-30.2) {U2 电源脚};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (4.22,-31.4) {5};
  \draw[draw={rgb,255:red,255;green,184;blue,77}, line width=0.914286pt] (4.22,-31.4) -- (4.22,-31);
  \draw[draw={rgb,255:red,255;green,184;blue,77}, line width=0.914286pt] (4.08,-31.12) -- (4.22,-31) -- (4.36,-31.12);
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,184;blue,77}] at (4.22,-30.72) {3.3V};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (5.38,-31.4) {3};
  \draw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.914286pt] (5.38,-31.4) -- (5.38,-31.76);
  \draw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.914286pt] (5.14,-31.76) -- (5.62,-31.76);
  \draw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.914286pt] (5.22,-31.86) -- (5.54,-31.86);
  \draw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.914286pt] (5.3,-31.96) -- (5.46,-31.96);
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (8.8,-30.2) {U3 电源脚};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (8.22,-31.4) {5};
  \draw[draw={rgb,255:red,255;green,184;blue,77}, line width=0.914286pt] (8.22,-31.4) -- (8.22,-31);
  \draw[draw={rgb,255:red,255;green,184;blue,77}, line width=0.914286pt] (8.08,-31.12) -- (8.22,-31) -- (8.36,-31.12);
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,184;blue,77}] at (8.22,-30.72) {3.3V};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (9.38,-31.4) {3};
  \draw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.914286pt] (9.38,-31.4) -- (9.38,-31.76);
  \draw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.914286pt] (9.14,-31.76) -- (9.62,-31.76);
  \draw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.914286pt] (9.22,-31.86) -- (9.54,-31.86);
  \draw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.914286pt] (9.3,-31.96) -- (9.46,-31.96);
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (13.6,-30.2) {J1 电源脚};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (11.86,-31.4) {1};
  \draw[draw={rgb,255:red,255;green,184;blue,77}, line width=0.914286pt] (11.86,-31.4) -- (11.86,-31);
  \draw[draw={rgb,255:red,255;green,184;blue,77}, line width=0.914286pt] (11.72,-31.12) -- (11.86,-31) -- (12,-31.12);
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,184;blue,77}] at (11.86,-30.72) {3.3V};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (13.02,-31.4) {17};
  \draw[draw={rgb,255:red,255;green,184;blue,77}, line width=0.914286pt] (13.02,-31.4) -- (13.02,-31);
  \draw[draw={rgb,255:red,255;green,184;blue,77}, line width=0.914286pt] (12.88,-31.12) -- (13.02,-31) -- (13.16,-31.12);
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,184;blue,77}] at (13.02,-30.72) {3.3V};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (14.18,-31.4) {2};
  \draw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.914286pt] (14.18,-31.4) -- (14.18,-31.76);
  \draw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.914286pt] (13.94,-31.76) -- (14.42,-31.76);
  \draw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.914286pt] (14.02,-31.86) -- (14.34,-31.86);
  \draw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.914286pt] (14.1,-31.96) -- (14.26,-31.96);
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (15.34,-31.4) {18};
  \draw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.914286pt] (15.34,-31.4) -- (15.34,-31.76);
  \draw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.914286pt] (15.1,-31.76) -- (15.58,-31.76);
  \draw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.914286pt] (15.18,-31.86) -- (15.5,-31.86);
  \draw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.914286pt] (15.26,-31.96) -- (15.42,-31.96);
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (19.4,-30.2) {J2 电源脚};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (18.82,-31.4) {1};
  \draw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.914286pt] (18.82,-31.4) -- (18.82,-31.76);
  \draw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.914286pt] (18.58,-31.76) -- (19.06,-31.76);
  \draw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.914286pt] (18.66,-31.86) -- (18.98,-31.86);
  \draw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.914286pt] (18.74,-31.96) -- (18.9,-31.96);
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (19.98,-31.4) {10};
  \draw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.914286pt] (19.98,-31.4) -- (19.98,-31.76);
  \draw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.914286pt] (19.74,-31.76) -- (20.22,-31.76);
  \draw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.914286pt] (19.82,-31.86) -- (20.14,-31.86);
  \draw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.914286pt] (19.9,-31.96) -- (20.06,-31.96);
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (24.2,-30.2) {J4 电源脚};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (23.62,-31.4) {1};
  \draw[draw={rgb,255:red,255;green,184;blue,77}, line width=0.914286pt] (23.62,-31.4) -- (23.62,-31);
  \draw[draw={rgb,255:red,255;green,184;blue,77}, line width=0.914286pt] (23.48,-31.12) -- (23.62,-31) -- (23.76,-31.12);
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,184;blue,77}] at (23.62,-30.72) {3.3V};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (24.78,-31.4) {2};
  \draw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.914286pt] (24.78,-31.4) -- (24.78,-31.76);
  \draw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.914286pt] (24.54,-31.76) -- (25.02,-31.76);
  \draw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.914286pt] (24.62,-31.86) -- (24.94,-31.86);
  \draw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.914286pt] (24.7,-31.96) -- (24.86,-31.96);
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (29,-30.2) {J3 电源脚};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (29,-31.4) {1};
  \draw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.914286pt] (29,-31.4) -- (29,-31.76);
  \draw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.914286pt] (28.76,-31.76) -- (29.24,-31.76);
  \draw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.914286pt] (28.84,-31.86) -- (29.16,-31.86);
  \draw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.914286pt] (28.92,-31.96) -- (29.08,-31.96);
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (10.4,-14.9) {电源旁路（布局时贴近对应供电脚）};
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (8.2,-16.32) -- (8.2,-16.88);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (7.88,-16.88) -- (8.52,-16.88);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (7.88,-17.12) -- (8.52,-17.12);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (8.2,-17.12) -- (8.2,-17.68);
  \draw[draw={rgb,255:red,255;green,184;blue,77}, line width=0.914286pt] (8.2,-16.32) -- (8.2,-15.92);
  \draw[draw={rgb,255:red,255;green,184;blue,77}, line width=0.914286pt] (8.06,-16.04) -- (8.2,-15.92) -- (8.34,-16.04);
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,184;blue,77}] at (8.2,-15.64) {3.3V};
  \draw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.914286pt] (8.2,-17.68) -- (8.2,-18.04);
  \draw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.914286pt] (7.96,-18.04) -- (8.44,-18.04);
  \draw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.914286pt] (8.04,-18.14) -- (8.36,-18.14);
  \draw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.914286pt] (8.12,-18.24) -- (8.28,-18.24);
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (8.2,-18.7) {C1 100nF};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (8.2,-19.2) {U1 VDD};
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (12.4,-16.32) -- (12.4,-16.88);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (12.08,-16.88) -- (12.72,-16.88);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (12.08,-17.12) -- (12.72,-17.12);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (12.4,-17.12) -- (12.4,-17.68);
  \draw[draw={rgb,255:red,255;green,184;blue,77}, line width=0.914286pt] (12.4,-16.32) -- (12.4,-15.92);
  \draw[draw={rgb,255:red,255;green,184;blue,77}, line width=0.914286pt] (12.26,-16.04) -- (12.4,-15.92) -- (12.54,-16.04);
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,184;blue,77}] at (12.4,-15.64) {3.3V};
  \draw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.914286pt] (12.4,-17.68) -- (12.4,-18.04);
  \draw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.914286pt] (12.16,-18.04) -- (12.64,-18.04);
  \draw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.914286pt] (12.24,-18.14) -- (12.56,-18.14);
  \draw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.914286pt] (12.32,-18.24) -- (12.48,-18.24);
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (12.4,-18.7) {C2 100nF};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (12.4,-19.2) {U1 DEC};
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (16.6,-16.32) -- (16.6,-16.88);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (16.28,-16.88) -- (16.92,-16.88);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (16.28,-17.12) -- (16.92,-17.12);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (16.6,-17.12) -- (16.6,-17.68);
  \draw[draw={rgb,255:red,255;green,184;blue,77}, line width=0.914286pt] (16.6,-16.32) -- (16.6,-15.92);
  \draw[draw={rgb,255:red,255;green,184;blue,77}, line width=0.914286pt] (16.46,-16.04) -- (16.6,-15.92) -- (16.74,-16.04);
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,184;blue,77}] at (16.6,-15.64) {3.3V};
  \draw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.914286pt] (16.6,-17.68) -- (16.6,-18.04);
  \draw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.914286pt] (16.36,-18.04) -- (16.84,-18.04);
  \draw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.914286pt] (16.44,-18.14) -- (16.76,-18.14);
  \draw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.914286pt] (16.52,-18.24) -- (16.68,-18.24);
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (16.6,-18.7) {C3 100nF};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (16.6,-19.2) {U2};
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (20.8,-16.32) -- (20.8,-16.88);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (20.48,-16.88) -- (21.12,-16.88);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (20.48,-17.12) -- (21.12,-17.12);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (20.8,-17.12) -- (20.8,-17.68);
  \draw[draw={rgb,255:red,255;green,184;blue,77}, line width=0.914286pt] (20.8,-16.32) -- (20.8,-15.92);
  \draw[draw={rgb,255:red,255;green,184;blue,77}, line width=0.914286pt] (20.66,-16.04) -- (20.8,-15.92) -- (20.94,-16.04);
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,184;blue,77}] at (20.8,-15.64) {3.3V};
  \draw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.914286pt] (20.8,-17.68) -- (20.8,-18.04);
  \draw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.914286pt] (20.56,-18.04) -- (21.04,-18.04);
  \draw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.914286pt] (20.64,-18.14) -- (20.96,-18.14);
  \draw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.914286pt] (20.72,-18.24) -- (20.88,-18.24);
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (20.8,-18.7) {C4 100nF};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (20.8,-19.2) {U3};
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (25,-16.32) -- (25,-16.88);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (24.68,-16.88) -- (25.32,-16.88);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (24.68,-17.12) -- (25.32,-17.12);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (25,-17.12) -- (25,-17.68);
  \draw[draw={rgb,255:red,255;green,184;blue,77}, line width=0.914286pt] (25,-16.32) -- (25,-15.92);
  \draw[draw={rgb,255:red,255;green,184;blue,77}, line width=0.914286pt] (24.86,-16.04) -- (25,-15.92) -- (25.14,-16.04);
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,184;blue,77}] at (25,-15.64) {3.3V};
  \draw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.914286pt] (25,-17.68) -- (25,-18.04);
  \draw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.914286pt] (24.76,-18.04) -- (25.24,-18.04);
  \draw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.914286pt] (24.84,-18.14) -- (25.16,-18.14);
  \draw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.914286pt] (24.92,-18.24) -- (25.08,-18.24);
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (25,-18.7) {C5 10uF};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (25,-19.2) {电源入口};
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (29.2,-16.32) -- (29.2,-16.88);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (28.88,-16.88) -- (29.52,-16.88);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (28.88,-17.12) -- (29.52,-17.12);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.914286pt] (29.2,-17.12) -- (29.2,-17.68);
  \draw[draw={rgb,255:red,255;green,184;blue,77}, line width=0.914286pt] (29.2,-16.32) -- (29.2,-15.92);
  \draw[draw={rgb,255:red,255;green,184;blue,77}, line width=0.914286pt] (29.06,-16.04) -- (29.2,-15.92) -- (29.34,-16.04);
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,184;blue,77}] at (29.2,-15.64) {3.3V};
  \draw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.914286pt] (29.2,-17.68) -- (29.2,-18.04);
  \draw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.914286pt] (28.96,-18.04) -- (29.44,-18.04);
  \draw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.914286pt] (29.04,-18.14) -- (29.36,-18.14);
  \draw[draw={rgb,255:red,189;green,203;blue,216}, line width=0.914286pt] (29.12,-18.24) -- (29.28,-18.24);
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (29.2,-18.7) {C6 100nF};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (29.2,-19.2) {相机接口};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (12,-32.9) {QVGA RGB565 · 原型未上板验证 · 连续刷新时钟和复位时序需固件实现 · 电阻0603 / 电容1206};
\end{tikzpicture}
```

写使能：`nWE = NOT(HREF AND CAPTURE_EN) AND nWRST`。AL422B需要连续刷新时钟；读写复位、首字节和指针保护间隔仍须固件实现与实测，当前直采固件不能直接使用。单颗可存QVGA RGB565，不能存VGA RGB565。


## USB 5V气泵：单键电子自锁开关

按一下开、再按一下关，不使用 MCU。**这是仅适用于 USB 5V 的短按实验设计，不能接此前提到的 5～20V 电源。尚未连接实际气泵验证。** 假设气泵插电即运行、无内置电池；带控制板的型号需确认恢复供电是否自动启动。

### 可编辑电路画板

控制信号均使用实际连线；实心连接点表示相连，交叉无点不相连。地符号与 USB GND 共地。图中 B/C/E 是晶体管电极名称，不代表通用 SOT-23 脚序。

```tikz
\begin{tikzpicture}[scale=1.18, line cap=round, line join=round]
  \color{white}
  \filldraw[draw={rgb,255:red,16;green,24;blue,32}, line width=0.742857pt, fill={rgb,255:red,16;green,24;blue,32}] (-12,7.6) -- (30,7.6) -- (30,-13) -- (-12,-13) -- cycle;
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (7.8,6.9) {USB 5V 气泵｜单键电子自锁开关 · 实验设计};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,227;blue,107}] at (7.8,6.14) {实际连线；实心方点相连，交叉无点不连；GND符号共地。仅5V，勿接此前提到的20V。};
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (-10,4.8) -- (26.2,4.8);
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,184;blue,77}] at (-9.8,5.28) {USB +5V};
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,143;green,236;blue,179}] at (-10,-9.04) {USB GND};
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (-10,-9.4) -- (26.2,-9.4);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (-7,2.8) -- (-7,2.4);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.742857pt] (-7.18,2.4) -- (-6.82,2.4) -- (-6.82,1.6) -- (-7.18,1.6) -- cycle;
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (-7,1.6) -- (-7,1.2);
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,227;blue,107}] at (-6.64,2) {R1 2.2M};
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (-7,4.8) -- (-7,2.8);
  \filldraw[draw={rgb,255:red,143;green,236;blue,179}, line width=0.742857pt, fill={rgb,255:red,143;green,236;blue,179}] (-7.06,4.86) -- (-6.94,4.86) -- (-6.94,4.74) -- (-7.06,4.74) -- cycle;
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (-7,1.2) -- (-7,-0.4) -- (-3.6,-0.4) -- (-3.6,-1);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (-7,-2) -- (-7,-2.4);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.742857pt] (-7.18,-2.4) -- (-6.82,-2.4) -- (-6.82,-3.2) -- (-7.18,-3.2) -- cycle;
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (-7,-3.2) -- (-7,-3.6);
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,227;blue,107}] at (-6.64,-2.8) {R2 470k};
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (-7,-0.4) -- (-7,-2);
  \filldraw[draw={rgb,255:red,143;green,236;blue,179}, line width=0.742857pt, fill={rgb,255:red,143;green,236;blue,179}] (-7.06,-0.34) -- (-6.94,-0.34) -- (-6.94,-0.46) -- (-7.06,-0.46) -- cycle;
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (-7,-3.6) -- (-7,-5.4) -- (-7,-6.6);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (-7,-6.6) -- (-7,-7.24);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (-7.4,-7.24) -- (-6.6,-7.24);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (-7.4,-7.56) -- (-6.6,-7.56);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (-7,-7.56) -- (-7,-8.2);
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,227;blue,107}] at (-6.5,-7.4) {C1};
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,227;blue,107}] at (-6.5,-7.88) {1uF / 16V};
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (-7,-8.2) -- (-7,-9.4);
  \filldraw[draw={rgb,255:red,143;green,236;blue,179}, line width=0.742857pt, fill={rgb,255:red,143;green,236;blue,179}] (-7.06,-9.34) -- (-6.94,-9.34) -- (-6.94,-9.46) -- (-7.06,-9.46) -- cycle;
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (-2.4,-2) -- (-3.2,-2);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (-3.2,-1.36) -- (-3.2,-2.64);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (-3.2,-1.6) -- (-3.6,-1);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (-3.2,-2.4) -- (-3.6,-3);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (-3.42,-2.54) -- (-3.58,-2.92) -- (-3.34,-2.78);
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (-2.14,-1.66) {B};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (-3.86,-1.04) {C};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (-3.86,-3) {E};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (-5.1,-1.84) {Q1 S8050};
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (-3.6,-3) -- (-3.6,-3.32);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (-3.86,-3.32) -- (-3.34,-3.32);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (-3.78,-3.46) -- (-3.42,-3.46);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (-3.68,-3.6) -- (-3.52,-3.6);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (0.8,-2) -- (1.2,-2);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.742857pt] (1.2,-1.82) -- (2,-1.82) -- (2,-2.18) -- (1.2,-2.18) -- cycle;
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (2,-2) -- (2.4,-2);
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,227;blue,107}] at (1.6,-1.52) {R3 470k};
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (-2.4,-2) -- (0.8,-2);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (2.4,-2) -- (6,-2);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (7.2,0.6) -- (6.4,0.6);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (6.4,1.24) -- (6.4,-0.04);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (6.4,1) -- (6,1.6);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (6.4,0.2) -- (6,-0.4);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (6.06,1.48) -- (6.28,1.3) -- (6.1,1.26);
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text=white] at (7.4,0.6) {B};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (5.7,1.6) {E};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (5.7,-0.4) {C};
  \node[anchor=east, inner sep=0pt, outer sep=0pt, text=white] at (5.4,0.6) {Q2 S8550 (PNP)};
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (6,4.8) -- (6,1.6);
  \filldraw[draw={rgb,255:red,143;green,236;blue,179}, line width=0.742857pt, fill={rgb,255:red,143;green,236;blue,179}] (5.94,4.86) -- (6.06,4.86) -- (6.06,4.74) -- (5.94,4.74) -- cycle;
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (6,-0.4) -- (6,-2.8);
  \filldraw[draw={rgb,255:red,143;green,236;blue,179}, line width=0.742857pt, fill={rgb,255:red,143;green,236;blue,179}] (5.94,-1.94) -- (6.06,-1.94) -- (6.06,-2.06) -- (5.94,-2.06) -- cycle;
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (6,-2.8) -- (6,-3.2);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.742857pt] (5.82,-3.2) -- (6.18,-3.2) -- (6.18,-4) -- (5.82,-4) -- cycle;
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (6,-4) -- (6,-4.4);
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,227;blue,107}] at (6.36,-3.6) {R5 47k};
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (6,-4.4) -- (6,-5.4) -- (6,-6.8);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (6,-6.8) -- (6,-7.2);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.742857pt] (5.82,-7.2) -- (6.18,-7.2) -- (6.18,-8) -- (5.82,-8) -- cycle;
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (6,-8) -- (6,-8.4);
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,227;blue,107}] at (6.36,-7.6) {R6 470k};
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (6,-8.4) -- (6,-9.4);
  \filldraw[draw={rgb,255:red,143;green,236;blue,179}, line width=0.742857pt, fill={rgb,255:red,143;green,236;blue,179}] (5.94,-9.34) -- (6.06,-9.34) -- (6.06,-9.46) -- (5.94,-9.46) -- cycle;
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (-7,-5.4) -- (-4.8,-5.4);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (-3.2,-5.4) -- (-1,-5.4);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (-4.8,-5.4) -- (-3.44,-4.9);
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (-4,-4.44) {S1 轻触开关};
  \filldraw[draw={rgb,255:red,143;green,236;blue,179}, line width=0.742857pt, fill={rgb,255:red,143;green,236;blue,179}] (-7.06,-5.34) -- (-6.94,-5.34) -- (-6.94,-5.46) -- (-7.06,-5.46) -- cycle;
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (-1,-5.4) -- (-0.6,-5.4);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.742857pt] (-0.6,-5.22) -- (0.2,-5.22) -- (0.2,-5.58) -- (-0.6,-5.58) -- cycle;
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (0.2,-5.4) -- (0.6,-5.4);
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,227;blue,107}] at (-0.2,-4.92) {R4 1k};
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (0.6,-5.4) -- (9,-5.4);
  \filldraw[draw={rgb,255:red,143;green,236;blue,179}, line width=0.742857pt, fill={rgb,255:red,143;green,236;blue,179}] (5.94,-5.34) -- (6.06,-5.34) -- (6.06,-5.46) -- (5.94,-5.46) -- cycle;
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (9,-5.4) -- (9.8,-5.4);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (9.8,-4.76) -- (9.8,-6.04);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (9.8,-5) -- (10.2,-4.4);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (9.8,-5.8) -- (10.2,-6.4);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (9.96,-6) -- (10.18,-6.32) -- (9.94,-6.22);
  \node[anchor=east, inner sep=0pt, outer sep=0pt, text=white] at (8.84,-5.4) {B};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (10.48,-4.4) {C};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (10.48,-6.4) {E};
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text=white] at (10.7,-5.4) {Q3 S8050};
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (10.2,-6.4) -- (10.2,-9.4);
  \filldraw[draw={rgb,255:red,143;green,236;blue,179}, line width=0.742857pt, fill={rgb,255:red,143;green,236;blue,179}] (10.14,-9.34) -- (10.26,-9.34) -- (10.26,-9.46) -- (10.14,-9.46) -- cycle;
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (10.2,3) -- (10.2,2.6);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.742857pt] (10.02,2.6) -- (10.38,2.6) -- (10.38,1.8) -- (10.02,1.8) -- cycle;
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (10.2,1.8) -- (10.2,1.4);
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,227;blue,107}] at (10.56,2.2) {R7 1M};
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (10.2,4.8) -- (10.2,3);
  \filldraw[draw={rgb,255:red,143;green,236;blue,179}, line width=0.742857pt, fill={rgb,255:red,143;green,236;blue,179}] (10.14,4.86) -- (10.26,4.86) -- (10.26,4.74) -- (10.14,4.74) -- cycle;
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (10.2,1.4) -- (10.2,-0.6);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (7.2,0.6) -- (10.2,0.6);
  \filldraw[draw={rgb,255:red,143;green,236;blue,179}, line width=0.742857pt, fill={rgb,255:red,143;green,236;blue,179}] (10.14,0.66) -- (10.26,0.66) -- (10.26,0.54) -- (10.14,0.54) -- cycle;
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (10.2,-0.6) -- (10.2,-1);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.742857pt] (10.02,-1) -- (10.38,-1) -- (10.38,-1.8) -- (10.02,-1.8) -- cycle;
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (10.2,-1.8) -- (10.2,-2.2);
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,227;blue,107}] at (10.56,-1.4) {R8 100k};
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (10.2,-2.2) -- (10.2,-4.4);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (11.8,-3.2) -- (12.2,-3.2);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.742857pt] (12.2,-3.02) -- (13,-3.02) -- (13,-3.38) -- (12.2,-3.38) -- cycle;
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (13,-3.2) -- (13.4,-3.2);
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,227;blue,107}] at (12.6,-2.72) {R9 1k};
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (10.2,-3.2) -- (11.8,-3.2);
  \filldraw[draw={rgb,255:red,143;green,236;blue,179}, line width=0.742857pt, fill={rgb,255:red,143;green,236;blue,179}] (10.14,-3.14) -- (10.26,-3.14) -- (10.26,-3.26) -- (10.14,-3.26) -- cycle;
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (13.4,-3.2) -- (14.4,-3.2) -- (14.4,3.2) -- (14.8,3.2);
  \filldraw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.742857pt, fill={rgb,255:red,22;green,51;blue,72}] (14.8,4.3) -- (17,4.3) -- (17,2.1) -- (14.8,2.1) -- cycle;
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (15.9,5.4) {Q4 AO3401 · P-MOS};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (15.9,3.92) {S (2)};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (15.4,3.2) {G (1)};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (15.9,2.5) {D (3)};
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (15.9,4.8) -- (15.9,4.3);
  \filldraw[draw={rgb,255:red,143;green,236;blue,179}, line width=0.742857pt, fill={rgb,255:red,143;green,236;blue,179}] (15.84,4.86) -- (15.96,4.86) -- (15.96,4.74) -- (15.84,4.74) -- cycle;
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (15.9,2.1) -- (15.9,1.6) -- (20.8,1.6) -- (20.8,0.4);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (12.8,3) -- (12.8,2.6);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.742857pt] (12.62,2.6) -- (12.98,2.6) -- (12.98,1.8) -- (12.62,1.8) -- cycle;
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (12.8,1.8) -- (12.8,1.4);
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,227;blue,107}] at (13.16,2.2) {R10 100k};
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (12.8,4.8) -- (12.8,3);
  \filldraw[draw={rgb,255:red,143;green,236;blue,179}, line width=0.742857pt, fill={rgb,255:red,143;green,236;blue,179}] (12.74,4.86) -- (12.86,4.86) -- (12.86,4.74) -- (12.74,4.74) -- cycle;
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (12.8,1.4) -- (14.4,1.4);
  \filldraw[draw={rgb,255:red,143;green,236;blue,179}, line width=0.742857pt, fill={rgb,255:red,143;green,236;blue,179}] (14.34,1.46) -- (14.46,1.46) -- (14.46,1.34) -- (14.34,1.34) -- cycle;
  \filldraw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.742857pt, fill={rgb,255:red,22;green,51;blue,72}] (19.6,0.4) -- (22,0.4) -- (22,-3.5) -- (19.6,-3.5) -- cycle;
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (20.8,-0.4) {USB 5V};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (20.8,-1.08) {气泵};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (20.8,-1.8) {+ / -};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (20.8,-2.8) {负载};
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (20.8,-3.5) -- (20.8,-9.4);
  \filldraw[draw={rgb,255:red,143;green,236;blue,179}, line width=0.742857pt, fill={rgb,255:red,143;green,236;blue,179}] (20.74,-9.34) -- (20.86,-9.34) -- (20.86,-9.46) -- (20.74,-9.46) -- cycle;
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (18.4,1.6) -- (18.4,-4.4);
  \filldraw[draw={rgb,255:red,143;green,236;blue,179}, line width=0.742857pt, fill={rgb,255:red,143;green,236;blue,179}] (18.34,1.66) -- (18.46,1.66) -- (18.46,1.54) -- (18.34,1.54) -- cycle;
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (18,-4.4) -- (18.8,-4.4);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (18.4,-4.4) -- (18,-5.2) -- (18.8,-5.2) -- (18.4,-4.4);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (18.4,-5.2) -- (18.4,-9.4);
  \filldraw[draw={rgb,255:red,143;green,236;blue,179}, line width=0.742857pt, fill={rgb,255:red,143;green,236;blue,179}] (18.34,-9.34) -- (18.46,-9.34) -- (18.46,-9.46) -- (18.34,-9.46) -- cycle;
  \node[anchor=east, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,227;blue,107}] at (17.8,-4.12) {K 条纹端};
  \node[anchor=east, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,227;blue,107}] at (17.8,-5.1) {D1 SS34};
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text=white] at (18.8,-5.9) {A → GND};
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (23.4,-0.6) -- (23.4,-1.24);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (23,-1.24) -- (23.8,-1.24);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (23,-1.56) -- (23.8,-1.56);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (23.4,-1.56) -- (23.4,-2.2);
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,227;blue,107}] at (23.9,-1.4) {C2};
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,227;blue,107}] at (23.9,-1.88) {10uF / 16V};
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (23.4,4.8) -- (23.4,-0.6);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (23.4,-2.2) -- (23.4,-9.4);
  \filldraw[draw={rgb,255:red,143;green,236;blue,179}, line width=0.742857pt, fill={rgb,255:red,143;green,236;blue,179}] (23.34,4.86) -- (23.46,4.86) -- (23.46,4.74) -- (23.34,4.74) -- cycle;
  \filldraw[draw={rgb,255:red,143;green,236;blue,179}, line width=0.742857pt, fill={rgb,255:red,143;green,236;blue,179}] (23.34,-9.34) -- (23.46,-9.34) -- (23.46,-9.46) -- (23.34,-9.46) -- cycle;
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (25.8,-4.6) -- (25.8,-5.24);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (25.4,-5.24) -- (26.2,-5.24);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (25.4,-5.56) -- (26.2,-5.56);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (25.8,-5.56) -- (25.8,-6.2);
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,227;blue,107}] at (26.3,-5.4) {C3};
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,227;blue,107}] at (26.3,-5.88) {100nF / 16V};
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (25.8,4.8) -- (25.8,-4.6);
  \draw[draw={rgb,255:red,40;green,215;blue,236}, line width=0.971429pt] (25.8,-6.2) -- (25.8,-9.4);
  \filldraw[draw={rgb,255:red,143;green,236;blue,179}, line width=0.742857pt, fill={rgb,255:red,143;green,236;blue,179}] (25.74,4.86) -- (25.86,4.86) -- (25.86,4.74) -- (25.74,4.74) -- cycle;
  \filldraw[draw={rgb,255:red,143;green,236;blue,179}, line width=0.742857pt, fill={rgb,255:red,143;green,236;blue,179}] (25.74,-9.34) -- (25.86,-9.34) -- (25.86,-9.46) -- (25.74,-9.46) -- cycle;
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,227;blue,107}] at (7.8,-10.4) {S8050 / S8550：图中按B/C/E接线；不同厂商SOT-23脚序先核对，不按丝印猜。};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (7.8,-11.2) {先用短按约0.1秒、间隔至少2秒试验；不保证长按、快速连按或电源跌落时的状态。};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=white] at (7.8,-12) {设计目标：5V / 连续1A，2A仅短时待验证。通用模型功能检查通过，实际气泵未上板验证。};
\end{tikzpicture}
```

### 物料清单

|位号|规格|数量与说明|
|---|---|---|
|Q1、Q3|S8050，NPN，SOT-23|2，已有；按具体厂商确认 B/C/E|
|Q2|S8550，PNP，SOT-23|1，已有；2TY 按此前物料更正记录|
|Q4|AO3401，P-MOS，SOT-23|1；G=1、S=2、D=3，焊接时核对封装方向|
|R1|2.2MΩ|1|
|R2、R3、R6|470kΩ|3|
|R4、R9|1kΩ|2|
|R5|47kΩ|1|
|R7|1MΩ|1|
|R8、R10|100kΩ|2|
|C1|1µF，16V|1，定时电容|
|C2|10µF，16V|1，输入去耦|
|C3|100nF，16V|1，输入高频去耦|
|S1|6×6mm 瞬时常开轻触开关|1；四个焊脚只有两组电气触点，先测通断|
|D1|SS34 肖特基二极管|1，需补充；条纹阴极 K 接气泵正极，阳极 A 接 GND|
|电源、负载|稳定 USB 5V 电源、USB 气泵|各1；电源可先选 5V/2A，气泵电流仍需实测|

电阻沿用现有 0603，电容沿用 1206；容值、耐压与实际可得物料核对。现有 1N4007 不直接视为满足本设计电流目标的等效替代。

### 工作过程与操作边界

关机时 C1 充电。第一次短按向 Q3 提供基极电流，Q2/Q3 正反馈保持导通，Q1 将定时节点拉低，Q4 栅极被拉低，气泵获得 5V。松开后 C1 经 R2 放电。第二次短按利用已放电的 C1 暂时拉低 Q3 基极，解除锁存；R10 将 Q4 栅极拉回源极，切断气泵供电。

先按**约 0.1 秒短按、两次操作间隔至少 2 秒**试验，上电后也先等 2 秒。R2×C1≈0.47 秒；关机充电路径 (R1+R2)×C1≈2.67 秒。它不是完整消抖控制器，**不保证长按、快速连按、慢上电或电源跌落时的状态**；若需要任意长按仍严格只翻转一次，需要另做消抖与单次触发设计。

### 功率与接线注意

- 设计检查目标为连续 1A、短时 2A，尚不是实物承载保证，也不是这只气泵的已知参数。典型值只能估算，启动电流应单独测量。
- AO3401 官方规格 VGS 极限为 ±12V，本电路 5V 驱动在其范围内；不可直接提高供电到 20V。其 RDS(on) 最大值为 60mΩ（VGS=-4.5V 测试条件），1A 时静态导通损耗估算约 0.06W，温升仍取决于铜面积、环境和器件状态。
- D1 并联在气泵供电端，正常运行时反偏，用于感性负载关断续流；它不提供过流保护。C2/C3 放在电源输入附近，泵电流走短、宽的回路，避免穿过锁存电路的细地线。
- 先用带限流电阻的 LED 检查开关状态，再接气泵；观察启动是否使锁存掉电、MOS 是否发热。不要用 STM32 的 3.3V 输出给气泵供电。

### 已完成的验证

采用通用 NPN/PNP 与简化 P-MOS 模型，在 5V、5Ω 电阻负载、120ms 按键脉冲且间隔 2 秒条件下运行瞬态仿真：

|采样时间|负载电压|状态|
|---|---|---|
|0.5s|约0V|初始关|
|1.5s|约4.96V|第一次按后开|
|3.5s|约0V|第二次按后关|
|5.5s|约4.96V|第三次按后开|
|7.5s|约0V|第四次按后关|

**仅证明所用模型和按键条件下能交替保持。** 模型不是器件厂商精确模型，负载不是实际电机；未验证电机启动、反电动势、按键抖动、全温范围与真实 USB 电源压降。实物测试通过前保留实验版标识。

### 参考与改动来源

原始来源链：[Anthony Smith 的 EDN 文章（2004）](https://www.edn.com/latching-power-switch-uses-momentary-action-pushbutton/) → [原始电路图](https://www.edn.com/wp-content/uploads/Fig_1_Latching-power-switch-w.pushbutton.gif) → 独立三晶体管锁存与按键定时网络 → 本图的 Q1/Q2/Q3、R1～R8、C1/S1。

本图把原负载开关级改为 AO3401，增加栅极上拉 R10 和气泵续流 D1，并为 5V 调整 R1=2.2MΩ、R5=47kΩ；这些改动只完成上述功能模型检查。功率管参数依据 [AO3401 官方数据手册](https://www.aosmd.com/res/data_sheets/AO3401.pdf)。本设计不依赖气泵输出电压维持锁存，但仍可能受输入电源扰动影响。
