1. 正交编码器原理

码盘:正交编码器有两个光电传感器,另一头有一个光源,当黑白相间的码盘转到白色对准光电传感器时,光电传感器发出一个脉冲。AB之间相隔的角度往往是90°的相位,即白格或者黑格的一半。

在这里插入图片描述

方向:A相和B相相差一个相位,一般来说是90°。A相信号在前表示正转,B相信号在前表示反转。

计数:在每个上升沿或者下降沿检测,检测到计数器就加+1。

线数和脉冲数的关系:假如一个编码器是1024线的,那么它转过一圈,若是只检测上升沿和下降沿,A相和B相应该各自发出了1024个脉冲,计数器记的数应该是2048。如果将其设置为上升沿下降沿都检测,则计数器应该计到了4096。

Z相:有的编码器还有一个Z相,它表示的是0位,即检测到0刻线即输出高电平,也就是给增量式编码器一个寻零的功能。

2. HAL库的编码器模式

STM32的定时器TIM1,2,3,5,8中有专门的编码器模式,省去了我们读脉冲和计数的操作。而且配置全面

可以配置:

计数方式(counter mode):即向上计数还是向下计数,不过使用编码器都是记录转的角度,读取计数器从0开始的计数,所以一般来说都是向上计数

编码器模式(encoder mode):Tl1是只检测上升沿,Tl2只检测下降沿。Tl1 and Tl2是上下沿都检测,那么脉冲数将是只检测一个沿的两倍。

检测极性(Polarity):触发捕获AB相的极性。意思是比如设为Rising Edge,那么检测到上升沿的时候就触发encoder捕获AB相的值

3. 具体配置

将所选TIM中的“Combined Channels”设为Encoder Mode

可以看到Channel1和Channel2已经灰了,表示这两个通道已经被使用为编码器模式了

这时候要在右侧的管脚图看看自动配置的是哪两个脚,和硬件原理图比对一下,若是不一样要改成原理图上的引脚

在这里插入图片描述

参数配置:主要参数含义已经在上面提过了

有一点就是,重载值,即计数器数到多少就清零,设为最大就行。16bit的就设为0xffff,32bit就设为0xffffffff。设的太小会用着用着跳零,编码器就失效了

在这里插入图片描述

若是带Z相的编码器,就把它配置成GPIO-INPUT模式,若是编码器经0输出高电平,则下拉;反之,上拉

4. 编程

4.1 函数

encoder模式的编程很简单,内容很少,HAL库定义的所有函数在stm32f4xx_hal_tim.c文件的2558到3143行。包括了:

初始化类函数

//编码器初始化
HAL_StatusTypeDef HAL_TIM_Encoder_Init(TIM_HandleTypeDef *htim,  TIM_Encoder_InitTypeDef *sConfig)
//编码器解初始化
HAL_StatusTypeDef HAL_TIM_Encoder_DeInit(TIM_HandleTypeDef *htim)

__weak void HAL_TIM_Encoder_MspInit(TIM_HandleTypeDef *htim)

__weak void HAL_TIM_Encoder_MspDeInit(TIM_HandleTypeDef *htim)

起止类函数:

//开启编码器
HAL_StatusTypeDef HAL_TIM_Encoder_Start(TIM_HandleTypeDef *htim, uint32_t Channel)
//关闭编码器
HAL_StatusTypeDef HAL_TIM_Encoder_Stop(TIM_HandleTypeDef *htim, uint32_t Channel)

中断类函数:

//开启成功中断
HAL_StatusTypeDef HAL_TIM_Encoder_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel)
//关闭成功中断
HAL_StatusTypeDef HAL_TIM_Encoder_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel)

DMA类函数:

//开启DMA
HAL_StatusTypeDef HAL_TIM_Encoder_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, uint32_t *pData1,uint32_t *pData2, uint16_t Length)
//关闭DMA
HAL_StatusTypeDef HAL_TIM_Encoder_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel)

4.2 基本操作

  1. 开启encoder:

    HAL_TIM_Encoder_Start(&htimx, TIM_CHANNEL_ALL);
    
  2. 读取编码器数据:

    int GetData;//编码器数值
    GetData = __HAL_TIM_GET_COUNTER(&htim3);//0位正,1为负
    
  3. 获取编码器方向:

    int Direction;//编码器方向
    Direction = __HAL_TIM_IS_TIM_COUNTING_DOWN(&htim3);		// 是否向下计数
    
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