stm32学习19--定时器之编码器
一、简介
Encoder Interface编码器接口
编码器接口可接收增量(正交)编码器的信号,根据编码器旋转产生的正交信号脉冲,自动控制CNT自增或自减,从而指示编码器的位置、旋转方向和旋转速度。
每个高级定时器和通用定时器都有1个编码器接口;
两个输入引脚借用了输入捕获的通道1和通道2;
二、基础原理
1、正交编码器信号
增量式正交编码器输出A相、B相。
正向旋转:A先跳变,随后B跳变;
反向旋转:B先跳变,随后A跳变;
定时器硬件自动识别相位先后,自动增减CNT寄存器,无需软件判断方向。

2、定时器编码器模式
STM32F1系列定时器编码器模式由TIM_EncoderMode配置,3种模式:
模式一:TIM_EncoderMode_TI1:仅检测TI1边沿,只在A相跳变计数;
模式二:TIM_EncoderMode_TI2:仅检测TI2边沿,只在B相跳变计数;
模式三:TIM_EncoderMode_TI12:TI1+TI2双边沿都计数(4倍频),比较常用,A、B上升沿+下降沿全部触发计数→分辨率x4;F103系列只有TIM1/TIM2/TIM3/TIM4支持编码器模式,TIM5/TIM6/TIM7不支持。

