1. 直流电机PWM开环调速系统搭建

直流电机PWM开环调速系统搭建 学习卡片

系统组成与信号链

本案例用一块通用MCU(以STM32F103为例)的定时器TIM3_CH1在PA6引脚输出PWM,经H桥驱动模块(如L298N或TB6612)放大后驱动直流有刷电机。开环意味着不采集转速反馈,占空比D直接决定电枢平均电压,从而决定空载/轻载转速。整条信号链为:定时器计数 → 比较寄存器CCR → 占空比D → 驱动平均电压 → 电机转速。

直流电机PWM开环调速信号链 MCU (STM32F103) TIM3 定时器 PSC=71, ARR=999 CCR1 = D × 1000 PA6 → PWM输出 PWM波形 (f=1kHz) D = 30% 示例 H桥驱动 L298N / TB6612 VCC = 12V 使能端 ENA=1 IN1=1, IN2=0 直流有刷电机 M 额定 12V / 3000rpm 占空比-转速关系(开环,空载近似线性) 占空比 D (%) 转速 n (rpm) 0 25 50 75 100 关键关系式: V_avg = D × V_supply = D × 12V n ≈ (V_avg − I·R_a) / K_e 空载时 I 很小,n 与 D 近似线性

硬件连接与定时器配置

接线要点:PA6接驱动模块PWM输入,驱动模块输出接电机两端,共地。定时器配置为PWM模式1,预分频PSC=71,自动重装ARR=999,系统时钟72MHz时PWM频率 = 72MHz / (72 × 1000) = 1kHz。占空比D由比较寄存器CCR1决定:CCR1 = D × (ARR+1) = D × 1000。

参数值说明
系统时钟72 MHzSTM32F103标准配置
PSC71分频后计数时钟 = 1 MHz
ARR999计数周期 = 1000 个时钟
PWM频率1 kHz1MHz / 1000
CCR10~1000对应占空比 0%~100%

关键代码实现

#include "stm32f10x.h"

void PWM_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
    TIM_OCInitTypeDef TIM_OCInitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);

    /* PA6 复用推挽输出 */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    /* 时基:72MHz/(71+1)=1MHz,ARR=999 → 1kHz */
    TIM_TimeBaseStructure.TIM_Period = 999;
    TIM_TimeBaseStructure.TIM_Prescaler = 71;
    TIM_TimeBaseStructure.TIM_ClockDivision = 0;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);

    /* PWM模式1,初始占空比0 */
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_Pulse = 0;
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
    TIM_OC1Init(TIM3, &TIM_OCInitStructure);
    TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);

    TIM_ARRPreloadConfig(TIM3, ENABLE);
    TIM_Cmd(TIM3, ENABLE);
}

/* 设置占空比,duty: 0~100 */
void PWM_SetDuty(uint8_t duty)
{
    if (duty > 100) duty = 100;
    TIM_SetCompare1(TIM3, duty * 10);  /* CCR1 = duty × 1000 / 100 */
}

int main(void)
{
    PWM_Init();
    while (1)
    {
        for (uint8_t d = 0; d <= 100; d += 10)
        {
            PWM_SetDuty(d);
            for (volatile uint32_t i = 0; i < 7200000; i++); /* 约1s延时 */
        }
    }
}

占空比-转速测量方法

用光电转速表或编码器(后续案例展开)测量电机轴端转速。操作流程:从D=0开始,每次增加10%,待转速稳定后记录读数,填入下表。注意:开环系统在低速段(D<15%)可能因静摩擦不转,属于正常死区现象。

占空比 D (%)CCR1 值实测转速 (rpm)现象记录
000停转
10100—可能不转(静摩擦)
20200约 500缓慢启动
40400约 1100平稳运行
60600约 1700平稳运行
80800约 2300接近额定
1001000约 2900全速
测量时保持电机空载或轻载恒定,否则负载变化会破坏占空比-转速的单值对应关系。若需提高低速分辨率,可降低PWM频率至500Hz或提高ARR值。
驱动模块使能端必须置有效电平,否则PWM信号无法到达电机。共地不良会导致PWM波形畸变、转速抖动。切勿将电机电源与MCU电源直接并联而不加滤波。

结果判读与验证

  • 线性度检查:以D为横轴、转速为纵轴作图,空载下应近似直线,斜率反映电机KV特性。
  • 死区确认:D从0缓慢增加,记录电机刚开始转动的最小D值,即为该电机的启动死区。
  • 重复性验证:同一D值下多次测量转速,偏差应在±5%以内(空载稳定后)。
  • 异常判断:若D增加但转速不增或下降,检查驱动供电是否跌落、电机是否堵转、PWM极性是否配置错误。