FOC控制原理8-源码解析3-ADC采样中断

1、基础框图

2、中断代码讲解

(1)ADC中断函数

/* USER CODE END PRIVATE */
/**
  * 函数功能: ADC1/ADC2中断处理函数
  * 输入参数: 无
  * 返 回 值: 无
  * 说    明: 无
  */
void ADC_IRQHandler(void)
{
  if(LL_ADC_IsActiveFlag_JEOS(ADC1))
  {
    // Clear Flags
    /* 注入转换中断 */
    ADC1->SR &= ~(uint32_t)(LL_ADC_FLAG_JEOS | LL_ADC_FLAG_JSTRT);
    TSK_HighFrequencyTask();// 执行高频任务(FOC控制)
  }
}

这段代码是一个中断处理函数,用于处理 ADC1 和 ADC2 的中断请求。具体来说,它处理的是 ADC1 的注入通道转换结束中断。以下是对这段代码的详细解释:

函数声明

void ADC_IRQHandler(void)

这是一个中断服务例程(ISR),用于处理 ADC1 和 ADC2 的中断请求。函数名 ADC_IRQHandler 是标准的命名方式,与 STM32 系列微控制器的中断向量表中的入口点相匹配。

中断处理逻辑

if(LL_ADC_IsActiveFlag_JEOS(ADC1))

这行代码检查 ADC1 的注入通道转换结束(JEOS)标志是否被置位。LL_ADC_IsActiveFlag_JEOS 是一个低层函数(Low-Level,LL),用于检查 ADC1 的 JEOS 标志是否被设置。如果该标志被设置,说明注入通道的转换已经完成。

清除标志

ADC1->SR &= ~(uint32_t)(LL_ADC_FLAG_JEOS | LL_ADC_FLAG_JSTRT);

如果 JEOS 标志被设置,这段代码会清除 ADC1 的状态寄存器(SR)中的 JEOS 和 JSTRT 标志。LL_ADC_FLAG_JEOS 和 LL_ADC_FLAG_JSTRT 是预定义的常量,分别表示注入转换结束标志和注入转换启动标志。通过与操作符 & 和按位取反操作符 ~,可以清除这些标志。

执行高频任务

TSK_HighFrequencyTask();

这行代码调用了一个名为 TSK_HighFrequencyTask 的函数,用于执行高频任务,例如 FOC(Field-Oriented Control,磁场定向控制)控制。FOC 是一种用于电机控制的高级技术,通常需要高精度和高频率的实时处理。

总结

  • 功能:处理 ADC1 的注入通道转换结束中断。
  • 输入参数:无。
  • 返回值:无。
  • 说明
    • 检查 ADC1 的 JEOS 标志是否被设置。
    • 如果设置,清除 JEOS 和 JSTRT 标志。
    • 调用 TSK_HighFrequencyTask 函数执行高频任务。

通过这种方式,中断处理函数确保在 ADC1 的注入通道转换完成后,能够及时清除相关的中断标志并执行必要的任务。这对于需要高精度和实时性的应用(如电机控制)非常重要。

(2)高频任务

/**
  * 函数功能: 高频任务
  * 输入参数: 无
  * 返 回 值: 无
  * 说    明: 执行频率是ADC的采样频率,也就是PWM频率
  */
uint8_t TSK_HighFrequencyTask(void)
{
  uint8_t bMotorNbr = 0;
  uint16_t hFOCreturn;
 
  HALL_CalcElAngle (&HALL_M1);          // 计算电角度

  hFOCreturn = FOC_CurrController(M1); // FOC 电流控制
  if(hFOCreturn == MC_FOC_DURATION)    // 在执行FOC算法期间出现定时器更新事件
  {
    STM_FaultProcessing(&STM[M1], MC_FOC_DURATION, 0);// 错误报警
  }
  return bMotorNbr;
}

这段代码定义了一个名为 TSK_HighFrequencyTask 的函数,用于执行高频任务,通常与电机控制相关。以下是对这段代码的详细解释:

函数声明

uint8_t TSK_HighFrequencyTask(void)