核心逻辑:检测到某一相边沿→立即读取另一相此刻电平→根据电平决定CNT+1(向上计数)还是CNT-1(向下计数)。
相对信号的电平指的是:
TI1FP1对应TI2:TI1发生跳变,参考信号是TI2电平;
TI1FP2对应TI1:TI2发生跳变,参考信号是TI1电平;
即:当TI1FP1出现跳变沿时,硬件读取TI2FP2当前电平;当TI2FP2出现跳变沿时,硬件读取TI1FP1当前电平。
举例:标准正转时序:A↑→B↑→A↓→B↓,对照模式三,4倍频查表得知:
A上升沿,此时B=0(低电平)→向上计数++;
B上升沿,此时A=1(高电平)→向上计数++;
A下降沿,此时B=1(高电平)→向上计数++;
B下降沿,此时A=0(低电平)→向上计数++;
一圈4次计数,即4倍频,反转时波形顺序颠倒,每次边沿查表都会触发向下计数,如下:
反转时序:B↑→A↑→B↓→A↓
B上升沿,此时A=0(低电平)→向下计数--;
A上升沿,此时B=1(高电平)→向下计数--;
B下降沿,此时A=1(高电平)→向下计数--;
A下降沿,此时B=0(低电平)→向下计数--;
再举例:仅TI1计数(TIM_EncoderMode_TI1)
规则:只有A相跳变才计数,B相任何变化直接无视。
同样正转波形:A↑→B↑→A↓→B↓
A上升沿,此时B=0(低电平)→向上计数++;
B上升沿→忽略不计数;
A下降沿,此时B=1(高电平)→向上计数++;
B下降沿→忽略不计数;
一个周期只+2,即2倍频;
3、工作模式表格注意点
1)日常一律使用TIM_EncoderMode_TI12,模式三,4倍频;
2)如果旋转时计数方向反了,2种修改方案:
方案一:硬件互换A、B两相接线;
方案二:软件修改TIM_EncodeInterfaceConfig的极性参数(翻转TI1或者TI2);
3)表格前提条件:A、B两相不会同时跳变。正常正交编码器本身满足,电机干扰出现同时跳变会造成计数误差,需要加大输入滤波ICFilter。
4、与输入捕获的关系
1)硬件结构
TIM的CHI1、CH2引脚,硬件本就是输入捕获通道,引脚→滤波器(ICFilter)→极性选择(CCxP)→TI1FP1/TI2FP2。编码器没有独立的引脚通路,需要共用捕获的前端电路。滤波、极性反转、信号选通,都是输入捕获的配置寄存器,所以都用到TIM_ICInit函数,只是不用捕获功能。
2)配置区别
TIM_ICInit:只配置信号前端(滤波、极性、直通TI),只负责:把引脚(比如TIM3的复用引脚PA6/PA7)的原始信号,处理成干净的TI1FP1、TI2FP2,传给后续编码器逻辑;TIM_ICPSC_DIV1在编码器模式下无效,赋值1即可。TIM_EncoderInterfaceConfig函数开启编码器计数逻辑,定时器内部切换成正交编码器模式,不再用输入捕获,而是根据A/B相位差自动加减CNT;
3)易混淆关键点
普通输入捕获:检测边沿,存捕获值、进中断,测脉冲周期/频率,是一套信号预处理模块。
编码器模式:关闭捕获逻辑,只用捕获的信号预处理电路,硬件自动累加CNT,不需要捕获中断等,是一个计数判断模块。
5、输入模式选择
编码器引脚浮空输入、上拉输入都可以用,上拉输入是工程常用方案。
浮空:电平由外部编码器决定,推挽输出编码器最常用,自带强高低电平驱动,浮空完全适配,理论上标准接法。但编码线很长、走线干扰大时,悬空易引起杂波误计数;
内部上拉:1)编码器NPN集电极开路/OC输出必须用上拉,否则静止时引脚电平不确定。
2)不会改变A/B相的相位先后,不影响正反转判断、计数倍率。
3)兼容性强:不会是推挽输出还是开路输出编码器,内部上拉均兼容。
3)抗干扰强:线束长、电磁干扰时,上拉能固定静态电平,减少毛刺导致的多计数。
4)必须浮空:编码器已经外接了上下拉电阻,如果再开内部上拉,会分压改变电平阈值。
三、代码
1、Encoder.c文件
#include "stm32f10x.h"
void Encoder_Init()
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,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 ;
TIM_TimeBaseInitTypeDef TIM_InitStructure;
TIM_InitStructure.TIM_ClockDivision =TIM_CKD_DIV1;
TIM_InitStructure.TIM_CounterMode =TIM_CounterMode_Up;
TIM_InitStructure.TIM_Period =65536-1;
TIM_InitStructure.TIM_Prescaler =0;
TIM_InitStructure.TIM_RepetitionCounter =0;
TIM_TimeBaseInit(TIM3,&TIM_InitStructure);
TIM_ICInitTypeDef IC_InitStructure;
IC_InitStructure.TIM_Channel =TIM_Channel_1;
IC_InitStructure.TIM_ICFilter =0xF;
IC_InitStructure.TIM_ICPolarity =TIM_ICPolarity_Rising;
IC_InitStructure.TIM_ICPrescaler =TIM_ICPSC_DIV1;
IC_InitStructure.TIM_ICSelection =TIM_ICSelection_DirectTI;
TIM_ICInit(TIM3,&IC_InitStructure);
IC_InitStructure.TIM_Channel =TIM_Channel_2;
TIM_ICInit(TIM3,&IC_InitStructure);
//编码器模式最终确定极性,覆盖上面IC里的极性配置
TIM_EncoderInterfaceConfig(TIM3,TIM_EncoderMode_TI12,TIM_ICPolarity_Rising,TIM_ICPolarity_Rising);
TIM_Cmd(TIM3,ENABLE);
}
int16_t GetEncoderCounter()
{
return TIM_GetCounter(TIM3);
}
2、Encoder.h文件
#ifndef __ENCODER_H
#define __ENCODER_H
void Encoder_Init();
int16_t GetEncoderCounter();
#endif
3、main函数
#include "stm32f10x.h"
#include "Delay.h"
#include "OLED.h"
#include "Encoder.h"
#include "Timer.h"
int16_t Counter;
int main()
{
OLED_Init();
Timer_Init();
Encoder_Init();
OLED_ShowString(1,1,"Counter:");
while(1)
{
OLED_ShowSignedNum(2,1,Counter,5);
}
}
void TIM2_IRQHandler(void)
{
if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET)
{
Counter = GetEncoderCounter();
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
}
}
4、代码补充说明
编码器测速一定要有定时中断:编码器CNT一直在累加,需要固定时间间隔读取计数值、算速度。
比如:10ms进一次中断,本次读CNT=500,清零CNT;代表10ms内编码器走了500个脉冲→换算速度,如果不使用定时中断,靠while循环读取,读取间隔不确定,速度算不准。
5、干扰(毛刺)的处理

编码器机械触点转动、齿轮咬合、导线受电磁干扰,会在正常跳变沿附近出现很多快速高低跳变的杂脉冲,即毛刺,TIM硬件会把每一次跳变都当成有效计数,计数器就会乱跳、多计数、正负来回跳、数值漂。
处理方案:
1、输入滤波ICFilter,寄存器TIM_CCMRx,0~15。短接线、干净环境:3~5;长线、电机旁边干扰大:8~15;
原理:连续N个定时器采样时钟都采到相同电平,才认定电平真的翻转,毛刺因持续时间短,采不到稳定电平,直接被过滤。采样时钟=定时器时钟(编码器PSC=0,72MHz)。ICF=0xF,需要连续15个采样周期电平不变,才判定电平真的翻转。
2、内部上拉:浮空输入时,毛刺易把悬空引脚电平拉乱,内部上拉将引脚电平钳在高电平,干扰不容易拉低电平,硬件层面减少毛刺产生。
3、硬件:编码器A/B线用屏蔽线,屏蔽层单端接地;走线尽量短,远离电机电源线、继电器大电流走线;引脚并联1000pF小电容到GND,RC滤波,吸收高频毛刺。
本文完!
更多推荐
所有评论(0)