STM32编码器接口使用指南

TIM编码器接口:

  • 编码器接口简介:
  • 正交编码器:
  • 正交编码器的旋转方向和旋转速度:
  • 正交信号:
  • 读取编码器:
  • 编码器接口:
  • 编码器接口通路:
  • 编码器接口基本结构:
  • 工作模式:
  • 实例:
  • 实例(均不反相):
  • 实例(TI1反相)
  • 代码实现:
  • 基本步骤:
  • 编码器接口配置函数:
  • 编码器接口计数:
  • 编码器接口简介:

    • Encoder Interface 编码器接口
    • 编码器接口可接收增量(正交)编码器的信号,根据编码器旋转产生的正交信号 脉冲,自动控制CNT自增或自减,从而指示编码器的位置、旋转方向和旋转速度
    • 每个高级定时器和通用定时器都拥有1个编码器接口
    • 两个输入引脚借用了输入捕获的通道1和通道2

    正交编码器:

    • 正交编码器一般可以测量位置,或者带有方向的速度值

    正交编码器的旋转方向和旋转速度:

    • 正交编码器的旋转速度:任意一相的信号的频率的倒数就是速度
    • 正交编码器的旋转方向: 在正转时,A相提前B相90度,反转时,A相滞后B相90度。正转时,是A相提前还是A相滞后,并不是绝对的,这是一个极性问题。总之就是朝一个方向转是A相提前,另一个方向转是A相滞后。

    正交信号:

    • 使用正交信号的优势: 首先就是正交信号的精度更高,因为A,B相都可以计次,相当于计次频率提高了一倍。其次正交信号抗噪声,因为正交信号,两个信号必须是交替跳变的,所以可以设置一个抗噪声电路,如果一个信号不变,另一个信号连续跳变,也就是产生了噪声,那这时计次值是不会变化的。

    读取编码器:

    当出现某个边沿,判断另一相的电平,如果对应另一相的状态出现在正转的表里,那就是正转,计数值自增。如果对应另一相的状态出现在反转的表里,那就是反转,计数值自减。

    编码器接口:

    • 编码器引脚详见这里

    编码器接口通路:

    编码器接口基本结构:


    • 输入部分:输入捕获前两个通道,通过GPIO口接入编码器的A,B相,产生TI1FP1和TI2FP2通过编码器接口。
    • 编码器接口:编码器接口通过预分频器控制CNT计数器的时钟,同时编码器接口还根据编码器的旋转方向,控制CNT的计数方向。编码器正转时,CNT自增,编码器反转时,CNT自减。
    • ARR: 一般设为65535,最大量程,利用补码特性,很容易得到负数。

    工作模式:

    实例:

    实例(均不反相):

    实例(TI1反相)


    • 将反相的信号取反,再查表

    代码实现:

    基本步骤:

    第一步:RCC开启时钟,开启GPIO和定时器的时钟。
    第二步:配置GPIO。(这里配置PA6和PA7)。
    第三步:配置时基单元,这里预分频器一般选择不分频,ARR配置为最大65535。
    第四步: 配置输入捕获单元。(只有滤波器和极性有用)。
    第五步:配置编码器模式。
    第六步:调用TIM_cmd,启动定时器。

    编码器接口配置函数:

    /**
      * @brief  配置TIMx编码器接口。
      * @param  TIMx: 选择TIMx,其中x可以是1、2、3、4、5或8来。
      * @param  TIM_EncoderMode: 指定TIMx的编码器接口模式。
      *   这个参数可以是下列值之一:
      *     @arg TIM_EncoderMode_TI1: 仅在TI1计数
      *     @arg TIM_EncoderMode_TI2: 仅在TI2计数
      *     @arg TIM_EncoderMode_TI12: 在TI1和TI2计数
      * @param  TIM_IC1Polarity: 指定IC1极性
      *   这个参数可以是下列值之一:
      *     @arg TIM_ICPolarity_Falling: 反向。
      *     @arg TIM_ICPolarity_Rising: 不反向。
      * @param  TIM_IC2Polarity: 指定IC2极性
      *   This parameter can be one of the following values:
      *     @arg TIM_ICPolarity_Falling: 反向。
      *     @arg TIM_ICPolarity_Rising: 不反向。
      * @retval None
      */
    void TIM_EncoderInterfaceConfig(TIM_TypeDef* TIMx, uint16_t TIM_EncoderMode,uint16_t TIM_IC1Polarity, uint16_t TIM_IC2Polarity)
    

    编码器接口计数:

    Encoder.c:

    void Encoder_Init()
    {
    ///开启GPIO和定时器的时钟
    	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
    配置GPIO/
    	GPIO_InitTypeDef GPIO_InitStruct;
    	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IPU;
    	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_6|GPIO_Pin_7;//	这里配置PA6和PA7
    	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
    	GPIO_Init(GPIOA,&GPIO_InitStruct);
    //配置时基单元///	
    	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配置为最大65535。
    	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);//将TIM3的编码器接口的工作模式配置为在TI1和TI2计数,将IC1配置为不反向,将IC2配置为不反向。
    启动定时器///	
    	TIM_Cmd(TIM3,ENABLE);
    }
    
    uint16_t Encoder_Get(void)
    {
    	int16_t Temp;
    	Temp= TIM_GetCounter(TIM3);//读取TIM3的CNT
    	TIM_SetCounter(TIM3,0);	//清零TIM3的CNT
    	return Temp;
    }
    

    main.c

    #include "stm32f10x.h"                  // Device header
    #include "Delay.h"
    #include "LED.h"
    #include "Key.h"
    #include "OLED.h"
    #include "Timer.h"
    #include "Encoder.h"
    int16_t Num=0;
     int main(void)
     {
    		OLED_Init();//OLED初始化
    		Encoder_Init();//TIM3编码器接口初始化
    		OLED_ShowString(1,1,"Speed:");
    		Timer_Init();//TIM2初始化
    		while(1)
    		{
    			OLED_ShowSignedNum(1,70,Num,5);//显示编码器的速度
    		}
     }
    void TIM2_IRQHandler(void)//TIM2的中断,一秒一次
    {
    	if(TIM_GetITStatus(TIM2,TIM_IT_Update)==SET)
    	{
    		Num=Encoder_Get();//获取编码器的速度
    		TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
    	}
    }
    

    作者:冯雪娟_00

    物联沃分享整理
    物联沃-IOTWORD物联网 » STM32编码器接口使用指南

    发表评论