news 2026/2/10 10:23:54

STM32直流电机PID控制 实现功能:直流电机转数PID闭环控制;控制板是stm32f103...

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
STM32直流电机PID控制 实现功能:直流电机转数PID闭环控制;控制板是stm32f103...

STM32直流电机PID控制 实现功能:直流电机转数PID闭环控制;控制板是stm32f103单片机,板载有液晶显示屏,实时的显示设定值、实际转数的曲线;霍尔传感器检测电机的转数,PID算法使用位置方式,PWM脉宽控制L298N的电压输出,最终实现闭环PID功能。 主要部件: 1:主控制器STM32F130C8T6; 2:128×160液晶显示屏; 3:25GA-260编码器减速电机 是工程文件,说明文档 只是资料

最近在搞一个直流电机转速闭环控制的项目,主控用的STM32F103C8T6。这玩意儿虽然便宜但性能足够,搭配L298N电机驱动模块能直接输出PWM波控制电机。关键是要实现PID算法闭环,还得在液晶屏上实时画曲线,这过程真是一波三折。

先说说霍尔编码器的处理。我用的25GA-260减速电机自带霍尔输出,AB相脉冲信号接在TIM3的CH1和CH2引脚。配置定时器的编码器模式相当重要:

void Encoder_Init(void){ TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_ICInitTypeDef TIM_ICInitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); TIM_TimeBaseStructure.TIM_Period = 0xFFFF; TIM_TimeBaseStructure.TIM_Prescaler = 0; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); TIM_EncoderInterfaceConfig(TIM3, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising); TIM_ICStructInit(&TIM_ICInitStructure); TIM_ICInitStructure.TIM_ICFilter = 6; //10阶滤波防抖 TIM_ICInit(TIM3, &TIM_ICInitStructure); TIM_Cmd(TIM3, ENABLE); }

这里用硬件计数比软件中断可靠多了,特别注意滤波器设置——电机运行时震动会产生毛刺,实测滤波值6刚好能稳定计数。每隔100ms通过TIM_GetCounter()读取计数值后要立即清零计数器,这操作最好放在定时器中断里同步处理。

PID算法采用位置式,结构体定义得实用点:

typedef struct{ float SetSpeed; float ActualSpeed; float Err; float ErrLast; float Kp,Ki,Kd; float Integral; float Output; }PID; void PID_Calc(PID *pid){ pid->Err = pid->SetSpeed - pid->ActualSpeed; pid->Integral += pid->Err; //积分限幅防止过冲 if(pid->Integral > 2000) pid->Integral = 2000; if(pid->Integral < -2000) pid->Integral = -2000; pid->Output = pid->Kp * pid->Err + pid->Ki * pid->Integral + pid->Kd * (pid->Err - pid->ErrLast); pid->ErrLast = pid->Err; }

实际调试时发现积分项必须限幅,否则启动瞬间误差积累太猛会导致PWM直接满占空比。参数整定过程最头大,先用试凑法:先调P到电机能勉强稳住,再加D抑制震荡,最后补点I消除静差。后来改用临界比例法,找到等幅振荡时的Ku=12.5,Tu=0.22s,按Z-N公式算出的参数确实省事不少。

STM32直流电机PID控制 实现功能:直流电机转数PID闭环控制;控制板是stm32f103单片机,板载有液晶显示屏,实时的显示设定值、实际转数的曲线;霍尔传感器检测电机的转数,PID算法使用位置方式,PWM脉宽控制L298N的电压输出,最终实现闭环PID功能。 主要部件: 1:主控制器STM32F130C8T6; 2:128×160液晶显示屏; 3:25GA-260编码器减速电机 是工程文件,说明文档 只是资料

液晶显示用的是ST7735驱动芯片,直接上DMA刷屏:

void LCD_DrawCurve(uint16_t *buf, uint16_t color){ static uint16_t prev_y = 0; for(uint8_t x=0; x<128; x++){ uint16_t y = 160 - buf[x]/65; //转速映射到Y轴 LCD_DrawLine(x-1, prev_y, x, y, color); prev_y = y; } }

这里有个坑——屏幕刷新率要和数据采样率匹配。开始直接每秒刷60帧,结果曲线闪得眼晕。后来改双缓冲机制,前台显示完成帧,后台准备下一帧数据,效果顺滑多了。

最后PWM输出到L298N部分,注意死区时间设置:

TIM_OCInitTypeDef TIM_OCInitStructure; 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(TIM1, &TIM_OCInitStructure); TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable); //设置死区时间防止上下管直通 TIM_BDTRInitStructure.TIM_DeadTime = 0x3F; TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure);

调试时烧过两次L298N,后来发现是死区时间不够。电机堵转时电流飙升,必须加装电流检测,超过阈值直接关断PWM输出才保住驱动模块。

整完这套系统,最大的体会是硬件和软件得协同调试——PID参数纸上算得再完美,实际电机惯性带来的滞后足够让理论值失效。后来在液晶屏上叠加显示目标曲线和实际曲线,边调参边观察响应,比单纯看数据直观多了。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/8 16:32:24

再也不怕依赖冲突!YOLOv13镜像统一开发环境

再也不怕依赖冲突&#xff01;YOLOv13镜像统一开发环境 在智能安防监控中心&#xff0c;上百路高清视频流同时接入&#xff0c;系统需在30毫秒内完成对遮挡行人、异常聚集、危险物品的多类别识别&#xff1b;在农业无人机巡检中&#xff0c;机载设备要在2W功耗限制下实时分析万…

作者头像 李华
网站建设 2026/2/8 3:16:53

MATLAB/Simulink仿真可运行 [1]光伏发电系统MPPT(最大功率点跟踪控制)

MATLAB/Simulink仿真可运行 [1]光伏发电系统MPPT&#xff08;最大功率点跟踪控制&#xff09; [2]扰动观察法光伏发电系统里有个挺头疼的问题——最大功率点跟踪&#xff08;MPPT&#xff09;。这玩意儿说白了就是让光伏板在各种天气条件下都能输出最大功率。今天咱们聊聊最接地…

作者头像 李华
网站建设 2026/2/9 14:05:08

GLM-4-9B-Chat-1M超长上下文模型:5分钟部署200万字处理神器

GLM-4-9B-Chat-1M超长上下文模型&#xff1a;5分钟部署200万字处理神器 1. 为什么你需要一个“能读完200万字”的AI&#xff1f; 你有没有遇到过这些场景&#xff1a; 法务同事发来一份83页、含47个附件的并购协议&#xff0c;要求3小时内提炼核心风险点&#xff1b;财务部门甩…

作者头像 李华