要使用 M251 的 TIMER 捕获功能获取输入信号频率,需配置 TIMER 为输入捕获模式,测量信号周期后计算频率。以下是详细步骤和代码示例:
原理说明
- 输入捕获:检测信号边沿(上升沿/下降沿),记录此时的定时器计数值。
- 周期计算:两次连续捕获的差值即为信号周期的定时器计数。
- 频率公式:
[
text{Frequency} = frac{text{Timer Clock}}{text{(Capture Difference)} times text{Prescaler}}
]
硬件连接
- 输入信号连接到支持 输入捕获 功能的引脚(如 TIMER 的通道引脚,例如 PB.5 对应 TIMER2_CH0)。
- 确认引脚复用功能为 TIMER 捕获模式。
配置步骤 (以 TIMER2 通道 0 为例)
使能 TIMER 时钟
CLK_EnableModuleClock(TMR2_MODULE);
配置引脚复用
SYS->GPB_MFPL = (SYS->GPB_MFPL & ~SYS_GPB_MFPL_PB5MFP_Msk) | SYS_GPB_MFPL_PB5MFP_TM2;
初始化 TIMER
TIMER_Open(TIMER2, TIMER_PERIODIC_MODE, 1); // 频率设为1仅占位,实际频率由捕获决定
TIMER_SET_PRESCALE_VALUE(TIMER2, 47); // 预分频值 (48分频)
TIMER_ResetCounter(TIMER2); // 复位计数器
配置输入捕获
// 上升沿捕获,使能捕获中断
TIMER_EnableCapture(TIMER2, TIMER_CH0, TIMER_CAPTURE_RISING_EDGE, 1);
TIMER_EnableCaptureInt(TIMER2, TIMER_CH0);
启用中断和 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。
- 频率范围:
- 最小频率:由计数器溢出限制(若溢出需扩展处理)。
- 最大频率:受限于中断响应时间。
注意事项
- 引脚复用:务必确认硬件引脚连接与配置一致。
- 中断处理:保持中断服务函数精简。
- 信号稳定性:高频信号需确保中断响应速度足够快。
- 扩展功能:
- 可结合上升沿+下降沿捕获测量占空比。
- 使用硬件自动捕获功能(如 M251 支持连续捕获到 FIFO)。
通过以上步骤,即可准确获取输入信号频率。
要使用 M251 的 TIMER 捕获功能获取输入信号频率,需配置 TIMER 为输入捕获模式,测量信号周期后计算频率。以下是详细步骤和代码示例:
原理说明
- 输入捕获:检测信号边沿(上升沿/下降沿),记录此时的定时器计数值。
- 周期计算:两次连续捕获的差值即为信号周期的定时器计数。
- 频率公式:
[
text{Frequency} = frac{text{Timer Clock}}{text{(Capture Difference)} times text{Prescaler}}
]
硬件连接
- 输入信号连接到支持 输入捕获 功能的引脚(如 TIMER 的通道引脚,例如 PB.5 对应 TIMER2_CH0)。
- 确认引脚复用功能为 TIMER 捕获模式。
配置步骤 (以 TIMER2 通道 0 为例)
使能 TIMER 时钟
CLK_EnableModuleClock(TMR2_MODULE);
配置引脚复用
SYS->GPB_MFPL = (SYS->GPB_MFPL & ~SYS_GPB_MFPL_PB5MFP_Msk) | SYS_GPB_MFPL_PB5MFP_TM2;
初始化 TIMER
TIMER_Open(TIMER2, TIMER_PERIODIC_MODE, 1); // 频率设为1仅占位,实际频率由捕获决定
TIMER_SET_PRESCALE_VALUE(TIMER2, 47); // 预分频值 (48分频)
TIMER_ResetCounter(TIMER2); // 复位计数器
配置输入捕获
// 上升沿捕获,使能捕获中断
TIMER_EnableCapture(TIMER2, TIMER_CH0, TIMER_CAPTURE_RISING_EDGE, 1);
TIMER_EnableCaptureInt(TIMER2, TIMER_CH0);
启用中断和 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。
- 频率范围:
- 最小频率:由计数器溢出限制(若溢出需扩展处理)。
- 最大频率:受限于中断响应时间。
注意事项
- 引脚复用:务必确认硬件引脚连接与配置一致。
- 中断处理:保持中断服务函数精简。
- 信号稳定性:高频信号需确保中断响应速度足够快。
- 扩展功能:
- 可结合上升沿+下降沿捕获测量占空比。
- 使用硬件自动捕获功能(如 M251 支持连续捕获到 FIFO)。
通过以上步骤,即可准确获取输入信号频率。
举报