这是一个无参数的函数,返回值类型为 uint8_t。函数的名称 TSK_HighFrequencyTask 表示这是一个高频任务,通常在每次 ADC 采样中断时调用,执行频率与 ADC 的采样频率(也就是 PWM 频率)相同。

函数功能

  • 功能:执行高频任务,主要用于电机控制。
  • 输入参数:无。
  • 返回值bMotorNbr,一个 uint8_t 类型的值,表示电机编号。
  • 说明:执行频率是 ADC 的采样频率,也就是 PWM 频率。

函数体

uint8_t bMotorNbr = 0;
uint16_t hFOCreturn;

HALL_CalcElAngle (&HALL_M1);          // 计算电角度

hFOCreturn = FOC_CurrController(M1); // FOC 电流控制
if(hFOCreturn == MC_FOC_DURATION)    // 在执行FOC算法期间出现定时器更新事件
{
  STM_FaultProcessing(&STM[M1], MC_FOC_DURATION, 0);// 错误报警
}
return bMotorNbr;

详细解释

  1. 变量声明

    uint8_t bMotorNbr = 0;
    uint16_t hFOCreturn;
    
    • bMotorNbr:用于存储电机编号,初始值为 0。
    • hFOCreturn:用于存储 FOC 电流控制函数的返回值。
  2. 计算电角度

    HALL_CalcElAngle (&HALL_M1);          // 计算电角度
    
    • HALL_CalcElAngle 是一个函数,用于计算电机的电角度。HALL_M1 是一个结构体指针,指向与电机 1 相关的霍尔传感器数据。
  3. FOC 电流控制

    hFOCreturn = FOC_CurrController(M1); // FOC 电流控制
    
    • FOC_CurrController 是一个函数,用于执行 FOC 电流控制。M1 是一个表示电机 1 的常量或枚举值。该函数的返回值存储在 hFOCreturn 中。
  4. 错误处理

    if(hFOCreturn == MC_FOC_DURATION)    // 在执行 FOC 算法期间出现定时器更新事件
    {
      STM_FaultProcessing(&STM[M1], MC_FOC_DURATION, 0);// 错误报警
    }
    
    • 检查 hFOCreturn 是否等于 MC_FOC_DURATION,这表示在执行 FOC 算法期间出现了定时器更新事件。
    • 如果条件成立,调用 STM_FaultProcessing 函数进行错误处理。STM[M1] 是一个指向与电机 1 相关的故障处理数据的指针,MC_FOC_DURATION 和 0 是错误处理函数的参数。
  5. 返回值

    return bMotorNbr;
    
    • 函数返回 bMotorNbr,表示电机编号。

总结

  • 功能:执行高频任务,主要用于电机控制。
  • 输入参数:无。
  • 返回值bMotorNbr,表示电机编号。
  • 说明
    • 计算电机的电角度。
    • 执行 FOC 电流控制。
    • 如果在 FOC 电流控制期间出现定时器更新事件,进行错误处理。
    • 返回电机编号。

这段代码通常用于需要高精度和高频率实时控制的电机控制系统中,确保电机的稳定运行和高效控制。

(3)计算电角度

/**
  * 函数功能: 计算电角度
  * 输入参数: @pHandle
  * 返 回 值: 电角度(s16degree)
  * 说    明: dpp(每周期的数字量化值(s16degree), 将每采样周期的数值累加就得到所需值)
  */
int16_t HALL_CalcElAngle( HALL_Handle_t * pHandle )
{

  if ( pHandle->_Super.hElSpeedDpp != HALL_MAX_PSEUDO_SPEED ) //最高转速
  {
    pHandle->MeasuredElAngle += pHandle->_Super.hElSpeedDpp;
    pHandle->TargetElAngle += pHandle->_Super.hElSpeedDpp;
    pHandle->_Super.hElAngle += pHandle->_Super.hElSpeedDpp + pHandle->CompSpeed;
    pHandle->PrevRotorFreq = pHandle->_Super.hElSpeedDpp;
  }
  else
  {
    pHandle->_Super.hElAngle += pHandle->PrevRotorFreq;
  }

  return pHandle->_Super.hElAngle;
}

