• 正文
  • 相关推荐
申请入驻 产业图谱

如何实现 Pulse‑Direction Encoder 的信号采集

20小时前
228
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

Pulse‑Direction(脉冲‑方向,也叫 Clock+Direction)编码器接口广泛用于步进驱动器、部分增量编码器:一路 Pulse 输出计数脉冲,一路 Direction 电平标识转动方向。

Pulse:每来一个脉冲代表一个位置增量;Direction:高电平正向计数、低电平反向计数。

STM32 正交编码器模式是针对 A/B 相 90° 相位差信号设计,早期 F4、H7 等芯片定时器并不原生支持 Pulse‑Direction 模式。传统方案使用外部中断判断方向,脉冲频率高时会产生大量中断,CPU 开销大,还会带来响应延迟、丢脉冲风险。

LAT1700 给出一套TIM 定时器 + DMA 纯硬件方案,一次性配置完成,方向切换全程硬件自动完成,不需要 CPU 中断介入,应用程序仅读取 TIM->CNT 就获取位置计数值。本文还原信号原理、硬件资源分配、配置逻辑、代码要点、工程踩坑清单。

资料获取:实战经验 | LAT1700 如何实现Pulse-Direction Encoder的信号采集

1. Pulse‑Direction 信号工作原理

  • Pulse 时钟脉冲:脉冲边沿触发计数;支持 ×1(单边沿计数)、×2(双边沿计数)模式。
  • Direction 方向电平:电平改变代表运动换向。
  • 关键痛点:方向信号跳变需要立刻修改定时器TIMx->CR1寄存器 DIR 位,切换向上 / 向下计数。如果靠中断处理,高频脉冲场景 CPU 负担重,容易丢脉冲。

本方案核心思路:利用定时器输入捕获边沿事件作为 DMA 触发源,DMA 存储器‑外设直接搬运,硬件改写 CR1 的 DIR 计数方向位,全程无 CPU 参与。

2. 硬件资源分配(示例使用 TIM1,STM32H743)

定时器通道 信号 功能说明
TIM1_CH1 Pulse 脉冲输入 脉冲计数源,上升沿 / 双边沿捕获,驱动 CNT 计数器增减
TIM1_CH3 Direction 方向输入 捕获 Direction 下降沿,触发 DMA,配置定时器为 DOWN 向下计数
TIM1_CH4 内部信号 TI3FP4 复用 CH3 的信号,捕获 Direction 上升沿,触发 DMA,配置定时器 UP 向上计数

关键点:Direction 只接外部 GPIO 到 CH3;CH4 不外接引脚,使用定时器内部信号TI3FP4,复用 CH3 输入信号,实现同一根 Direction 信号同时检测上升、下降两个边沿。

外设行为逻辑

  1. Direction 下降沿:CH3 捕获事件产生,触发 DMA,把预定义 DOWN 模式配置值直接写入TIM1->CR1,定时器切换向下计数;
  2. Direction 上升沿:内部 TI3FP4 给到 CH4,捕获事件产生,触发 DMA,把预定义 UP 模式配置值写入TIM1->CR1,定时器切换向上计数;
  3. Pulse 接到 CH1,定时器时基单元对脉冲边沿自动计数;
  4. 用户业务层直接读取TIM1->CNT寄存器,获取当前位置,无需任何中断服务函数。

3. 外设配置要点

3.1 Pulse 通道(TIM1_CH1)

  • 输入捕获模式;
  • 根据业务选择:上升沿(×1 模式)或者双边沿捕获(×2 倍频计数);
  • 定时器时基开启计数,CNT 随 Pulse 边沿自动增减。

3.2 Direction 通道 CH3 / CH4

  1. CH3 配置输入捕获,下降沿触发,开启 CC3 DMA 请求;
  2. CH4 使用内部信号 TI3FP4,上升沿触发,开启 CC4 DMA 请求;
  3. 两路捕获事件分别作为各自 DMA 的硬件触发源;
  4. DMA 工作模式:Memory‑to‑Peripheral,存储器到外设寄存器一次性传输。

3.3 DMA 源变量定义

预先定义两个全局常量,存放 CR1 寄存器对应的 UP、DOWN 配置,作为 DMA 传输源。

uint32_t tim_crl_reg_up = TIM_CR1_CEN | TIM_COUNTERMODE_UP;
uint32_t tim_crl_reg_down = TIM_CR1_CEN | TIM_COUNTERMODE_DOWN;

