06:TIM timer function------encoder interface function

Table of contents

1: Resume

2: Quadrature encoder

 3: Basic structure of encoder interface

 4: Encoder working mode

5: Polarity reversal

A: Encoder interface speed measurement

1: Connection diagram

 2: Function introduction

3: Steps

4: Code

B: Encoder interface counting

1: Connection diagram

2: Code


1: Resume

        Encoder Interface encoder interface

        The encoder interface can receive signals from incremental (quadrature) encoders and automatically control the CNT to increase or decrease based on the quadrature signal pulses generated by the encoder rotation, thereby indicating the position, rotation direction and rotation speed of the encoder.

        Each advanced timer and general timer has 1 encoder interface

        The two input pins are borrowed from channel 1 and channel 2 of the input capture

2: Quadrature encoder

When the encoder rotates, it will output the following square wave signal

 3: Basic structure of encoder interface

        The encoder interface is valid for both rising and falling edges. Both rising and falling edges need to be counted. Therefore, in the encoder interface mode, the edge detection polarity selection is no longer the edge polarity selection. It is the polarity selection of high and low levels.

        Select the parameters of the rising edge------the signal passes through directly, and the high and low level polarity is not reversed---5: Polarity reversal

        Select the parameter of the rising edge-------the signal comes through a NOT gate, and the high and low level polarity is reversed----5: Polarity reversal

        

 4: Encoder working mode

         Forward rotation states count upwards, and reverse rotation states count downwards----TIM_EncoderMode_TI12

        The 2 modes above -- only count in one

5: Polarity reversal

None are reversed

 TI1 inversion

 

A: Encoder interface speed measurement

1: Connection diagram

 2: Function introduction

The function in the stm32f10x tim.h file ------ configure the timer encoder interface

void TIM_EncoderInterfaceConfig(TIM_TypeDef* TIMx, uint16_t TIM_EncoderMode,
                                uint16_t TIM_IC1Polarity, uint16_t TIM_IC2Polarity)
 

  TIM_EncoderInterfaceConfig  TIM_EncoderInterfaceConfig(TIM3, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);

Parameters : The second parameter---see 4 above: Encoder working mode

           The third (IC1 polarity) and fourth (IC2 polarity) parameters are the same: ---- 3: Edge detection polarity selection in the basic structure of the encoder interface

        The rising edge here does not mean that the rising edge is valid, because the encoder interface is always valid on both the rising edge and the falling edge. The rising edge parameter here represents that the high and low level polarities are not reversed -----5: polarity reversal

The function in the stm32f10x tim.h file------reads the value of the counter CNT

uint16_t TIM_GetCounter(TIM_TypeDef* TIMx)

TIM_SetCounter : The counter is cleared when 65535 is read.

The function in the stm32f10x tim.h file ------- reassigns CNT

void TIM_SetCounter(TIM_TypeDef* TIMx, uint16_t Counter)
 

TIM_SetCounter: The second parameter: after reading CNT, change it and assign a new value; here we choose to clear it to zero

Functions in the stm32f10x tim.h file------interrupt flag bits and flag bit clearing

ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t TIM_IT);

void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT)
 

TIM_GetITStatus :  Get whether the interrupt flag bit is set to 1 ( detect the status of the external interrupt )

TIM_ClearITPendingBit Clear the interrupt pending flag bit

3: Steps

To configure the timer encoder interface

1: RCC turns on the clock, (the clocks of TIM peripherals---RCC_APB1PeriphClockCmd and GPIO peripherals--RCC_APB2PeriphClockCmd are turned on)

2: Configure GPIO----GPIO_Init (write the second step last)

3: Configure time base unit-----TIM_TimeBaseInit()

4: Configure input capture (ic ) ----TIM_ICInit()---IC needs to be configured 2 articles see code

5: Configure the timer encoder interface---TIM_EncoderInterfaceConfig()

6: Start the timer-----TIM_Cmd()

Timer starting steps

1: Turn on the clock (RCC)

2: Select the clock of the time base unit (TIM_InternalClockConfig--select the internal clock )

3: Configure time base unit (TIM_TimeBaseInit)

4: Enable update interrupt (TIM_ITConfig interrupt clock control )

5: Configuration of NICV (see 02: STM32)

6: Start timer (TIM_Cmd)

Steps to start the timer. For details, see: 03: TIM timer.

4: Code

#include "stm32f10x.h"                  // Device header
#include "OLED.h"
#include "Timer.h"
#include "Encoder.h"
#include "Delay.h"

void Timer_init(void){
//第一步是开启时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
//第二步,选择时基单元的时钟 (stm23上电默认使用的是内部时钟,这一行代码可以省略)
TIM_InternalClockConfig(TIM2);
//第三步,配置时基单元
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数
/*计数器溢出频率:CK_CNT_OV = CK_CNT / (ARR + 1)
					       = CK_PSC / (PSC + 1) / (ARR + 1
	定时频率=72M/(PSC+1)/(ARR+1)
	72MHZ=72000KHZ
	72000KHZ/7200=10KHZ=10000HZ
	T=1/F   T=1/10000hz=0.0001s=0.1ms
	然后以0.1ms的周期计10 000个数,所以就是1s
	
	*/
TIM_TimeBaseInitStructure.TIM_Period=10000-1;			//自动重装载寄存器ARR
TIM_TimeBaseInitStructure.TIM_Prescaler=7200-1;  //预分频器PSC
TIM_TimeBaseInitStructure.TIM_RepetitionCounter=0;//高级定时器特有的(重复寄存器)
TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);
	
