闭环控制就一定是存在反馈的调节,而对于直流电机来说就要通过传感器来经行信息的获取了。
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+的协议经行进行共同的调节。