手机网站建设银川网站建设

辽宁方软科技有限公司 2026/09/09 20:55:14

位置式PID控制原理

位置式PID算法的离散形式为:

u(k)=Kp×e(k)+Ki×∑e(j)+Kd×[e(k)−e(k−1)]u(k) = Kp × e(k) + Ki × ∑e(j) + Kd × [e(k) - e(k-1)]u(k)=Kp×e(k)+Ki×e(j)+Kd×[e(k)e(k1)]

其中:

  • u(k)u(k)u(k):当前时刻控制输出(PWM占空比)
  • e(k)e(k)e(k):当前误差 = 目标转速 - 实际转速
  • ∑e(j)∑e(j)e(j):误差累积和(积分项)
  • Kp,Ki,KdKp, Ki, KdKp,Ki,Kd:PID参数

硬件配置

所需外设

  • 编码器接口:测量电机转速
  • PWM输出:控制电机驱动
  • 定时器:用于定时采样和PID计算

引脚配置示例

// PWM输出引脚 (控制电机)#defineMOTOR_PWM_PINGPIO_Pin_8#defineMOTOR_PWM_PORTGPIOA#defineMOTOR_PWM_TIMTIM1// 编码器输入引脚#defineENCODER_A_PINGPIO_Pin_6#defineENCODER_B_PINGPIO_Pin_7#defineENCODER_PORTGPIOA#defineENCODER_TIMTIM3

完整程序代码

1. PID结构体定义

