STM32
直播中

邓长生

11年用户 997经验值
擅长:可编程逻辑
私信 关注
[问答]

求助,关于STM32定时器级联做计数器的问题求解

最近在做一个设计,使用STM32L1的定时器做一个大的计数器,每当外部PPS信号进来后,利用捕获功能来计算捕获值。这个计数器是采用定时器级联方式(三个16位组成一个48位的大计数器),由于硬件条件限制,目前使用的是tiM3(主)-TIM2-TIM4的方式。由第一个有效的PPS沿触发TIM3启动。
定时器配置如下:
         //配置TIM3为触发启动
        TIM_SelectSlaveMode(TIM3,TIM_SlaveMode_Trigger);
        TIM_SelectInputTrigger( TIM3, TIM_TS_TI1FP1 );
        //配置TIM3为主定时器
        TIM_SelectMasterSlaveMode        (TIM3, TIM_MasterSlaveMode_Enable);
        TIM_SelectOutputTrigger                (TIM3, TIM_TRGOSource_Update);
        //配置TIM2为从定时器
        TIM_SelectSlaveMode(TIM2, TIM_SlaveMode_External1);
        TIM_SelectInputTrigger(TIM2, TIM_TS_ITR2);
        //配置TIM2为主定时器
        TIM_SelectMasterSlaveMode        (TIM2, TIM_MasterSlaveMode_Enable);
        TIM_SelectOutputTrigger                (TIM2, TIM_TRGOSource_Update);
        //配置TIM4为从定时器
        TIM_SelectSlaveMode(TIM4, TIM_SlaveMode_External1);
        TIM_SelectInputTrigger(TIM4, TIM_TS_ITR1);        
        TIM_Cmd(TIM2, ENABLE);
        TIM_Cmd(TIM4, ENABLE);
        TIM_ITConfig( TIM3,  TIM_IT_CC1,  ENABLE);
实际的调试过程中发现,上述标红部分的代码换成        TIM_SelectInputTrigger( TIM3, TIM_TS_TI1F_ED);

也没有问题,请帮忙看下这两个的区别是什么啊?

回帖(1)

李英

2024-5-10 16:51:21
首先,让我们了解一下STM32定时器级联计数器的基本概念。在STM32中,定时器级联是一种将多个定时器组合在一起以形成一个更大位数计数器的方法。在您的情况下,您希望使用三个16位定时器(TIM3为主定时器,TIM2和TIM4为从定时器)来形成一个48位的大计数器。

根据您的描述,您已经配置了TIM3为触发启动模式,并且选择了PPS信号作为触发源。接下来,我们需要完成以下步骤:

1. 初始化定时器TIM3、TIM2和TIM4。

```c
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;

// 初始化TIM3
TIM_TimeBaseStructure.TIM_Period = 0xFFFF; // 设置自动重载寄存器值
TIM_TimeBaseStructure.TIM_Prescaler = 0; // 预分频器
TIM_TimeBaseStructure.TIM_ClockDivision = 0; // 时钟分频系数
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; // 向上计数模式
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);

// 初始化TIM2
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

// 初始化TIM4
TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);
```

2. 配置定时器级联。

```c
// 配置TIM3为主定时器,TIM2和TIM4为从定时器
TIM_SelectInputTrigger(TIM3, TIM_TS_TIM2); // 选择TIM2作为TIM3的触发源
TIM_SelectInputTrigger(TIM2, TIM_TS_TIM4); // 选择TIM4作为TIM2的触发源

// 配置定时器级联模式
TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Trigger); // TIM3触发启动
TIM_SelectSlaveMode(TIM2, TIM_SlaveMode_Gated); // TIM2门控模式
TIM_SelectSlaveMode(TIM4, TIM_SlaveMode_Reset); // TIM4重置模式
```

3. 配置捕获功能。

```c
// 配置TIM3捕获功能
TIM_ICInitTypeDef TIM_ICInitStructure;
TIM_ICInitStructure.TIM_Channel = TIM_Channel_1; // 选择通道1
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; // 上升沿触发
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; // 直接TI模式
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; // 预分频器
TIM_ICInitStructure.TIM_ICFilter = 0; // 无滤波器
TIM_PWMIConfig(TIM3, &TIM_ICInitStructure);
```

4. 启动定时器。

```c
// 启动TIM3、TIM2和TIM4
TIM_Cmd(TIM3, ENABLE);
TIM_Cmd(TIM2, ENABLE);
TIM_Cmd(TIM4, ENABLE);
```

5. 在PPS信号触发时读取计数器值。

```c
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
    if (htim->Instance == TIM3) {
        // 读取TIM3、TIM2和TIM4的计数器值
        uint32_t tim3_value = TIM_GetCounter(TIM3);
        uint32_t tim2_value = TIM_GetCounter(TIM2);
        uint32_t tim4_value = TIM_GetCounter(TIM4);

        // 将三个定时器的值组合成一个48位的大计数器值
        uint64_t counter_value = (uint64_t)tim3_value << 32 | (uint64_t)tim2_value << 16 | (uint64_t)tim4_value;
    }
}
```

请注意,您需要在代码中添加适当的中断处理函数,以便在PPS信号触发时读取计数器值。此外,根据您的硬件配置,您可能需要调整定时器的配置参数。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分