tttt5tttttttttttt

#ifndef ENCODER_H

#define ENCODER_H

#include "stm32f1xx_hal.h"

#include <stdint.h>

#include <stdbool.h>

/**

 * 机械旋转编码器(正交AB)→ “格”计数封装

 * 典型用法:TI12(四倍频),每 4 计数 = 1 格

 */

#ifdef __cplusplus

extern "C" {

#endif

typedef struct

{

    TIM_HandleTypeDef *htim; // 指向 CubeMX 生成的 TIM 句柄(如 &htim2)

    int16_t last_cnt; // 上次读取的硬件 CNT(16位)

    int32_t edge_acc; // 边沿累计(正/负),用于“每K计数=1格”的折算

    int32_t notch_pos; // 以“格”为单位的累计位置(可多圈)

    uint16_t ticks_per_notch; // 每“格”需要的硬件计数(TI12 通常是 4)

    uint16_t notches_per_rev; // 一圈有多少“格”(如 20)

    bool invert; // 方向取反(true 则翻转)

} Encoder_t;

/**

 * @brief 初始化结构体(不启动定时器)

 * @param enc 你的 Encoder 对象

 * @param htim 绑定的 TIM 句柄(CubeMX 里配置好的 Encoder 模式)

 * @param notches_per_rev 每圈“格”数(如 20)

 * @param ticks_per_notch 每“格”对应的硬件计数(TI12 常用 4;TI1/TI2 可为 2 或 1)

 */

void Encoder_Init(Encoder_t *enc,

                  TIM_HandleTypeDef *htim,

                  uint16_t notches_per_rev,

                  uint16_t ticks_per_notch);

/**

 * @brief 启动定时器编码器模式(等价 HAL_TIM_Encoder_Start)

 */

void Encoder_Start(Encoder_t *enc);

/**

 * @brief 清零硬件 CNT 与软件累计(相当于“回零/标定当前为0格”)

 */

void Encoder_Reset(Encoder_t *enc);

/**

 * @brief 周期调用,完成(硬件计数 → 边沿累计 → 折算为“格”)的更新

 * 建议 1~10ms 调用一次(定时器中断、SysTick、或任务里都可以)

 */

void Encoder_Update(Encoder_t *enc);

/**

 * @brief 读取“格”为单位的累计位置(多圈可正可负)

 */

static inline int32_t Encoder_GetNotchPos(const Encoder_t *enc)

{

    return enc->notch_pos;

}

/**

 * @brief 设置“格”为单位的当前位置(重定位)

 */

static inline void Encoder_SetNotchPos(Encoder_t *enc, int32_t pos)

{

    enc->notch_pos = pos;

}

/**

 * @brief 读取一圈内的“格”索引(0..notches_per_rev-1)

 * 负数也会被正确映射到该范围

 */

int32_t Encoder_GetNotchMod(const Encoder_t *enc);

/**

 * @brief 读取原始硬件 CNT(当前计数器值)

 */

static inline int16_t Encoder_GetRawCNT(const Encoder_t *enc)

{

    return (int16_t)__HAL_TIM_GET_COUNTER(enc->htim);

}

/**

 * @brief 设置方向是否取反(等价把A/B通道互换或极性反相)

 */

static inline void Encoder_SetInvert(Encoder_t *enc, bool inv)

{

    enc->invert = inv;

}

#ifdef __cplusplus

}

#endif

#endif // ENCODER_H// main.c / app.c

#include "encoder.h"

extern TIM_HandleTypeDef htim2; // 由 CubeMX 生成

static Encoder_t gEnc;

void App_Init(void)

{

    // CubeMX 已经初始化 TIM2 为 Encoder TI12; ARR=65535; PSC=0; 过滤器已设

    Encoder_Init(&gEnc, &htim2, /*notches_per_rev=*/20, /*ticks_per_notch=*/4);

    Encoder_Start(&gEnc);

    // 如果方向反了,打开反向

    // Encoder_SetInvert(&gEnc, true);

}

void App_Loop_1ms(void) // 每 1ms 调用一次(可放 SysTick 或定时器中断里)

{

    Encoder_Update(&gEnc);

}

void Turn_Left_One_Notch(void)

{

    int32_t target = Encoder_GetNotchPos(&gEnc) - 1;

    // 启动电机左转...

    // while(Encoder_GetNotchPos(&gEnc) > target) { /* 等到位或配合超时/陀螺 */ }

    // 停止电机...

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值