typedefstruct{floatTarget;// 目标转速floatCurrent;// 当前转速floatError;// 当前误差floatLastError;// 上一次误差floatPreError;// 上上次误差floatKp;// 比例系数floatKi;// 积分系数floatKd;// 微分系数floatIntegral;// 积分累计floatIntegralMax;// 积分限幅floatOutput;// PID输出floatOutputMax;// 输出限幅floatOutputMin;// 输出下限}PID_TypeDef;// 初始化PID参数voidPID_Init(PID_TypeDef*pid,floatkp,floatki,floatkd,floatmax_output){pid->Kp=kp;pid->Ki=ki;pid->Kd=kd;pid->Integral=0;pid->Target=0;pid->Current=0;pid->Output=0;pid->OutputMax=max_output;pid->OutputMin=0;pid->IntegralMax=max_output*0.8f;// 积分限幅为输出的80%}

2. 位置式PID计算函数

// 位置式PID计算floatPID_Calculate(PID_TypeDef*pid,floattarget,floatcurrent){floatincrement=0;// 更新目标值和当前值pid->Target=target;pid->Current=current;// 计算误差pid->PreError=pid->LastError;pid->LastError=pid->Error;pid->Error=pid->Target-pid->Current;// 积分项处理(带积分限幅和抗积分饱和)pid->Integral+=pid->Error;// 积分限幅if(pid->Integral>pid->IntegralMax){pid->Integral=pid->IntegralMax;}elseif(pid->Integral<-pid->IntegralMax){pid->Integral=-pid->IntegralMax;}// 位置式PID计算pid->Output=pid->Kp*pid->Error+pid->Ki*pid->Integral+pid->Kd*(pid->Error-pid->LastError);// 输出限幅if(pid->Output>pid->OutputMax){pid->Output=pid->OutputMax;}elseif(pid->Output<pid->OutputMin){pid->Output=pid->OutputMin;}returnpid->Output;}

3. 编码器速度测量

// 编码器相关变量volatileint32_tEncoderCount=0;volatileint32_tLastEncoderCount=0;volatilefloatMotorSpeed=0;// 转速 RPM// 编码器计数读取(在编码器中断中调用)voidEncoder_Update(void){EncoderCount=(int32_t)TIM_GetCounter(ENCODER_TIM);TIM_SetCounter(ENCODER_TIM,0);// 清零计数器}// 速度计算函数(在定时中断中调用,如10ms)voidSpeed_Calculate(void){staticuint32_tlast_time=0;uint32_tcurrent_time=HAL_GetTick();uint32_ttime_diff=current_time-last_time;if(time_diff>=10){// 10ms计算一次速度int32_tpulse_diff=EncoderCount;EncoderCount=0;// 计算转速 (RPM)// 假设编码器分辨率: 1000脉冲/转// 公式: RPM = (脉冲数 / 编码器分辨率) × (60000 / 采样时间ms)MotorSpeed=(pulse_diff/1000.0f)*(60000.0f/time_diff);last_time=current_time;}}

4. PWM输出控制

// PWM初始化voidPWM_Init(void){TIM_OC_InitTypeDef sConfigOC={0};// PWM频率设置 (例如: 10kHz)htim1.Instance=TIM1;htim1.Init.Prescaler=84-1;// 84MHz/84 = 1MHzhtim1.Init.CounterMode=TIM_COUNTERMODE_UP;htim1.Init.Period=100-1;// 1MHz/100 = 10kHzhtim1.Init.ClockDivision=TIM_CLOCKDIVISION_DIV1;HAL_TIM_PWM_Init(&htim1);sConfigOC.OCMode=TIM_OCMODE_PWM1;sConfigOC.Pulse=0;// 初始占空比0%sConfigOC.OCPolarity=TIM_OCPOLARITY_HIGH;sConfigOC.OCFastMode=TIM_OCFAST_DISABLE;HAL_TIM_PWM_ConfigChannel(&htim1,&sConfigOC,TIM_CHANNEL_1);HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_1);}// 设置PWM占空比voidSet_PWM_Duty(floatduty_cycle){uint32_tpulse;// 限制占空比范围 0~100%if(duty_cycle<0)duty_cycle=0;if(duty_cycle>100)duty_cycle=100;// 计算PWM脉冲值pulse=(uint32_t)(duty_cycle*(TIM1->ARR+1)/100.0f);// 更新PWM占空比__HAL_TIM_SET_COMPARE(&htim1,TIM_CHANNEL_1,pulse);}

5. 主控制程序

PID_TypeDef MotorPID;floatTargetSpeed=1000.0f;// 目标转速 1000 RPMintmain(void){// 系统初始化HAL_Init();SystemClock_Config();// 外设初始化PWM_Init();Encoder_Init();// 编码器初始化(需要自己实现)TIM_Init();// 定时器初始化(用于定时采样)// PID参数初始化(需要根据实际电机调试)PID_Init(&MotorPID,0.5f,0.01f,0.05f,100.0f);while(1){// 在定时中断中调用Speed_Calculate()更新速度// 主循环中可以处理目标速度设定等// 每50ms执行一次PID控制staticuint32_tlast_pid_time=0;if(HAL_GetTick()-last_pid_time>=50){floatpwm_output;// PID计算pwm_output=PID_Calculate(&MotorPID,TargetSpeed,MotorSpeed);// 更新PWM输出Set_PWM_Duty(pwm_output);last_pid_time=HAL_GetTick();// 可以通过串口输出调试信息printf("Target: %.1f, Current: %.1f, PWM: %.1f%%
",TargetSpeed,MotorSpeed,pwm_output);}// 其他任务...HAL_Delay(1);}}

6. 定时器中断处理

// 定时器中断回调函数(例如1kHz)voidHAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef*htim){if(htim->Instance==TIM2){// 假设TIM2用于定时采样// 更新编码器计数Encoder_Update();// 计算速度(每10次调用计算一次速度)staticuint8_tspeed_counter=0;if(++speed_counter>=10){Speed_Calculate();speed_counter=0;}}}

PID参数整定方法

手动整定步骤:

  1. 先调Kp:将Ki、Kd设为0,逐渐增大Kp直到系统开始振荡
  2. 再调Ki:加入Ki消除静差,但不要太大以免超调
  3. 最后调Kd:加入Kd抑制超调,改善动态性能

典型参数范围(需要根据实际电机调整):

// 直流有刷电机典型参数#defineKP_START0.1f// 开始调试值#defineKI_START0.001f#defineKD_START0.01f// 无刷电机典型参数#defineKP_BLDC0.3f#defineKI_BLDC0.005f#defineKD_BLDC0.02f

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

注意事项

  1. 采样时间选择:速度采样和PID计算周期要匹配,通常10-50ms
  2. 积分抗饱和:必须对积分项进行限幅
  3. 输出限幅:PWM占空比限制在安全范围内
  4. 编码器分辨率:根据实际编码器参数调整速度计算公式
  5. 电机死区:有些电机在低占空比时不转动,需要设置最小启动占空比

调试技巧

  1. 串口监控:实时输出目标速度、实际速度、PWM占空比
  2. 阶跃响应:观察系统对目标速度突变的响应
  3. 抗扰动测试:在电机运行时施加负载,观察恢复性能
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

律师网站建设网站建设团队

CosyVoice3能否识别儿童声音?不同年龄层声纹适应性分析在智能语音助手走进千家万户的今天,越来越多家长开始期待一个能“像孩子一样说话”的AI角色——无论是为儿童故事配

2026/06/30 10:32:20

电器网站建设app网站建设

OpenMV视觉实战:一帧图像中同时识别多种颜色与形状的高效方案你有没有遇到过这样的情况?——你的智能小车明明看到前方有个红色标志,却把它当成了绿色ÿ

2026/06/30 12:54:03

网站建设报价长沙网站建设公司

温馨提示:文末有资源获取方式线上送水服务市场潜力巨大,但自主开发一套系统对初创者而言成本高昂、周期漫长。幸运的是,市场上存在成熟的开源解决方案,

2026/06/30 10:34:51

建设网站公司邢台网站建设

免费PPT计时器终极指南:5分钟学会演讲时间精准把控【免费下载链接】ppttimer一个简易的 PPT 计时器项目地址: https://gitcode.com/gh_mirrors/p

2026/06/30 10:45:21

沧州网站建设萧山网站建设

吐血推荐8个AI论文写作软件,本科生轻松搞定毕业论文!AI 工具让论文写作不再难对于许多本科生来说,毕业论文是大学生活中最令人头疼的任务之一。从选题到撰写&#

2026/06/30 11:29:56

律师网站建设荆门网站建设

无需高端显卡!FP8量化版SD3.5让消费级GPU畅跑文生图大模型在AI生成内容(AIGC)迅猛发展的今天,图像生成技术已经从实验室走向创意一线

2026/06/30 12:39:32

牡丹江网站建设长沙网站建设

MHY_Scanner终极指南:米哈游游戏扫码登录的完整解决方案【免费下载链接】MHY_Scanner崩坏3,原神,星穹铁道的Windows平台的扫码和抢码登

2026/06/30 12:26:01

网站建设案例番禺网站建设

西门子smart200三轴码垛机械手,触摸屏为昆仑通泰,CAD电气图纸,程序已经应用于设备上,稳定可靠,值得学习借鉴最近在产线升级

2026/06/30 11:39:27

建设银行网站低价网站建设

3分钟掌握百度网盘秒传技术:告别龟速下载的终极解决方案【免费下载链接】baidupan-rapidupload百度网盘秒传链接转存/生成/转换 网页工具 (全平台可用)项目地址: htt

2026/06/30 13:07:34