这段代码是一个函数,用于计算电角度(electrical angle)。电角度是电机控制中一个重要的参数,它反映了电机转子的位置和速度。下面是对这段代码的详细解释:

函数声明

int16_t HALL_CalcElAngle(HALL_Handle_t * pHandle)

  • 函数名HALL_CalcElAngle
  • 返回值int16_t,表示电角度,类型为16位有符号整数。
  • 参数HALL_Handle_t * pHandle,这是一个指向结构体的指针,包含了与霍尔传感器相关的信息和状态变量。

函数逻辑

  1. 条件判断

    if (pHandle->_Super.hElSpeedDpp != HALL_MAX_PSEUDO_SPEED)
    {
        ...
    }
    else
    {
        pHandle->_Super.hElAngle += pHandle->PrevRotorFreq;
    }
    
    • 条件: 检查当前的电速度(hElSpeedDpp)是否不等于最大伪速度(HALL_MAX_PSEUDO_SPEED)。
    • 最大伪速度: 可能表示电机处于最高转速状态。
  2. 如果电速度不等于最大伪速度

    • 更新测量电角度:

      pHandle->MeasuredElAngle += pHandle->_Super.hElSpeedDpp;
      
      • MeasuredElAngle:累计每周期的电角度增量,表示实际测量的电角度。
    • 更新目标电角度:

      pHandle->TargetElAngle += pHandle->_Super.hElSpeedDpp;
      
      • TargetElAngle:可能用于控制算法中的目标角度。
    • 更新电角度:

      pHandle->_Super.hElAngle += pHandle->_Super.hElSpeedDpp + pHandle->CompSpeed;
      
      • hElAngle:综合考虑了电速度和补偿速度(CompSpeed)的电角度。
    • 保存前一次的转子频率:

      pHandle->PrevRotorFreq = pHandle->_Super.hElSpeedDpp;
      
      • PrevRotorFreq:保存上一次的电速度值,可能用于在下次电速度为最大伪速度时使用。
  3. 如果电速度等于最大伪速度

    • 更新电角度:

      pHandle->_Super.hElAngle += pHandle->PrevRotorFreq;
      
      • 在最高转速时,使用前一次的转子频率来更新电角度,以避免使用最大伪速度值。
  4. 返回电角度:

    return pHandle->_Super.hElAngle;
    
    • 返回更新后的电角度值。

总结

这个函数通过累加每周期的电角度增量来计算电角度,考虑了电机的电速度和补偿速度,并在最高转速时使用前一次的转子频率来更新电角度,以确保角度计算的连续性和准确性。.Transactional和湝higher溹㎕ข้อความ

(4)FOC电流控制器

/**
  * 函数功能: FOC电流控制器
  * 输入参数: @bMotor 电机编号
  * 返 回 值: @MC_NO_FAULTS or @MC_FOC_DURATION 
  * 说    明: 获取电角度,相电流
  */
inline uint16_t FOC_CurrController(uint8_t bMotor)
{
  Curr_Components Iab, Ialphabeta, Iqd;
  Volt_Components Valphabeta, Vqd;
  int16_t hElAngle;
  uint16_t hCodeError;

  hElAngle = SPD_GetElAngle(STC_GetSpeedSensor(pSTC[bMotor])); // 电角度
  PWMC_GetPhaseCurrents(pwmcHandle[bMotor], &Iab); // 获取相电流 根据扇区获取A,B,C相电流 Ia, Ib, Ic
  Ialphabeta = MCM_Clarke(Iab);                    // Clarke变换 Ia,Ib,Ic -> Iα,Iβ
  Iqd = MCM_Park(Ialphabeta, hElAngle);            // Park变换   Iα,Iβ - >  Iq,Id
  Vqd.qV_Component1 = PI_Controller(pPIDIq[bMotor],// PI控制器   Iq -> Vq
            (int32_t)(FOCVars[bMotor].Iqdref.qI_Component1) - Iqd.qI_Component1);

  Vqd.qV_Component2 = PI_Controller(pPIDId[bMotor],// PI控制器   Id -> Vd
            (int32_t)(FOCVars[bMotor].Iqdref.qI_Component2) - Iqd.qI_Component2);
  Vqd = Circle_Limitation(pCLM[bMotor], Vqd);      // 圆限制 97%
  Valphabeta = MCM_Rev_Park(Vqd, hElAngle);        // Rev_Park变换 Vq, Vd -> Vα,Vβ
  hCodeError = PWMC_SetPhaseVoltage(pwmcHandle[bMotor], Valphabeta);// SVPWM实现函数
  return(hCodeError);
}

