STM32 learning notes on quadrature encoder interface

Publisher:caijtLatest update time:2016-08-21 Source: eefocusKeywords:STM32 Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere
I recently worked on a project, the main control chip is STM32RBT6, and I need to use a grating ruler. It originally came with a controller, and the data of the grating ruler can be read through the controller's 232, but this controller is too large to fit in the device, so I considered making one myself. I saw many useful CPLD solutions on the Internet, and later I accidentally discovered that the timer of stm32 can be configured as an encoder, which made me very

happy. I was very happy, but suddenly I found that the timer of stm32 is 16 bits, and the count of my grating ruler will exceed 65535, so I consulted several experts on the 21ic forum, and finally determined the solution. The

working process is to configure TIM3 to orthogonal encoder mode, and set a 10ms interrupt, read the count value every 10ms, and the premise of 10ms is that the counter does not overflow within 10ms (thanks to lxyppc of 21ic for this idea) )

The following is some code: (These codes are modified from ST official routines, but my project uses the V3 firmware library, and their routines seem to be 0.3, so some places have been changed)
The following is to initialize TIM3 to quadrature encoder mode
void ENC_Init(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_ICInitTypeDef TIM_ICInitStructure;

/* Encoder unit connected to TIM3, 4X mode */    
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;

/* TIM3 clock source enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
/* Enable GPIOA, clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

GPIO_StructInit(&GPIO_InitStructure);
/* Configure PA.06,07 as encoder input */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);

/* Enable the T IM3 Update Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = TIMx_PRE_EMPTION_PRIORITY;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = TIMx_SUB_PRIORITY;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

/* Timer configuration in Encoder mode */
TIM_DeInit(ENCODER_TIMER);
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);

TIM_TimeBaseStructure.TIM_Prescaler = 0x0; // No prescaling 
TIM _TimeBaseStructure.TIM_Period = ENCODER_TIM_PERIOD; 
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;   
TIM_TimeBaseInit(ENCODER_TIMER, &TIM_TimeBaseStructure);

TIM_EncoderInterfaceConfig(EN CODER_TIMER, TIM_EncoderMode_TI12, 
                             TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);
TIM_ICStructInit(&TIM_ICInitStructure);
TIM_ICInitStructure.TIM_ICFilter = ICx_FILTER;
TIM_ICInit(ENCODER_TIMER, &TIM_ICInitStructure);

// Clear all pending interrupts
TIM_ClearFlag(ENCODER_TIMER, TIM_FLAG_Update);
TIM_ITConfig(ENCODER_TIMER, TIM_IT_Update, ENABLE);
//Reset counter
TIM2->CNT = COUNTER_RESET;

// ENC_Clear_Speed_Buffer();

TIM_Cmd(ENCODER_TIMER, ENABLE); 
}
The following is to obtain a count value, this algorithm comes from lxyppc, you can avoid the situation of exceeding 16 bits. For details, see the discussion at http://bbs.21ic.com/viewthread.php?tid=110623

s16 ENC_Get_Electrical_Angle(void)
{
static u16 lastCount = 0;
u16 curCount = ENCODER_TIMER->CNT;
s32 dAngle = curCount - lastCount;
if(dAngle >= MAX_COUNT){
    dAngle -= ENCODER_TIM_PERIOD;
}else if(dAngle < -MAX_COUNT){
    dAngle += ENCODER_TIM_PERIOD;
}
lastCount = curCount;
return (s16)dAngle; 
}

The following is the system tick initialization and interrupt function
void TB_Init(void)
{   
/* Setup SysTick Timer for 10 msec interrupts */
if (SysTick_Config(SystemFrequency / 100))

    /* Capture error */ 
    while (1);
}
}

void SysTick_Handler(void)
{   
/*if (hTimebase_display_500us != 0) 
{
    hTimebase_display_500us --;
}
   */
if (hSpeedMeas_Timebase_500us !=0)
{
    hSpeedMeas_Timebase_500us--;
}
else
{
    hSpeedMeas_Timebase_500us = SPEED_SAMPLING_TIME;

    CurrentCount += ENC_Get_Electrical_Angle();
        
    //ENC_Calc_Average_Speed ​​must be called ONLY every SPEED_MEAS_TIMEBASE ms
    //ENC_Calc_Average_Speed();    
}
}
The above code has passed the test, the firmware library version is: V3.1.2
ST official routines and Chinese documentation: http://www.stmicroelectronics.com.cn/stonline/mcu/images/STM32F10xxx_Encoder_AN%28CH%29.pdf
http://images.stmicroelectronics.com.cn/stonline/mcu/images/STM32F10xxx_Encoder_AN(CH).zip

Finally, I have to complain, why doesn’t ST make the timer 32-bit? Can it increase the cost by 1 cent?
Keywords:STM32 Reference address:STM32 learning notes on quadrature encoder interface

Previous article:I/O driver based on AT91RM9200 (linux)
Next article:STM32 SysTick system clock super simple timer SysTick

Recommended ReadingLatest update time:2024-11-16 14:40

Hardware connection of STM32 transplantation lwip
I have always wanted to write some posts and blogs, but I just couldn't bear to do it as I just graduated. After some preparation, I decided to write down some of the things I learned in the past few days as a record. Some  time ago, I came into contact with the transplantation of lwip on stm32, the establishment of T
[Microcontroller]
Design of home service robot system based on STM32
introduction   With the development of artificial intelligence and sensor technology, robots have entered people's daily life environment from the structured environment of factories. Robots can not only complete tasks autonomously, but also collaborate with people to complete tasks or complete tasks under the guidanc
[Microcontroller]
STM32 Learning Path (VI) - AD Conversion
        ADC input channel management mode can be divided into rule group and injection group. Rule group refers to normal conversion; injection group is triggered by external trigger or software, interrupting normal rule group conversion. Rule group can be a single channel or a combination of several channels. The conv
[Microcontroller]
STM32 CAN communication
CAN communication using stm32: 1. Initialization,     1) Including pin initialization    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;    GPIO_Init(GPIOA, &GPIO_InitStructure);         GPIO_InitStructure.GPIO_Pin = GP
[Microcontroller]
Hardware circuit connection diagram and software program design based on STM32 processor
    This paper introduces a single-chip network interface chip W5100, which integrates TCP/IP hardware protocol stack and supports multiple network protocols. The hardware circuit connection diagram and software program design based on STM32 processor are given. At present, the system has been successfully applied in
[Microcontroller]
Hardware circuit connection diagram and software program design based on STM32 processor
Writing STM32 I2C library functions
I2C Protocol:  I2c is a bidirectional serial communication standard, commonly used in embedded systems. The I2c bus can be used to expand multifunctional peripheral devices with limited I/O interfaces. It is mainly composed of SCL (clock line) and SDA (data line). Multiple devices with I2c interfaces can be connected
[Microcontroller]
Writing STM32 I2C library functions
STM32 Get the address of the register
If you need to use DMA transmission of TX1, it will involve configuring the peripheral address of DMA. Here, the peripheral address should be the address of DR register of USART1. But how to get the address of this register? We have tested three methods and all of them are feasible. method 1: Directly query the
[Microcontroller]
stm32 usb data buffer question
Different USB applications require different endpoint numbers and endpoint data lengths. It is very wasteful to plan a separate storage area for each endpoint. Therefore, STM32 provides a total of 512 bytes of storage area for the USB module. As for how to allocate and use this 512B space for each endpoint, it is up
[Microcontroller]
Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
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号