STM32 TIM编码器接口测速(最详细的编码器接口笔记)

编码器接口简单介绍

方波的频率其实就代表了速度

编码器接口测速原理

TIM编码器测速本质上就是测频法,在指定时间内,对高电平信号进行计次

编码器接口的设计逻辑就是,首先把A相和B 项的所有边沿作为计数器的计数时钟,出现边沿信号的时候,就自增或者自减,如何判断自增还是自减?当出现边沿信号的时候,我们去判断另一项的状态,如果这时候另一项为低电平,那么就为正转,如果为高电平,那么就为翻转,以此判断正交编码器的旋转方向。

这里的从模式自动电路也是一样的,当出现了边沿信号,并且另一向为低电平就控制CNt自增 否则控制CNT自减

编码器接口基本结构

工作模式

因为旋转器编码接口有两个向的输入,可以选择只对一个向进行计数,一般情况下,我们都对两个向进行计数

正交编码器抗噪声原理

当一个向的电平不变化,另一个向的电平连续变化的时候,这时候,由于一项保持高电平或是低电平,对应表的关闭,根据跳变信号向CNT计数器就会反复的自增自减自增自减,那么最终的数,还是毛刺信号前的数值,不会收到干扰影响。

总结:编码器接口模式基本上相当于使用了一个带有方向选择的外部时钟

代码部分

初始化流程

GPIO 模式选择原则:一般可以看外部模块输出默认电平,如果外部模块空闲默认输出高电平,我们就选择上拉输入,默认输入高电平,反之,如果外部模块默认输出低电平,我们就配置下拉输入,默认输入低电平,和外部模块保持默认一致,防止默认电平打架,这是上拉下拉的选择原则,不过一般来说,默认高电平,这是一个习惯的状态,所以一般上拉输入用的比较多,如果你不确认外部输入的默认状态,或是外部信号输出功率非常小,这时候就尽量选择浮空输入,因为他没有上拉或是下拉电阻干扰外部信号,缺点就是当引脚悬空的时候,容易受到干扰

主函数部分
#include "stm32f10x.h"                  // Device header
#include "OLED.h"
#include "Timer.h"
#include "Encoder.h"
#include "Delay.h"
int16_t Speed;
int main(void){
  
  OLED_Init();
  Encoder_Init();
  OLED_ShowString(1,1,"Speed:");
  Timer_Init();
  
  //  Timer_Init();
  while(1){
    OLED_ShowSignedNum(1,7,Speed,5);
  }
}

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

初始化函数部分
#include "stm32f10x.h"                  // Device header

void Encoder_Init(void)
{
  
  //1.开启时钟,开启定时器跟GPIO的时钟
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
  
  //将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(GPIOA,&GPIO_InitStructure);
  
  //配置TIM3 时钟源为内部时钟
  //        TIM_InternalClockConfig(TIM3); //编码器接口会托管时钟,所以不需要时钟源
  
  TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
  TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
  TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up;//也是无效的
  TIM_TimeBaseInitStructure.TIM_Period=65536-1;
  TIM_TimeBaseInitStructure.TIM_Prescaler=1-1;
  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 Ecoder_Get(void)
{
  int16_t Temp;
  Temp = TIM_GetCounter(TIM3);
  TIM_SetCounter(TIM3,0);
  return  Temp;
}        

程序现象

OLED 屏幕呈现编码器正/反旋转速度 频率1 秒

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值