这段代码定义了一个名为 FOC_CurrController 的函数,用于实现 FOC(Field-Oriented Control,磁场定向控制)电流控制。以下是对这段代码的详细解释:

函数声明

inline uint16_t FOC_CurrController(uint8_t bMotor)

这是一个内联函数(inline),用于减少函数调用的开销。函数的输入参数是一个 uint8_t 类型的电机编号 bMotor,返回值是一个 uint16_t 类型的值,表示控制过程中可能出现的错误代码(MC_NO_FAULTS 或 MC_FOC_DURATION)。

函数功能

  • 功能:实现 FOC 电流控制。
  • 输入参数@bMotor,电机编号。
  • 返回值@MC_NO_FAULTS 或 @MC_FOC_DURATION
  • 说明:获取电角度和相电流,进行一系列变换和控制,最终设置相电压。

函数体

Curr_Components Iab, Ialphabeta, Iqd;
Volt_Components Valphabeta, Vqd;
int16_t hElAngle;
uint16_t hCodeError;

hElAngle = SPD_GetElAngle(STC_GetSpeedSensor(pSTC[bMotor])); // 电角度
PWMC_GetPhaseCurrents(pwmcHandle[bMotor], &Iab); // 获取相电流 根据扇区获取A,B,C相电流 Ia, Ib, Ic
Ialphabeta = MCM_Clarke(Iab);                    // Clarke变换 Ia,Ib,Ic -> Iα,Iβ
Iqd = MCM_Park(Ialphabeta, hElAngle);            // Park变换   Iα,Iβ - >  Iq,Id
Vqd.qV_Component1 = PI_Controller(pPIDIq[bMotor],// PI控制器   Iq -> Vq
            (int32_t)(FOCVars[bMotor].Iqdref.qI_Component1) - Iqd.qI_Component1);

Vqd.qV_Component2 = PI_Controller(pPIDId[bMotor],// PI控制器   Id -> Vd
            (int32_t)(FOCVars[bMotor].Iqdref.qI_Component2) - Iqd.qI_Component2);
Vqd = Circle_Limitation(pCLM[bMotor], Vqd);      // 圆限制 97%
Valphabeta = MCM_Rev_Park(Vqd, hElAngle);        // Rev_Park变换 Vq, Vd -> Vα,Vβ
hCodeError = PWMC_SetPhaseVoltage(pwmcHandle[bMotor], Valphabeta);// SVPWM实现函数
return(hCodeError);

