STM32f103入门(9)编码器接口测速

STM32f103入门(9)编码器接口测速_第1张图片
STM32f103入门(9)编码器接口测速_第2张图片
TIM3
PA6 PA7 上拉输入
原理上也是PWM捕获输入 捕获两个输入
我们用中断处理读取CNT的值
读取完将CNT置0
这样我们就得到了旋转编码器的速度/s
中断配置代码

#include "stm32f10x.h"                  // Device header

void Timer_Init(void)
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
	
	TIM_InternalClockConfig(TIM2);
	
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeBaseInitStructure.TIM_Period = 10000 - 1;
	TIM_TimeBaseInitStructure.TIM_Prescaler = 7200 - 1;
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);
	
	TIM_ClearFlag(TIM2, TIM_FLAG_Update);
	TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	
	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
	NVIC_Init(&NVIC_InitStructure);
	
	TIM_Cmd(TIM2, ENABLE);
}

/*
void TIM2_IRQHandler(void)
{
	if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET)
	{
		
		TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
	}
}
*/

捕获接口代码

#include "stm32f10x.h"                  // Device header

void Encoder_Init(void)
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	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(GPIOA, &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);
	
	TIM_ICInitTypeDef TIM_ICInitStructure;
	TIM_ICStructInit(&TIM_ICInitStructure);
	TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;
	TIM_ICInitStructure.TIM_ICFilter = 0xF;
	TIM_ICInit(TIM3, &TIM_ICInitStructure);
	TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;
	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;
	Temp = TIM_GetCounter(TIM3);
	TIM_SetCounter(TIM3, 0);
	return Temp;
}

这段代码主要是用来配置 TIM3 定时器的编码器接口模式。这里采用了 TI1 和 TI2 两个通道来实现编码器的计数。

具体来说,代码设置了两个通道(TIM_Channel_1 和 TIM_Channel_2)的输入捕获滤波器为 0xF,意味着输入信号会经过 15 个连续采样周期的滤波。这样可以减少输入信号中的噪声,并提高计数器的计数精度。

接着,代码调用了 TIM_EncoderInterfaceConfig 函数对编码器接口进行配置。这个函数需要传入以下参数:

TIMx:定时器的基地址,这里使用的是 TIM3。
TIM_EncoderMode_TI12:编码器接口模式,此处使用的是 TI1 和 TI2 两个输入通道来实现编码器的计数。
TIM_ICPolarity_Rising:输入捕获触发边沿。这里设置为上升沿触发。
TIM_ICPolarity_Rising:输入捕获触发边沿。这里也设置为上升沿触发。
设置了编码器接口模式之后,就可以通过 TIM_GetCounter() 函数获取定时器的计数器值,从而实现编码器的计数功能。

需要注意的是,此处的代码片段并没有完整的实现编码器的计数功能,只是完成了配置定时器模式和通道滤波的工作。如果需要进行编码器的计数操作,还需要编写相应的中断服务函数,并在其中根据编码器的方向和计数规则对计数器值进行增减操作。

你可能感兴趣的:(stm32,单片机,嵌入式硬件)