STM32电机库5.4开源注释 KEIL工程文件 辅助理解S STM32电机库5.4开源注释 KEIL工程文件 辅助理解ST库 寄存器设置AD TIM1 龙贝格+PLL 前馈控制 弱磁控制 foc的基本流 svpwm占空比计算方法 斜坡启动 死区补偿 有详细的注释, 当前是无传感器版本龙贝格观测,三电阻双AD采样。
最近在研究电机控制相关项目时,发现了 STM32 电机库 5.4,这个开源项目还带有 KEIL 工程文件以及详细注释,对于理解 ST 库和电机控制算法简直是一大福音,今天就来和大家分享下我的一些研究心得。
寄存器设置之 AD 和 TIM1
在电机控制中,AD(模数转换)和 TIM1(定时器)的寄存器设置非常关键。比如在 ADC 配置部分,我们要设置采样时间、转换模式等参数。
c
// 使能 ADC 时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
// ADC 初始化结构体
ADC_InitTypeDef ADC_InitStructure;
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfChannel = 1;
ADC_Init(ADC1, &ADC_InitStructure);
// 设置通道 0,采样时间为 239.5 周期
ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_239Cycles5);
// 使能 ADC
ADC_Cmd(ADC1, ENABLE);
上述代码中,首先使能了 ADC1 的时钟,然后对 ADC 进行初始化配置,设置为独立模式,非扫描、非连续转换,软件触发,数据右对齐,单通道转换。接着配置通道 0 以及采样时间,最后使能 ADC,这样 ADC 就可以准备好采集数据了。

而 TIM1 定时器通常用于生成 PWM 波来驱动电机。
c
// 使能 TIM1 时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
TIM_TimeBaseStructure.TIM_Period = arr;
TIM_TimeBaseStructure.TIM_Prescaler = psc;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
// PWM 模式配置
TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 0;
TIM_OC1Init(TIM1, &TIM_OCInitStructure);
// 使能 TIM1
TIM_Cmd(TIM1, ENABLE);
这里先使能 TIM1 时钟,接着设置定时器的周期(arr)、预分频器(psc)等参数,确定计数器模式为向上计数。然后配置 PWM 模式为 PWM1 模式并使能输出,最后使能 TIM1,这样 TIM1 就能按照设定生成 PWM 波了。
龙贝格 + PLL:独特的组合
龙贝格观测器在这个无传感器版本中起着重要作用。它通过对电机的电流、电压等信息进行估算,从而得出电机的转速和位置信息。
PLL(锁相环)则用于倍频,为系统提供更稳定、精准的时钟信号。比如在系统初始化中可能会有这样的代码:
c
// 配置 PLL 时钟源为 HSE,倍频因子为 9
RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
// 使能 PLL
RCC_PLLCmd(ENABLE);
// 等待 PLL 稳定
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
// 选择 PLL 作为系统时钟
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
通过上述代码,先配置 PLL 以 HSE 为时钟源并进行 9 倍频,使能后等待其稳定,最后选择 PLL 输出作为系统时钟,保证系统各模块能在合适的时钟频率下稳定运行。
前馈控制与弱磁控制
前馈控制能够根据系统的输入或干扰提前进行控制补偿,在电机控制中,能让电机更快更准确地响应指令。比如在速度环控制中,我们可以根据给定速度的变化率提前调整控制量。

STM32电机库5.4开源注释 KEIL工程文件 辅助理解S STM32电机库5.4开源注释 KEIL工程文件 辅助理解ST库 寄存器设置AD TIM1 龙贝格+PLL 前馈控制 弱磁控制 foc的基本流 svpwm占空比计算方法 斜坡启动 死区补偿 有详细的注释, 当前是无传感器版本龙贝格观测,三电阻双AD采样。
弱磁控制则是在电机高速运行时,通过减弱磁场来提高电机的转速范围。在代码实现上,可能会涉及到对电机励磁电流的调整。
FOC 的基本流与 SVPWM 占空比计算方法
FOC(磁场定向控制)是现代电机控制的核心算法之一。其基本流程大致是通过坐标变换,将三相静止坐标系下的电流转换到两相旋转坐标系(d - q 轴)下进行控制。
c
// 假设已经采集到三相电流 ia, ib, ic
float id, iq;
// Clarke 变换
float alpha = ia;
float beta = (sqrt(3) / 3) * (ib - ic);
// Park 变换
float theta = get_estimated_angle(); // 通过龙贝格观测器获取估计角度
id = alpha * cos(theta) + beta * sin(theta);
iq = -alpha * sin(theta) + beta * cos(theta);
上述代码展示了 Clarke 变换和 Park 变换的简单实现,通过这些变换可以将三相电流分解为 d - q 轴电流,方便进行控制。

SVPWM(空间矢量脉宽调制)则是用于生成逆变器的驱动信号。它通过合理分配逆变器的开关状态,使电机获得更接近圆形的旋转磁场。其占空比计算方法相对复杂一些,通常要考虑到扇区判断等因素。
c
// 假设已经计算出 d - q 轴电压 Vd, Vq
float Valpha = Vd * cos(theta) - Vq * sin(theta);
float Vbeta = Vd * sin(theta) + Vq * cos(theta);
// 扇区判断
int sector = get_sector(Valpha, Vbeta);
// 计算占空比
float T1, T2, T0;
calculate_duty_cycle(Valpha, Vbeta, sector, &T1, &T2, &T0);
上述代码中,先将 d - q 轴电压转换为 alpha - beta 轴电压,然后判断扇区,最后根据扇区和电压值计算出各个开关状态的占空比 T1、T2 和 T0。
斜坡启动与死区补偿
斜坡启动是为了让电机平稳启动,避免启动瞬间电流过大对电机和电源造成冲击。在代码中可能会设置一个速度或电流的上升斜率。
c
float target_speed = get_target_speed();
float current_speed = 0;
float ramp_rate = 0.1; // 速度上升斜率
while(current_speed < target_speed) {
current_speed += ramp_rate;
set_motor_speed(current_speed);
delay(100); // 延时控制上升速度
}
上述代码简单模拟了斜坡启动过程,通过不断增加当前速度并设置给电机,同时利用延时来控制速度上升的快慢。
死区补偿则是因为逆变器的功率器件在导通和关断时存在延迟,需要添加死区时间来防止上下桥臂直通。在代码中通常会对 PWM 波的输出进行调整。
c
// 假设已经生成基本的 PWM 波
TIM_SetCompare1(TIM1, duty_cycle1);
TIM_SetCompare2(TIM1, duty_cycle2);
TIM_SetCompare3(TIM1, duty_cycle3);
// 死区补偿
TIM_BDTRConfig(TIM1, TIM_OSSRState_Enable | TIM_OSSIState_Enable |
TIM_LOCKLevel_OFF | TIM_DeadTime_5, TIM_Break_Disable,
TIM_BreakPolarity_High, TIM_AutomaticOutput_Disable);
通过上述代码,在设置完基本的 PWM 占空比后,利用 TIM_BDTRConfig 函数对 TIM1 进行死区配置,确保电机驱动的安全性。

这个 STM32 电机库 5.4 开源项目涵盖了丰富的电机控制知识和实用算法,无论是对于新手学习还是老手优化项目,都具有很高的价值,希望大家也能从中获得启发。