【STM32G4-FOC】(6)三相电流采样与标定

【STM32G4-FOC】(1)STM32G431 之创建项目
【STM32G4-FOC】(2)STM32G431 之 TIM+ADC
【STM32G4-FOC】(3)STM32G431之三相互补 PWM
【STM32G4-FOC】(4)PWM 硬件触发 ADC 同步采样
【STM32G4-FOC】(5)DAC 受控输出闭环链路
【STM32G4-FOC】(6)三相电流采样与标定

【STM32G4-FOC】(6)三相电流采样与标定 ------ 实验设计与验证

    • [1. 项目介绍](#1. 项目介绍)
      • [1.1 目的与意义](#1.1 目的与意义)
      • [1.2 实验设计](#1.2 实验设计)
      • [1.3 硬件需求与连接](#1.3 硬件需求与连接)
    • [2 技术原理](#2 技术原理)
    • [3. CubeMX 配置](#3. CubeMX 配置)
      • [3.1 MCU 外设及其分工](#3.1 MCU 外设及其分工)
      • [3.2 新建工程与系统配置](#3.2 新建工程与系统配置)
      • [3.3 TIM 与 ADC 的配置](#3.3 TIM 与 ADC 的配置)
      • [3.4 工程配置](#3.4 工程配置)
    • [4. 三相电流数据结构与变量命名规范](#4. 三相电流数据结构与变量命名规范)
    • [5. 实验 6-1:三相电流零点标定](#5. 实验 6-1:三相电流零点标定)
    • [6. 小结:](#6. 小结:)

1. 项目介绍

1.1 目的与意义

【STM32G4-FOC】(5)DAC 受控输出闭环链路 中,通过"采样---计算---输出"的实时闭环控制链路,验证了 STM32G431 在实时控制场景下构建闭环系统的可行性。

在此基础上,本章引入 FOC 控制中最关键的物理反馈量------三相定子电流,围绕电流采样链路的建立与标定展开实验。通过三相电流零点标定、静态通流一致性验证以及低速运行条件下的电流波形观测,系统性地验证电流采样数据的准确性与一致性,为后续坐标变换和电流闭环控制做好准备。

本章围绕三相电流采样与标定,将完成以下几个目标:

  1. 建立完整的三相电流采样链路

    在真实功率驱动与电机负载条件下,打通电流信号从功率级到 ADC 的采样路径,确保采样流程可控、稳定。

  2. 完成电流采样的基础标定与一致性验证

    通过零点偏置校正和静态通流实验,确保三相电流采样结果准确且相互一致。

  3. 为后续 FOC 控制提供可信的电流数据基础

    验证电流采样在静态与低速动态条件下的可靠性,为坐标变换和电流闭环控制做好准备。

1.2 实验设计

本章围绕三相电流采样与标定展开,实验设计遵循由静态到动态、由验证到应用的工程思路,整体划分为以下三个层次:

  1. 零点标定实验(不依赖电机旋转)

    在关闭或固定 PWM 输出的条件下,对三相电流采样通道进行连续采样,测量并补偿采样链路中的零点偏置,用于验证采样通道的稳定性与一致性。

  2. 静态通流一致性验证(不引入动态控制)

    在完成零点标定的基础上,通过控制不同相位通流并对比三相电流采样结果,评估各相采样通道在幅值和趋势上的一致性,为后续坐标变换提供可信输入。

  3. 低速运行电流波形观测(接近实际工况)

    在保证前两步结果可靠的前提下,引入低速开环运行条件,对三相电流波形的连续性和相位关系进行观测,用于验证采样链路在动态情况下的稳定性。

本章重点在于采样链路与数据可信度验证,而非完整 FOC 控制。通过上述分层实验设计,逐步验证三相电流采样数据的准确性与可靠性,为后续控制算法的实现做好准备。

1.3 硬件需求与连接

为完成本章"三相电流采样与标定"相关实验,需要构建包含控制、功率与负载的基本硬件系统。

本文使用 ST 官方提供的 P-NUCLEO-IHM03:基于 STM32 的电机控制套件 作为实验的硬件平台。P-NUCLEO-IHM03 STM32 电机控制套件包括:X-NUCLEO-IHM16M1 电机驱动板、NUCLEO-G431RB 主控板、GBM2804H-100T 云台直流无刷电机和 12V 直流电源。

  • 控制模块:NUCLEO-G431RB 控制板

    NUCLEO-G431RB 控制板,它连接用户命令和配置参数以驱动电机,以执行电机驱动控制算法(如FOC)。

    基于高性能Arm® Cortex®-M4 32位 RISC内核,最高频率可达170 MHz且带有浮点单元(FPU),内嵌高级模拟外设集。

  • 驱动模块:X-NUCLEO-IHM16M1 电机驱动板

    NUCLEO-IHM16M1 电机驱动板,基于STSPIN830面向BLDC/PMSM电机的三相驱动板。

    内嵌PWM电流控制器,支持单电阻或三电阻电流采样架构,支持并配置不同的闭环控制、FOC或6步有感或无感方案。

  • 电机负载:GBM2804H-100T 直流无刷电机(PMSM)

    以低压三相直流无刷电机作为实际负载,用于形成真实的三相电流通路。

P-NUCLEO-IHM03 电机控制套件的硬件连接如下:

  1. 堆叠连接电机驱动板与控制板。将 IHM16M1电机驱动板通过两侧的 CN7 和 CN10 连接器插接到 G431RB 控制板上,NUCLEO-G431RB 板上的两个按钮(用户按钮 B1和重置按钮 B2)应保持未覆盖状态。

  2. 将三相电机连接线 U、V、W 连接到 IHM16M1 电机驱动板上 CN1 连接器的 3/4/5 输出端。

  3. 配置 NUCLEO-G431RB 控制板上的跳线:

    • 从 USB 为 NUCLEO-G431RB 供电时,将 JP5 的 5V-STLK 源设为 [1-2] 位置(跳线安装在 pin1、pin2 针脚);
    • JP6(IDD)设为 ON 状态(安装 2针跳线);
    • JP7(BOOT0)设为 OFF 状态(不安装跳线);
    • JP8 的 VREF 设为 [1-2] 位置(跳线装在 pin1、pin2 针脚)。
  4. 配置 IHM16M1 电机驱动板的跳线,以选择所需的控制算法。注意:更改控制模式之前,必须关闭电源电压。

    以FOC 控制为例:

    • 三电阻采样配置:默认模式,背面的 JP4、JP7 处于开路状态(Open)。
    • 电流采样模式:J5、J6 安装跳线,使电流采样信号连接到 ADC输入端。
    • 过流保护:J2 设为 [2-3] 位置(跳线装在 pin2、pin3),使用软件过流保护。
    • 限流阈值:J3 设为 [1-2] 位置(跳线装在 pin1、pin2),使用固定参考电压作为电流限制阈值。
  5. 将 12V/2A 直流电源连接到 NUCLEO-G431RB 控制板上的 CN1 连接端口(mini-USB),或连接到 X-NUCLEO-IHM16M1 电机驱动板上的 J4 连接器(电源插座),并通电(IHM03 套件中标配的云台电机的最大电压为12 VDC-youcans)。

通过上述硬件配置与连接方式,本章实验能够在保证安全和可控的前提下,获取具有工程意义的三相电流采样数据,为后续 FOC 控制实验提供可靠硬件基础。

2 技术原理

在 FOC 控制系统中,三相电流是坐标变换和电流闭环控制的直接输入,其采样结果由功率回路、电流采样电路以及 ADC 等多个硬件环节共同决定。

由于采样电路通常引入固定偏置和放大误差,即使在电流为零或条件相同的情况下,不同相位的采样结果也可能存在偏差。如果不对这些误差进行处理,误差将被进一步传递并放大,直接影响 FOC 控制的稳定性与性能。

本章通过分层实验的方式完成电流标定:

  • 首先在不依赖电机旋转的条件下,对三相电流采样通道进行零点偏置测量并在软件中加以补偿;
  • 随后在静态通流条件下对比三相电流采样结果,验证各相采样的一致性;
  • 最后在低速运行条件下观测三相电流波形,确认标定结果在接近实际工况下依然有效。

通过上述过程,可在不引入完整 FOC 控制复杂度的前提下,确保三相电流采样数据具有足够的准确性与可靠性,为后续控制算法的实现提供可信输入。

说明:为与三相数学建模与坐标变换理论统一,本文使用 Ia / Ib / Ic 表示三相电流,与前文中的 Iu / Iv / Iw 在物理意义上是等价的。

3. CubeMX 配置

3.1 MCU 外设及其分工

"三相电流采样与标定"实验主要围绕电流的同步采样与数据获取展开,涉及的 STM32G431 片上外设及其分工如下:

  • 高级定时器(TIM1)

    用于生成三相互补 PWM 信号,驱动功率级形成三相电流;同时提供精确的硬件触发事件,用于触发 ADC 在指定时刻进行电流采样,保证采样时序与 PWM 周期严格同步。

  • 模数转换器(ADC)

    负责对三相电流采样电路输出的模拟电压进行转换,获取对应的数字量。本章通过配置 ADC 多通道采样,实现对 Ia、Ib、Ic 的连续采集,为电流标定与一致性验证提供数据基础。

  • DMA(可选)

    用于在 ADC 转换完成后自动搬运采样数据,减少 CPU 干预,提高采样过程的实时性与稳定性。

  • GPIO(辅助)

    用于实验过程中的调试与状态指示,例如使能控制、测试点输出或波形观测。

3.2 新建工程与系统配置

  1. 新建工程。
    启动 STM32CubeMX,点击 "Start New Project"(或使用快捷键 Ctrl+N)新建工程,进入 New Project 界面。
    选择 MCU 型号 STM32G431RBT6(与所使用开发板一致),或直接选择 NUCLEO-G431RB 开发板。
    完成器件选择后,点击右上角 "Start Project" 创建工程,并将工程文件另存为:FOC_calib01.ioc。该工程将作为三相电流采样与标定实验的基础工程。

  2. 系统时钟配置。
    点击顶部 "Clock Configuration" 选项卡,进入时钟树配置界面。本实验采用外部高速晶振(HSE)作为系统时钟源,并通过 PLL 将系统主频配置为 160 MHz。
    主要时钟参数配置如下:

bash 复制代码
Input frequency: 24 MHz (HSE)
SysCLK frequency: 160 MHz (HSE)
System Clock Mux: PLLCLK(youcans@qq.com)
AHB Prescaler: 1 (不分频)
APB1 Prescaler: 1
APB2 Prescaler: 1

配置完成后,System Clock、HCLK、PCLK1 与 PCLK2 均应显示为 160 MHz。

该配置为后续 PWM 生成与 ADC 高速采样提供充足的时钟裕量。

  1. 系统功能配置。
    在 Pinout & Configuration 页面中,完成以下系统相关配置,确保系统以外部晶振为基准稳定运行。
  • (1)SYS 配置

    • 调试器类型:Debug 模式设置为 Serial Wire,以支持 SWD 调试
    • 基础时钟源:保持默认的 SysTick
  • (2)RCC 配置

    • High Speed Clock (HSE) 设置为 Crystal/Ceramic Resonator
    • Low Speed Clock (LSE) 设置为 Disable(本章实验不使用低速时钟)
  1. GPIO 基础配置
    为便于实验调试与状态指示,配置以下基础 GPIO 资源:
    • LD2(PA5)

      配置为 GPIO_Output,用于程序运行状态指示或简单调试输出。

    • 用户按键(PC13)

      配置为 GPIO_EXTI13,作为外部中断输入,后续可用于实验控制或状态切换。

3.3 TIM 与 ADC 的配置

3.3.1 配置思路

在之前的实验中,已完成基于 TIM1 硬件触发的 ADC 注入组三相电流同步采样配置,并对其时序与稳定性进行了验证。为保持采样机制的一致性,本章实验中继续采用 ADC 注入组进行采样。

  1. 由高级定时器 TIM1 负责 PWM 生成与采样时序控制;
  2. 通过 TIM1 的比较事件或更新事件 作为 ADC 的硬件触发源;
  3. 使用 ADC 注入组 依次采样三相电流;
  4. 通过 硬件触发(而非软件触发),保证每次采样都发生在 PWM 周期中的固定位置。

这种配置方式可以避免采样时刻在 PWM 周期内随机漂移,从而确保在静态与动态条件下获得具有可比性的电流数据,为电流标定和后续 FOC 控制提供可靠基础。

3.3.2 定时器(TIM1)配置方案

在本章实验中,使用 STM32G431 的TIM1 高级定时器,实现 三相 PWM 生成 与 ADC 采样触发控制 这两项关键任务。通过将 TIM1 的 CH1/CH2/CH3 用于三相 PWM 输出、CH4 专用于 ADC 采样触发,构建了一种清晰、稳定且可扩展的定时器配置方案。

  1. PWM 输出通道配置(CH1、CH2、CH3)
    TIM1 的 Channel 1、Channel 2 和 Channel 3 用于生成三相互补 PWM 信号,直接驱动功率级,形成三相电流通路。在 CubeMX 中,对 TIM1 的配置要点如下:
  • 计数模式:设置为中心对齐模式(Center-aligned Mode),用于在 PWM 周期中部获得稳定的电流采样窗口。
  • TRGO 模式:Update Event
  • PWM 输出:
    • 启用 CH1 / CH2 / CH3 及其互补通道 CH1N / CH2N / CH3N;
    • 死区时间(Dead Time):根据功率器件特性配置合适的死区时间,防止功率器件直通;
    • PWM 模式:PWM Mode 1
    • 输出极性:保持默认或根据硬件需求配置
      TIM1_CH4 的配置:
    • CH4 模式:PWM Generation No Output
    • Pulse(CCR4):设置为 PWM 周期中部(例如 ARR/2),对应电流相对稳定的时刻
    • Preload:Enable(推荐)
  1. ADC 采样触发通道配置(CH4)
    为实现电流采样与 PWM 周期的严格同步,使用 TIM1_CH4 硬件触发 ADC 注入组采样,而不参与 PWM 输出。
    当定时器计数器运行到 CCR4 所设定的位置时,将产生一次 Capture Compare 4(CC4)事件,该事件作为 ADC 注入组的外部触发源,用于启动一次三相电流采样序列。通过这种方式,可以在不改变三相 PWM 输出波形的前提下,灵活、精确地控制电流采样时刻。
    • 触发源:Timer 1 Catture Compare 4 event

TIM1 的详细配置参数,请参见《(4)PWM 硬件触发 ADC 同步采样》内容。

3.3.3 ADC 配置方案

在本章实验中,ADC1 用于完成三相电流的同步采样,并采用 注入组(Injected Group) 的方式进行转换,外部触发源配置为 Timer 1 Capture Compare 4 event(TIM1_CC4)。该配置方式已在前序实验中完成验证,能够在 PWM 驱动条件下实现采样时刻固定、时序可控的同步采样。

  1. ADC 工作模式配置

    在 CubeMX 中,对 ADC1 的基本工作模式配置如下:

    • ADCs_Commeon_Settings:Independent mode
    • Resolution:12-bit
    • Data Alignment:Right
    • Scan Conversion Mode:Enable(用于多通道注入采样)
    • Continuous Conversion Mode:Disable
    • Overrun:Preserve Data
  2. 注入组触发源配置

    为保证电流采样与 PWM 周期严格同步,ADC 注入组采用 TIM1 的硬件事件作为外部触发源。

    在 CubeMX 中,ADC 注入组触发方式配置为:

    • Injected Conversion Mode:Enable
    • Injected Trigger Source:Timer 1 Capture Compare 4 event (TIM1_CC4)
    • Injected Trigger Edge:Trigger detection on the rising edge
    • ADC Injected End of Conversion Interrupt:Enable
      通过该配置,ADC 注入组将在 TIM1 产生指定触发事件时启动一次注入序列转换,确保每次采样都发生在 PWM 周期中的固定位置,从而避免采样相位在 PWM 周期内漂移。
  3. 注入组通道顺序配置

    ADC 注入组用于采样三相电流信号 Ia、Ib、Ic。

    为保证数据组织清晰、处理逻辑简单,注入组通道顺序在 CubeMX 中固定配置为:

    • Number of Conversions: 3
    • Injected Rank 1:Channel 2 (PA1, Ia)
    • Injected Rank 2:Channel 12 (PB1, Ib)
    • Injected Rank 3:Channel 15 (PB0, Ic)

所有通道采用相同的采样时间设置,以避免通道间由于采样时间不同而引入额外误差。

在每次注入触发到来时,ADC 将按照上述顺序依次完成三相电流的采样。

  1. 注入组中断与数据读取方式
    ADC1 注入组转换完成后,通过 ADC 全局中断进入中断服务函数。
    在 CubeMX 中需启用 ADC1 的 NVIC 全局中断:在 NVIC Settings 页面中,勾选 ✅ ADC1 and ADC2 global interrupt。HAL 库将在注入组转换完成时调用 HAL_ADCEx_InjectedConvCpltCallback() 回调函数,用于读取注入组采样结果。

ADC 的详细配置参数,请参见《(4)PWM 硬件触发 ADC 同步采样》内容。

3.4 工程配置

  1. 工程管理配置。
    (1)点击 "Project Manager"→ "Project",输入项目名称 "FOC_calib01.ioc"。
    (2)点击 "Project Manager"→ "Code Generator",设置如下。
bash 复制代码
Project:
  - Project Name: FOC_calib01.ioc
  - Toolchain/IDE: STM32CubeIDE

Code Generator:
  √ Generate peripheral initialization as a pair of '.c/.h'
  √ Keep User Code when re-generating
  √ Backup previously generated files
youcans@qq.com

4. 三相电流数据结构与变量命名规范

本文采用"原始采样值 raw → 偏置补偿 off → 物理量 i"的三级变量体系,并保持 a/b/c 相与注入组 Rank 顺序一致。

  1. 通道与相位的对应关系

    Injected Rank 1 → Ia

    Injected Rank 2 → Ib

    Injected Rank 3 → Ic

  2. 变量命名约定

    (1)原始 ADC 采样值(未处理):ia_raw, ib_raw, ic_raw:三相原始采样值(ADC 码值,uint16_t)

    (2)零点偏置(Offset)的码值:ia_off, ib_off, ic_off:三相零点偏置(建议用 int32_t 保存均值结果)

    (3)补偿后的码值:ia_adc, ib_adc, ic_adc:扣除偏置后的采样码值(建议 int32_t,允许出现正负)

    (4)物理电流值(可选,单位 A):ia, ib, ic:三相电流(float,单位 A)

  3. 数据结构(结构体 + 数组并存)

    为了兼顾可读性与可扩展性,建议字段划分如下(概念层面,后续代码中实现即可):

    • raw[3]:ADC 原始值
    • off[3]:偏置(标定值)
    • adc[3]:补偿后码值
    • i[3]:电流物理量(可选)
    • tick/sample_id:采样序号(用于日志与波形对齐)
    • flag_new:新数据标志(主循环/日志读取用)

5. 实验 6-1:三相电流零点标定

实验目的:测量并补偿三相电流采样的零点偏置

三相电流采样链路通常包含采样电阻、运放(或电流传感器)与 ADC 等环节,即使实际电流为 0,ADC 也可能读到非零值(零点偏置/Offset)。本实验的目的就是在"理论电流为零"的条件下测得三相采样通道的偏置,并在软件中进行补偿,为后续一致性验证与电流环控制提供可靠基础。

实验条件:

  1. 硬件连接:控制板 + 功率级 + 电机负载均已连接(形成真实采样通路)。
  2. 电机状态:本实验不要求电机旋转。
  3. PWM 状态:关闭 PWM 输出,或将占空比设为 0,确保功率级不向电机施加有效电压。
  4. 采样触发:ADC1 注入组由 TIM1_CC4 硬件触发。
  5. 安全建议:首次上电建议限流/低母线电压,并确认功率级使能逻辑正确。

实验内容:

  1. 连续采样 Ia / Ib / Ic:在"电流为零"的状态下,连续采集一段时间的三相电流 ADC 原始值 ia_raw/ib_raw/ic_raw;
  2. 计算三相电流的偏置量:对每一相分别求平均值(或中位数/均值滤波)得到偏置 ia_off/ib_off/ic_off;
  3. 在软件中进行偏置补偿:后续每次采样都执行 i a d c = i r a w − i o f f i_{adc}=i_{raw} − i_{off} iadc=iraw−ioff,得到扣除偏置后的电流码值 ia_adc/ib_adc/ic_adc(允许正负)。

参考代码:

  1. 参数和变量定义
c 复制代码
// 固定索引:0->A, 1->B, 2->C
#define PH_A 0
#define PH_B 1
#define PH_C 2
#define N_PHASE 3

volatile uint16_t iabc_raw[N_PHASE];   // ADC原始采样
volatile int32_t  iabc_off[N_PHASE];   // 偏置(标定结果)
volatile int32_t  iabc_adc[N_PHASE];   // 扣偏置后的码值

static volatile int64_t sum_off[N_PHASE];
static volatile uint32_t cnt_off;
static volatile uint8_t  calib_done;
  1. 回调函数
c 复制代码
/**
  * @brief  ADC1 注入组转换完成回调(JEOC)
  * @note   触发源:TIM1_CC4;注入Rank顺序:Rank1->Ia, Rank2->Ib, Rank3->Ic
  */
void HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef* hadc)
{
    /* 只处理 ADC1 */
    if (hadc->Instance != ADC1) return;

    /* 1) 读取注入组 3 个 Rank 的值(顺序必须与 CubeMX 配置一致) */
    iabc_raw[PH_A] = (uint16_t)HAL_ADCEx_InjectedGetValue(hadc, ADC_INJECTED_RANK_1);
    iabc_raw[PH_B] = (uint16_t)HAL_ADCEx_InjectedGetValue(hadc, ADC_INJECTED_RANK_2);
    iabc_raw[PH_C] = (uint16_t)HAL_ADCEx_InjectedGetValue(hadc, ADC_INJECTED_RANK_3);

    /* 2) 若标定未完成:累加求均值 */
    if (!calib_done)
    {
        sum_off[PH_A] += (int64_t)iabc_raw[PH_A];
        sum_off[PH_B] += (int64_t)iabc_raw[PH_B];
        sum_off[PH_C] += (int64_t)iabc_raw[PH_C];
        cnt_off++;

        if (cnt_off >= OFFSET_CALIB_SAMPLES)
        {
            /* 用整除求均值即可(如需更稳健可用中位数/去极值平均) */
            iabc_off[PH_A] = (int32_t)(sum_off[PH_A] / (int64_t)cnt_off);
            iabc_off[PH_B] = (int32_t)(sum_off[PH_B] / (int64_t)cnt_off);
            iabc_off[PH_C] = (int32_t)(sum_off[PH_C] / (int64_t)cnt_off);

            calib_done = 1;
        }
    }

    /* 3) 正常运行:扣偏置(标定完成后才有严格意义,但提前做也无妨) */
    iabc_adc[PH_A] = (int32_t)iabc_raw[PH_A] - iabc_off[PH_A];
    iabc_adc[PH_B] = (int32_t)iabc_raw[PH_B] - iabc_off[PH_B];
    iabc_adc[PH_C] = (int32_t)iabc_raw[PH_C] - iabc_off[PH_C];

    /* 4) 新数据标志:通知主循环/日志模块读取 */
    flag_new = 1;
}
  1. 主程序 main.c 关于标定的关键代码:
c 复制代码
  /* USER CODE BEGIN 2 */
  printf("\r\n=== Exp6-1 Current Offset Calibration (ADC Injected, TIM1_CC4) ===\r\n");

  // 1) 启动 TIM1_CH4 用于产生ADC触发事件,暂不启动CH1~CH3
  HAL_TIM_Base_Start( &htim1);  // 启动定时器计数
  HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_4);

  // 2) 启动 ADC1 注入组(外部触发 + 中断方式)
  if (HAL_ADCEx_InjectedStart_IT(&hadc1) != HAL_OK) {
      printf("ERROR: ADC Injected Start IT failed!\r\n");
      Error_Handler();
  }
  __HAL_ADC_ENABLE_IT(&hadc1, ADC_IT_JEOC);
//  __HAL_TIM_SetCompare(&htim1,TIM_CHANNEL_4,4000);  // TIM1_CH4 三角波触发 ADC1 采样
  HAL_Delay(100);

  // 3) 开始标定(清零累加器)
  for (int k = 0; k < N_PHASE; k++) sum_off[k] = 0;
  cnt_off = 0;
  calib_done = 0;  
  printf("Calibrating... please keep current = 0\r\n");

  // 等待标定完成(calib_done 在 JEOC 回调里置1)
  while (!calib_done)
  {
	  // 闪灯提示正在标定
      HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin);
      HAL_Delay(50);
  }
  printf("Calib done.\r\n");
  printf("Offset: ia_off=%ld, ib_off=%ld, ic_off=%ld\r\n",
         (long)iabc_off[PH_A], (long)iabc_off[PH_B], (long)iabc_off[PH_C]);
  /* USER CODE END 2 */

  // 4) 补偿效果观测:统计补偿后均值和峰值
  /* Infinite loop */
  while (1)
  {
	  int32_t mean[3] = {0};
	  int32_t vmin[3] = {  2147483647,  2147483647,  2147483647};
	  int32_t vmax[3] = { -2147483647, -2147483647, -2147483647};

	  const uint32_t M = 1000;  // 统计1000组(取决于触发频率)
	  for (uint32_t n = 0; n < M; n++)
	  {
		  // 等待新数据(flag_new在回调中置1)
		  while (!flag_new) {}
		  flag_new = 0;

		  for (int k = 0; k < 3; k++)
		  {
			  int32_t x = iabc_adc[k];
			  mean[k] += x;
			  if (x < vmin[k]) vmin[k] = x;
			  if (x > vmax[k]) vmax[k] = x;
		  }
	  }

	  for (int k = 0; k < 3; k++) mean[k] /= (int32_t)M;

	  printf("Compensated ADC: mean=[%ld,%ld,%ld], p2p=[%ld,%ld,%ld]\r\n",
			   (long)mean[0], (long)mean[1], (long)mean[2],
			   (long)(vmax[0]-vmin[0]), (long)(vmax[1]-vmin[1]), (long)(vmax[2]-vmin[2]));

	  HAL_Delay(500);
      HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin);
  }

实验结果

运行程序,通过串口调试助手接收输出数据如下。

bash 复制代码
=== Exp6-1 Current Offset Calibration (ADC Injected, TIM1_CC4) === 
Calibrating... please keep current = 0 
Calib done. 
Offset: ia_off=1893, ib_off=1896, ic_off=1904 
Compensated ADC: mean=[0,0,0], p2p=[10,5,6] 
Compensated ADC: mean=[0,0,0], p2p=[10,5,6] 
Compensated ADC: mean=[0,0,0], p2p=[10,5,6] 
Compensated ADC: mean=[0,0,0], p2p=[10,5,5] 
Compensated ADC: mean=[0,0,0], p2p=[9,4,5] 
...

实验结果表明:

  1. 得到三相偏置参数:ia_off=1893, ib_off=1896, ic_off=1904。三相偏置接近、差异很小,符合真实电流为零时"通道偏置略有不同"的典型情况。Offset 在 1900 左右,说明电流采样电路带了中点偏置。
  2. 补偿后零点的稳定性:补偿后均值为 0(mean=[0,0,0])。说明在后续每次采样都进行了偏置补偿,并且统计窗口足够大,使得均值收敛到 0。
  3. 补偿后只有小幅噪声(p2p 很小),说明残余波动主要是 ADC + 模拟前端噪声,而不是残余直流偏置或错误触发。

结果分析:

  1. 本实验得到的 iabc_off 是后续所有电流相关计算的"基础校正参数"。在后续实验以及电流环控制中,必须在每次采样后执行偏置补偿(推荐直接在 JEOC 回调中处理):
c 复制代码
ia_adc = ia_raw - ia_off
ib_adc = ib_raw - ib_off
ic_adc = ic_raw - ic_off
  1. 偏置参数的保存

    (1)在教学/实验中,可以每次上电都做一次零点标定。简单可靠,可以自动适应温漂。

    (2)在产品化中,推荐上电标定一次后保存(Flash/EEPROM),运行中只做小幅更新,启动速度更快。

  2. 单位换算。

    电流环最终需要电流单位一致(通常用 A)。可以增加如下代码实现:

c 复制代码
i[A] = i_adc * adc_to_amp

其中 adc_to_amp 由采样电阻、运放增益、ADC 参考电压共同决定。

6. 小结:

本实验在零电流条件下测得三相采样通道的零点偏置分别为 1893、1896、1904(LSB),三相偏置差异很小,表明采样链路一致性良好。扣除偏置后,三相电流码值均值收敛至 0,峰峰值波动在 4~10 LSB 范围内,主要反映 ADC 与模拟前端噪声水平。后续所有电流相关计算(通流一致性验证、波形观测、坐标变换与电流环控制)均应基于补偿后的电流数据进行。

后记:

  1. 本打算在这篇把 3个实验都写完,看来有些长了,另外两个实验后文再补充吧。
  2. 本项目开源,需要项目资源的读者请留言。

版权声明:

【动手学电机驱动】是 youcans@qq 原创作品,转载必须标注原文链接: 【STM32G4-FOC】(6)三相电流采样与标定(https://blog.csdn.net/youcans/article/details/157504296)

Copyright@youcans 2026

Crated:2026-1

相关推荐
帅次4 小时前
系统分析师-信息物理系统分析与设计
stm32·单片机·嵌入式硬件·mcu·物联网·iot·rtdbs
澜莲Alice4 小时前
STM32 MPLAB X IDE 软件安装-玩转单片机-英文版沉浸式安装
stm32·单片机·嵌入式硬件
良许Linux5 小时前
IIC总线的硬件部分的两个关键点:开漏输出+上拉电阻
单片机·嵌入式硬件
✎ ﹏梦醒͜ღ҉繁华落℘5 小时前
单片机基础知识 -- ADC分辨率
单片机·嵌入式硬件
Q_21932764555 小时前
车灯控制与报警系统设计
人工智能·嵌入式硬件·无人机
雾削木6 小时前
树莓派部署 HomeAssistant 教程
stm32·单片机·嵌入式硬件
Q_21932764556 小时前
基于单片机的破壁机自动控制系统设计
单片机·嵌入式硬件
我是一棵无人问荆的小草6 小时前
stm32f103芯片多个IO配置成外部中断
stm32·单片机·嵌入式硬件
wjykp7 小时前
ESP32xxx烧录
stm32·单片机·嵌入式硬件
早起huo杯黑咖啡8 小时前
【NOR Flash】关于芯片的高耐久性分区的编程/擦除周期和最小保留时间的数据
单片机·嵌入式硬件