stm32 balance trolley (2) -----encoder motor drive

Foreword: I used the L298N motor when I made the arduino car before, and I have never used an encoder. This is the first time I use an encoder, and I am still confused. Let me record the whole process of learning.

1. Introduction to the encoder

Hall encoder is a sensor that converts the mechanical geometric displacement on the output shaft into pulse or digital quantity through magnetoelectric conversion.

The Hall encoder is composed of a Hall code disc (magnetic ring) and a Hall element.

The Hall code disc is arranged with different magnetic poles equally divided on a circular plate with a certain diameter. The Hall code disc is coaxial with the motor. When the motor rotates, the Hall element detects and outputs a number of pulse signals. In order to judge the steering, two sets of square wave signals with a certain phase difference are generally output.

In order to obtain the number of pulses per circle, the encoder can convert it into the current motor speed through the formula, so as to achieve the purpose of speed measurement.

2. Wiring method:

I bought a comprehensive driver module of tb6612, which is more convenient for wiring.

 v---5v power supply G----GND [grounding] A and B are the A and B phases of the encoder.

M1 and M2 are connected to E1A and E1B of the motor   

3. The frequency multiplication principle of the encoder

 The normal situation is to capture the rising or falling edge of a phase, so that it can only be captured once per cycle

The quadrupling frequency technology of the encoder is to capture the rising and falling edges of A and B at the same time in a single cycle, so that four times can be captured in a single cycle, which is quadrupled. When A triggers an external interrupt due to a jump, In the interrupt, judge what level B is, so as to judge whether the current wheel is rotating forward or reverse.

4. The counting principle of the encoder

The encoder chooses quadruple frequency technology, that is, counts at T1 and T2 at the same time.

With the help of this count, the number of pulses of the encoder in a fixed period can be calculated, and the current speed of the motor can be calculated with the help of the M speed measurement method.

At the same time, according to the figure, it can be found that if phase A is in front, the wheel is rotating forward, and if phase B is in front, the wheel is rotating reversely.

5. Encoder code understanding

 Set it to 65536, in order to increase the counting cycle and speed up the counting frequency, to ensure that the system can detect the current number of pulses regardless of the wheel speed

 TIM_EncoderInterfaceConfig(TIM3, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);

The first one: the choice of timer

The second one: the choice is T1 and T2, and the upper and lower edges of the dual channels are counted.

Third, fourth: inversion or not inversion

Non-inversion: forward rotation, counting ++, reverse rotation, counting --.

Reverse phase: forward rotation, counting --, reverse rotation, counting ++. 

 Here, a minus sign is added in front of the reading of one of the pulse values, because the installation of the two wheels is opposite, so as to keep the polarity consistent.

At this time, the value of the counter is to calculate the number of pulses of the left and right wheels in a single cycle of the TIM4 timer.

This picture of Mouhu clearly introduces the operation mode of the Hall encoder.

 6. PWM output enable

Set the channel PWM output enable of the timer, and then set the output of the IO port control level.

Set the polarity of the output channel, and PWM output mode.

void TIM1_PWM_Init(u16 arr,u16 psc)
{  
	GPIO_InitTypeDef GPIO_InitStructure;
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	TIM_OCInitTypeDef  TIM_OCInitStructure;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);// 
 	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE);  //使能GPIO外设时钟使能
   //设置该引脚为复用输出功能,输出TIM1 CH1 CH4的PWM脉冲波形
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_11; //TIM_CH1 //TIM_CH4
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //复用推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值	 
	TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值  不分频
	TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
	TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位

 
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式1
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
	TIM_OCInitStructure.TIM_Pulse = 0;                            //设置待装入捕获比较寄存器的脉冲值
	TIM_OCInitStructure.TIM_Pulse = arr >> 1;
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;     //输出极性:TIM输出比较极性高
	TIM_OC1Init(TIM1, &TIM_OCInitStructure);  //根据TIM_OCInitStruct中指定的参数初始化外设TIMx
	TIM_OC4Init(TIM1, &TIM_OCInitStructure);  //根据TIM_OCInitStruct中指定的参数初始化外设TIMx

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

	TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);  //CH1预装载使能	 
	TIM_OC4PreloadConfig(TIM1, TIM_OCPreload_Enable);  //CH4预装载使能	 
	
	TIM_ARRPreloadConfig(TIM1, ENABLE); //使能TIMx在ARR上的预装载寄存器
	
	TIM_Cmd(TIM1, ENABLE);  //使能TIM1
}

Set the IO port for level output.

void Motor_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //使能PB端口时钟
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15;	//端口配置
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;      //推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;     //50MHZ
  GPIO_Init(GPIOB, &GPIO_InitStructure);					      //根据设定参数初始化GPIOB 
	AIN1=0,AIN2=0;
	BIN1=0,BIN1=0;
}

The forward and reverse rotation of the wheel is performed by setting AIN.

Guess you like

Origin blog.csdn.net/weixin_63032791/article/details/128625962