STM32 encoder mode learning

Publisher:乐呵的挑Latest update time:2018-12-13 Source: eefocusKeywords:STM32 Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

1. Encoder mode theoretical reserve


Usually in order to improve accuracy we will choose to count both the rising and falling edges!


insert image description here


There is also a very important picture recorded here


insert image description here


The most confusing part is probably the relative signal level in the second column, so let's discuss this in detail.


In fact, it is not difficult to understand. As we said above, in order to improve accuracy, we usually count both the rising and falling edges of phases A and B. Then, we can count four times in one cycle. The increase in the number of counts means an increase in accuracy!


In encoder mode, if it is in forward rotation, then these four counts should all be added. Similarly, if it is in reverse rotation, then these four counts should all be subtracted. So the question is, how to judge forward and reverse rotation?


Isn't it just based on the relative level!!!


insert image description here


By carefully comparing the diagram, you can clearly understand the level of A relative to B and the counting direction in the table above in the case of forward or reverse rotation!!!


2. STM32 actual code


By the way, it must be pointed out that the encoder mode can only correspond to one timer's CH1/CH2 channel, which means it just connects to phase A and B! Perfect!!!


/*TIM2 initialized as encoder interface*/

void Encoder_Init_TIM2(void)

{

TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;  

TIM_ICInitTypeDef TIM_ICInitStructure;  

GPIO_InitTypeDef GPIO_InitStructure;


RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //Enable the clock of timer 4

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //Enable PA port clock

 

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1; //Port configuration

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //Floating input

GPIO_Init(GPIOA, &GPIO_InitStructure); //Initialize GPIOA according to the set parameters


TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);

TIM_TimeBaseStructure.TIM_Prescaler = 0x0; // Prescaler 

TIM_TimeBaseStructure.TIM_Period = ENCODER_TIM_PERIOD; //Set the counter to automatically reload value

TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //Select clock division: no division

TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; ////TIM counts up  

TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

TIM_EncoderInterfaceConfig(TIM2, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising); //Use encoder mode 3

TIM_ICStructInit(&TIM_ICInitStructure);

TIM_ICInitStructure.TIM_ICFilter = 10;

TIM_ICInit(TIM2, &TIM_ICInitStructure);

TIM_ClearFlag(TIM2, TIM_FLAG_Update); //Clear the update flag of TIM

TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);

//Reset counter

TIM_SetCounter(TIM2,0);

TIM_Cmd(TIM2, ENABLE); 

}


/*TIM4 initialized as encoder interface*/

void Encoder_Init_TIM4(void)

{

TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;  

TIM_ICInitTypeDef TIM_ICInitStructure;  

GPIO_InitTypeDef GPIO_InitStructure;

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); //Enable the clock of timer 4

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //Enable PB port clock


GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7; //Port configuration

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //Floating input

GPIO_Init(GPIOB, &GPIO_InitStructure); //Initialize GPIOB according to the set parameters


TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);

TIM_TimeBaseStructure.TIM_Prescaler = 0x0; // Prescaler 

TIM_TimeBaseStructure.TIM_Period = ENCODER_TIM_PERIOD; //Set the counter to automatically reload value

TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //Select clock division: no division

TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; ////TIM counts up  

TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);

TIM_EncoderInterfaceConfig(TIM4, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising); //Use encoder mode 3

TIM_ICStructInit(&TIM_ICInitStructure);

TIM_ICInitStructure.TIM_ICFilter = 10;

TIM_ICInit(TIM4, &TIM_ICInitStructure);

TIM_ClearFlag(TIM4, TIM_FLAG_Update); //Clear the update flag of TIM

TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE);

//Reset counter

TIM_SetCounter(TIM4,0);

TIM_Cmd(TIM4, ENABLE); 

}


/*Unit time encoder count input timer output speed value*/

int Read_Encoder(u8 TIMX)

{

int Encoder_TIM;    

switch(TIMX)

{

case 2: Encoder_TIM= (short)TIM2 -> CNT; TIM2 -> CNT=0;break;

case 3: Encoder_TIM= (short)TIM3 -> CNT; TIM3 -> CNT=0;break;

case 4: Encoder_TIM= (short)TIM4 -> CNT; TIM4 -> CNT=0;break;

default: Encoder_TIM=0;

}

return Encoder_TIM;

}


void TIM4_IRQHandler(void)

{           

if(TIM4->SR&0X0001)//overflow interrupt

{                 

}    

TIM4->SR&=~(1<<0); //Clear interrupt flag     

}


void TIM2_IRQHandler(void)

{           

if(TIM2->SR&0X0001)//overflow interrupt

{                 

}    

TIM2->SR&=~(1<<0); //Clear interrupt flag     

}


Keywords:STM32 Reference address:STM32 encoder mode learning

Previous article:STM32 ADC gets battery voltage
Next article:STM32 printf usage

Latest Microcontroller Articles
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号