变压变频(V/f)电机控制程序
目标:不用复杂 FOC,只用 V/f 开环控制,实现电机平滑调速。
一、控制原理
频率 ↑ → 电压 ↑,保持 V/f ≈ 常数
\(\frac{V}{f} = \text{Const}\)
适用于:
- 三相异步电机(最常用)
- PMSM(开环弱磁前)
- 风机 / 水泵 / 传送带
二、系统结构
STM32
├─ TIM1(高级定时器)
│ ├─ 三路 PWM(U/V/W)
│ └─ 死区控制
├─ ADC(母线电压采样)
└─ 主循环
└─ 根据目标频率计算 PWM 占空比
三、关键参数定义
#define PWM_FREQ_MAX 20000 // PWM 载波频率 (Hz)
#define MOTOR_BASE_FREQ 50.0f // 额定频率
#define MOTOR_BASE_VOLT 220.0f // 额定电压
#define VOLT_PER_HZ (MOTOR_BASE_VOLT / MOTOR_BASE_FREQ)
四、V/f 计算函数
#include <math.h>
float Get_Vf_Voltage(float freq)
{
float volt;
if (freq < 1.0f)
return 0.0f;
// 线性 V/f
volt = VOLT_PER_HZ * freq;
// 弱磁区(可选)
if (volt > MOTOR_BASE_VOLT)
volt = MOTOR_BASE_VOLT;
return volt;
}
五、SPWM 生成(正弦 PWM)
1、正弦表
#define SIN_TABLE_SIZE 512
static uint16_t sin_table[SIN_TABLE_SIZE];
void SinTable_Init(void)
{
for (int i = 0; i < SIN_TABLE_SIZE; i++) {
sin_table[i] = (uint16_t)(
(sin(2 * 3.1415926f * i / SIN_TABLE_SIZE) + 1.0f) * 0.5f * 1000
);
}
}
2、更新 PWM(V/f 核心)
void Update_Vf_PWM(float freq)
{
static uint32_t phase_u = 0;
uint32_t step;
float volt_ratio;
if (freq < 0.5f) {
__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, 0);
__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_2, 0);
__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_3, 0);
return;
}
// 频率 → 相位增量
step = (uint32_t)(freq * SIN_TABLE_SIZE / PWM_FREQ_MAX);
// V/f 电压比例
volt_ratio = Get_Vf_Voltage(freq) / MOTOR_BASE_VOLT;
// 更新三相 PWM
__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1,
(uint16_t)(sin_table[(phase_u) % SIN_TABLE_SIZE] * volt_ratio));
__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_2,
(uint16_t)(sin_table[(phase_u + 171) % SIN_TABLE_SIZE] * volt_ratio));
__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_3,
(uint16_t)(sin_table[(phase_u + 342) % SIN_TABLE_SIZE] * volt_ratio));
phase_u += step;
}
六、定时器 PWM 初始化(STM32 HAL)
void MX_TIM1_Init(void)
{
TIM_MasterConfigTypeDef sMasterConfig = {0};
TIM_OC_InitTypeDef sConfigOC = {0};
TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0};
htim1.Instance = TIM1;
htim1.Init.Prescaler = 0;
htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
htim1.Init.Period = 1000; // PWM 分辨率
htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim1.Init.RepetitionCounter = 0;
HAL_TIM_PWM_Init(&htim1);
sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = 0;
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;
sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;
HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1);
HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_2);
HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_3);
sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE;
sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE;
sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;
sBreakDeadTimeConfig.DeadTime = 100; // 死区时间(ns)
sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;
sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;
HAL_TIMEx_ConfigBreakDeadTime(&htim1, &sBreakDeadTimeConfig);
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_2);
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_3);
HAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_1);
HAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_2);
HAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_3);
}
参考代码 简单的电机控制程序,实现变压变频的功能 www.youwenfan.com/contentcnu/69804.html
七、主循环(最简单的 V/f 控制)
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_TIM1_Init();
SinTable_Init();
float freq = 5.0f; // 初始频率 5Hz
while (1)
{
// 缓慢加速
if (freq < 50.0f)
freq += 0.1f;
Update_Vf_PWM(freq);
HAL_Delay(50);
}
}
八、调试要点
先不加电机,用示波器看 UVW 波形
确认三相正弦、120° 相位差
死区时间 ≥ MOSFET 开关时间
低频电压补偿(防堵转)

浙公网安备 33010602011771号