STM32编码器接口测速方法及实例
单片机学习!
目录
文章目录
前言
一、编码器接口测速配置步骤
二、使用库函数
三、代码配置示例
3.1 RCC开启时钟
3.2 配置GPIO
3.3 配置时基单元
3.4 配置输入捕获单元
3.5 配置编码器接口模式
3.6 启动定时器
总结
前言
如何用编码器旋转控制CNT自增自减,本文介绍编码器接口测速的配置步骤。
一、编码器接口测速配置步骤
第一步、RCC开启时钟,开启GPIO和定时器的时钟。
第二步、配置GPIO,这里举例把PA6和PA7配置成输入模式。
第三步、配置时基单元,这里预分频器一般选择不分频;自动重装一般给最大65535;只需要CNT执行计数。
第四步、配置输入捕获单元,这里输入捕获单元只有滤波器和极性这两个参数有用,其他参数没有用到与编码器无关。
第五步、配置编码器接口模式,这个直接调用库函数就可以配置。
第六步、启动定时器,调用TIM_Cmd函数。
电路初始化完成之后,CNT就会随着编码器旋转而自增自减。
二、使用库函数
TIM_EncoderInterfaceConfig函数
定时器编码接口配置。
三、代码配置示例
3.1 RCC开启时钟
第一步、RCC开启时钟,将需要的TIM外设和GPIO外设的时钟打开。
代码示例:
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);//使用APB1的开启时钟函数,输入捕获定时器为TIM3。TIM3也是APB1的外设
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//这里计划用TIM3的通道1,根据引脚定义表,TIM3_CH1对应PA6引脚,所以开启GPIOA的时钟
3.2 配置GPIO
第二步、配置GPIO,把PA6和PA7配置成上拉输入模式,
GPIO模式可以选择上拉、下拉或者浮空。那么上拉、下拉和浮空如何选择?
上拉和下拉:
可以看接在引脚的外部模块输出的默认电平,
GPIO模式和外部模块保持默认状态一致,防止默认电平打架。这是上拉和下拉的选择原则。一般默认高电平是一个习惯的状态,所以上拉输入用的比较多。
浮空:
如果不确定外部模块输出的默认状态,或者外部信号输出功率非常小的时候就尽量选择浮空输入。浮空输入没有上拉电阻和下拉电阻去影响外部信号。但是缺点是当引脚悬空时没有默认的电平了,输入就会受噪声干扰,来回不断地跳变。
以上就是三种输入模式的选择原则。
代码示例:
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Mode= GPIO_Mode_IPU;//这里选择上拉输入
GPIO_InitStruct.GPIO_Pin= GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStruct.GPIO_Speed= GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStruct);
3.3 配置时基单元
第三步:配置时基单元,包括预分频器、自动重装器、计数模式等,这些参数可用结构体配置。
代码示例:
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= 0;//PSC预分频器
TIM_TimeBaseInitStructure.TIM_RepetitionCounter= 0;//重复计数器的值
TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure);//最后初始化TIM3
注:PSC和ARR的取值都要在0~65535之间,不能超范围。
3.4 配置输入捕获单元
由编码器接口测速配置步骤图可以看出,输入捕获单元并没有全部使用到,编码器接口只使用了通道1和通道2的滤波器和极性选择,所以只需要配置这两部分的参数即可。
在结构体中只配置其中两部分是不完整的,为了防止结构体中出现的不确定值可能会造成的问题,最好在定义结构体变量之后用TIM_ICStructInit函数给结构体初始化,把结构体的地址传入函数赋一个初始值。
TIM_ICStructInit函数默认给的初始值:
void TIM_ICStructInit(TIM_ICInitTypeDef* TIM_ICInitStruct)
{
/* Set the default configuration */
TIM_ICInitStruct->TIM_Channel = TIM_Channel_1;
TIM_ICInitStruct->TIM_ICPolarity = TIM_ICPolarity_Rising;
TIM_ICInitStruct->TIM_ICSelection = TIM_ICSelection_DirectTI;
TIM_ICInitStruct->TIM_ICPrescaler = TIM_ICPSC_DIV1;
TIM_ICInitStruct->TIM_ICFilter = 0x00;
}
结构体初始值赋值好后,再指定通道为1,滤波器为0xF,电平极性为上升沿。
代码示例:
TIM_ICInitTypeDef TIM_ICInitStructure;
TIM_ICStructInit(&TIM_ICInitStructure);
TIM_ICInitStructure.TIM_Channel=TIM_Channel_1;//TIM_Channel选择通道
TIM_ICInitStructure.TIM_ICFilter=0xF;//TIM_ICFilter用来配置输入捕获的滤波器
TIM_ICInitStructure.TIM_ICPolarity=TIM_ICPolarity_Rising;//TIM_ICPolarity极性
TIM_ICInit(TIM3,&TIM_ICInitStructure);
TIM_Channel选择通道,因为TIM_ICInit函数只有一个,所以要靠结构体的这个参数来指定是配置哪个通道。这里先配置通道1.
TIM_ICFilter用来配置输入捕获的滤波器,如果信号有毛刺和噪声,就可以增大滤波器参数,可以有效避免干扰。参数的取值范围0x0到0xF之间,数越大滤波效果越好,每个数值对应的采样频率和采样次数,可查看参考手册。
注意滤波器和分频器的区别,虽然两者都可以计次,但是滤波器计次并不会改变信号的原有频率,一般滤波器的采样频率会远高于信号频率,所以它只会滤除高频噪声,使信号更平滑,1KHz滤波之后仍然是1KHz,信号频率不会变化。而分频器就是对信号本身进行计次了,会改变频率。1KHz,2分频之后就是500Hz,4分频之后就是250Hz。
TIM_ICPolarity极性
电平极性为上升沿并不代表上升沿有效,因为编码器接口始终都是上升沿、下降沿都有效的。这里的上升沿参数代表的是高低电平极性不反转。也就是之前博文说的TI1、TI2是否反相(STM32 TIM编码器接口-CSDN博客 )对应通道给上升沿就是不反相,给下降沿就是反相。这里的极性参数在配置编码器接口的时候也有,这里的配置也可以删掉。
参数配置好后,最后传给函数TIM_ICInit,把这些参数写入到通道1。还有通道2的配置,
加上通道2配置后的代码示例:
TIM_ICInitTypeDef TIM_ICInitStructure;
TIM_ICStructInit(&TIM_ICInitStructure);
TIM_ICInitStructure.TIM_Channel=TIM_Channel_1;//TIM_Channel选择通道1
TIM_ICInitStructure.TIM_ICFilter=0xF;//TIM_ICFilter用来配置输入捕获的滤波器
TIM_ICInitStructure.TIM_ICPolarity=TIM_ICPolarity_Rising;//TIM_ICPolarity极性
TIM_ICInit(TIM3,&TIM_ICInitStructure);
TIM_ICInitStructure.TIM_Channel=TIM_Channel_2;//TIM_Channel选择通道2
TIM_ICInitStructure.TIM_ICFilter=0xF;//TIM_ICFilter用来配置输入捕获的滤波器
TIM_ICInitStructure.TIM_ICPolarity=TIM_ICPolarity_Rising;//TIM_ICPolarity极性
TIM_ICInit(TIM3,&TIM_ICInitStructure);
选择通道2,滤波器为0xF,电平极性为上升沿。配置好之后再调用TIM_ICInit函数,把配置的参数写入到通道2.
代码逻辑总结:
首先定义结构体变量,然后TIM_ICStructInit函数给结构体赋一个初始值,再部分修改需要配置的参数,调用TIM_ICInit函数配置一遍电路,这个结构体变量的配置调用TIM_ICInit函数之后,就写入到硬件寄存器了,所以调用TIM_ICInit函数之后这个结构体可以换个值继续使用,不需要重新定义新的结构体了。
3.5 配置编码器接口模式
配置编码器接口只需要调用一个函数就可以了。
代码示例:
TIM_EncoderInterfaceConfig(TIM3,TIM_EncoderMode_TI12,TIM_ICPolarity_Rising,TIM_ICPolarity_Rising);
TIM_EncoderInterfaceConfig函数用于定时器编码接口配置。
第一个参数:选择定时器TIM3。
第二个参数:编码器模式,一般选择TI1和TI2都计数。
后两个参数是IC1和IC2的极性,可更具实际情况来配置,这里选择TIM_ICPolarity_Rising。
这里TIM_EncoderInterfaceConfig函数的后两个参数和配置输入捕获单元的极性参数是一样的,实际的效果确实就是一样的,这两个地方的参数其实都是配置的同一个寄存器。这里属于重复配置,后面配置的参数会覆盖前面的参数,可以将输入捕获单元配置的极性参数删掉,只使用后面函数来配置极性。这里需要注意TIM_EncoderInterfaceConfig函数和配置输入捕获单元结构体的代码先后位置,后面的配置会覆盖前面的配置。
3.6 启动定时器
启动定时器,调用TIM_Cmd函数。
代码示例:
TIM_Cmd(TIM3,ENABLE);
以上初始化配置就结束了,调用后编码器旋转就能控制CNT自增自减。
总结
以上就是今天要讲的内容,本文仅仅简单介绍了编码器接口测速配置步骤、需要用到的库函数以及具体参数配置。
作者:Echo_cy_