Summary of STM32 encoder counting and overflow processing debugging

Publisher:心想的45号Latest update time:2018-09-16 Source: eefocusKeywords:STM32 Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

Error 1: PC6 and PC7 are used for other purposes, and the GPIO mode is configured incorrectly, resulting in inaccurate counting;

Error 2: The pin mode is set incorrectly. It should be set to GPIO_Mode_IPD; //GPIO_Mode_IPU GPIO_Mode_IN_FLOATING is OK;

Error 3: Pin remapping does not enable AFIO clock;

Summarize

Regarding encoder overflow processing:

The methods for detecting value mutations on the Internet are unreliable and may miss detections. Detect encoder value mutations in the tick timer

void SysTick_Handler(void)

{//systick interrupt, once every 1ms

 static int encoder[2] = {0 , 0}; // Two encoder readings to calculate overflow direction

 static int N = 0; // Number of turns

 encoder[1] = TIM3->CNT;

  if((encoder[1] - encoder[0] ) > 0x7FFF)

  {

    N--;

  }

 else if( (encoder[0] - encoder[1] ) > 0x7FFF)

  {

   N++;

  }

 EncCnt = N * 0xFFFF + encoder[1];

 encoder[0] = encoder[1];

}

 

I used two methods to deal with it: one is to use another timer to detect the overflow flag and direction flag in real time. This method is feasible. Even when the speed is very fast, the count is still accurate. But a new problem has arisen. The clock used as the timer can only count accurately when the timing period is set very small, but due to the high priority of the interrupt, it is impossible to enter the main loop program. Attached is the detection code. This processing method can detect correctly when the speed is slow. But the timing period must be set small enough. Bit 4 of CR1 represents the counting direction flag, 1 represents minus two represents addition; bit 0 of SR represents the overflow interrupt flag, 1 represents overflow. This bit is set to 1 by hardware and cleared by software. Another method is to use the encoder overflow interrupt. When the interrupt occurs, the encoder overflow direction is judged, and then accumulation is performed according to the direction.

void TIM2_IRQHandler(void)

{

      

   if ( TIM_GetITStatus(TIM2 , TIM_IT_Update) != RESET )

    {

       TIM_ClearITPendingBit(TIM2 , TIM_FLAG_Update);

                           

              encoder= TIM3->CNT;

          if((TIM3->CR1&0x10) == 0x10) // count down

          {          

               if(TIM3->SR&0x01 == 0x01)//tim3 count overflow

                 {

                            TIM3->SR= TIM3->SR&0xFE; //bit0 of sr is cleared

                            N--;

                     }                    

          }

          else if((TIM3->CR1&0x10) == 0x00)//Count up

          {

               if(TIM3->SR&0x01 == 0x01)//tim3 count overflow

                 {

                            TIM3->SR= TIM3->SR&0xFE; //bit0 of sr is cleared

                            N++;

                     }                   

          }

              EncCnt= N * 65536 + TIM3->CNT;  

          //        encoder[0] = encoder[1];

       }                

      

}

 

Finally, I found a simpler way to detect the encoder overflow interrupt and accumulate it.

In fact, when the encoder timer overflows, it will cause an interrupt. In this case, you can directly use the encoder interrupt function. However, it should be noted that the interrupt needs to be configured when the encoder timer is configured. If it is not configured, the program will freeze as soon as it runs. It will always stop at the sentence DMA2_Channel4_5_IRQHandler.

Attached is the code for the final test verification

Encoder initialization configuration (Note. If the interrupt overflow method is not used, no configuration is required

NVIC_InitStructure.NVIC_IRQChannel =TIM3_IRQn;

   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

    NVIC_Init(&NVIC_InitStructure);

this part...)

And I used tim3 to redefine pc7 pc6. You can also use partial remapping and default pins.

void EncoderTimInit()

{

// The configuration of TIM_ICInitStructure and the use of TIM_EncoderInterfaceConfig function are actually conflicting, and the polarity settings in the two statements are repeated

       //--------------1

       GPIO_InitTypeDefGPIO_InitStructure;

   TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;

   TIM_ICInitTypeDef TIM_ICInitStructure;

   NVIC_InitTypeDef NVIC_InitStructure;

      

      

   RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //Enable TIM3 clock

   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); //Enable GPIOC clock

       RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //AFIO clock

      

       GPIO_PinRemapConfig(GPIO_FullRemap_TIM3,ENABLE); //TIM selects full multiplexing function enable

   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; // PC6 and PC7 floating input

   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;//GPIO_Mode_IPU  GPIO_Mode_IN_FLOATING

   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

   GPIO_Init(GPIOC,&GPIO_InitStructure);

      

      

       TIM_DeInit(TIM3); //TIM3 initialization

   /* Timer configuration in Encoder mode */

   TIM_TimeBaseStructure.TIM_Prescaler = 0; // No frequency division

   TIM_TimeBaseStructure.TIM_Period = ENCODER_TIM3_PERIOD-1; //Count 40000 Timing T = 1/72000000 *40000 S = 1/1.8ms

   TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //Set the clock division factor: no division

   TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //Upward counting mode

   TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);

      

