定时器在嵌入式系统中常用于执行周期性任务、中断服务或测量时间间隔。输入输出捕获(Input Capture and Output Compare,简称ICP和OCM)是定时器的两种重要功能,用于处理与时间相关的事件。以下是它们的基本概念:
1、输入捕获(Input Capture,ICP)
输入捕获功能允许定时器记录外部信号(如脉冲、边缘)到达的时间。当外部输入信号(通常是GPIO引脚上的电平变化)发生时,定时器的当前计数值会被记录下来,从而可以计算出信号的频率、宽度或者周期。通常,输入捕获模式有以下特点:
- 边沿触发:捕获发生在信号的上升沿或下降沿。
- 中心对齐:在信号的中间时刻捕获计数值。
- 软件触发:在软件触发事件时捕获计数值。
应用场景:对于时间检测相关外设的使用时,如:使用超声波传感器的距离测算(自动开门)、按钮按下时间的测算(常见的长按n秒重置)等。
在这个例子中,我们配置TIM3的通道1作为输入捕获,当输入信号的上升沿到来时,TIM3会记录当前的计数值,从而可以计算脉冲的宽度。
// 假设TIM3的CH1被配置为输入捕获 void configureInputCapture(void) {RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); // 启用TIM3时钟TIM_TimeBaseInitTypeDef timerConfig;timerConfig.TIM_Prescaler = 84 - 1; // 分频因子,假设系统时钟为72MHztimerConfig.TIM_CounterMode = TIM_CounterMode_Up; // 上升计数timerConfig.TIM_Period = 65535; // 最大计数值timerConfig.TIM_ClockDivision = TIM_CKD_DIV1; // 无分频TIM_TimeBaseInit(TIM3, &timerConfig); // 初始化定时器TIM_ICInitTypeDef inputCaptureConfig;inputCaptureConfig.TIM_Channel = TIM_Channel_1; // 通道1inputCaptureConfig.TIM_ICPolarity = TIM_ICPolarity_Rising; // 上升沿触发inputCaptureConfig.TIM_ICSelection = TIM_ICSelection_DirectTI; // 直接TIinputCaptureConfig.TIM_ICPrescaler = TIM_ICPSC_DIV1; // 不分频inputCaptureConfig.TIM_ICFilter = 0x00; // 无滤波TIM_ICInit(TIM3, &inputCaptureConfig); // 初始化输入捕获NVIC_EnableIRQ(TIM3_IRQn); // 开启TIM3中断TIM_ITConfig(TIM3, TIM_IT_CC1, ENABLE); // 启用通道1中断TIM_Cmd(TIM3, ENABLE); // 启动定时器 }// 中断服务程序 void TIM3_IRQHandler(void) {if (TIM_GetITStatus(TIM3, TIM_IT_CC1) != RESET) {pulseWidth = TIM_GetCapture1(TIM3); // 获取捕获的计数值TIM_ClearITPendingBit(TIM3, TIM_IT_CC1); // 清除中断标志} }
2、输出比较(Output Compare,OCM)
输出比较功能用于控制定时器的输出信号。当定时器的计数值与预设的比较值匹配时,定时器的输出状态会发生变化。这可以用来生成精确的时序信号,如PWM(脉宽调制)信号、方波或驱动LED等。输出比较模式包括:
- 正常模式:计数值匹配时,输出信号翻转。
- PWM模式:计数值匹配时,输出信号的高电平或低电平持续时间发生变化。
- 自动重载:计数值匹配后,自动重新加载预设值并继续计数,保持输出信号的连续性。
在这个例子中,我们配置TIM3的通道1为PWM模式,设置占空比为50%,然后启动定时器。这样,TIM3的输出引脚将生成一个周期性的PWM信号。
// 假设TIM3的CH1被配置为PWM void configurePWM(void) {RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); // 启用TIM3时钟TIM_TimeBaseInitTypeDef timerConfig;timerConfig.TIM_Prescaler = 84 - 1; // 分频因子timerConfig.TIM_CounterMode = TIM_CounterMode_Up; // 上升计数timerConfig.TIM_Period = 65535; // 最大计数值timerConfig.TIM_ClockDivision = TIM_CKD_DIV1; // 无分频TIM_TimeBaseInit(TIM3, &timerConfig); // 初始化定时器TIM_OCInitTypeDef pwmConfig;pwmConfig.TIM_OCMode = TIM_OCMode_PWM1; // PWM模式1pwmConfig.TIM_OutputState = TIM_OutputState_Enable; // 输出使能pwmConfig.TIM_Pulse = 32767; // 设置占空比,假设50%pwmConfig.TIM_OCPolarity = TIM_OCPolarity_High; // 高电平有效TIM_OC1Init(TIM3, &pwmConfig); // 初始化通道1TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable); // 预装载使能TIM_ARRPreloadConfig(ENABLE); // 使能自动重装载预装载寄存器TIM_Cmd(TIM3, ENABLE); // 启动定时器 }
3、使用示例
在使用输入输出捕获时,你可能需要进行以下步骤:
- 配置定时器:设置定时器的工作模式(边沿触发、中心对齐等)、时钟源、分频因子等。
- 设置捕获/比较寄存器:为输入捕获设置触发边沿,为输出比较设置比较值。
- 启用中断:如果需要在捕获或比较事件发生时执行特定操作,需要开启相应的定时器中断。
- 处理中断服务程序:在中断服务程序中更新计数、处理捕获到的数据或改变输出信号状态。
- 启动定时器:开始计数,等待输入捕获或输出比较事件。