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;
详细解释
-
变量声明
uint8_t bMotorNbr = 0; uint16_t hFOCreturn;
bMotorNbr
:用于存储电机编号,初始值为 0。hFOCreturn
:用于存储 FOC 电流控制函数的返回值。
-
计算电角度
HALL_CalcElAngle (&HALL_M1); // 计算电角度
HALL_CalcElAngle
是一个函数,用于计算电机的电角度。HALL_M1
是一个结构体指针,指向与电机 1 相关的霍尔传感器数据。
-
FOC 电流控制
hFOCreturn = FOC_CurrController(M1); // FOC 电流控制
FOC_CurrController
是一个函数,用于执行 FOC 电流控制。M1
是一个表示电机 1 的常量或枚举值。该函数的返回值存储在hFOCreturn
中。
-
错误处理
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
是错误处理函数的参数。
- 检查
-
返回值
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
,这是一个指向结构体的指针,包含了与霍尔传感器相关的信息和状态变量。
函数逻辑
-
条件判断:
if (pHandle->_Super.hElSpeedDpp != HALL_MAX_PSEUDO_SPEED) {... } else {pHandle->_Super.hElAngle += pHandle->PrevRotorFreq; }
- 条件: 检查当前的电速度(
hElSpeedDpp
)是否不等于最大伪速度(HALL_MAX_PSEUDO_SPEED
)。 - 最大伪速度: 可能表示电机处于最高转速状态。
- 条件: 检查当前的电速度(
-
如果电速度不等于最大伪速度:
-
更新测量电角度:
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
:保存上一次的电速度值,可能用于在下次电速度为最大伪速度时使用。
-
-
如果电速度等于最大伪速度:
-
更新电角度:
pHandle->_Super.hElAngle += pHandle->PrevRotorFreq;
- 在最高转速时,使用前一次的转子频率来更新电角度,以避免使用最大伪速度值。
-
-
返回电角度:
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, IcIalphabeta = MCM_Clarke(Iab); // Clarke变换 Ia,Ib,Ic -> Iα,IβIqd = MCM_Park(Ialphabeta, hElAngle); // Park变换 Iα,Iβ - > Iq,IdVqd.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);
详细解释
-
变量声明
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
:用于存储控制过程中可能出现的错误代码。
-
获取电角度
hElAngle = SPD_GetElAngle(STC_GetSpeedSensor(pSTC[bMotor])); // 电角度
STC_GetSpeedSensor
函数获取与电机bMotor
相关的速度传感器数据。SPD_GetElAngle
函数根据速度传感器数据计算电角度,结果存储在hElAngle
中。
-
获取相电流
PWMC_GetPhaseCurrents(pwmcHandle[bMotor], &Iab); // 获取相电流 根据扇区获取A,B,C相电流 Ia, Ib, Ic
PWMC_GetPhaseCurrents
函数根据与电机bMotor
相关的 PWM 控制器数据获取相电流(Ia, Ib, Ic),结果存储在Iab
中。
-
Clarke 变换
Ialphabeta = MCM_Clarke(Iab); // Clarke变换 Ia,Ib,Ic -> Iα,Iβ
MCM_Clarke
函数将三相电流(Ia, Ib, Ic)转换为 α-β 坐标系中的电流(Iα, Iβ),结果存储在Ialphabeta
中。
-
Park 变换
Iqd = MCM_Park(Ialphabeta, hElAngle); // Park变换 Iα,Iβ - > Iq,Id
MCM_Park
函数将 α-β 坐标系中的电流(Iα, Iβ)转换为 dq 坐标系中的电流(Iq, Id),结果存储在Iqd
中。
-
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
中。
-
圆限制
Vqd = Circle_Limitation(pCLM[bMotor], Vqd); // 圆限制 97%
Circle_Limitation
函数对 dq 坐标系中的电压(Vq, Vd)进行圆限制,确保它们在安全范围内。结果存储在Vqd
中。
-
反 Park 变换
Valphabeta = MCM_Rev_Park(Vqd, hElAngle); // Rev_Park变换 Vq, Vd -> Vα,Vβ
MCM_Rev_Park
函数将 dq 坐标系中的电压(Vq, Vd)转换为 α-β 坐标系中的电压(Vα, Vβ),结果存储在Valphabeta
中。
-
设置相电压
hCodeError = PWMC_SetPhaseVoltage(pwmcHandle[bMotor], Valphabeta);// SVPWM实现函数
PWMC_SetPhaseVoltage
函数根据 α-β 坐标系中的电压(Vα, Vβ)设置相电压,使用 SVPWM 技术实现。结果存储在hCodeError
中,表示控制过程中可能出现的错误代码。
-
返回值
return(hCodeError);
- 函数返回
hCodeError
,表示控制过程中可能出现的错误代码。
- 函数返回
总结
- 功能:实现 FOC 电流控制,用于电机控制。
- 输入参数:
@bMotor
,电机编号。 - 返回值:
@MC_NO_FAULTS
或@MC_FOC_DURATION
。 - 说明:
- 获取电机的电角度和相电流。
- 进行 Clarke 变换和 Park 变换,将相电流转换为 dq 坐标系中的电流。
- 通过 PI 控制器计算 dq 坐标系中的电压。
- 对电压进行圆限制,确保其在安全范围内。
- 进行反 Park 变换,将电压转换回 α-β 坐标系。
- 使用 SVPWM 技术设置相电压。
- 返回控制过程中可能出现的错误代码。