HAL——TIM编码器接口

一、预备知识

1.单片机与编码器配合使用:编码器接口可接收增量(正交)编码器的信号,根据编码器旋转产生的正交信号脉冲,自动控制CNT自增或自减,从而指示编码器的位置旋转方向旋转速度。

2.每个高级定时器和通用定时器都只拥有1个编码器接口,两个输入引脚借用了输入捕获的通道1和通道2(CH1和CH2可以左右编码器输入引脚,CH3和CH4不能作为编码器输入引脚)

脉冲个数→位置(检测到一相跳边沿的同时检测另一相电平状态判断旋转方向,如果正转CNT++,如果反转CNT--)

脉冲频率→速度

两相脉冲边沿情况→方向 

                                

3.关于编码器

                                

编码器种类:机械式,光电式,磁场/霍尔式,最终效果均是将电机旋转的状态转化为单片机可以识别的脉冲信号。

编码器接线:两根电源线(输入),两根正交相线(输出),一个固定位置输出脉冲线(0位校准)

4.编码器倍频:只计次单相脉冲的单个边沿为一倍频;计次单相脉冲的双边沿为二倍频,计次双相脉冲的双边沿为四倍频。倍频越高精度越高,且正交信号可以抵抗噪声干扰(A相发生电平变化但B相无变化则认为A相变化是由噪声引起不产生计次)

5.编码器接口电路结构

                       

下面两排是TIM的输入捕获的通道1和通道2

6.编码器三种工作模式:

                ​​​​​​​    ​​​​​​​

7.示例

 

二、CubeMX配置

1.选编码器模式,该模式可以直接读取脉冲数(不用特意设置捕获了,非常方便)

2.具体参数配置:

d4030a46e1108d4c8c36e3d137200270.jpeg

 1)计数周期一般配置为最大值65535,可以disable自动重装

 2)选择的encoderMode是TI1和TI2模式。这种模式下,AB两相的上升沿和下降沿都会计数,所以计数值是实际值的4倍,需要做分频。也就是第一个参数,分频值设为3,实际上是3+1=4分频。

3)还有个地方需要解释一下,Polarity参数设置的是Rising Edge。这个参数的意思是在检测到上升沿的时候就触发encoder捕获AB相的值,而并不是这里设置的是上升沿就只检测AB相的上升沿,下降沿还是同样会计数的。对于T1T2均计次模式下,极性配置用来选择是否反相

如果CNT增减和电机方向不一致可以通过反向设置某一相的极性解决,也可以将AB相线反接

4)Input Filter滤波值是从1-15,看情况设定,是用来滤除一些杂波的。​​​​​​​

5)GPIO模式配置,上拉下拉与外部接口的默认电平保持一致,不确定时可以选择浮空输入,但是在无输入时会受噪声干扰

3.函数配置

在初始化中添加打开定时器的encoder模式:   

HAL_TIM_Encoder_Start(&htim2, TIM_CHANNEL_ALL);

调用下面一句函数设定计数值:

__HAL_TIM_SET_COUNTER(&htim4, 0);

  然后定期调用下面这一句函数就可以获取到encoder编码器的计数值:

enc1 = (uint32_t)(__HAL_TIM_GET_COUNTER(&htim2));//获取定时器的值

可以使用强制类型转换为有符号的int32_t

4.如果有z相的话,额外将CH3打开作为一个中断, 作为脉冲中断触发,找到每一圈的零点位置

        ​​​​​​​        ​​​​​​​        ​​​​​​​      

同时打开中断

        ​​​​​​​        ​​​​​​​        ​​​​​​​        

三、应用层代码编写(测速)

利用定时中断,每隔一定时间(闸门时间t)将CNT数值赋给一个变量后清零,得到t时间内CNT值,并基于该时间计算速度

w=CNT*2π/(4*3*t)

或者在mian函数中利用延时函数(不推荐)

 

 相关函数介绍

//1.定时器3的通道1和通道2的Encoder Mode开启使能函数
HAL_TIM_Encoder_Start(&htim3,TIM_CHANNEL_1 | TIM_CHANNEL_2);
 
//2.返回值当前脉冲计数值,也可对脉冲计数值进行重新置位
int cnt=__HAL_TIM_GET_COUNTER(&htim3);
__HAL_TIM_GET_COUNTER(&htim3)=0;//脉冲计数值清0
 
//3.返回值为bool类型,当计数器向下计数时,返回true,可以用来判断编码器旋转方向
 __HAL_TIM_IS_TIM_COUNTING_DOWN(&htim3);

定义两个全局变量(之所以定义成全局变量,是为了方便后边将这个变量变量在debug模式中添加到watch窗口中查看)

/* USER CODE BEGIN PV */
uint8_t Direction;
uint16_t CaptureNumber;
/* USER CODE END PV */

在main函数中开启编码器模式

/* USER CODE BEGIN 2 */
HAL_TIM_Encoder_Start(&htim3,TIM_CHANNEL_1 | TIM_CHANNEL_2);
/* USER CODE END 2 */

while(1)循环中不断循环检测当前的脉冲计数值

/* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */
 
    /* USER CODE BEGIN 3 */
    Direction=__HAL_TIM_IS_TIM_COUNTING_DOWN(&htim3); //读取编码器旋转方向
    CaptureNumber=__HAL_TIM_GET_COUNTER(&htim3);   //读取脉冲计数值
  }
  /* USER CODE END 3 */

  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值