日期: 2026-11-04
类型: 测试记录
项目: CloseLoop_AlphaV3_2
固件版本: 59 号(1103 海林版)+ 高速三相 ADC 自动抓拍
2026-11-04 高速三相 ADC 自动抓拍(验证"电流采样窗口"猜想)
一句话结论:59 号程序加了自动抓拍。车进入高速段(前进、转速 ≥ 1500 rpm 连续 0.5 s)后,自动记录 400 个 PWM 周期(约 27 ms)的三相 ADC 原始值、CC1~CC3 和电角度,记完自动从 CAN 0x4F0~0x4F4 发出。之后每隔约 4 s 再抓一次,不需要发任何 CAN 命令。SIL 已验证整条链路能跑通。实车只要照常录 ASC,交给 Claude 解码即可。
为什么要抓
- 猜想:高速时最大占空比相的下管导通时间很短。再扣掉死区 2.0 µs,采样时运放还没稳定,读数偏小,电流环被"骗"了。详见 [[2026-11-04_工况数据与小模型标定]] 第三步。
- 死区设置:现在 59 号
deadtime = 205 ≈ 2.0 µs;9 月能跑 2800 rpm 的老程序 V7.6 是 192 ≈ 1.42 µs。PWM 周期、采样点(CH4 = 5989,下管窗口正中)两版相同。
- 采样前的稳定时间 = 下管窗口的一半 − 死区。最大相占空比 90 % 时只剩 1.3 µs(老程序 1.9 µs);93 % 时只剩 0.3 µs;94 % 以上采样时下管还没导通。
固件改动(只加诊断,不改任何控制参数)
| 文件 |
改动 |
| [pwm_capture.inc](<file:///D:/Users/12078/at32ide-workspace3/CloseLoop_AlphaV3_2/AT32M412CBT7_YC_MCU_0612/project/AT32_IDE/user/APP/app/pwm_capture.inc>)、[pwm_capture.h](<file:///D:/Users/12078/at32ide-workspace3/CloseLoop_AlphaV3_2/AT32M412CBT7_YC_MCU_0612/project/AT32_IDE/user/APP/app/pwm_capture.h>) |
新增:触发、记录、分帧发送 |
| task.c |
加 include;200 µs 任务里先调 pwm_capture_service() |
| control_pipeline.inc |
FOC 计算前读本次生效的 CC1~CC3,计算后记一条 |
| .cproject、Debug/makefile |
去掉 -u _printf_float(程序里没有用 %f 打印),腾出 Flash |
- 编译:Flash 112.7 KB / 122 KB(剩约 12 KB),RAM 剩约 3 KB,无警告。
- 烧录文件:[AT32M412CBT7_WorkBench_59_PwmCap_20261104.hex](<file:///D:/Users/12078/at32ide-workspace3/CloseLoop_AlphaV3_2/AT32M412CBT7_YC_MCU_0612/project/AT32_IDE/Debug/>)
- 改之前的备份:📂 [bak_capture](<file:///C:/Users/12078/AppData/Local/Temp/claude/3f3d7f858c3082ff/d75ac5ba-e6a4-4f46-89cb-b0af5b4c3a30/scratchpad/bak_capture/>)(task.c、control_pipeline.inc、can.c、at32m412_416_int.c、makefile、cproject.xml)
- 存储借用开机零偏标定的
g_calib_raw_u/v/w(6 KB)。这块缓冲区平时被起步交接诊断(0x480~0x48E)借用,抓拍时让出:本次起步的交接诊断数据会被丢弃,发完再还给交接诊断。
- 每次发送约 940 帧,1 帧/ms,约 1 s 发完,总线负载增加约 26 %(500 kbps)。ID 0x4F0~0x4F4 优先级低,不影响其他报文。
- 可调宏(
pwm_capture.inc 开头):触发转速 PWM_CAP_TRIG_RPM 1500、持续 0.5 s、两次间隔 3 s、周期数 400。
报文格式(大端)
| ID |
内容 |
| 0x4F0 |
抓拍编号、周期数、U 零偏、V 零偏 |
| 0x4F2 |
抓拍编号、W 零偏、触发时转速 rpm、母线电压 ×100 |
| 0x4F4 |
抓拍编号、Iq 指令 ×100、Iq 实测 ×100、Id 实测 ×100 |
| 0x4F1 |
帧序号 + 3 个字。每周期 7 个字:U/V/W 原始值(低 12 位,高位放序号、饱和、桥臂、母线标志)、CC1~CC3、电角度 |
| 0x4F3 |
抓拍编号、累加和、发送失败次数、漏周期次数 |
实车测试步骤
- 烧
..._59_PwmCap_20261104.hex。
- 开始录 ASC,然后照常跑:经济模式满把到平台,保持 10 s 以上;动力模式中油门、满把到平台,各保持 10 s 以上。
- 每到平台都会自动抓拍,约每 4 s 一次,不用做任何操作。停车前多跑几秒,让最后一次发完。
- 把 ASC 交给 Claude;或者自己运行:
python D:\Users\12078\at32ide-workspace3\tools\pwm_cap_decode.py 记录.asc
- 解码脚本:[pwm_cap_decode.py](<file:///D:/Users/12078/at32ide-workspace3/tools/pwm_cap_decode.py>)。每次抓拍输出一个 CSV,屏幕打印"最大占空比那一相读数 / 另外两相反推值"的分档表。
怎么判断
- 三相电流之和理论上是 0。最大占空比相的读数如果偏小,用另外两相反推它的真实值,比值就会小于 1。
- 比值在"稳定时间 < 约 1 µs"那几档明显小于 1 → 采样窗口猜想成立,下一步考虑:按扇区挑选下管导通时间长的两相、调采样时刻,或者和硬件确认死区能否减小。
- 各档比值都接近 1 → 采样没问题,"指令大、实际小"另找原因(电压波动、抗饱和等)。
SIL 验证(2026-11-04)
- 11-4 实车数据回放,固件版本含抓拍。
- 经济满把自动抓到 6 次,动力满把自动抓到 8 次。校验全部通过,漏周期 0。动力模式有 1 帧丢失:SIL 写日志时两条报文混进了同一行,属于仿真日志的问题;解码脚本正确报出了"校验不通过"。
- 动力满把时最大占空比 94~95 %。按 SIL 预设的 5 µs 窗口模型:稳定时间 < 0 µs 那档比值 0.73,0~0.5 µs 档 0.94,其余各档约 1.01。说明解码和判断方法能识别读数偏小。实车结果要看真实数据。
- 回放时发现
drive_mode.inc 已改成经济 1800 / 动力 2400 rpm(11-04 14:31 修改)。所以触发转速定为 1500,两种模式都能触发。
- 加了
SIL_CANLOG=<路径> 环境变量,sil_drive 可以把全部 CAN 报文写成 ASC。
第一份台架数据(11-04 16:19)
📂 [台架/00.asc](<file:///D:/01-英创汇智文件/01测试数据/01-我的测试数据/11-4/台架/00.asc>),空载台架,抓到 1 次(205.1 s)。
- 工况:2173 rpm,母线 75.9 V,Iq 指令 84 A / 实测 2 A,Id −6 A,最大占空比 95.2 %,400 个周期里 66 个电压饱和。校验通过,没有丢帧、漏周期。
- 三相电流之和的均方根 12.5 A。空载时真实相电流只有约 3.5 A 均方根,所以这个误差相对真实电流很大。
- W 相不参与控制,只能当参考,而且本身偏差较大:三相稳定时间都 ≥ 3 µs 时,三相和平均 3.9 A、均方根 5.5 A;W 的均方根 6.4 A,比 U、V 的 3.5 A 大。这就是误差底线。
- V 相(电流环在用):稳定时间 0~1 µs 时,平均误差 +18.3 A(10 个周期);1~3 µs 时,均方根 10~12 A;≥ 3 µs 时回到底线 5.3 A。稳定时间越短,V 相读数越不准,和采样窗口猜想一致。
- U 相:这次很少处在短稳定时间(< 2 µs 只有 14 个周期),误差和底线差不多,还不能下结论。
- 局限:只有 1 次抓拍,而且空载电流很小。实车带负载的数据才能看出读数是不是系统性偏小。
台架数据结论(结合同一份 ASC 的其他报文)
- 抓拍功能在硬件上可用:触发、记录、发送、校验都正常。
- 空载也复现了"指令大、实际小":动力模式满油门,目标 2400 rpm,实际停在 2170~2178 rpm;Iq 指令 84 A,实测 3.5 A;Vq 28.4 V、Vd −7 V,电压幅值约 29 V,只用了上限 39.4 V 的 73 %;锁存一直是 0。说明问题和负载、车辆无关,也不是锁存造成的:控制器还有约 27 % 的电压余量没用上。
- 霍尔角度每圈在固定位置跳变(可信度高):FOC 角度正常每个 PWM 周期走 4.34°,但在固定几个角度上,每圈都会修正一次:
- 约 264°、327°、88° 处停顿,少走 4~6°;
- 约 14°、137°、200° 处突进,多走 3.5~6.8°;
- 每圈的修正合计约等于 0。说明霍尔表的边沿位置和电机实际霍尔边沿对不上,误差约 ±7° 电角度。
- 电压矢量每圈在固定位置鼓起来:转子角 60~150° 时电压幅值 0.80~0.90,其他位置约 0.70~0.75;66 个饱和周期里有 61 个落在这里。这个位置正好在 88° 停顿和 137° 突进这两个霍尔修正附近。推测:角度跳变 → 电流瞬变 → 电流环每圈短暂顶到电压上限 → 抗饱和把积分往回拉 → 平均电压上不去。可信度中等,需要带载数据确认。
- V 相读数在稳定时间 < 1 µs 时偏差约 +18 A,误差底线约 5 A(可信度中等:空载,只有 10 个周期)。U 相样本不够。W 不参与控制,本身偏差较大。
- 另一个现象,待查:经济模式目标 1800 rpm,实际只到 1630~1685,Iq 指令只有约 2 A,转速爬得很慢。
下一步
- 带载(台架加载或实车满把)录 ASC,确认结论 4 和 5。
- 用抓拍里的角度跳变位置重新核对霍尔表的六个边沿角度。这一项是离线分析,不改程序。
带载四组数据(11-04 17:06~17:10,LOUXIA,全部满油门)
📂 [LOUXIA](<file:///D:/01-英创汇智文件/01测试数据/01-我的测试数据/11-4/台架/LOUXIA/>):00经济模式、000经济模式、01动力模式、001动力模式。同一次上电,抓拍编号 #1~#4,每个文件 1 次。
- 转速目标按
drive_mode.inc:经济 1800 rpm,动力 2400 rpm。SPEED_COMMAND_MAX_RPM 2300 只在开机第 1 ms 起作用。
| 文件 |
抓拍工况 |
结果 |
| 00经济 / 000经济 |
1922 / 1925 rpm,Iq 指令 23.8 / 24.5 A,实测 22.8 / 23.6 A |
到达目标 1800(先冲到 1920 再回落),指令 ≈ 实测,正常 |
| 01动力 |
1839 rpm,松油门回收 −20 A |
抓在减速段,参考意义小 |
| 001动力 |
2181 rpm(12 s 后爬到 2254),Iq 指令 82 A / 实测 22~25 A,Vd −11、Vq 21.7,电压利用率约 81 %,锁存 0,38 个周期饱和 |
和实车平台段一模一样的现象 |
结论 1:采样窗口猜想不成立(修正前面的判断)
- 新方法:每相只用自己稳定时间 ≥ 3 µs 的周期拟合正弦波,再看短窗口时的读数偏离多少。不依赖其他相。
- 001 动力模式,最大占空比 94.9 %,稳定时间一直短到 < 0 µs:
- U 相偏差 −0.7~+1.0 A,V 相 −2.3~−3.8 A,都在拟合残差(3~4 A)以内;
- 只有 W 相(不参与控制)短窗口时偏大 +4~+5.5 A。
- 前面用"另外两相反推"得出的"U 偏小 15 A",是把 W 的偏差算到了 U 头上。作废。16:19 空载那次的"V 偏差 +18 A",用新方法只有 +6 A(残差 4.8 A),也不算明显。
- 所以:U、V 两相的采样在现有死区和采样点下是够用的,"电流采样窗口不够"不是平台段的原因。小模型里的
ADC_MINLOW_US 5 没有实车依据,要重新考虑。
结论 2:三相增益、零偏不一致(可信度高,4 次抓拍一致)
| 抓拍 |
U 幅值 |
V 幅值 |
W 幅值 |
V 直流偏置 |
| #1 经济 |
23.2 |
25.3 |
26.5 |
+1.7 A |
| #3 经济 |
24.5 |
26.5 |
28.1 |
+1.6 A |
| #4 动力 |
25.9 |
29.2 |
29.3 |
+2.8 A |
- U 相幅值一直比 V 小 8~11 %。电流环用的正好是 U、V,增益不一致会让 dq 电流出现 2 倍电频率的波动。
- V 相带约 +2 A 的直流偏置,会让 dq 电流每转一圈波动一次。开机零偏 V = 2095,比理论值 2048 高 47 个计数。
- 是采样电路的增益 / 零偏问题,还是电机三相真的不平衡,要用钳形表或示波器测一相实际电流来区分。
结论 3:电机运行时主循环被挤占,1 ms 任务实际约 2.5 ms 才执行一次(可信度高)
- 抓拍帧按设计每 1 ms 发一帧。实测:桥臂关闭时正好 1.00 ms;桥臂打开(运行、回收)时 10~13 ms。说明 200 µs 任务实际每 2~2.5 ms 才执行一次。
- 用目标转速斜坡交叉验证:动力模式设计每 1 ms 升 6 rpm,实测 2.4 rpm/ms;经济模式设计 4 rpm/ms,实测约 1.6 rpm/ms。两者都对应 1 ms 任务实际每 2.5 ms 执行一次。
- 原因:0x422 显示 FOC 电流环分支每次 34.5 µs,占 PWM 周期 66.7 µs 的 52 %,再加上 ADC、霍尔、提交 PWM 等中断,留给主循环的 CPU 不多,而且是 -O0 编译。
SoftTask_update 每轮主循环最多执行一次,counter %= period 会把漏掉的周期直接丢掉。
- 影响:速度环、油门、驱动模式斜坡、保护等 1 ms 任务都只有设计速度的约 40 %。斜坡和积分都按"每次 1 ms"算,所以响应慢了约 2.5 倍。经济模式先冲过目标到 1920 rpm、动力模式平台段慢慢爬,可能都和这个有关。SIL 没有模拟这个 CPU 占用,小模型的速度环响应比实车快。
- 抓拍也受影响:触发要求的 0.5 s 实际变成约 6 s,冷却 3 s 实际变成约 36 s,所以每次加速只抓到 1 次。
结论 4:霍尔角度每圈在固定位置修正(可信度高)
- LOUXIA 这 4 次抓拍的规律一致:约 330° 处每圈往回拉 8~10°,30°、90° 处往前推 3~4°。
- 16:19 那次的规律不一样(270° 处 −6°,0° 处 +7°),可能是台架和 LOUXIA 用的不是同一台电机或同一套霍尔。
- 001 动力的电压鼓包在转子角 0~120°,也就是 330° 回拉刚过之后;38 个饱和周期里 31 个在这一段。这支持"角度跳变 → 电流环每圈短暂顶到电压上限 → 抗饱和回拉积分 → 平均电压只有约 81 %"的推测(可信度中等)。
下一步
- 平台段的原因,现在的嫌疑是:每圈的角度跳变和电压饱和、加上抗饱和回拉,再加上 U/V 增益和零偏不一致。不再是采样窗口。
- 用抓拍的角度修正量离线核对霍尔表的六个边沿,尤其是 330° 那个。
- 抓拍触发改成按真实时间(ms 计时)判断,而不是按任务调用次数计数。这样每次加速能抓到多次。这需要改程序,等确认后再做。
- 主循环被挤占的问题,要评估:Release(-O2)编译,或者 1 ms 任务按实际经过的时间计算。这个改动影响面大,要单独决定。