新唐MCU技术
直播中

张鹏

8年用户 1243经验值
私信 关注
[问答]

如何使用 M251 TIMER 捕获函数来获取输入信号的频率?


  • 使用 M251 tiMER 捕获函数来获取输入信号的频率

回帖(1)

dplion5

2025-8-25 17:21:01

要使用 M251 的 TIMER 捕获功能获取输入信号频率,需配置 TIMER 为输入捕获模式,测量信号周期后计算频率。以下是详细步骤和代码示例:




原理说明



  1. 输入捕获:检测信号边沿(上升沿/下降沿),记录此时的定时器计数值。

  2. 周期计算:两次连续捕获的差值即为信号周期的定时器计数。

  3. 频率公式

    [
    text{Frequency} = frac{text{Timer Clock}}{text{(Capture Difference)} times text{Prescaler}}
    ]




硬件连接



  • 输入信号连接到支持 输入捕获 功能的引脚(如 TIMER 的通道引脚,例如 PB.5 对应 TIMER2_CH0)。

  • 确认引脚复用功能为 TIMER 捕获模式。




配置步骤 (以 TIMER2 通道 0 为例)




  1. 使能 TIMER 时钟  


    CLK_EnableModuleClock(TMR2_MODULE);



  2. 配置引脚复用  


    SYS->GPB_MFPL = (SYS->GPB_MFPL & ~SYS_GPB_MFPL_PB5MFP_Msk) | SYS_GPB_MFPL_PB5MFP_TM2;



  3. 初始化 TIMER  


    TIMER_Open(TIMER2, TIMER_PERIODIC_MODE, 1); // 频率设为1仅占位,实际频率由捕获决定
    TIMER_SET_PRESCALE_VALUE(TIMER2, 47);       // 预分频值 (48分频)
    TIMER_ResetCounter(TIMER2);                 // 复位计数器



  4. 配置输入捕获  


    // 上升沿捕获,使能捕获中断
    TIMER_EnableCapture(TIMER2, TIMER_CH0, TIMER_CAPTURE_RISING_EDGE, 1);
    TIMER_EnableCaptureInt(TIMER2, TIMER_CH0);



  5. 启用中断和 TIMER  


    NVIC_EnableIRQ(TMR2_IRQn);
    TIMER_Start(TIMER2);





中断服务函数


在中断中计算两次捕获的差值,进而求出频率:


volatile uint32_t g_u32PrevCapture = 0;
volatile uint32_t g_u32PeriodTicks = 0;
volatile float g_fFrequency = 0.0;

void TMR2_IRQHandler(void) {
    if (TIMER_GetCaptureIntFlag(TIMER2, TIMER_CH0)) {
        // 清除中断标志
        TIMER_ClearCaptureIntFlag(TIMER2, TIMER_CH0);

        // 读取当前捕获值
        uint32_t curCapture = TIMER_GetCaptureData(TIMER2, TIMER_CH0);

        // 计算周期(处理计数器溢出)
        g_u32PeriodTicks = (curCapture >= g_u32PrevCapture) ?
                          (curCapture - g_u32PrevCapture) :
                          (curCapture + (0x10000 - g_u32PrevCapture)); // 16位计数器

        g_u32PrevCapture = curCapture; // 更新前次值

        // 计算频率(系统时钟48MHz,预分频48)
        g_fFrequency = 48000000.0 / (g_u32PeriodTicks * 48);
    }
}



主函数示例


#include "M251Series.h"

int main() {
    SYS_Init();                      // 系统初始化
    Capture_Init();                  // 调用上述初始化函数

    while(1) {
        // 主循环中可读取 g_fFrequency 使用
        printf("Frequency: %.2f Hzn", g_fFrequency);
        CLK_SysTickDelay(1000000);   // 延时1秒
    }
}



关键参数说明



  • 预分频 (Prescaler)

    若系统时钟为 48MHz,预分频设为 48,则 TIMER 实际频率为 1MHz。

  • 计数器宽度

    M251 TIMER 为 16 位计数器,最大计数值为 0xFFFF。

  • 频率范围:  

    • 最小频率:由计数器溢出限制(若溢出需扩展处理)。

    • 最大频率:受限于中断响应时间。





注意事项



  1. 引脚复用:务必确认硬件引脚连接与配置一致。

  2. 中断处理:保持中断服务函数精简。

  3. 信号稳定性:高频信号需确保中断响应速度足够快。

  4. 扩展功能:  

    • 可结合上升沿+下降沿捕获测量占空比。  

    • 使用硬件自动捕获功能(如 M251 支持连续捕获到 FIFO)。



通过以上步骤,即可准确获取输入信号频率。

举报

更多回帖

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