本帖最后由 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 的 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多定时器的级联控制与动态触发参数调整,可以实现复杂的时间序列任务。该方法灵活高效,适用于工业自动化、电机控制、信号处理等领域。
|