//第四使能更新中断

TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
	
	
TIM_ClearFlag(TIM2, TIM_FLAG_Update);//手动清除更新中断标志位
	
//第五步NICV的配置
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);	
	
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel=TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;
NVIC_Init(&NVIC_InitStructure);
//第六步启动定时器
TIM_Cmd(TIM2,ENABLE);
}

void Encoder_Init(void)
{
	//1:配置RCC,把我们这里涉及的外设的时钟都打开(GPIO,AFIO)
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	//2:配置GPIO,选择我们的端口为输入模式  注意打开了2个中断
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	//第四步,配置时基单元
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeBaseInitStructure.TIM_Period = 65536 - 1;		//ARR
	TIM_TimeBaseInitStructure.TIM_Prescaler = 1 - 1;		//PSC
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStructure);
	//配置输入捕获(IC)
	TIM_ICInitTypeDef TIM_ICInitStructure;
	TIM_ICStructInit(&TIM_ICInitStructure);
	TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;
	TIM_ICInitStructure.TIM_ICPolarity=TIM_ICPolarity_Rising;
	TIM_ICInitStructure.TIM_ICFilter = 0xF;
	TIM_ICInit(TIM3, &TIM_ICInitStructure);
	
	
	TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;
	TIM_ICInitStructure.TIM_ICPolarity=TIM_ICPolarity_Rising;
	TIM_ICInitStructure.TIM_ICFilter = 0xF;
	TIM_ICInit(TIM3, &TIM_ICInitStructure);
	//配置定时器编码器接口
	TIM_EncoderInterfaceConfig(TIM3, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);
	//启动定时器
	TIM_Cmd(TIM3, ENABLE);
}



int16_t Encoder_Get(void)
{
	int16_t Temp;
	//读取CNT的值
	Temp = TIM_GetCounter(TIM3);
	TIM_SetCounter(TIM3, 0);
	return Temp;
}



int16_t Speed;
int main(void)
{
	OLED_Init();
	Timer_init();
	Encoder_Init();
	OLED_ShowString(1, 1, "Speed:");
	
	while (1)
	{
		OLED_ShowSignedNum(1,7,Speed,5);
		//Delay_ms(1000);
	}
}

void TIM2_IRQHandler(){
	//检查中断标志位
	if (	TIM_GetITStatus(TIM2,TIM_IT_Update)==SET)
	{
		//清除标志位
		//Num++;
		Speed=Encoder_Get();
		TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
	
	}


}

        Only the channel 1 and channel 2 interfaces of the TIM timer can be used as encoder interfaces

        Channel 3 and channel 4 cannot be used as encoder interfaces

IC needs to be configured twice

B: Encoder interface counting

        This code automatically counts times through the timer's encoder interface;  

        The previous code was to trigger an external interrupt, and then manually count the times in the interrupt function - see 02: STM32--EXTI external interrupt

1: Connection diagram

2: Code

#include "stm32f10x.h"                  // Device header
#include "OLED.h"
#include "Timer.h"
#include "Encoder.h"
#include "Delay.h"


void Encoder_Init(void)
{
	//1:配置RCC,把我们这里涉及的外设的时钟都打开(GPIO,AFIO)
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	//2:配置GPIO,选择我们的端口为输入模式  
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	//第四步,配置时基单元
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeBaseInitStructure.TIM_Period = 65536 - 1;		//ARR
	TIM_TimeBaseInitStructure.TIM_Prescaler = 1 - 1;		//PSC
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStructure);
	//配置输入捕获(IC)
	TIM_ICInitTypeDef TIM_ICInitStructure;
	TIM_ICStructInit(&TIM_ICInitStructure);
	TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;
	TIM_ICInitStructure.TIM_ICPolarity=TIM_ICPolarity_Rising;
	TIM_ICInitStructure.TIM_ICFilter = 0xF;
	TIM_ICInit(TIM3, &TIM_ICInitStructure);
	
	
	TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;
	TIM_ICInitStructure.TIM_ICPolarity=TIM_ICPolarity_Rising;
	TIM_ICInitStructure.TIM_ICFilter = 0xF;
	TIM_ICInit(TIM3, &TIM_ICInitStructure);
	//配置定时器编码器接口
	TIM_EncoderInterfaceConfig(TIM3, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);
	//启动定时器
	TIM_Cmd(TIM3, ENABLE);
}



int16_t Encoder_Get(void)
{
	
	return  TIM_GetCounter(TIM3);
}



int main(void)
{
	OLED_Init();
	
	Encoder_Init();
	OLED_ShowString(1, 1, "Speed:");
	
	while (1)
	{
		OLED_ShowSignedNum(1,7,Encoder_Get(),5);
		
	}
}

The TIM chapter is completed

Guess you like

Origin blog.csdn.net/m0_74739916/article/details/132500035