详细解释

  1. 变量声明

    Curr_Components Iab, Ialphabeta, Iqd;
    Volt_Components Valphabeta, Vqd;
    int16_t hElAngle;
    uint16_t hCodeError;
    
    • Iab:用于存储相电流(Ia, Ib, Ic)。
    • Ialphabeta:用于存储 α-β 坐标系中的电流(Iα, Iβ)。
    • Iqd:用于存储 dq 坐标系中的电流(Iq, Id)。
    • Valphabeta:用于存储 α-β 坐标系中的电压(Vα, Vβ)。
    • Vqd:用于存储 dq 坐标系中的电压(Vq, Vd)。
    • hElAngle:用于存储电机的电角度。
    • hCodeError:用于存储控制过程中可能出现的错误代码。
  2. 获取电角度

    hElAngle = SPD_GetElAngle(STC_GetSpeedSensor(pSTC[bMotor])); // 电角度
    
    • STC_GetSpeedSensor 函数获取与电机 bMotor 相关的速度传感器数据。
    • SPD_GetElAngle 函数根据速度传感器数据计算电角度,结果存储在 hElAngle 中。
  3. 获取相电流

    PWMC_GetPhaseCurrents(pwmcHandle[bMotor], &Iab); // 获取相电流 根据扇区获取A,B,C相电流 Ia, Ib, Ic
    
    • PWMC_GetPhaseCurrents 函数根据与电机 bMotor 相关的 PWM 控制器数据获取相电流(Ia, Ib, Ic),结果存储在 Iab 中。
  4. Clarke 变换

    Ialphabeta = MCM_Clarke(Iab);                    // Clarke变换 Ia,Ib,Ic -> Iα,Iβ
    
    • MCM_Clarke 函数将三相电流(Ia, Ib, Ic)转换为 α-β 坐标系中的电流(Iα, Iβ),结果存储在 Ialphabeta 中。
  5. Park 变换

    Iqd = MCM_Park(Ialphabeta, hElAngle);            // Park变换   Iα,Iβ - >  Iq,Id
    
    • MCM_Park 函数将 α-β 坐标系中的电流(Iα, Iβ)转换为 dq 坐标系中的电流(Iq, Id),结果存储在 Iqd 中。
  6. PI 控制器

    Vqd.qV_Component1 = PI_Controller(pPIDIq[bMotor],// PI控制器   Iq -> Vq
                (int32_t)(FOCVars[bMotor].Iqdref.qI_Component1) - Iqd.qI_Component1);
    Vqd.qV_Component2 = PI_Controller(pPIDId[bMotor],// PI控制器   Id -> Vd
                (int32_t)(FOCVars[bMotor].Iqdref.qI_Component2) - Iqd.qI_Component2);
    
    • PI_Controller 函数用于实现 PI 控制器。
    • pPIDIq[bMotor] 和 pPIDId[bMotor] 分别是与电机 bMotor 相关的 Iq 和 Id 控制器。
    • FOCVars[bMotor].Iqdref.qI_Component1 和 FOCVars[bMotor].Iqdref.qI_Component2 分别是 Iq 和 Id 的参考值。
    • 计算 Iq 和 Id 的误差(参考值 - 实际值),通过 PI 控制器计算出 Vq 和 Vd,结果分别存储在 Vqd.qV_Component1 和 Vqd.qV_Component2 中。
  7. 圆限制

    Vqd = Circle_Limitation(pCLM[bMotor], Vqd);      // 圆限制 97%
    
    • Circle_Limitation 函数对 dq 坐标系中的电压(Vq, Vd)进行圆限制,确保它们在安全范围内。结果存储在 Vqd 中。
  8. 反 Park 变换

    Valphabeta = MCM_Rev_Park(Vqd, hElAngle);        // Rev_Park变换 Vq, Vd -> Vα,Vβ
    
    • MCM_Rev_Park 函数将 dq 坐标系中的电压(Vq, Vd)转换为 α-β 坐标系中的电压(Vα, Vβ),结果存储在 Valphabeta 中。
  9. 设置相电压

    hCodeError = PWMC_SetPhaseVoltage(pwmcHandle[bMotor], Valphabeta);// SVPWM实现函数
    
    • PWMC_SetPhaseVoltage 函数根据 α-β 坐标系中的电压(Vα, Vβ)设置相电压,使用 SVPWM 技术实现。结果存储在 hCodeError 中,表示控制过程中可能出现的错误代码。
  10. 返回值

    return(hCodeError);
    
    • 函数返回 hCodeError,表示控制过程中可能出现的错误代码。

总结

  • 功能:实现 FOC 电流控制,用于电机控制。
  • 输入参数@bMotor,电机编号。
  • 返回值@MC_NO_FAULTS 或 @MC_FOC_DURATION
  • 说明
    • 获取电机的电角度和相电流。
    • 进行 Clarke 变换和 Park 变换,将相电流转换为 dq 坐标系中的电流。
    • 通过 PI 控制器计算 dq 坐标系中的电压。
    • 对电压进行圆限制,确保其在安全范围内。
    • 进行反 Park 变换,将电压转换回 α-β 坐标系。
    • 使用 SVPWM 技术设置相电压。
    • 返回控制过程中可能出现的错误代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值