基于位置式PID算法调节PWM占空比实现电机转速控制

基于位置式PID算法调节PWM占空比实现电机转速控制


一、系统架构设计

1. 硬件组成
模块 核心组件 功能说明
主控单元 STM32F407(TIM1+TIM2) PWM生成与PID运算
电机驱动 TB6612(PWMA/PWMB) PWM输入控制电机转速
反馈装置 霍尔编码器(500线) 转速检测(2000脉冲/转)
电源模块 12V/2A DC电源 电机供电
2. 电路连接
复制代码
STM32引脚连接                | 功能说明
----------------------------|----------------------------
TIM1_CH1 (PA8)              | 电机PWM输出
TIM2_CH1 (PA0)              | 编码器A相信号输入
TIM2_CH2 (PA1)              | 编码器B相信号输入
PB6 (BOOT0)                 | 电机方向控制
3.3V                        | 编码器供电
GND                         | 公共地

二、PID算法实现

1. 位置式PID公式

u(k)=Kpe(k)+Kii=0∑ke(i)+Kd[e(k)−e(k−1)]u(k)=Kpe(k)+Kii=0∑ke(i)+Kd[e(k)−e(k−1)]u(k)=Kpe(k)+Kii=0∑ke(i)+Kd[e(k)−e(k−1)]

  • 输入变量:目标转速(Setpoint)与实际转速(Feedback)的差值
  • 输出变量:PWM占空比(0-100%)
2. 关键参数定义
c 复制代码
typedef struct {
    float Kp;      // 比例系数(建议初始值2.0-5.0)
    float Ki;      // 积分系数(建议初始值0.1-0.5)
    float Kd;      // 微分系数(建议初始值0.01-0.1)
    float integral;// 积分项累加值
    float prev_err;// 上一次误差
    float max_out; // 输出上限(PWM最大占空比)
} PID_HandleTypeDef;
3. PID初始化函数
c 复制代码
void PID_Init(PID_HandleTypeDef *pid, float Kp, float Ki, float Kd) {
    pid->Kp = Kp;
    pid->Ki = Ki;
    pid->Kd = Kd;
    pid->integral = 0.0f;
    pid->prev_err = 0.0f;
    pid->max_out = 100.0f; // PWM占空比上限
}
4. PID计算函数
c 复制代码
float PID_Compute(PID_HandleTypeDef *pid, float setpoint, float feedback, float dt) {
    float error = setpoint - feedback;
    
    // 比例项
    float Pout = pid->Kp * error;
    
    // 积分项
    pid->integral += error * dt;
    float Iout = pid->Ki * pid->integral;
    
    // 微分项
    float derivative = (error - pid->prev_err) / dt;
    float Dout = pid->Kd * derivative;
    
    // 计算总输出
    float output = Pout + Iout + Dout;
    
    // 输出限幅
    if(output > pid->max_out) {
        pid->integral -= error * dt; // 防止积分饱和
        output = pid->max_out;
    } else if(output < 0) {
        output = 0;
    }
    
    pid->prev_err = error;
    return output;
}

三、硬件驱动实现

1. PWM配置(STM32 HAL库)
c 复制代码
void MX_TIM1_Init(void) {
    TIM_HandleTypeDef htim1;
    
    htim1.Instance = TIM1;
    htim1.Init.Prescaler = 84-1;      // 84MHz / 84 = 1MHz
    htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
    htim1.Init.Period = 1000-1;       // 1kHz PWM频率
    htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
    HAL_TIM_PWM_Init(&htim1);
    
    // 配置通道1
    TIM_OC_InitTypeDef sConfigOC = {0};
    sConfigOC.OCMode = TIM_OCMODE_PWM1;
    sConfigOC.Pulse = 0;              // 初始占空比0%
    sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
    HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1);
    
    HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);
}
2. 编码器测速
c 复制代码
volatile uint32_t encoder_count = 0;
volatile float motor_speed = 0.0f;

// 编码器中断处理(TIM2)
void TIM2_IRQHandler(void) {
    if(TIM_GetITStatus(TIM2, TIM_IT_CC1) != RESET) {
        if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1) == GPIO_PIN_SET) {
            encoder_count++;
        }
        TIM_ClearITPendingBit(TIM2, TIM_IT_CC1);
    }
}

// 计算转速(每100ms更新一次)
void Calc_Speed() {
    static uint32_t last_count = 0;
    static float rpm = 0.0f;
    
    motor_speed = (encoder_count - last_count) * 60.0f / 0.1f; // 500线编码器
    last_count = encoder_count;
}

四、主控制循环

c 复制代码
int main(void) {
    HAL_Init();
    SystemClock_Config();
    
    MX_TIM1_Init();   // PWM初始化
    MX_TIM2_Init();   // 编码器初始化
    
    PID_HandleTypeDef motor_pid;
    PID_Init(&motor_pid, 2.5f, 0.2f, 0.05f); // 初始参数
    
    while(1) {
        Calc_Speed();               // 更新转速测量值
        float duty = PID_Compute(&motor_pid, 1000.0f, motor_speed, 0.001f); // 1kHz采样
        __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, duty); // 更新占空比
        HAL_Delay(1);
    }
}

参考代码 位置式PID调节PWM占空比控制电动机转速 www.youwenfan.com/contentcsj/70961.html

五、参数整定方法

1. Ziegler-Nichols法
步骤 操作 结果记录
1 关闭I/D项(Ki=0, Kd=0) 基准Kp值
2 逐渐增大Kp至系统持续振荡 记录Ku和Tu
3 计算PID参数:
Kp = 0.6*Ku
Ki = 1.2*Ku/Tu
Kd = 0.075KuTu
2. 实际调试建议
  • 初始参数:Kp=2.0, Ki=0.1, Kd=0.01
  • 调整顺序:先调P→再调I→最后调D
  • 典型调试现象: Kp过小:响应慢,稳态误差大 Kp过大:超调严重,振荡 Ki过大:积分饱和,爬行现象 Kd过大:噪声敏感,产生振荡
相关推荐
三佛科技-134163842123 小时前
暴力风扇方案MCU控制芯片开发
单片机·嵌入式硬件·智能家居·pcb工艺
不到满级不改名3 小时前
EM算法 & 隐马尔可夫模型
算法
我先去打把游戏先4 小时前
ESP32学习笔记(基于IDF):SmartConfig一键配网
笔记·嵌入式硬件·mcu·物联网·学习·esp32·硬件工程
workflower8 小时前
单元测试-例子
java·开发语言·算法·django·个人开发·结对编程
小莞尔10 小时前
【51单片机】【protues仿真】基于51单片机数字温度计数码管系统
单片机·嵌入式硬件
MicroTech202510 小时前
微算法科技(MLGO)研发突破性低复杂度CFG算法,成功缓解边缘分裂学习中的掉队者问题
科技·学习·算法
墨染点香10 小时前
LeetCode 刷题【126. 单词接龙 II】
算法·leetcode·职场和发展
aloha_78911 小时前
力扣hot100做题整理91-100
数据结构·算法·leetcode
Tiny番茄11 小时前
31.下一个排列
数据结构·python·算法·leetcode