STM32中使用增量式编码器检测转速及转向的技术疑问
增量式正交编码器转向判断问题解答
关于__HAL_TIM_IS_TIM_COUNTING_DOWN(&htim4)与逆时针旋转的关系
这个函数的返回值和车轮逆时针旋转是否对应,不能直接一概而论,核心取决于你的硬件接线和定时器编码器模式的配置:
- STM32的正交编码器模式中,计数器的增减方向由A、B两相的相位差决定:默认配置下(比如TIMx_SMCR寄存器的SMS=011,且CC1、CC2极性默认),当A相超前B相90度时,计数器递增;B相超前A相90度时,计数器递减。
__HAL_TIM_IS_TIM_COUNTING_DOWN(&htim4)本质是检查定时器CR1寄存器的DIR位:当DIR=1时返回true,表示计数器正在递减。- 如果你在硬件接线上,车轮逆时针旋转时恰好让B相超前A相,且定时器配置未修改极性,此时该函数会返回true;但如果接线或配置相反,结果也会反过来。所以需要结合实际硬件和配置验证。
不使用HAL函数实现转向判断的方法
方法1:直接读取定时器寄存器的DIR位
HAL函数的底层就是读取寄存器,你可以直接操作寄存器替代:
// 判断计数器是否递减(对应转向) uint8_t is_counting_down = (htim4.Instance->CR1 & TIM_CR1_DIR) != 0;
方法2:通过A、B相的相位电平判断
利用正交编码的相位差特性,在A相或B相的边沿触发中断,或者定时采样两相电平,通过相位关系判断方向:
比如在A相上升沿触发的外部中断中,读取B相的电平:
// 假设A相接GPIO_PIN_x,B相接GPIO_PIN_y if(HAL_GPIO_ReadPin(GPIOx, GPIO_PIN_x) == GPIO_PIN_SET) { // A相上升沿触发时 if(HAL_GPIO_ReadPin(GPIOy, GPIO_PIN_y) == GPIO_PIN_SET) { // B相为高,对应某一转向(比如顺时针) } else { // B相为低,对应另一转向(比如逆时针) } }
注意:这种方式需要处理信号抖动,建议配合硬件滤波或软件防抖逻辑。
方法3:通过计数器差值的符号判断
从你提供的代码来看,TIM4_DiffCount已经包含了方向信息:
- 当计数器递增时,
TIM4_DiffCount为正数,对应一个转向; - 当计数器递减时,
TIM4_DiffCount为负数,对应另一个转向。
你可以直接通过这个变量的正负来判断转向,无需额外调用HAL函数:
if(TIM4_DiffCount > 0) { // 计数器递增,对应某一转向 } else if(TIM4_DiffCount < 0) { // 计数器递减,对应另一转向 } else { // 车轮未转动 }
内容的提问来源于stack exchange,提问作者امیرحسین محمد امری
相关产品推荐
相关产品推荐

