当前位置: 首页 > news >正文

STM32F103直流有刷电机速度闭环控制

在《基于直流有刷电机的速度闭环控制以及matlab仿真》我们介绍了速度闭环控制的实现,其采用的是PID控制算法,本节我们就基于STM32F103来实现直流电机的增量式PID速度闭环控制。

一、软件实现

我们需要将PID控制器应用于STM32F103的速度闭环电机控制,以下是接下来的步骤:

  • 电机速度测量:使用编码器来测量电机的实际转速,需要配置定时器的编码器模式来读取编码器脉冲,从而计算速度;具体参考《STM32F103霍尔编码器测速》;
  • 电机驱动:通常使用PWM驱动电机,需要配置定时器的PWM输出模式,并设置占空比来控制电机速度;具体参考《基于直流有刷电机的开环调速控制以及matlab仿真》;
  • 系统定时:PID计算需要定期执行,因此需要配置一个定时器中断,在中断服务函数中执行PID计算和更新PWM输出;
  • 主程序初始化:初始化所有外设(编码器定时器、电机PWM、中断定时器等)和PID参数;
  • 主循环:通常主循环可以处理一些非实时任务,比如接收用户指令(例如通过串口改变目标速度)等。

1.1 pid.h

control目录下新建pid文件,自定义PID结构体;

/******************************************************************************************************/
#ifndef _STM32f10x_PID__H
#define _STM32f10x_PID__Htypedef struct {float Kp, Ki, Kd;      // 比例、积分、微分系数float Ts;              // 周期float prev_error;      // e(k-1)float prev_error2;     // e(k-2)float out_max;         // 输出的最大值(占空比)float out_min;         // 输出的最小值(占空比)float output;          // 当前总输出 u(k)float target_val;      // 目标值 
} PID;extern PID g_pid;                    // 全局PID参数
extern void pid_param_init(void);    // 初始化PID参数
extern float pid_compute(float measurement);  // PID计算#endif 

1.2 pid.c

1.2.1 初始化PID参数
/*****************************************************************************/
#include "pid.h"PID g_pid;     // 全局pid参数/*******************************************************************************		 Description:   初始化g_pid参数********************************************************************************/
void pid_param_init()
{g_pid.target_val = 5000.0f;  // 目标值5000 RPMg_pid.Ts = 0.01f;            // 10ms控制周期g_pid.output = 0.0f;g_pid.prev_error = 0.0f;g_pid.prev_error2 = 0.0f;g_pid.out_max = 100.0f;      // 最大输出(占空比)g_pid.out_min = 0.0f;        // 最小输出g_pid.Kp = 0.6f;g_pid.Ki = 0.4f;g_pid.Kd = 0.2f;
}

pid_param_init()函数把结构体g_pid参数初始化,将目标值g_pid.target_val设置为5000.00;将实际值、上一次偏差值和上上次偏差值等初始化为0

1.2.2 PID算法实现

增量式PID算法:

\[Δu(k)=K_p[e(k)-e(k-1)]+K_iT_se(k)+\frac{K_d}{T_s}[e(k)-2e(k-1)+e(k-2)] \]

\[u(k)=u(k-1)+Δu(k) \]

PID算法实现:

/****************************************************************************************************************		 Description: PID控制算法*       Parameter  :  measurement:测量值*       Return     :  PID输出值***************************************************************************************************************/
float pid_compute(float measurement) {float error = g_pid.target_val - measurement;// 计算控制增量float delta_u = g_pid.Kp * (error - g_pid.prev_error)+ g_pid.Ki * g_pid.Ts * error+ (g_pid.Kd / g_pid.Ts) * (error - 2.0f * g_pid.prev_error + g_pid.prev_error2);// 计算新的总输出g_pid.output = g_pid.output + delta_u;// 输出限幅if (g_pid.output > g_pid.out_max) g_pid.output = g_pid.out_max;if (g_pid.output < g_pid.out_min) g_pid.output = g_pid.out_min;// 更新误差历史g_pid.prev_error2 = g_pid.prev_error;g_pid.prev_error = error;return g_pid.output;
}

1.3 TIM6_IRQHandler中断处理函数

开启定时中断,这里使用的定时器6,定时周期为10ms,在定时器溢出中断中执行PID运算;修改time.c文件:

#include "encoder.h"
#include "pid.h"/******************************************************************************** Function Name  : TIM6_IRQHandler* Description    : This function handles TIM6 global interrupt request.* Input          : None* Output         : None* Return         : None*******************************************************************************/
void TIM6_IRQHandler(void)
{//**********************自定义用户任务****************************//int res_pwm = 0;    /*PWM值(PID输出)*/// 1. 获取编码器速度g_motor_speed = get_encoder_speed(10);// 2. 进行PID运算,得到PWM输出值res_pwm = pid_compute(g_motor_speed);// 3. 更新PWM输出motor_set_duty(res_pwm);//*****************************************************************//TIM6->SR &= ~(1 << 0); // 清中断标志
}

其中motor_set_duty定义在motor.c文件中;