重点:DMA 源变量必须放在 DMA 可以访问的内存区域。在有多域 RAM、缓存管理的 MCU,需要注意内存属性,避免 DMA 无法读取源数据。

3.4 HAL 库关键启动代码片段

//启动CH3、CH4输入捕获
HAL_TIM_IC_Start(&htim1, TIM_CHANNEL3);
HAL_TIM_IC_Start(&htim1, TIM_CHANNEL4);

//DMA:CH3下降沿触发,写入DOWN模式到TIM1->CR1
HAL_DMA_Start(&hdma_tim1_ch3,(uint32_t)&tim_crl_reg_down,(uint32_t)&TIM1->CR1, 1);
HAL_TIM_ENABLE_DMA(&htim1, TIM_DMA_CC3);

//DMA:CH4上升沿触发,写入UP模式到TIM1->CR1
HAL_DMA_Start(&hdma_tim1_ch4,(uint32_t)&tim_crl_reg_up,(uint32_t)&TIM1->CR1, 1);
HAL_TIM_ENABLE_DMA(&htim1, TIM_DMA_CC4);

//开启定时器时基计数
HAL_TIM_Base_Start(&htim1);
HAL_TIM_ENABLE_DMA(&htim1, TIM_DMA_CC4);

启动定时器之前,需要先读取 Direction 引脚当前电平,预先设置 CR1 的 DIR 初始方向,保证上电初始计数方向正确。 应用层读取位置:int32_t pos = TIM1->CNT;

4. 工程落地排查清单

  1. 脉冲计数正常,但是方向切换不生效
    • 核查 CH4 是否配置内部信号TI3FP4,不是外部 GPIO 输入;
    • 确认 CC3、CC4 的 DMA 请求已经使能;
    • 检查 DMA 源变量内存位置,多域 RAM 芯片,不要放在 DMA 无法访问的内存段。
  2. 上电初始计数方向反了
    • 启动 TIM/DMA 之前读取 Direction 引脚电平,手动设置 CR1.DIR 初始状态;本方案 DMA 只响应 Direction 跳变沿,上电静态电平不会自动设置方向。
  3. 高速脉冲偶尔丢计数
    • 检查输入捕获滤波器配置 ICxF,根据信号质量配置滤波器,抑制毛刺干扰;
    • Pulse 通道边沿配置确认:×1 选择单边沿、×2 选择双边沿捕获。
  4. DMA 不触发,CR1 寄存器不会被改写
    • 确认 DMA 是 Memory‑to‑Peripheral 传输方向;源地址是全局常量变量地址,目标地址为&TIM1->CR1;
    • 确认 TIM 的 CC3、CC4 DMA 使能位打开。

5. 小结

  1. Pulse‑Direction(Clock+Direction)接口和 STM32 原生正交编码器模式不一样,F4/H7 老芯片定时器没有硬件原生支持;传统外部中断判断方向,高频脉冲场景 CPU 开销大,容易丢脉冲。
  2. 本方案利用 TIM 输入捕获边沿事件触发 DMA,硬件直接改写 TIMx‑>CR1 的 DIR 计数方向位,换向全程硬件自动处理,不需要 CPU 中断介入;业务只读取 CNT 得到位置。
  3. 硬件关键点:Direction 信号接入 CH3,CH4 复用内部 TI3FP4 信号,实现同一根信号线同时捕获上升、下降沿;DMA 源变量要放在 DMA 可访问内存。
  4. 注意:DMA 只响应 Direction 电平跳变沿,上电启动前必须读取 Direction 引脚电平,初始化定时器计数方向。

6. FAQ

Q:这套方案最大支持多高 Pulse 脉冲频率?

A:上限取决于定时器输入捕获最大频率、DMA 响应速度;不受 CPU 中断延迟限制,适合步进驱动高频脉冲场景,实际需要结合示波器验证。

Q:是不是所有 STM32 都可以直接照搬这套 TIM+DMA 方案?

A:需要定时器支持内部 TIxFPy 信号路由、通道独立 DMA 捕获触发;移植其他芯片要核对参考手册定时器内部信号连接关系,不能直接复制硬件配置。

Q:我需要 Z 索引归零信号,这套方案怎么处理?

A:Z 信号可以另外使用定时器输入捕获,捕获 Z 脉冲时软件手动把TIMx->CNT清零。

免责声明:本文全部基于 ST 官方 LAT1700 文档,寄存器配置、DMA 内存约束以芯片参考手册为准。

相关推荐