机器人开发过程中,对于直流电机来说,编码器至关重要,它不仅可以使我们对电极进行精确的速度闭环,位置闭环,还可以通过时间积分,根据运动学关系,获得速度、位置等信息
STM32的定时器有编码器模式,大大的方便我们的开发
使用STM32cubeMX配置工具,使得这个过程变得无比简单
我使用STM32cubeMX 开发一个机器人中 使用两个定时器TIM3 和TIM4编码器模式读取编码器的值,做闭环控制
##STM32定时器编码器模式(Encoder Mode)
CubeMX配置过程
选择芯片过程不再赘述
RCC: HSE高速总线始终改为外部晶振
![在这里插入图片描述](https://imgconvert.csdnimg.cn/aHR0cHM6Ly91cGxvYWQtaW1hZ2VzLmppYW5zaHUuaW8vdXBsb2FkX2ltYWdlcy8yMDI5MDAwMi05YmE3NWE3OTkwOWI1NmI2?x-oss-process=image/format,png)
SYS: DEBUG选择 SW模式
![在这里插入图片描述](https://imgconvert.csdnimg.cn/aHR0cHM6Ly91cGxvYWQtaW1hZ2VzLmppYW5zaHUuaW8vdXBsb2FkX2ltYWdlcy8yMDI5MDAwMi0xOTY2ZGE3NTJhNGY2ZGZl?x-oss-process=image/format,png)
TIM3 TIM4 配置成定时器模式 Combined Channels: Encoder Mode
![encode_tim3.png](https://imgconvert.csdnimg.cn/aHR0cHM6Ly91cGxvYWQtaW1hZ2VzLmppYW5zaHUuaW8vdXBsb2FkX2ltYWdlcy8yMDI5MDAwMi0yMDNkZDE4NDhiOWI1NzdjLnBuZw?x-oss-process=image/format,png)
![encoder_tim4.png](https://imgconvert.csdnimg.cn/aHR0cHM6Ly91cGxvYWQtaW1hZ2VzLmppYW5zaHUuaW8vdXBsb2FkX2ltYWdlcy8yMDI5MDAwMi04OGNlNTNhYTZmODIzMTE5LnBuZw?x-oss-process=image/format,png)
TIM3 TIM4 定时器分频配置: 这里分频数要注意一下,Prescaler 直接给0 ,Counter Period给65535,下面的Encoder Mode 如果是TI1的话就是只计数上升沿的脉冲,如果是TI2 andTI2 就是上下沿都计,脉冲是前一个的两倍
![tim_192.png](https://imgconvert.csdnimg.cn/aHR0cHM6Ly91cGxvYWQtaW1hZ2VzLmppYW5zaHUuaW8vdXBsb2FkX2ltYWdlcy8yMDI5MDAwMi1iMTJkZjI5N2I1ZDM1YWFjLnBuZw?x-oss-process=image/format,png)
![tim_382.png](https://imgconvert.csdnimg.cn/aHR0cHM6Ly91cGxvYWQtaW1hZ2VzLmppYW5zaHUuaW8vdXBsb2FkX2ltYWdlcy8yMDI5MDAwMi0wMDc4Njg3MDQwY2E2MTkzLnBuZw?x-oss-process=image/format,png)
TIM Encoder GPIO上拉模式配置,两个定时器四个引脚,全部改成 Pull-Up,即上拉模式,主要用于没有外部上拉的编码器读取时,可以确定引脚电平,防止出错
![GPIO.png](https://imgconvert.csdnimg.cn/aHR0cHM6Ly91cGxvYWQtaW1hZ2VzLmppYW5zaHUuaW8vdXBsb2FkX2ltYWdlcy8yMDI5MDAwMi0xOTEzMzljYThhOTQzMGNkLnBuZw?x-oss-process=image/format,png)
时钟树配置
![时钟树](https://imgconvert.csdnimg.cn/aHR0cHM6Ly91cGxvYWQtaW1hZ2VzLmppYW5zaHUuaW8vdXBsb2FkX2ltYWdlcy8yMDI5MDAwMi1kYzkwYTA0MzA0YzY2Yjc0?x-oss-process=image/format,png)
工程配置 IDE选择 MDK V5
![project](https://imgconvert.csdnimg.cn/aHR0cHM6Ly91cGxvYWQtaW1hZ2VzLmppYW5zaHUuaW8vdXBsb2FkX2ltYWdlcy8yMDI5MDAwMi04OTkwZWRmNWY1ODBlYzZh?x-oss-process=image/format,png)
第一栏里选择复制必要的库文件 第二栏里勾选将文件分为.c和.h
![codegen](https://imgconvert.csdnimg.cn/aHR0cHM6Ly91cGxvYWQtaW1hZ2VzLmppYW5zaHUuaW8vdXBsb2FkX2ltYWdlcy8yMDI5MDAwMi0xMTg5MDBjNzMxZjc0NDcy?x-oss-process=image/format,png)
最后点击生成文件
注意 !
工程路径绝对不能有中文名,否则会报错,无法复制stm32的库文件到你的工程
keil中添加处理函数
打开生成的文件,在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](https://imgconvert.csdnimg.cn/aHR0cHM6Ly91cGxvYWQtaW1hZ2VzLmppYW5zaHUuaW8vdXBsb2FkX2ltYWdlcy8yMDI5MDAwMi00Mzc2NTJmZDIxNWYxNDc0LnBuZw?x-oss-process=image/format,png)
![384.png](https://imgconvert.csdnimg.cn/aHR0cHM6Ly91cGxvYWQtaW1hZ2VzLmppYW5zaHUuaW8vdXBsb2FkX2ltYWdlcy8yMDI5MDAwMi1hMDA5Y2M4ZGU1YmIyMWE4LnBuZw?x-oss-process=image/format,png)
电机转过的角度
如果使用Encoder Mode TI1 andTI2 那么
电机真实方向= 0为正、1为负
电机真实角度= 得到的脉冲数 / 384 * 360