共计 2441 个字符,预计需要花费 7 分钟才能阅读完成。
背景介绍
编码器接口在电机控制、位置检测等领域扮演着核心角色。AT32F403A 作为雅特力科技的高性能微控制器,其编码器接口模块具备以下优势:

- 支持正交编码器(AB 相)和脉冲计数两种模式
- 最高可处理 10MHz 的输入信号频率
- 内置硬件滤波和方向判断逻辑
- 与定时器深度集成,实现位置 / 速度的无 CPU 干预采集
硬件原理
AT32F403A 的编码器接口实际上是定时器的一个特殊功能模式。其核心工作原理如下:
- 通过 TIMx_CH1 和 TIMx_CH2 引脚接收 AB 相信号
- 硬件自动处理 4 倍频计数(正交模式)或直接计数(脉冲模式)
- 计数器寄存器根据旋转方向自动增减
- 可配置的输入滤波器消除毛刺干扰
配置指南
工作模式对比
| 模式类型 | 信号要求 | 计数方式 | 典型应用 |
|---|---|---|---|
| 正交编码 | AB 相 90°相位差 | 4 倍频计数 | 高精度位置检测 |
| 脉冲计数 | 单脉冲信号 | 直接计数 | 简单转速测量 |
初始化代码示例
/**
* @brief 编码器接口初始化
* @param 无
* @retval 无
*/
void Encoder_Init(void)
{
GPIO_InitType GPIO_InitStructure;
TIM_TimeBaseInitType TIM_TimeBaseStructure;
TIM_ICInitType TIM_ICInitStructure;
// 1. GPIO 配置
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9; // TIM1_CH1/CH2
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// 2. 定时器基础配置
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
TIM_TimeBaseStructure.TIM_Period = 65535; // 16 位计数器
TIM_TimeBaseStructure.TIM_Prescaler = 0; // 无分频
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
// 3. 编码器接口配置
TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;
TIM_ICInitStructure.TIM_ICFilter = 0x6; // 6 个时钟周期滤波
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
TIM_ICInit(TIM1, &TIM_ICInitStructure);
TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;
TIM_ICInit(TIM1, &TIM_ICInitStructure);
// 4. 启用编码器模式
TIM_EncoderInterfaceConfig(TIM1, TIM_EncoderMode_TI12,
TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);
TIM_Cmd(TIM1, ENABLE);
}
实战案例
转速计算实现
// 全局变量
uint16_t last_count = 0;
int32_t total_pulses = 0;
/**
* @brief 定时中断中计算转速 (RPM)
* @param 采样间隔 (ms)
* @retval 转速值
*/
int32_t Calc_Speed(uint32_t interval_ms)
{uint16_t current_count = TIM_GetCounter(TIM1);
int16_t delta = (int16_t)(current_count - last_count);
// 处理计数器溢出
if(delta > 32767) delta -= 65536;
else if(delta < -32768) delta += 65536;
total_pulses += delta;
last_count = current_count;
// 假设编码器为 500 线,4 倍频后每转 2000 脉冲
return (delta * 60000) / (interval_ms * 2000);
}
避坑指南
常见问题排查
- 无计数响应
- 检查 GPIO 模式是否配置为浮空输入
- 确认 TIMx_REMAP 寄存器是否正确映射通道
-
测量信号电压是否满足 VIH/VIL 要求
-
计数方向错误
- 交换 AB 相接线测试
-
检查 TIM_EncoderInterfaceConfig() 的极性参数
-
数据跳变严重
- 增大输入滤波器值 (TIM_ICInitStructure.TIM_ICFilter)
- 在 PCB 上增加 RC 硬件滤波 (推荐 100Ω+100pF)
性能优化建议
- 启用定时器的溢出中断处理多圈计数
- 使用 DMA 将计数值传输到内存
- 对于高速应用,关闭调试器以减少时序干扰
测试验证
基础测试方案
- 连接编码器并上电
- 旋转编码器观察 TIMx_CNT 寄存器变化
- 正转时应递增
- 反转时应递减
- 测量最大响应频率(建议信号发生器 + 示波器验证)
预期结果
| 测试项 | 合格标准 |
|---|---|
| 低速旋转 (60RPM) | 计数误差 <±1 脉冲 |
| 高速旋转 (3000RPM) | 无丢失脉冲 |
| 急停 / 反转 | 无计数异常 |
思考题
- 如何扩展实现多圈绝对位置记录?
- 在电机控制应用中,编码器接口配置与 PWM 输出如何协同工作?
- 当需要同时使用多个编码器时,如何优化系统资源分配?
正文完
