Skip to main content

CubeMx 定时器正交编码


机器人开发过程中,对于直流电机来说,编码器至关重要,它不仅可以使我们对电极进行精确的速度闭环,位置闭环,还可以通过时间积分,根据运动学关系,获得速度、位置等信息

STM32的定时器有编码器模式,大大的方便我们的开发,使用STM32cubeMX配置工具,使得这个过程变得无比简单

我使用STM32cubeMX 开发一个机器人中 使用两个定时器TIM3 和TIM4编码器模式读取编码器的值,做闭环控制

CubeMX配置

选择芯片过程不再赘述

RCC: HSE高速总线始终改为外部晶振

rcc

SYS: DEBUG选择 SW模式

sys

TIM3 TIM4 配置成定时器模式 Combined Channels: Encoder Mode

tim3:

encode_tim3

tim4:

encoder_tim4

TIM3 TIM4 定时器分频配置: 这里分频数要注意一下,Prescaler 直接给0 ,Counter Period给65535,下面的Encoder Mode 如果是TI1的话就是只计数上升沿的脉冲,如果是TI2 andTI2 就是上下沿都计,脉冲是前一个的两倍

tim_192.png

tim_382.png

TIM Encoder GPIO上拉模式配置,两个定时器四个引脚,全部改成 Pull-Up,即上拉模式,主要用于没有外部上拉的编码器读取时,可以确定引脚电平,防止出错

GPIO

时钟树配置

时钟树

工程配置 IDE选择 MDK V5

project

第一栏里选择复制必要的库文件 第二栏里勾选将文件分为.c和.h

code_gen

最后点击生成文件 注意 ! 工程路径绝对不能有中文名,否则会报错,无法复制stm32的库文件到你的工程

添加配置

打开生成的文件,在main.c中初始化的时候开启编码器计数

HAL_TIM_Encoder_Start(&htim3, TIM_CHANNEL_ALL);
HAL_TIM_Encoder_Start(&htim4, TIM_CHANNEL_ALL);

在循环中调用 __HAL_TIM_IS_TIM_COUNTING_DOWN 可以获得当前电机的转向 0为正、1为负

DirectionA = __HAL_TIM_IS_TIM_COUNTING_DOWN(&htim3);     
DirectionB = __HAL_TIM_IS_TIM_COUNTING_DOWN(&htim4);

在循环中调用 __HAL_TIM_GET_COUNTER 获取计数器的计数值,即编码器的脉冲数

CaptureNumberA=__HAL_TIM_GET_COUNTER(&htim3);
CaptureNumberB=__HAL_TIM_GET_COUNTER(&htim4);

脉冲计算方法

我的电机编码器是AB相位差90度,栅格数是96,无减速器,码盘转一圈,A相和B相分别输出96个矩形脉冲,总共输出192个脉冲。 如果使用 Encoder Mode TI1 或者Encoder Mode TI2,码盘转一圈得到的计数值为192。 如果使用Encoder Mode TI1 andTI2 那么得到的脉冲数为384。

ti1_192.png

384.png

电机转过的角度 如果使用Encoder Mode TI1 andTI2 那么

电机真实方向= 0为正、1为负
电机真实角度= 得到的脉冲数 / 384 * 360