【STM32HAL库】PID控制单个电机

pid被广泛应用于电机控制,本文章就是关于PID控制电机运动,包括速度环和位置环。

一.设置电机旋转方向

AIN1和AN2是指STM32上的两个引脚

//设置方向
void motor_set_direction(int direction) 
{
    if(direction == 1)
	{
    HAL_GPIO_WritePin(AIN1_GPIO_Port,AIN1_Pin,GPIO_PIN_RESET);
	HAL_GPIO_WritePin(AIN2_GPIO_Port,AIN2_Pin,GPIO_PIN_SET);//即01,正转
    } 
		else if(direction == 2) 
		{
        HAL_GPIO_WritePin(AIN1_GPIO_Port,AIN1_Pin,GPIO_PIN_SET);
		HAL_GPIO_WritePin(AIN2_GPIO_Port,AIN2_Pin,GPIO_PIN_RESET);//即01,反转
        }  

		else 
		{
		HAL_GPIO_WritePin(AIN1_GPIO_Port,AIN1_Pin,GPIO_PIN_SET);
		HAL_GPIO_WritePin(AIN2_GPIO_Port,AIN2_Pin,GPIO_PIN_SET);//停止
		}

}

二.获取编码器中的脉冲数

void GET_NUM(void)
{
	encoder_counter=myabs((short) __HAL_TIM_GET_COUNTER(&htim2));
	__HAL_TIM_SET_COUNTER(&htim2,0);//将编码器模式的定时器清零
}

三.速度PID

如果需要快速到达目标速度时,可以设置全量输出

int Incremental_PI (int Encoder,int Target)
{ 	
	 static float Bias,Pwm,Last_bias,last_last_bias;//bias=Err
	 Encoder=myabs(Encoder);
	 Bias=Target-Encoder;//计算偏差
	// Integral_bias+=Bias;
	// Integral_bias=Xianfu(Integral_bias,5000);  
	 /*全量输出*/
//	if(Bias>30)
//	Pwm=5000;
//	else if(Bias<-30)
//	Pwm=-5000;
//	else //一般
	Bias =  Xianfu(Bias,30);	
	Pwm+=(Velocity_KP*(Bias-Last_bias)+Velocity_KI*Bias+Velocity_KD*(Bias+last_last_bias-2*Last_bias));   //增量式PID控制
	last_last_bias = Last_bias;
	Last_bias=Bias;	                                  
	Xianfu(Pwm,8000);
	return Pwm;  

} 

四.位置PID

整个原理大家应该都懂,其他各位大佬有很详细的解说,我在这里就不解释了。

int Position_PID (int position,int target)
{ 	
	 static float Bias,Pwm,Integral_bias,Last_Bias;
	 Bias=target-position;                                
	 Integral_bias+=Bias;	                            
	 Integral_bias=Xianfu(Integral_bias,myabs(Target_Velocity));
//	 Integral_bias=Xianfu(Integral_bias,30);
	 Pwm=Position_KP*Bias+Position_KI*Integral_bias+Position_KD*(Bias-Last_Bias);//位置式PID控制
	 Last_Bias=Bias;                                      
     Pwm=Xianfu(Pwm,9000);
	 return Pwm;                                           
}

五.设置PWM输出

void Set_Pwm(int moto)
{
	moto=myabs(moto);
		
	__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1,moto);	
}

六.定时回调函数

这里后期可以在VOFA中,既可以呈现出正的目标位置脉冲曲线,又可以呈现负的目标位置脉冲曲线。

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
  t++;
  if (htim == &htim6)
  {
     GET_NUM();  // 获取编码器的脉冲数

	 if(Target_Position==0)
	 {
	  output = Incremental_PI(encoder_counter,Target_Velocity);//只有速度pid控制
	 }
	 else
	{
	 if(Target_Position>0)
     {Position += encoder_counter; } // 累积脉冲数
	 else 
	 {Position -= encoder_counter; } 
	 // 计算位置控制的PWM值
    Position_PWM = Position_PID(Position, Target_Position);
    output = Incremental_PI(encoder_counter, Xianfu(Position_PWM, Target_Velocity));//串级
	}

  }
}

七.其他函数

(一).绝对值函数

float myabs(float num)
{
	float temp;
	if(num<0)	temp=-num;
	else temp =num;
	return temp;
}

(二).限幅函数

int Xianfu(int value,int Amplitude)
{
	int temp;
	if(value>Amplitude) temp = Amplitude;
	else if(value<-Amplitude) temp = -Amplitude;
	else temp = value;
	return temp;
}

八.小结

后期在main.c中设置目标值,调用方向函数和设置PWM函数即可。祝大家都能实现PID控制。

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值