赞
踩
电机控制速度代码来自小白学移动机器人中的PID控制:
#ifndef __PID_H__ #define __PID_H__ #include "stm32f10x.h" struct pid_uint { s32 U_kk; //上一次的输出量 s32 ekk; //上一次的输入偏差 s32 ekkk; //前一次的输入偏差 s32 Ur; //限幅输出值,需初始化 s32 Kp; //比例 s32 Ki; //积分 s32 Kd; //微分 u8 En; //开关 s16 Adjust; //调节量 s16 speedSet; //速度设置 s16 speedNow; //当前速度 }; /****************************外接函数***************************/ extern struct pid_uint pid_Task_Letf; extern struct pid_uint pid_Task_Right; void PID_Init(void); void reset_Uk(struct pid_uint *p); s32 PID_common(int set,int jiance,struct pid_uint *p); void Pid_Ctrl(int *leftMotor,int *rightMotor); #endif //__PID_H__
#include "pid.h" /*=================================================================== 程序功能:双路电机速度PID,不同的电机,可能出现默认参数,不会产生速度控制的效果,请自行更改 程序编写:公众号:小白学移动机器人 其他 :如果对代码有任何疑问,可以私信小编,一定会回复的。 ===================================================================== ------------------关注公众号,获得更多有趣的分享--------------------- ===================================================================*/ struct pid_uint pid_Task_Letf; struct pid_uint pid_Task_Right; /**************************************************************************** *函数名称:PID_Init(void) *函数功能:初始化PID结构体参数 ****************************************************************************/ void PID_Init(void) { //乘以1024原因避免出现浮点数运算,全部是整数运算,这样PID控制器运算速度会更快 /***********************左轮速度pid****************************/ pid_Task_Letf.Kp = 1024 * 0.5;//0.4 pid_Task_Letf.Ki = 1024 * 0; pid_Task_Letf.Kd = 1024 * 0.08; pid_Task_Letf.Ur = 1024 * 4000; pid_Task_Letf.Adjust = 0; pid_Task_Letf.En = 1; pid_Task_Letf.speedSet = 0; pid_Task_Letf.speedNow = 0; reset_Uk(&pid_Task_Letf); /***********************右轮速度pid****************************/ pid_Task_Right.Kp = 1024 * 0.35;//0.2 pid_Task_Right.Ki = 1024 * 0; //不使用积分 pid_Task_Right.Kd = 1024 * 0.06; pid_Task_Right.Ur = 1024 * 4000; pid_Task_Right.Adjust = 0; pid_Task_Right.En = 1; pid_Task_Right.speedSet = 0; pid_Task_Right.speedNow = 0; reset_Uk(&pid_Task_Right); } /*********************************************************************************************** 函 数 名:void reset_Uk(PID_Uint *p) 功 能:初始化U_kk,ekk,ekkk 说 明:在初始化时调用,改变PID参数时有可能需要调用 入口参数:PID单元的参数结构体 地址 ************************************************************************************************/ void reset_Uk(struct pid_uint *p) { p->U_kk=0; p->ekk=0; p->ekkk=0; } /*********************************************************************************************** 函 数 名:s32 PID_commen(int set,int jiance,PID_Uint *p) 功 能:PID计算函数 说 明:求任意单个PID的控制量 入口参数:期望值,实测值,PID单元结构体 返 回 值:PID控制量 ************************************************************************************************/ s32 PID_common(int set,int jiance,struct pid_uint *p) { int ek=0,U_k=0; ek=jiance - set; //当前时刻的输入偏差 U_k=p->U_kk + p->Kp*(ek - p->ekk) + p->Ki*ek + p->Kd*(ek - 2*p->ekk + p->ekkk); //当前时刻的输出等于上一时刻的输出U_kk + 当前时刻的增量变化 p->U_kk=U_k; p->ekkk=p->ekk; p->ekk=ek; if(U_k>(p->Ur)) U_k=p->Ur; if(U_k<-(p->Ur)) U_k=-(p->Ur); return U_k>>10; //在先前的比例、积分、微分系数中都乘以了1024,因此最后的控制输出量要除以2^10(即1024) } /*********************************************************************************** ** 函数名称 :void Pid_Which(struct pid_uint *pl, struct pid_uint *pr) ** 函数功能 :pid选择函数 ***********************************************************************************/ void Pid_Which(struct pid_uint *pl, struct pid_uint *pr) { /**********************左轮速度pid*************************/ if(pl->En == 1) { pl->Adjust = -PID_common(pl->speedSet, pl->speedNow, pl); } else { pl->Adjust = 0; reset_Uk(pl); pl->En = 2; } /***********************右轮速度pid*************************/ if(pr->En == 1) { pr->Adjust = -PID_common(pr->speedSet, pr->speedNow, pr); } else { pr->Adjust = 0; reset_Uk(pr); pr->En = 2; } } /******************************************************************************* * 函数名:Pid_Ctrl(int *leftMotor,int *rightMotor) * 描述 :Pid控制 *******************************************************************************/ void Pid_Ctrl(int *leftMotor,int *rightMotor) { Pid_Which(&pid_Task_Letf, &pid_Task_Right); *leftMotor += pid_Task_Letf.Adjust; *rightMotor += pid_Task_Right.Adjust; }
#include "sys.h" //====================自己加入的头文件=============================== #include "delay.h" #include "led.h" #include "encoder.h" #include "usart3.h" #include "timer.h" #include "pwm.h" #include "pid.h" #include "motor.h" #include <stdio.h> /*=================================================================== 程序功能:直流减速电机的速度闭环控制测试,可同时控制两路,带编码器的直流减速电机 程序编写:公众号:小白学移动机器人 其他 :如果对代码有任何疑问,可以私信小编,一定会回复的。 ===================================================================== ------------------关注公众号,获得更多有趣的分享--------------------- ===================================================================*/ int leftSpeedNow =0; int rightSpeedNow =0; int leftSpeeSet = 300;//mm/s int rightSpeedSet = 300;//mm/s int main(void) { GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable,ENABLE); GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);//禁用JTAG 启用 SWD MY_NVIC_PriorityGroupConfig(2); //=====设置中断分组 delay_init(); //=====延时函数初始化 LED_Init(); //=====LED初始化 程序灯 usart3_init(9600); //=====串口3初始化 蓝牙 发送调试信息 Encoder_Init_TIM2(); //=====初始化编码器1接口 Encoder_Init_TIM4(); //=====初始化编码器2接口 Motor_Init(7199,0); //=====初始化PWM 10KHZ,用于驱动电机 如需初始化驱动器接口 TIM3_Int_Init(50-1,7200-1); //=====定时器初始化 5ms一次中断 PID_Init(); //=====PID参数初始化 //闭环速度控制 while(1) { //给速度设定值,想修改速度,就更该leftSpeeSet、rightSpeedSet变量的值 pid_Task_Letf.speedSet = leftSpeeSet; pid_Task_Right.speedSet = rightSpeedSet; //给定速度实时值 pid_Task_Letf.speedNow = leftSpeedNow; pid_Task_Right.speedNow = rightSpeedNow; //执行PID控制函数 Pid_Ctrl(&motorLeft,&motorRight); //根据PID计算的PWM数据进行设置PWM Set_Pwm(motorLeft,motorRight); //打印速度 printf("%d,%d\r\n",leftSpeedNow,rightSpeedNow); delay_ms(2); } } //5ms 定时器中断服务函数 --> 计算速度实时值,运行该程序之前,确保自己已经能获得轮速,如果不懂,可看之前电机测速的文章 void TIM3_IRQHandler(void) //TIM3中断 { if(TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) //检查指定的TIM中断发生与否 { TIM_ClearITPendingBit(TIM3, TIM_IT_Update); //清除TIMx的中断待处理位 Get_Motor_Speed(&leftSpeedNow,&rightSpeedNow);//计算电机速度 Led_Flash(100); //程序闪烁灯 } }
文章参考小白学移动机器人的教程:
https://mp.weixin.qq.com/s?__biz=MzIwOTc5Njg2Mg==&mid=2247486694&idx=1&sn=a2e9bdadc77517c5b5fa5d1eaee9ee3f&chksm=976f2777a018ae61707cbe426c3a95cd954a47982a196c4a3af3d7727134078873ad6470cbe7&cur_album_id=2255869189385355271&scene=190#rd
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。