直流电机速度闭环控制(结合vofa+经行串口调试)

闭环控制就一定是存在反馈的调节,而对于直流电机来说就要通过传感器来经行信息的获取了。

一、对编码器经行初始化:

void MotorEncoder_Init(void)
{
    //初始化定义结构体
	GPIO_InitTypeDef GPIO_InitStructure; 
	TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
    TIM_ICInitTypeDef TIM_ICInitStructure; 
	
    //使能时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); 
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); 
    
    //GPIO模式配置
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;	//TIM4_CH1¡¢TIM4_CH2
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; 
	GPIO_Init(GPIOB, &GPIO_InitStructure);	
    
    //时钟配置
	TIM_TimeBaseStructure.TIM_Period = 0xffff; //65536  设定计数器自动重装值
	TIM_TimeBaseStructure.TIM_Prescaler = 0; //  预分频器
	TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //不分频
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数模式
	TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); //初始化参数
	

    TIM_EncoderInterfaceConfig(TIM4, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);  //使用编码器模式3,CH1/CH2同时计数,为四分频
    TIM_ICStructInit(&TIM_ICInitStructure); //
	TIM_ICInitStructure.TIM_ICFilter = 10;  //设置滤波器长度
    TIM_ICInit(TIM4, &TIM_ICInitStructure); //根据¸TIM_ICInitStructure 参数初始化定时器4编码模式
	
	TIM_ClearFlag(TIM4, TIM_FLAG_Update);//清除TIM更新标志位
    TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE); //更新中断使能
    TIM_SetCounter(TIM4,0); //初始化清空编码器数据
	
	TIM_Cmd(TIM4, ENABLE); //使能
}

以上就是对霍尔编码器经行初始化的基本配置,而获取的脉冲值从CNT这个寄存器中获取,获取方法如下,

int Read_Encoder(void)
{
	int Encoder_TIM;
	Encoder_TIM=TIM4->CNT; /读取计数
	if(Encoder_TIM>0xefff)Encoder_TIM=Encoder_TIM-0xffff; //转换计数值为有方向的值,大于零正转小于零反转
	                                                      //TIM4->CNT范围为0~65536,初值为0
	TIM4->CNT=0; //读取完之后计数清零
	return Encoder_TIM; //返回值
}

二、定义一个定时器用来决定中断时间

初始化一个定时器中断服务函数,用来定时读取编码器的数值,并进行速度闭环控制。

void EncoderRead_TIM2(u16 arr, u16 psc)//7199 99
{
    //结构体定义
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStrue; 
	NVIC_InitTypeDef NVIC_InitStrue;
	
    //使能通用定时器
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
	
	TIM_TimeBaseInitStrue.TIM_Period=arr; 
	TIM_TimeBaseInitStrue.TIM_Prescaler=psc;
	TIM_TimeBaseInitStrue.TIM_CounterMode=TIM_CounterMode_Up; 
	TIM_TimeBaseInitStrue.TIM_ClockDivision=TIM_CKD_DIV1;
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStrue); 
	TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
	NVIC_InitStrue.NVIC_IRQChannel=TIM2_IRQn; 
	NVIC_InitStrue.NVIC_IRQChannelCmd=ENABLE; 
	NVIC_InitStrue.NVIC_IRQChannelPreemptionPriority=1; 
	NVIC_InitStrue.NVIC_IRQChannelSubPriority=1; 
	NVIC_Init(&NVIC_InitStrue); 
	TIM_Cmd(TIM2, ENABLE); 
}

void TIM2_IRQHandler()
{
  if(TIM_GetITStatus(TIM2, TIM_IT_Update)==1) 
	{
	  Encoder=Read_Encoder();  

	  PWM=Velocity_FeedbackControl(TargetVelocity, Encoder);//速度闭环控制
				
	  SetPWM(PWM); //设置PWM
			
	  TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
	}
}

PID 速度闭环控制(具体解释可以到我前边发的一些博客中了解)

入口参数为:目标速度,当当前速度

再我们的速度控制闭环系统里边只使用PI控制


int Velocity_FeedbackControl(int TargetVelocity, int CurrentVelocity)
{
		int Bias;  //定义相关变量
		static int ControlVelocity, Last_bias; //静态变量
		
		Bias=TargetVelocity-CurrentVelocity; //求速度偏差
		
		ControlVelocity+=Velcity_Kp*(Bias-Last_bias)+Velcity_Ki*Bias; //增量式PID控制
        //Velcity_Kp*(Bias-Last_bias) 作用为限制加速度
        //Velcity_Ki*Bias 速度控制值由Bian不断积分得到 偏差越大加速度越大
		Last_bias=Bias;	
		return ControlVelocity; //返回速度控制值
}

三、电机控制

电机驱动用的是TB6612,而电机的控制主要有电机正反转口和PWM组成,如下

void TB6612_Init(int arr, int psc)
{
	GPIO_InitTypeDef GPIO_InitStructure; 
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStrue; 
	TIM_OCInitTypeDef TIM_OCInitTypeStrue; 
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); 
	
	//电机转向
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_12|GPIO_Pin_13; 
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; 
	GPIO_Init(GPIOB, &GPIO_InitStructure); 
	
	GPIO_ResetBits(GPIOB, GPIO_Pin_12|GPIO_Pin_13); 

	//PWM
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP; 
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
  GPIO_Init(GPIOB, &GPIO_InitStructure); 
	
	TIM_TimeBaseInitStrue.TIM_Period=arr;
	TIM_TimeBaseInitStrue.TIM_Prescaler=psc; 
	TIM_TimeBaseInitStrue.TIM_CounterMode=TIM_CounterMode_Up; 
	TIM_TimeBaseInitStrue.TIM_ClockDivision=TIM_CKD_DIV1; 
	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStrue);
	
	TIM_OCInitTypeStrue.TIM_OCMode=TIM_OCMode_PWM1; 
	TIM_OCInitTypeStrue.TIM_OCPolarity=TIM_OCNPolarity_High;
	TIM_OCInitTypeStrue.TIM_OutputState=TIM_OutputState_Enable; 
	TIM_OCInitTypeStrue.TIM_Pulse = 0; 
	TIM_OC4Init(TIM3, &TIM_OCInitTypeStrue); 

  //TIM_CtrlPWMOutputs(TIM3,ENABLE);	//MOE主输出使能

	TIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Disable); //CH4预装载使能
	TIM_ARRPreloadConfig(TIM3, ENABLE); //TIM3预装载使能
	
	TIM_Cmd(TIM3, ENABLE); //使能定时器TIM3
}

//PWM设计
void SetPWM(int pwm)
{
  if(pwm>=0)
  {
		PBout(13)=0; //BIN1=0
		PBout(12)=1; //BIN2=1
		TIM3->CCR4=pwm;
		TIM_SetCompare4(TIM3, pwm);
  }
  else if(pwm<0)
  {
		PBout(13)=1; //BIN1=1
		PBout(12)=0; //BIN2=0
		TIM3->CCR4=-pwm;
		TIM_SetCompare4(TIM3, -pwm);
  }
}

四、vofa+调试

直流电机速度闭环控制(结合vofa+经行串口调试)_第1张图片

 上机位操作显示。可通过串口协议,和vofa+的协议经行进行共同的调节。

你可能感兴趣的:(单片机,嵌入式硬件)