[应用方案] APM32F407 多定时器级联控制与动态触发参数调整

[复制链接]
927|0
 楼主| a976209770 发表于 2024-12-9 14:13 | 显示全部楼层 |阅读模式
本帖最后由 a976209770 于 2024-12-9 14:15 编辑

1. 引言

在复杂嵌入式系统中,多定时器级联控制能够实现精确的时间序列任务。例如,工业自动化中多步操作的时间控制、多相PWM波形输出、电机控制中的动态事件调度等。通过动态调整触发参数,可以在运行时灵活修改级联定时器的行为,适应实时任务需求。

2. 原理与特点

2.1 多定时器级联原理

  • 定时器触发链:利用一个定时器的触发信号(TRGO)作为另一个定时器的触发输入(TRGI),形成级联关系。
  • 触发类型:定时器支持多种触发信号,包括更新事件、中断信号等,可选择合适的类型。

2.2 动态触发参数调整

  • 计数周期调整:通过修改定时器的ARR(自动重装载寄存器)实现周期性变化。
  • 触发延迟调整:动态修改预分频值实现延迟时间的调整。
  • 占空比控制:在PWM模式中,修改CCR(捕获/比较寄存器)实现占空比动态控制。

3. 应用场景

  • 多步任务控制:例如机械臂的多步运动,每步动作之间有精确的时间间隔。
  • 多段PWM生成:不同阶段输出不同频率和占空比的PWM波形。
  • 动态序列触发:基于实时反馈调整任务触发时序。

4. 系统设计与实现


4.1 定时器结构

  • 定时器链
    • TMR1 → TMR2 → TMR3
  • 触发信号链
    • TMR1 的 TRGO → TMR2 的 TRGI
    • TMR2 的 TRGO → TMR3 的 TRGI

4.2 硬件连接

无需外部连线,定时器的触发信号通过内部总线连接。

4.3 软件实现架构

  • 初始化每个定时器,建立级联关系。
  • 实现动态修改参数的接口。
  • 利用中断或其他方式调整运行时行为。

5. 软件实现

5.1 主定时器 (TMR1) 初始化

TMR1 作为触发链的起点,产生周期性触发信号:
  1. #include "apm32f4xx_tmr.h"

  2. void TMR1_Init(void)
  3. {
  4.     TMR_BaseConfig_T baseConfig;

  5.     // 启用TMR1时钟
  6.     RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_TMR1);

  7.     // 配置基础定时器
  8.     baseConfig.countMode = TMR_COUNTER_MODE_UP;
  9.     baseConfig.clockDivision = TMR_CLOCK_DIV_1;
  10.     baseConfig.period = 1000 - 1;  // 1ms周期
  11.     baseConfig.division = 84 - 1;  // 1MHz计数频率
  12.     TMR_ConfigTimeBase(TMR1, &baseConfig);

  13.     // 配置主输出为TRGO信号
  14.     TMR_ConfigOutputTrigger(TMR1, TMR_TRGO_SRC_UPDATE);

  15.     // 启动定时器
  16.     TMR_Enable(TMR1);
  17. }
5.2 第一级从定时器 (TMR2) 初始化

TMR2 从 TMR1 触发,支持动态延迟调整。
  1. void TMR2_Init(void)
  2. {
  3.     TMR_BaseConfig_T baseConfig;

  4.     // 启用TMR2时钟
  5.     RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_TMR2);

  6.     // 配置基础定时器
  7.     baseConfig.countMode = TMR_COUNTER_MODE_UP;
  8.     baseConfig.clockDivision = TMR_CLOCK_DIV_1;
  9.     baseConfig.period = 500 - 1;  // 初始周期500us
  10.     baseConfig.division = 84 - 1;  // 1MHz计数频率
  11.     TMR_ConfigTimeBase(TMR2, &baseConfig);

  12.     // 配置从模式,触发输入为TMR1的TRGO
  13.     TMR_ConfigSlaveMode(TMR2, TMR_SLAVE_MODE_TRIGGER);
  14.     TMR_SelectInputTrigger(TMR2, TMR_TS_ITR0);  // ITR0对应TMR1

  15.     // 启动定时器
  16.     TMR_Enable(TMR2);
  17. }
5.3 第二级从定时器 (TMR3) 初始化

TMR3 从 TMR2 触发,构建级联链的最后一级。
  1. void TMR3_Init(void)
  2. {
  3.     TMR_BaseConfig_T baseConfig;

  4.     // 启用TMR3时钟
  5.     RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_TMR3);

  6.     // 配置基础定时器
  7.     baseConfig.countMode = TMR_COUNTER_MODE_UP;
  8.     baseConfig.clockDivision = TMR_CLOCK_DIV_1;
  9.     baseConfig.period = 300 - 1;  // 初始周期300us
  10.     baseConfig.division = 84 - 1;  // 1MHz计数频率
  11.     TMR_ConfigTimeBase(TMR3, &baseConfig);

  12.     // 配置从模式,触发输入为TMR2的TRGO
  13.     TMR_ConfigSlaveMode(TMR3, TMR_SLAVE_MODE_TRIGGER);
  14.     TMR_SelectInputTrigger(TMR3, TMR_TS_ITR1);  // ITR1对应TMR2

  15.     // 启动定时器
  16.     TMR_Enable(TMR3);
  17. }

5.4 动态参数调整

提供运行时调整触发参数的函数接口:
  1. void AdjustTimerParameters(TMR_T* timer, uint32_t newPeriod, uint32_t newPrescaler)
  2. {
  3.     // 停止定时器
  4.     TMR_Enable(timer, DISABLE);

  5.     // 修改计数周期和分频值
  6.     TMR_ConfigPeriod(timer, newPeriod);
  7.     TMR_ConfigPrescaler(timer, newPrescaler, TMR_PSC_RELOAD_IMMEDIATE);

  8.     // 重启定时器
  9.     TMR_Enable(timer, ENABLE);
  10. }
5.5 主函数

初始化所有定时器,并动态调整参数以验证级联效果。
  1. int main(void)
  2. {
  3.     // 初始化系统时钟
  4.     SystemInit();

  5.     // 初始化定时器链
  6.     TMR1_Init();
  7.     TMR2_Init();
  8.     TMR3_Init();

  9.     while (1)
  10.     {
  11.         // 动态调整TMR2的触发延迟
  12.         AdjustTimerParameters(TMR2, 600 - 1, 84 - 1);

  13.         // 动态调整TMR3的触发延迟
  14.         AdjustTimerParameters(TMR3, 400 - 1, 84 - 1);

  15. Delay(1000);  // 模拟其他任务
  16.     }
  17. }

7. 总结

通过APM32F407多定时器的级联控制与动态触发参数调整,可以实现复杂的时间序列任务。该方法灵活高效,适用于工业自动化、电机控制、信号处理等领域。

您需要登录后才可以回帖 登录 | 注册

本版积分规则

40

主题

43

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部