打印
[应用方案]

APM32F407 多定时器级联控制与动态触发参数调整

[复制链接]
166|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 作为触发链的起点,产生周期性触发信号:
#include "apm32f4xx_tmr.h"

void TMR1_Init(void)
{
    TMR_BaseConfig_T baseConfig;

    // 启用TMR1时钟
    RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_TMR1);

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

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

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

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

    // 启用TMR2时钟
    RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_TMR2);

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

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

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

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

    // 启用TMR3时钟
    RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_TMR3);

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

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

    // 启动定时器
    TMR_Enable(TMR3);
}

5.4 动态参数调整

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

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

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

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

    // 初始化定时器链
    TMR1_Init();
    TMR2_Init();
    TMR3_Init();

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

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

Delay(1000);  // 模拟其他任务
    }
}

7. 总结

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

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

28

主题

31

帖子

0

粉丝