stm32编码器模式控制增量编码器

16位计数器ARR最大到65535

/* * Encoder.c * * Created on: Feb 27, 2025 * Author: 13624 */ #include "main.h" #include "Encoder.h" #include "tim.h" #define DIR_UP 0//正向 #define DIR_DOWN 1//反向 volatile int32_t overflowcount = 0;//溢出计数 EncoderObject Encoder[]={{.htimx = &htim4,.EncoderCount = 0,.EncoderDir = 0}};//初始化结构体变量 void Encoder_Start(EncoderObject* Encoder) { if(Encoder == NULL) { printf("please input true Encoder param %s,%d",__FILE__,__LINE__); return ; } //编码器中断并不能开启定时器溢出中断,一定要清除更新中断标志位,计数值设置为0然后在开启溢出中断,直接开启会直接从65536计数直接溢出 HAL_TIM_Encoder_Start_IT(Encoder->htimx, TIM_CHANNEL_ALL); __HAL_TIM_SET_COUNTER(Encoder->htimx,0); __HAL_TIM_CLEAR_FLAG(&htim4, TIM_FLAG_UPDATE); __HAL_TIM_ENABLE_IT(&htim4, TIM_IT_UPDATE); } void Encoder_Stop(EncoderObject* Encoder) { if(Encoder == NULL) { printf("please input true Encoder param %s,%d",__FILE__,__LINE__); return ; } HAL_TIM_Encoder_Stop_IT(Encoder->htimx, TIM_CHANNEL_ALL); } void Encoder_Set_Zero(EncoderObject* Encoder) { if(Encoder == NULL) { printf("please input true Encoder param %s,%d",__FILE__,__LINE__); return ; } __HAL_TIM_SET_COUNTER(Encoder->htimx,0); Encoder->EncoderCount = 0; } uint8_t Encoder_Dir(EncoderObject* Encoder) { if(Encoder == NULL) { printf("please input true Encoder param %s,%d",__FILE__,__LINE__); return ERROR; } if(__HAL_TIM_IS_TIM_COUNTING_DOWN(Encoder->htimx) == DIR_UP) { Encoder->EncoderDir = 0; return DIR_UP; } else if(__HAL_TIM_IS_TIM_COUNTING_DOWN(Encoder->htimx) == DIR_DOWN) { Encoder->EncoderDir = 1; return DIR_DOWN; } } void Encoder_Getcount(EncoderObject* Encoder) { if(Encoder == NULL) { printf("please input true Encoder param %s,%d",__FILE__,__LINE__); return ; } Encoder->EncoderCount = overflowcount*65536+__HAL_TIM_GET_COUNTER(Encoder->htimx); // printf("Encoder count is %d\r\n",Encoder->EncoderCount); }
/*
* Encoder.h
*
* Created on: Feb 27, 2025
* Author: 13624
*/
#ifndef INC_ENCODER_H_
#define INC_ENCODER_H_
#include "main.h"
#include "stdio.h"
#include "stdbool.h"
#include "string.h"
#define ENCODER_MAX_NUM 1
typedef struct _EncoderObject
{
TIM_HandleTypeDef *htimx;
uint8_t EncoderDir;//A相>B相 正向Dir 1 四倍频向上计数当前数++,,,反之当前数--,
volatile int32_t EncoderCount;//获取编码器计数
}EncoderObject;
extern volatile uint32_t overflowcount ;//溢出计数
extern EncoderObject Encoder[];
//启动编码器
void Encoder_Start(EncoderObject* Encoder);
void Encoder_Getcount(EncoderObject* Encoder);
uint8_t Encoder_Dir(EncoderObject* Encoder);
void Encoder_Set_Zero(EncoderObject* Encoder);
void Encoder_Stop(EncoderObject* Encoder);
#endif /* INC_ENCODER_H_ */
//在定时器中断回调函数判断,可以判断正负
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance == htim4.Instance)
{
if(Encoder_Dir(Encoder) == 0)
{
overflowcount++;//正向加
}
else
{
overflowcount--;反向减少
}
// Encoder_Getcount(Encoder);
}
电机的方向与编码器模式捕获AB的方式也有关系,如果电机的移动方向与编码器的捕获方向不一致编码器计数就会异常
极性修改对编码器方向的影响
(1) 默认极性(全上升沿)
- 电机正向旋转:TI1 上升沿时,TI2 为低电平。
- 反向旋转:TI1 上升沿时,TI2 为高电平。
(2) 修改 TI1 为下降沿
- 正向旋转:TI1 下降沿时,TI2 为低电平。
- 反向旋转:TI1 下降沿时,TI2 为高电平。
(3) 修改 TI2 为下降沿
- 正向旋转:TI2 下降沿时,TI1 为高电平。
- 反向旋转:TI2 下降沿时,TI1 为低电平。
按照当前项目,驱动器的方向引脚通过改变高低电平的正向反向
正向测试程序先设置为DIR引脚高电平,反向后改变方向DIR引脚低电平,编码器T1,T2的极性为T1上升沿,T2为下降沿,编码器滤波可以是0.
正向测试程序先设置为DIR引脚低电平,反向后改变方向DIR引脚高电平,编码器T1,T2的极性为T1下降沿,T2为下降沿,编码器滤波可以是0.
可以在电机移动的时候把编码器的值打印出来,判断电机的移动方向与编码器计数方向是否一致,如果一致就可以去掉打印
浙公网安备 33010602011771号