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
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
- Popular Resources
- Popular amplifiers
- Naxin Micro and Xinxian jointly launched the NS800RT series of real-time control MCUs
- How to learn embedded systems based on ARM platform
- Summary of jffs2_scan_eraseblock issues
- Application of SPCOMM Control in Serial Communication of Delphi7.0
- Using TComm component to realize serial communication in Delphi environment
- Bar chart code for embedded development practices
- Embedded Development Learning (10)
- Embedded Development Learning (8)
- Embedded Development Learning (6)
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- Intel promotes AI with multi-dimensional efforts in technology, application, and ecology
- ChinaJoy Qualcomm Snapdragon Theme Pavilion takes you to experience the new changes in digital entertainment in the 5G era
- Infineon's latest generation IGBT technology platform enables precise control of speed and position
- Two test methods for LED lighting life
- Don't Let Lightning Induced Surges Scare You
- Application of brushless motor controller ML4425/4426
- Easy identification of LED power supply quality
- World's first integrated photovoltaic solar system completed in Israel
- Sliding window mean filter for avr microcontroller AD conversion
- What does call mean in the detailed explanation of ABB robot programming instructions?
- STMicroelectronics discloses its 2027-2028 financial model and path to achieve its 2030 goals
- 2024 China Automotive Charging and Battery Swapping Ecosystem Conference held in Taiyuan
- State-owned enterprises team up to invest in solid-state battery giant
- The evolution of electronic and electrical architecture is accelerating
- The first! National Automotive Chip Quality Inspection Center established
- BYD releases self-developed automotive chip using 4nm process, with a running score of up to 1.15 million
- GEODNET launches GEO-PULSE, a car GPS navigation device
- Should Chinese car companies develop their own high-computing chips?
- Infineon and Siemens combine embedded automotive software platform with microcontrollers to provide the necessary functions for next-generation SDVs
- Continental launches invisible biometric sensor display to monitor passengers' vital signs
- Can RTthread be ported to nrf51822?
- CDS photoresistor instruction manual
- I want to control the on and off of NMOS through a 3.3V microcontroller
- "Detailed Explanation of Embedded Linux System Development Technology--Based on ARM (Full Version)" e-book free
- Essential controlSUITE Software Suite for C2000 Microcontrollers
- Development of the electronics industry
- [National Technology N32 MCU Development Package] --N32G031 Series
- If signal modulation was like this back then, would you still not be able to learn it?
- Components Science Popularization: Pressure Sensor
- Question: How to accurately measure the duty cycle of a 100MHZ square wave? Thank you!