/**************************************************************************************************
*
*    Function  :  设置电机PWM占空比
*    Parameter :  duty:PWM占空比
*
**************************************************************************************************/
void  motor_set_duty(int duty)
{g_motor_pwm = duty;if(g_motor_pwm < 0){g_motor_pwm = 0;}if(g_motor_pwm >100){g_motor_pwm = 100;}motor_update_speed();
}

1.4 主函数

#include "common.h"
#include "stdio.h"int main()
{int duty;int speed;STM32_Clock_Init(9); // 系统时钟初始化// 串口初始化STM32_NVIC_Init(2, USART1_IRQn, 0, 1); // 串口中断优先级初始化,其中包括中断使能usart_init(USART_1, 115200);           // 串口1初始化,波特率115200 映射到PA9 PA10// 按键KEY初始化gpio_init(PC5, GPI_UP, HIGH);             // PC5接按键KEY0gpio_init(PA15, GPI_UP, HIGH);            // PA15接按键KEY1Ex_NVIC_Congig(PC5, FALLING);             // 按键KEY0按下触发 高电平->低电平Ex_NVIC_Congig(PA15, FALLING);            // 按键KEY1按下触发 高电平->低电平STM32_NVIC_Init(2, EXTI9_5_IRQn, 2, 2);   // EXTI线[9:5]中断优先级初始化,其中包括中断使能STM32_NVIC_Init(2, EXTI15_10_IRQn, 2, 2); // EXTI线[15:10]中断优先级初始化,其中包括中断使能motor_init(); // 电机初始化,使用的定时器2,PA0/PA1encoder_init(); // 编码器初始化,使用的定时器4,PB6/PB7STM32_NVIC_Init(2, TIM6_IRQn, 0, 0); // TIM6溢出中端使能TIM_Init_MS(TIMER6, 10);             // TIM6计数到10ms发生中断,在TIM6_IRQHandler中获取转速,并保存到全局变量g_motor_speedwhile (1){duty = get_motor_duty();printf("duty: %d\n", duty);delay_ms(1000);printf("Speed: %d RPM\n", g_motor_speed); // 打印转速}
}

二、 测试

编译程序并下载测试,可以通过串口查看当前输出的占空比以及对应的转速;

三、源码下载

源码下载路径:stm32f103

参考文章

[1] 基于直流有刷电机的开环调速控制以及matlab仿真

[2] STM32F103霍尔编码器测速

http://www.jsqmd.com/news/57509/

相关文章:

  • 英语_阅读_City Park Facilities Survey_待读
  • 2025年石笼网优质供应商排名,这5家好评不断,双隔板石笼网/抗冲击抗腐蚀石笼网/锌铝合金石笼网/镀锌低碳钢丝石笼网源头厂家选哪家
  • 2025成都抖音代运营机构口碑排行榜单发布,网络营销/小红书代运营/快手代运营/GEO优化/抖音代运营/抖音代运营公司找哪家
  • 格宾石笼网2025年生产公司排名,哪家更值得选择?镀锌低碳钢丝石笼网/抗冲击抗腐蚀石笼网/格宾石笼网实力厂家选哪家
  • 2025.12.1
  • Keep dreaming, remain loving. / NOIP2025 游记
  • 2025十大私域电商核心工具:小鹅通领跑全链路生态,赋能增长新范式
  • 第四十三天
  • 哪家无人机培训机构可以考证?国内正规机构推荐
  • 明日也要加油
  • 完整教程:【图像处理】jpeg 格式详解
  • 12.1 日志
  • 无人机培训学校有哪些?国内优质机构推荐
  • 我在CSDN学MYSQL之----数据库基本概念和基本知识(下) - 教程
  • 基于Springboot的旧物公益捐赠管理系统3726v22v(程序、源码、数据库、调试部署方案及开发环境)架构界面展示及获取方式置于文档末尾,可供参考。
  • 2025年最新防雨棚供应商排行榜,联系电话一键获取,一体化监控杆/方舟控制台/八角监控杆/交通监控杆/防雨棚供应厂家联系电话
  • 3.5 分页系统中的设计问题 Design Issues For Paging Systems
  • 英语_阅读_calligraphy_待读
  • 初一初二初三全适配!带你寒假精准提分的初中数学名师排行榜来了
  • 我的第一个自动化测试用例:从零开始的Selenium实战指南 - 实践
  • Kafka - Install Kafka-4.1.1
  • GitHub Actions 供应链攻击:Reviewdog 多个动作在特定时间段遭入侵
  • 快关注Jason227!!!
  • 企业 IT 系统安全防护与漏洞管理实践探索 - 教程
  • 英语_阅读_Lets build a robot!_待读
  • 【折点计数】简单谷底和峰顶的找寻
  • 详细介绍:蓝牙钥匙 第25次 蓝牙钥匙与信息娱乐系统:智能座舱的个性化体验
  • 开发文档 - OUC
  • Alpha阶段第一周 - OUC
  • 买二手车怎么选 首选唐山汇海汽车