新增:AT32F422KBT7 替换 AT32F421K8T7 固件迁移与硬件适配清单

This commit is contained in:
2026-07-21 17:53:46 +08:00
parent bf1d875fe7
commit 9a8521bd58
@@ -0,0 +1,706 @@
# AT32F422KBT7 替换 AT32F421K8T7 —— 固件迁移与硬件适配清单
**文档编号**MIG-AT32-422-001
**版本**V1.0
**日期**2026-07-21
**目标产品**SenseLoop™ ILD 系列环路车辆检测器(信号处理核)
---
## 目录
1. [芯片差异总览](#1-芯片差异总览)
2. [硬件适配 —— PCB 兼容性检查表](#2-硬件适配--pcb-兼容性检查表)
3. [引脚复用配置差异](#3-引脚复用配置差异)
4. [固件迁移 —— 启动与系统时钟](#4-固件迁移--启动与系统时钟)
5. [FPU 编译开关设置](#5-fpu-编译开关设置)
6. [固件迁移 —— 外设驱动检查表](#6-固件迁移--外设驱动检查表)
7. [ALP 分类器 —— 定点化回退到浮点的变更](#7-alp-分类器--定点化回退到浮点的变更)
8. [内存布局调整(Flash + SRAM](#8-内存布局调整flash--sram)
9. [迁移步骤时间线](#9-迁移步骤时间线)
10. [回归测试清单](#10-回归测试清单)
11. [附录:AT32F421 ↔ AT32F422 寄存器兼容性速查](#11-附录at32f421--at32f422-寄存器兼容性速查)
---
## 1 芯片差异总览
### 1.1 关键参数对比
| 参数 | AT32F421K8T7 | AT32F422KBT7 | 变化类型 | 迁移影响 |
|------|:------------:|:------------:|:---------|:---------|
| **内核** | ARM Cortex-M4(无 FPU | ARM Cortex-M4F**有 FPU** | ⭐ 架构级 | 编译选项 + ALP 模型浮点化 |
| **主频** | 120 MHz | **180 MHz** | 时钟树 | PLL 配置变更 |
| **Flash** | 64 KB | **128 KB** | 内存 | 链接脚本 + 分区调整 |
| **SRAM** | 16 KB | **20 KB** | 内存 | 链接脚本调整 |
| **ADC 采样率** | 2.0 M SPS | **2.5 M SPS** | 模拟外设 | 时序参数微调 |
| **高级定时器** | 16位 7通道 | **16位 8通道** | 定时器 | 无影响(只用 4 通道做捕获) |
| **DMA 通道** | 5 通道 | **7 通道** | DMA | 新增通道号可用,旧代码兼容 |
| **CAN 外设** | 无 | **有(CAN 2.0** | 新增 | 不用则不处理 |
| **备份寄存器** | 5 × 32位 | **20 × 32位** | RTC | 无影响 |
| **GPIO 数量** | 25 个(LQFP32 | **28 个(LQFP32** | I/O | 多出 3 个 GPIO(见引脚表) |
### 1.2 寄存器兼容性
**✅ 完全兼容(主要外设)**
- GPIO、USART、SPI、I²C、高级/通用定时器、基本定时器、SysTick、看门狗、RTC/ERTC
- DMA(通道 0~4 与 F421 一致,通道 5~6 为新增)
**⚠️ 有差异(需核对)**
- ADCF422 新增 2.5M SPS 模式,采样时间寄存器 T-SMPR 域的取值对应关系有变化
- PLL 配置:F422 最高 180 MHzVCO 范围不同,PLLMUL/PLLDIV 寄存器值需重新计算
- 电源管理:F422 新增低电压复位(LVR)阈值档位
**✅ 可选启用(F421 没有的)**:
- CAN 外设:如果不使用 CAN,无需配置
- 额外的 DMA 通道 5~6
---
## 2 硬件适配 —— PCB 兼容性检查表
### 2.1 封装与引脚
AT32F421K8T7LQFP32)与 AT32F422KBT7LQFP32)为**同一封装(7×7mmLQFP32**。
**✅ PCB 兼容性结论:PCB 不需要做任何修改。**
- 封装:完全一致(LQFP320.8mm pitch7×7mm
- 供电:同为 2.6~3.6V(推荐 3.3V),电源去耦电容不变
- 晶振:同为 4~25 MHz 主晶振 + 32.768 kHz RTC 晶振(可选)
### 2.2 供电与去耦
| 供电引脚 | AT32F421 | AT32F422 | 兼容性 |
|:---------|:---------|:---------|:-------|
| VDD / VSS | 2 对(LQFP32 | 2 对(LQFP32 | ✅ 完全一致 |
| VDDA / VSSA | 1 对(pin 13/14 | 1 对(pin 13/14 | ✅ 完全一致 |
| VREF+ / VREF- | 内部参考 | 内部参考 | ✅ |
| 去耦电容 | 0.1µF + 10µF 各引脚 | 同左 | ✅ 不变 |
### 2.3 晶振与时钟
| 元件 | 原设计 | 新设计 | 说明 |
|:-----|:-------|:-------|:-----|
| HEXT 主晶振 | 8 MHz(推荐) | 8 MHz(推荐) | 兼容,F422 推荐 4~16 MHz 配合 PLL 出 180 MHz |
| HEXT 负载电容 | 18 pF × 2 | 18 pF × 2 | ✅ 不变 |
| LEXT RTC 晶振 | 32.768 kHz(可选) | 32.768 kHz(可选) | ✅ 不变 |
**注意**F422 最高 180 MHz,若主晶振原为 8 MHz
- PLL 配置:8 MHz × 45 / 2 = 180 MHzF421 是 8 MHz × 15 = 120 MHz
- 如果原来用的 16 MHz 晶振:16 MHz × 45 / 4 = 180 MHz(需核对 PLL 分频比)
### 2.4 新增 GPIO 的利用建议
F422KBT7LQFP32)相比 F421K8T7LQFP32**多出 3 个 GPIO**,具体为 F421 没有引出的 NC 脚在 F422 上被赋予了 GPIO 功能。
> **实际增加的 GPIO 引脚号需以官方数据手册(Datasheet)引脚定义表为准**。建议拿到 F422 的 datasheet 后,逐脚对照 F421 的引脚定义,找出多出的 3 个 GPIO。
**推荐用途**(按优先级):
| 优先级 | 用途 | 理由 |
|:------:|:-----|:-----|
| 1 | **SPI FlashW25Qxx)时钟线** | 用于存储 ALP 分类模型参数/固件升级包,Flash 256KB→128KB 的冗余 |
| 2 | **外部看门狗触发** | 独立硬件看门狗(如 TPL5010)的 WDI 输入,增强可靠性 |
| 3 | **蜂鸣器/状态音** | 调试/故障时声音提示 |
---
## 3 引脚复用配置差异
### 3.1 主要外设的 AFIO 映射对照
以下列出信号处理核**关键外设**的 AFIO 复用功能映射,确认 F422 与 F421 一致:
| 外设功能 | F421 引脚 | F422 引脚 | 兼容性 |
|:---------|:----------|:----------|:-------|
| **USART1_TX** | PA9 (AF7) | PA9 (AF7) | ✅ |
| **USART1_RX** | PA10 (AF7) | PA10 (AF7) | ✅ |
| **USART2_TX** | PA2 (AF7) | PA2 (AF7) | ✅ |
| **USART2_RX** | PA3 (AF7) | PA3 (AF7) | ✅ |
| **TIM1_CH1**(捕获) | PA8 (AF1) | PA8 (AF1) | ✅ |
| **TIM1_CH2**(捕获) | PA9 (AF1) | PA9 (AF1) | ✅ |
| **TIM1_CH3**(捕获) | PA10 (AF1) | PA10 (AF1) | ✅ |
| **TIM1_CH4**(捕获) | PA11 (AF1) | PA11 (AF1) | ✅ |
| **ADC1_IN0** | PA0 | PA0 | ✅ |
| **ADC1_IN1** | PA1 | PA1 | ✅ |
| **ADC1_IN2** | PA2 | PA2 | ✅ |
| **ADC1_IN3** | PA3 | PA3 | ✅ |
| **SWDIO** | PA13 | PA13 | ✅ |
| **SWCLK** | PA14 | PA14 | ✅ |
| **NRST** | NRST | NRST | ✅ |
> **结论**:F421 已使用的所有外设引脚在 F422 上完全一致,**AFIO 编号和复用功能无变化**。原有 GPIO 配置代码无需修改。
### 3.2 复用功能冲突检查
| 潜在冲突点 | F421 配置 | F422 配置 | 结论 |
|:-----------|:---------|:---------|:-----|
| PA9 = USART1_TX vs TIM1_CH2 | 同时使用? | 同 | AFIO 可配置,不同时使能即可 |
| PA10 = USART1_RX vs TIM1_CH3 | 同时使用? | 同 | AFIO 可配置,不同时使能即可 |
| PA2 = USART2_TX vs ADC1_IN2 | 分时复用 | 同 | USART 在初始化前禁用 ADC,无冲突 |
| PA3 = USART2_RX vs ADC1_IN3 | 分时复用 | 同 | 同上 |
**结论:无新增冲突,原 F421 的 AFIO 配置完好继承。**
---
## 4 固件迁移 —— 启动与系统时钟
### 4.1 PLL 配置变更
**F421120 MHz 配置,8 MHz HEXT**
```c
/* AT32F421 PLL: 8MHz × 15 = 120MHz */
Crm pll_init(CRM_PLL_SOURCE_HEXT, 0, 0, 0, 15); /* 参数: src, usb_div, pll_div, pll_r, pll_mul */
/* 或直接操作寄存器 */
CRM->PLL_CTRL = CRM_PLL_SOURCE_HEXT | (15 << CRM_PLL_MUL_SHIFT);
```
**F422180 MHz 配置,8 MHz HEXT**
```c
/* AT32F422 PLL: 8MHz × 45 / 2 = 180MHz */
/* 注意 F422 的 PLL 结构有分频器 PLL_div */
Crm pll_init(CRM_PLL_SOURCE_HEXT, CRM_PLL_USB_DIV_2, CRM_PLL_DIV_2, CRM_PLL_R_2, 45);
/* 参数: src, usb_div, pll_div, pll_r, pll_mul */
```
**详细 PLL 寄存器差异**
| 寄存器域 | F421 | F422 | 说明 |
|:---------|:-----|:-----|:-----|
| PLL_MUL | 2~16(仅整数倍) | 2~63(更精细) | F422 支持非整数?不,是 63 倍以内 |
| PLL_DIV | 无 | 有(/2, /4 | **F422 新增分频级**,关键变化 |
| PLL_USB_DIV | 固定 48MHz | 可配置 /2 等 | USB 时钟源可选 |
| 最大输出 | 120 MHz | 180 MHz | 需确保 HCLK ≤ 180 MHz |
**⚠️ 关键提醒**
- F422 的 PLL 输出需要经过 `PLL_DIV` 分频后才能达到 HCLK,不能直接倍频到 180 MHz
- 建议使用雅特力 BSP 中的 `system_clock_config()` 函数(BSP 已包含正确的 PLL 配置)
### 4.2 AHB/APB 总线分频
| 总线 | F421 推荐 | F422 推荐 | 说明 |
|:-----|:----------|:----------|:-----|
| **HCLK**AHB | 120 MHz | **180 MHz** | CPU 核心供电 |
| **PCLK1**APB1 | 60 MHz (÷2) | **90 MHz (÷2)** | ≤ 90 MHz 上限 |
| **PCLK2**APB2 | 120 MHz (÷1) | **180 MHz (÷1)** | ≤ 180 MHz 上限 |
| **ADCCLK** | 14 MHz (÷8) | **14 MHz (÷12)** | ADC 时钟 ≤ 14 MHz (2.5M SPS) |
**代码示例(system_at32f422.c**
```c
void system_clock_config(void)
{
/* 1. 复位 PLL */
CRM->CTRL &= ~CRM_CTRL_PLLEN;
while (CRM->CTRL & CRM_CTRL_PLLSTB);
/* 2. 配置 PLL */
CRM->PLL_CTRL = CRM_PLL_SOURCE_HEXT /* HEXT 作为 PLL 源 */
| CRM_PLL_DIV_2 /* PLL 分频 ÷2 */
| (45 << CRM_PLL_MUL_SHIFT) /* 倍频 ×45 */
| CRM_PLL_USB_DIV_2; /* USB 时钟分频 */
/* 3. 等待 PLL 锁定 */
CRM->CTRL |= CRM_CTRL_PLLEN;
while (!(CRM->CTRL & CRM_CTRL_PLLSTB));
/* 4. 设置总线分频 */
CRM->CFG = CRM_CFG_AHBDIV_1 /* AHB = HCLK = 180 MHz (实际是 sysclk/1) */
| CRM_CFG_APB1DIV_2 /* APB1 = 90 MHz */
| CRM_CFG_APB2DIV_1; /* APB2 = 180 MHz */
/* 5. ADC 时钟分频(在 ADC 初始化中设置) */
/* ADC 时钟 = PCLK2 / (ADC 分频系数) = 180 / 12.86 ≈ 14 MHz */
}
```
### 4.3 Flash 等待周期
| 频率 | F421 等待周期 | F422 等待周期 |
|:----|:-------------|:-------------|
| ≤ 48 MHz | 0 wait | 0 wait |
| ≤ 72 MHz | 1 wait | 1 wait |
| ≤ 120 MHz | 2 wait | 2 wait |
| ≤ 180 MHz | N/A | **3 wait** |
**代码**
```c
/* F422: 180 MHz 需要 3 个等待周期 */
CRM->CTRL |= 3 << CRM_CTRL_FLASH_WAIT_SHIFT;
```
### 4.4 启动文件(Startup)更换
- F421 启动文件:`startup_at32f421.s`(来自 AT32F421 BSP
- F422 启动文件:`startup_at32f422.s`(来自 AT32F422 BSP
**必须更换**,因为中断向量表不同(F422 新增 CAN/额外 DMA 等中断向量)。
**关键变更**:F422 的中断号在 NVIC 中后移了,如果代码中有直接操作 NVIC 优先级分组的固化值,需按新向量表调整。
---
## 5 FPU 编译开关设置
### 5.1 编译器设置
#### ARMCCKeil MDK
**Step 1Target 选项卡**
```
Options for Target → Target → Floating Point Hardware:
[ ] Not used
[x] Use Single Precision ← 选择此项
[ ] Use Double Precision
```
**Step 2C/C++ 编译器选项**
`C/C++ (AC6)` 选项卡的 Misc Controls 中添加:
```
-mfloat-abi=hard
-mfpu=fpv4-sp-d16
```
或在 `C/C++` 选项卡 Define 中添加:
```
__FPU_PRESENT=1
ARM_MATH_CM4 ← 如果有使用 CMSIS-DSP
```
**Step 3:启动文件**
确保启动文件 `startup_at32f422.s` 中的 `FPU` 初始化代码未被注释掉(通常在 Reset_Handler 开头):
```asm
; Enable FPU (在 Reset_Handler 中)
LDR R0, =0xE000ED88
LDR R1, [R0]
ORR R1, R1, #(0xF << 20) ; CP10, CP11 全权限
STR R1, [R0]
DSB
ISB
```
#### GCCARM GCC / AT32 IDE
**CFLAGS 中添加**
```makefile
# 打开 FPU 和浮点 ABI
CFLAGS += -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard
# CMSIS-DSP 库(如果使用)
CFLAGS += -DARM_MATH_CM4 -D__FPU_PRESENT=1
# 链接器 flags
LDFLAGS += -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard
# ASM flags(汇编器也需要 FPU 支持)
ASFLAGS += -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard
```
#### IAR Embedded Workbench
```
Options → General Options → Target → FPU:
[ ] None
[x] Single precision (VFPv4) ← 选择此项
```
### 5.2 CMSIS-DSP 库启用
如果 ALP 分类器中使用了 CMSIS-DSP 的数学函数(如向量乘加):
```c
/* 包含 CMSIS-DSP 头 */
#include "arm_math.h"
/* FPU 启用状态下,arm_math.h 会自动使用硬件浮点指令 */
/* 浮点 MAC 示例:*/
float32_t w[15]; /* 神经网络权重 */
float32_t x[7]; /* 输入特征 */
float32_t sum = 0.0f;
/* CMSIS 优化的浮点矩阵乘 */
arm_dot_prod_f32(w, x, 7, &sum); /* 硬件 FPU 加速 */
```
**对比**:在没有 FPU 的 F421 上,同样的 `arm_dot_prod_f32()` 由软件模拟浮点库完成(~50 周期/次 MAC),在 F422 上的硬件 FPU 单周期完成 MAC——**提速约 50 倍**。
### 5.3 编译后验证
在编译完成后,检查生成的 map 文件或反汇编确认 FPU 指令已启用:
```bash
# 从生成的 .elf 或 .axf 中检查 FPU 指令
arm-none-eabi-objdump -d firmware.elf | grep -E "vldr|vstr|vadd|vmul|vdiv" | head -20
```
如果有 `vldr``vstr``vadd.f32``vmul.f32` 等指令输出,说明 FPU 已正确启用。
### 5.4 浮点性能对比(F421 vs F422
| 运算 | F421(无FPU,软件浮点) | F422FPU 启用) | 加速比 |
|:----|:----------------------:|:----------------:|:------:|
| float32 加法 | ~45 周期 | **1 周期** | **45×** |
| float32 乘法 | ~50 周期 | **1 周期** | **50×** |
| float32 MAC(乘加) | ~80 周期 | **1 周期** | **80×** |
| BP 推理(3×15 网络) | ~6000 周期 @ 120MHz = 50µs | **~120 周期 @ 180MHz = 0.67µs** | **75×** |
> ALP 分类时间从 50µs 降到 0.67µs,对整个检测周期来说可以忽略不计。
---
## 6 固件迁移 —— 外设驱动检查表
### 6.1 DMA 通道映射变更
| DMA 请求 | F421 通道 | F422 通道 | 兼容性 |
|:---------|:---------:|:---------:|:------|
| TIM1_UP | DMA1_CH1 | DMA1_CH1 | ✅ |
| ADC1 | DMA1_CH2 | DMA1_CH2 | ✅ |
| USART1_TX | DMA1_CH3 | DMA1_CH3 | ✅ |
| USART1_RX | DMA1_CH4 | DMA1_CH4 | ✅ |
| USART2_TX | DMA1_CH5 | **DMA1_CH5** | ✅(F421 也有 CH5,只是 F422 扩展了) |
| SPI1_TX | — | **DMA1_CH6(新增)** | ✨ 可选启用 |
**⚠️ 注意**:原 F421 代码中如果使用了 DMA_CH5,请确认此通道的硬件请求映射在 F422 上是否有变化(建议查阅 F422 DMA 请求映射表)。
### 6.2 定时器
| 定时器 | F421 | F422 | 差异 |
|:-------|:----:|:----:|:-----|
| **TMR1(高级)** | 1 个(7 通道 PWM | 1 个(**8 通道 PWM**) | +1 通道,但不影响现有代码 |
| **TMR2~TMR5(通用)** | 4 个 | 4 个 | ✅ 相同 |
| **TMR6/7(基本)** | 1 个 | 1 个(TMR6 | ✅ |
| **TMR14** | 1 个 | 1 个 | ✅ 相同 |
**结论**:原 F421 使用 TIM1_CH1~4 做输入捕获,TIM2~5 做其他用途,移到 F422 无任何差异。
### 6.3 ADC
| ADC 参数 | F421 | F422 | 迁移操作 |
|:---------|:----:|:----:|:---------|
| ADC 通道数 | 15 | 15 | ✅ 无变化 |
| ADC 分辨率 | 12/10/8/6 位 | 12/10/8/6 位 | ✅ 无变化 |
| 最大采样率 | 2.0 M SPS | **2.5 M SPS** | 若需要更高速率,调整采样时间 |
| ADC 时钟源 | PCLK2 分频 | PCLK2 分频 | PCLK2 由 120 变为 180 MHz,分频系数需调整 |
| 采样时间寄存器 | 相同 | 相同 | ✅ |
| 转换序列 | 相同 | 相同 | ✅ |
**ADC 时钟调整示例**
```c
/* F421: PCLK2 = 120 MHz, 14 MHz ADCCLK = 120/8.57 */
CRM->ADC_CLK_CTRL = CRM_ADC_DIV_8;
/* F422: PCLK2 = 180 MHz, 14 MHz ADCCLK = 180/12.86 */
CRM->ADC_CLK_CTRL = CRM_ADC_DIV_12; /* 或 DIV_14,需最接近 14MHz 的值 */
```
### 6.4 USART
| 参数 | F421 | F422 | 兼容性 |
|:-----|:----:|:----:|:-------|
| USART 数量 | 2 | 2 | ✅ |
| USART1 基址 | 0x4001_3800 | 0x4001_3800 | ✅ |
| USART2 基址 | 0x4000_4400 | 0x4000_4400 | ✅ |
| 寄存器结构 | 相同 | 相同 | ✅ |
**结论**USART 驱动代码零修改。
---
## 7 ALP 分类器 —— 定点化回退到浮点的变更
### 7.1 背景
AT32F421(无 FPU)上,ALP 分类器的 BP 神经网络权重从 float32 手工量化为 **Q15 定点格式**,用整数乘加 + 移位模拟浮点运算。
AT32F422(有 FPU)上,可以直接使用 **float32** 原值,精度更高,代码更简单。
### 7.2 变更清单
| 文件/函数 | F421 定点版本 | F422 浮点版本 | 改动量 |
|:----------|:--------------|:--------------|:------|
| `model_weights.h` | Q15 量化数组 | **float32 数组** | 全量替换 |
| `model_forward()` | 手工定点乘加移位 | **arm_dot_prod_f32()** | 函数重写 |
| `feature_extract()` | Q15 输出 | **float32 输出** | 类型变换 |
| `classify()` | Q15 比较阈值 | **float32 比较阈值** | 类型变换 |
### 7.3 定点 → 浮点代码对比
```c
/* ============ F421 定点版本(Q15 ============ */
#define Q15_ONE 32768
#define Q15_HALF 16384
/* 量化权重(在训练时生成) */
const q15_t w_hidden[7*15] = {
0x1234, 0x5678, /* ... */ /* Q15 格式 */
};
/* 手工定点 MAC */
int32_t sum = 0;
for (int i = 0; i < 7; i++) {
sum += (int32_t)x_q15[i] * w_hidden[j * 7 + i];
}
/* 移位恢复 */
q15_t out = (q15_t)(sum >> 15);
```
```c
/* ============ F422 浮点版本(FPU ============ */
const float32_t w_hidden[7*15] = {
0.5678f, 0.1234f, /* ... */ /* float32 原值 */
};
/* CMSIS-DSP 浮点 MAC */
float32_t sum;
arm_dot_prod_f32(x_f32, &w_hidden[j * 7], 7, &sum);
/* 或直接用 C 编译器内置浮点(编译器会生成 FPU 指令) */
sum = 0.0f;
for (int i = 0; i < 7; i++) {
sum += x_f32[i] * w_hidden[j * 7 + i];
}
```
### 7.4 精度对比
| 指标 | F421 Q15 定点 | F422 float32 浮点 |
|:-----|:-------------:|:-----------------:|
| 权重精度 | ~15 位有效位 | ~23 位有效位 |
| 累积误差 | 157 次 MAC 后误差 ≈ Q15_LSB | 无累积误差 |
| 分类准确率(13 类) | ≥ 90% | **≥ 92%**(预计提升 1~2% |
| 推理时间 @ 对应主频 | ~50 µs | **~0.7 µs** |
---
## 8 内存布局调整(Flash + SRAM
### 8.1 Flash 分区(链接脚本变更)
**F42164KB Flash)—— 原版**
```
MEMORY
{
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 64K
SRAM (rw) : ORIGIN = 0x20000000, LENGTH = 16K
}
```
典型占用(以 F421 全功能固件为例):
| 分区 | 大小 | 用途 |
|:-----|:----:|:-----|
| Bootloader | 8 KB | OTA 升级引导 |
| App 固件 | ~48 KB | 信号处理 + ALP + 通信 |
| 配置参数 | 4 KB | EEPROM 模拟页 |
| 模型权重 | 4 KB | Q15 量化 BP 权重 |
| **总占用** | **~64 KB** | **100% 填满** |
**F422128KB Flash)—— 新版**
```
MEMORY
{
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 128K
SRAM (rw) : ORIGIN = 0x20000000, LENGTH = 20K
}
```
建议分区:
| 分区 | 大小 | 用途 | 备注 |
|:-----|:----:|:-----|:-----|
| Bootloader | 8 KB | OTA 升级引导 | 不变 |
| **更新缓冲** | **32 KB** | OTA 双 Bank 升级 | 新分区 |
| App 固件 | 64 KB | 信号处理 + ALP + 通信 | 空间翻倍 |
| 配置参数 | 8 KB | EEPROM 模拟页 | 翻倍 |
| 模型权重 | 8 KB | float32 BP 权重 + 备选模型 | 翻倍 |
| OTP(硬件) | 1 KB | 设备序列号/密钥 | F422 新增硬件 |
| **总占用** | **~120 KB** | **还剩 8 KB** | 不再紧张 |
### 8.2 SRAM 使用规划
**F42116KB SRAM)—— 原版**
| SRAM 使用 | 大小 | 说明 |
|:----------|:----:|:-----|
| FreeRTOS 堆 + 任务栈 | 6 KB | 4 个任务 |
| 波形缓冲区(4ch 循环) | 4 KB | 1 KB/通道 × 4 |
| ALP 推理工作区 | 2 KB | Q15 运算中间变量 |
| 通信缓冲区 | 2 KB | Modbus / UART 收发 |
| 其他 | 2 KB | 全局变量/调试 |
| **总计** | **16 KB** | **100% 填满** |
**F42220KB SRAM)—— 新版**
| SRAM 使用 | 大小 | 说明 |
|:----------|:----:|:-----|
| FreeRTOS 堆 + 任务栈 | 6 KB | 不变(够用) |
| 波形缓冲区(4ch 独立) | **8 KB** | **翻倍,2 KB/通道 → 更高采样深度** |
| ALP 推理工作区 | 4 KB | 浮点运算 + 中间变量 |
| 通信缓冲区 | 2 KB | 不变 |
| **剩余** | **4 KB** | 可用于更精细的波形分析 |
| **总计** | **20 KB** | **有 4 KB 余量** |
---
## 9 迁移步骤时间线
```
阶段 1:环境准备(1 天)
├── 获取 AT32F422 BSP + Datasheet + Reference Manual
├── 安装/更新 Keil/GCC Pack for AT32F422
├── 确认 AT32F422 样品到货
└── 创建新工程目录(复制 F421 工程,修改 target 为 F422
阶段 2:时钟与启动移植(0.5 天)
├── 更换启动文件 startup_at32f422.s
├── 修改 PLL 配置(8MHz × 45 / 2 = 180MHz
├── 修改 Flash 等待周期(3 wait
├── 修改总线分频(AHB=1, APB1=2, APB2=1
└── 验证:LED 闪烁(确认系统时钟正确)
阶段 3:FPU 启用 + 最小验证(0.5 天)
├── 打开 FPU 编译开关(-mfloat-abi=hard -mfpu=fpv4-sp-d16
├── 编写浮点计算测试(如 float a = 1.1f * 2.2f
├── 反汇编确认 FPU 指令生成
└── 验证:FPU 运算结果正确
阶段 4:外设驱动验证(1.5 天)
├── GPIO → LED 测试
├── USART1/2 → 回环测试
├── 定时器(TIM1_CH1~4 捕获)→ 信号源测试
├── ADC1(4 通道)→ 波形采集测试
├── DMA → USART + ADC 传输测试
└── 验证:各外设功能与 F421 一致
阶段 5:应用层迁移(1 天)
├── 替换链接脚本(128KB + 20KB 内存映射)
├── 调整 Flash 分区(增加 OTA 双 Bank 分区)
├── ALP 模型:Q15 → float32 浮点回退
├── 定点 MAC → arm_dot_prod_f32() 或原生 C 浮点
└── 验证:与 F421 输出的检测结果一致(±0.1% 以内)
阶段 6:整机回归测试(2 天)
├── 功能测试(见第 10 章回归测试清单)
├── 运行 48 小时老化
├── 对比 F421 与 F422 的检测结果一致性
└── 确认迁移完成
预计总耗时:6.5 人·天
```
---
## 10 回归测试清单
### 10.1 功能测试
| 测试项 | 通过条件 | F421 基准 | F422 实测 |
|:-------|:---------|:---------:|:---------:|
| 存在检测(标准轿车) | 通过率 ≥ 99.9% @ 5~200 km/h | ✅ | ☐ |
| 摩托车检测 | 灵敏度 ≤ 5 级可靠触发 | ✅ | ☐ |
| 响应时间 | ≤ 8 ms @ 灵敏度 7 | ✅ | ☐ |
| 速度测量精度 | ±1%(双环)/ ±0.5%(四环) | ✅ | ☐ |
| ALP 分类准确率 | ≥ 95%5+1/ ≥ 90%13 类) | ✅ | ☐ |
| 方向逻辑 | 正反向正确识别 | ✅ | ☐ |
| 尾随检测 | 间距 ≤ 0.5s 正确区分 | ✅ | ☐ |
| 抗锁定 | 超时后自动释放 | ✅ | ☐ |
| 连续 48h 运行 | 无死机/误触发 | ✅ | ☐ |
### 10.2 功耗测试
| 测试项 | 规格 | F421 基准 | F422 实测 |
|:-------|:----:|:---------:|:---------:|
| 运行功耗(180MHz / 120MHz | ≤ 2 W | 1.8 W | ☐ |
| 待机电流 | ≤ 10 mA | 8.5 mA | ☐ |
| 睡眠模式 | ≤ 500 µA | 420 µA | ☐ |
> F422 在 180 MHz 全速运行的理论功耗会比 F421 120 MHz 高 30~50%。需要实测确认是否超出 ≤ 2W 的规格上限。若超标,可考虑降频到 120 MHz 运行,同时保留 FPU 优势。
### 10.3 EMC 快速扫描
| 测试项 | 等级 | F421 基准 | F422 实测 |
|:-------|:----:|:---------:|:---------:|
| 辐射发射(30~230 MHz | Class A 限值 | 余量 ≥ 6 dB | ☐ |
| 传导发射(150 kHz~30 MHz | Class A 限值 | 余量 ≥ 4 dB | ☐ |
> 主频升到 180 MHz 后,辐射发射可能比 120 MHz 增大(E ∝ f²,理论上辐射增加约 3~4 dB)。需确认 PCB 布局已做好 EMC 设计后再投产。
---
## 11 附录:AT32F421 ↔ AT32F422 寄存器兼容性速查
### 11.1 相同寄存器(零修改)
| 外设 | 基址 | 寄存器结构 | 兼容性说明 |
|:-----|:----:|:----------|:----------|
| **GPIOA~C** | 0x4001_0800~ | 相同 | ✅ |
| **USART1** | 0x4001_3800 | 相同 | ✅ |
| **USART2** | 0x4000_4400 | 相同 | ✅ |
| **SPI1** | 0x4001_3000 | 相同 | ✅ |
| **I2C1** | 0x4000_5400 | 相同 | ✅ |
| **TMR1** | 0x4001_2C00 | 相同(F422 多 1 通道) | ✅ |
| **TMR2~5** | 0x4000_0000~ | 相同 | ✅ |
| **TMR6** | 0x4000_0400 | 相同 | ✅ |
| **WDT** | 0x4000_3000 | 相同 | ✅ |
| **WWDT** | 0x4000_2C00 | 相同 | ✅ |
| **SysTick** | 0xE000_E010 | 相同 | ✅ |
| **NVIC** | 0xE000_E100 | 相同(中断号多 16 个) | ⚠️ 若硬编码中断号需调整 |
### 11.2 有差异的寄存器(需核对/修改)
| 寄存器 | 地址 | F421 | F422 | 修改操作 |
|:-------|:----:|:-----|:-----|:---------|
| **CRM_CTRL** | 0x4002_1000 | 含 PLLEN、HICKEN | 新增 LVR 控制位 | 检查 LVR 配置 |
| **CRM_CFG** | 0x4002_1004 | AHBDIV[3:0], APB1/2DIV | 同位,域宽可能不同 | 确认分频值 |
| **CRM_PLL_CTRL** | 0x4002_1008 | PLL_MUL[3:0] 等 | **新增 PLL_DIV 位域** | **必须修改 PLL 配置** |
| **CRM_ADC_CLK_CTRL** | 0x4002_101C | 8 分频 | **更多分频选项** | 选择最接近 14 MHz 的分频 |
| **ADC1_SMPR** | 0x4001_240C | 采样时间域 | 相同位域,但 2.5M SPS 对应的 SMP 值不同 | 核对 SMP 取值 |
| **IVT(中断向量表基址)** | 0x0800_0000 | 60 个中断 | **76 个中断**(+16 个新增) | 更换启动文件即可 |
### 11.3 新增寄存器(可选使用)
| 外设 | 基址 | 说明 |
|:-----|:----:|:-----|
| **CAN** | 0x4000_6400 | F421 无,F422 新增 CAN 2.0 |
| **DMA1_CH5~6** | 0x4002_00B0~ | F421 只有 CH1~5F422 扩展了 CH 配置 |
---
## 附录:快速决策树
```
开始迁移
├─ PCB 是否需要修改? → ❌ 不需要(pin2pin 兼容)
├─ 启动文件和 PLL 是否需要改? → ✅ 是(更换 startup + PLL 配置 + Flash wait
├─ FPU 是否需要启用? → ✅ 强烈建议(编译 + startup 修改)
├─ ALP 模型是否需要重写? → ✅ 定点 → 浮点回退(推荐,精度更高)
├─ 链接脚本是否需要改? → ✅ 是(FLASH 64K→128K, SRAM 16K→20K
├─ ADC 时钟是否需要调? → ✅ 是(PCLK2 120→180MHz,分频变)
├─ USART/定时器/DMA 需要改? → ❌ 不需要(寄存器兼容)
├─ CAN 外设需要配置? → ⬜ 可选(不使用则跳过)
└─ EMC 是否需要重测? → ✅ 建议(主频升 50% 辐射可能增大)
```
---
*文档版本:V1.0 / 2026-07-21*
*目标芯片:AT32F421K8T7 → AT32F422KBT7 迁移*