// //Encoding configuration encoding mode   

   TIM_EncoderInterfaceConfig(TIM3, TIM_EncoderMode_TI12,TIM_ICPolarity_Rising, TIM_ICPolarity_Rising); //TIM_ICPolarity_Rising rising edge capture

   TIM_ICStructInit(&TIM_ICInitStructure); //Input capture mode is configured as hardware default

   TIM_ICInitStructure.TIM_ICFilter = 0x06; //ICx_FILTER; //Comparison filter

   TIM_ICInit(TIM3, &TIM_ICInitStructure); //Call library function to fill in configuration information

 

   NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;

   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

   NVIC_Init(&NVIC_InitStructure);

 

//     TIM_ARRPreloadConfig(TIM3,ENABLE);

//     TIM_OC1PreloadConfig(TIM3,TIM_OCPreload_Disable);

 

       //Clear all pending interrupts

//     TIM_SetAutoreload(TIM3,0xffff);

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

       TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);//Enable interrupt                                                                                                    

 

   //Reset counter to initial value

   TIM3->CNT = 0;

   TIM_Cmd(TIM3, ENABLE);

}

 

Encoder counting module

void TIM3_IRQHandler(void)

{     

       if(TIM_GetITStatus(TIM3,TIM_IT_Update) != RESET)

   {

    TIM_ClearITPendingBit(TIM3 , TIM_FLAG_Update);

          if((TIM3->CR1&0x10) == 0x10) // count down

          {          

                     N--;               

          }

          else if((TIM3->CR1&0x10) == 0x00)//Count up

          {

                     N++;            

          }

              EncCnt= N * 65536 + TIM3->CNT;        

   }           

}

Note: N and EncCnt variables are best defined as volatile


Keywords:STM32 Reference address:Summary of STM32 encoder counting and overflow processing debugging

Previous article:The problem of reading "negative numbers" in encoder mode in stm32
Next article:STM32F103 Experiment 2 Control 1 motor and use encoder to read motor speed

Recommended ReadingLatest update time:2024-11-23 08:28

STM32 ADC conversion (DMA)
Last time I talked about how to implement ADC conversion. This time I used DMA to help with ADC conversion. With DMA, multiple ADC channels can be converted simultaneously. Next, I will talk about how to use DMA to achieve DAC multiplexing. It is still based on my own standard project. 1. Modification of the proje
[Microcontroller]
STM32 ADC conversion (DMA)
stm32 firmware library file description
Firmware library file description The new version V3.5stm32f10x_map.h becomes stm32f10x.h Table 2. Firmware library file description (where ppp stands for peripheral) File name Description stm32f10x_conf.h parameter setting file, which acts as an interface between the application and the library. Users must modify th
[Microcontroller]
stm32 firmware library file description
Understanding the use of STM32's NVIC_PriorityGroupConfig and priority grouping
STM32 has 43 channel settable interrupt sources; the AIRC (Application Interrupt and Reset Register) register has 4 bits for specifying priority. /* Preemption Priority Group -----------------------------------------------------------------*/ #define NVIC_PriorityGroup_0 ((u32)0x700) /* 0 bits for pre-emption priority
[Microcontroller]
STM32 general timer
There are many types of timers in STM32, which are divided into 2 advanced controller timers, 4 ordinary timers, 2 basic timers, 2 watchdog timers, and 1 system tick timer SysTick according to their functions. The key to the timer is the calculation of the timing time. For example, when using a timer to control the
[Microcontroller]
STM32 general timer
Summary of problems in PWM wave generation of STM32
Using STM32F103RC Question: The calculation result of PWM duty cycle is correct, but the output is wrong. The motor of Xinxida cannot be unlocked because the function of register is not understood. #include "tim2_pwm.h" #include "stm32f10x_tim.h" void Init_GPIO(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB
[Microcontroller]
STM32 configuration PC13~PC15
In the pinout diagram of the STM32 data sheet, you can see that PC14 and OSC32_IN share a pin, and PC15 and OSC32_OUT share a pin. Their usage is as follows: When LSE (low-speed external clock signal) is turned on, the functions of these two common pins are OSC32_IN and OSC32_OUT. When LSE (low-speed external clock
[Microcontroller]
STM32 configuration PC13~PC15
STM32 clock introduction and configuration method
When using any peripheral in STM32, the corresponding clock must be turned on. There are 5 clock sources for users to choose from in STM32: 1.HSI high-speed internal clock, RC oscillator, frequency is 8MHz. 2.HSE high speed external clock, right-hand/ceramic resonator, or external clock source, 4MHz-16MHz. 3.LSI inter
[Microcontroller]
STM32 emulates I2C
Use STM32 to access ferroelectric memory of I2C interface, FM24CL16, 2K bytes ====================================  I2C pin configuration:  /* Configure I2C1 pins: SCL and SDA */    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;    GPIO_InitStructure.GPIO_Speed ​​= GPIO_Speed_50MHz;    GPIO_InitStructur
[Microcontroller]
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号