STM32—TIM系列(TIM编码器接口)

目录

一、编码器接口介绍

1.1、电路部分

​编辑 1.3、计数方向与编码信号

 二、代码配置

2.1、TIM_EncoderInterfaceConfig()

2.2、Encoder_Init()配置

 2.2.1、开启时钟部分

 2.2.2、时基单元部分

2.2.3、输入捕获单元的配置

2.2.4、编码器接口配置

2.2.5、Encoder_Init()完整代码

2.2.5、实现速度测试


一、编码器接口介绍

编码器接口可接收增量(正交)编码器的信号,根据编码器旋转产生的正交信号脉冲,自动控制CNT自增或自减,从而指示编码器的位置、旋转方向和旋转速度。

两个输入引脚借用了输入捕获的通道1和通道2,且无法使用通道3/4,。

1.1、电路部分

1.2、编码器的基本配置流程

 1.3、计数方向与编码信号

 该表与下图是关系对应的

 

 二、代码配置

2.1、TIM_EncoderInterfaceConfig()

//定时器编码器接口配置函数
//参数1:选择定时器;参数2:选择定时器模式;参数3/4分别为选择通道1/2的电平极性

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

2.2、Encoder_Init()配置

 2.2.1、开启时钟部分

 

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);  //开启时钟,
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//开启时钟,选择GPIOkou 
	
	GPIO_InitTypeDef GPIO_InitStructure;
 	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//选择上拉输入模式
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;
 	GPIO_Init(GPIOA, &GPIO_InitStructure);

 2.2.2、时基单元部分

    TIM_InternalClockConfig(TIM3);//初始化时基单元
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;//指定参数分频值(选择1分频),
	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);	//配置时基单元

2.2.3、输入捕获单元的配置

 

 由2.2.3、图1可以看出编码器接口仅用到输入捕获单元的部分配置,因此输入捕获单元不需要像2.2.3、图2那样全部配置。因此下图中的28、29代码可以略去,但是略去后结构体配置不完整,为避免出现不确定值造成不必要的麻烦,所以需要用到 24 条代码,为结构体赋初始值。其实第 27 条代码也可以删去,因为接口配置中会有相关函数配置极性。

    TIM_ICInitTypeDef TIM_ICINitstructure;
	TIM_ICStructInit(&TIM_ICINitstructure);//结构体TIM_ICINitstructure赋初始值
	TIM_ICINitstructure.TIM_Channel=TIM_Channel_1; //选择通道,本例程中使用的是TIM3的通道1
	TIM_ICINitstructure.TIM_ICFilter=0xF;//配置输入捕获的滤波器,数值大,滤波效果越好
	TIM_ICINitstructure.TIM_ICPolarity=TIM_ICPolarity_Rising;//极性选择 上升沿or下降沿,

以下是配置两个通道,蓝色部分是通道1,红色部分为通道2

以下是给部分最终代码。已经删去关于极性配置代码。

	TIM_ICInitTypeDef TIM_ICINitstructure;
	TIM_ICStructInit(&TIM_ICINitstructure);//结构体TIM_ICINitstructure赋初始值
	TIM_ICINitstructure.TIM_Channel=TIM_Channel_1; //选择通道,本例程中使用的是TIM3的通道1
	TIM_ICINitstructure.TIM_ICFilter=0xF;	//配置输入捕获的滤波器,数值大,滤波效果越好,
	TIM_ICInit(TIM3,&TIM_ICINitstructure);
	TIM_ICINitstructure.TIM_Channel=TIM_Channel_2; //选择通道,本例程中使用的是TIM3的通道1
	TIM_ICINitstructure.TIM_ICFilter=0xF;		//配置输入捕获的滤波器,数值大,滤波效果越好
	TIM_ICInit(TIM3,&TIM_ICINitstructure);

2.2.4、编码器接口配置

该部分仅需要用到函数 TIM_EncoderInterfaceConfig()便可配置

//定时器编码器接口配置函数
//参数1:选择定时器;参数2:选择定时器模式;参数3/4分别为选择通道1/2的电平极性

该函数的参数3和参数4便起到替代 2.2.3、图3的第27、31条函数的作用。

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

    TIM_EncoderInterfaceConfig(TIM3,TIM_EncoderMode_TI12,TIM_ICPolarity_Rising,TIM_ICPolarity_Rising);	
    TIM_Cmd(TIM3,ENABLE);//开启定时器

2.2.5、Encoder_Init()完整代码

void Encoder_Init()
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);  //开启时钟,
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//开启时钟,选择GPIOkou 
	
	GPIO_InitTypeDef GPIO_InitStructure;
 	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//选择上拉输入模式
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;
 	GPIO_Init(GPIOA, &GPIO_InitStructure);

	TIM_InternalClockConfig(TIM3);//初始化时基单元
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;//指定参数分频值(选择1分频)
	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_ICINitstructure.TIM_Channel=TIM_Channel_1; //选择通道,本例程中使用的是TIM3的通道1
	TIM_ICInit(TIM3,&TIM_ICINitstructure);
	TIM_ICINitstructure.TIM_Channel=TIM_Channel_2; //选择通道,本例程中使用的是TIM3的通道1
	TIM_ICInit(TIM3,&TIM_ICINitstructure);
	            TIM_EncoderInterfaceConfig(TIM3,TIM_EncoderMode_TI12,TIM_ICPolarity_Rising,TIM_ICPolarity_Rising);	
	TIM_Cmd(TIM3,ENABLE);//开启定时器

}

2.2.5、实现速度测试

//读取CNT的值后将其清零
int16_t Encoder_Get(void)
{
	int16_t Temp;
	Temp=TIM_GetCounter(TIM3);//获取TIMx计数器值;
	TIM_SetCounter(TIM3,0);//设置TIMx计数器寄存器值
	return Temp;
}

while(1)
	{	
		OLED_ShowSignedNum(1,7,Encoder_Get(),5);	
		Delay_ms(1000);

	}

首先我们使用以上的代码获取CNT的值然后在while(1)中每1s获取一次CNT的值,那么读取的CNT值即为速度(以上代码非演示代码)。但是在主函数中需要慎用Delay()。所以们需要使用中断函数配置。以下即为中断代码,对于具体多久进一次中断需要查看中断函数的ARR以及PSC参数。

void TIM2_IRQHandler(void)
{
	if(TIM_GetITStatus(TIM2,TIM_IT_Update)==SET)
	{
		Speed=Encoder_Get();
		TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
	}
}

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

橘洲青年

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值