欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 科技 > 名人名企 > STM32标准库-输入捕获

STM32标准库-输入捕获

2025/6/8 12:14:48 来源:https://blog.csdn.net/weixin_50242782/article/details/148483343  浏览:    关键词:STM32标准库-输入捕获

一、输入捕获

1.简介

  • IC(Input Capture)输入捕获输入

  • 捕获模式下,当通道输入引脚出现指定电平跳变时,当前CNT的值将被锁存到CCR中,可用于测量PWM波形的频率、占空比、脉冲间隔、电平持续时间等参数

  • 每个高级定时器和通用定时器都拥有4个输入捕获通道

  • 可配置为PWMI模式,同时测量频率和占空比

  • 可配合主从触发模式,实现硬件全自动测量

2.频率测量

在这里插入图片描述

  • 测频法适合测量高频信号,测周法适合测量低频信号。测频法要求信号频率要稍微高一些。那对于测周法就要求信号频率低一些了,低频信号周期比较长,计次就会比较多,有助于减小误差。
  • 对应图上,当待测信号频率小于中介频率时,测周法误差更小,选用测周法更合适。当待测信号频率大于中间频率时,测频法误差更小,选用测频法更合适。

3.输入捕获通道

在这里插入图片描述

4.主从触发模式

在这里插入图片描述

  • 主从触发模式就是主模式、从模式和触发源选择这三个功能的简称。
  • 其中主模式可以将定时器内部的信号映射到TRGO引脚。用于触发别的外设。所以这部分叫做主模式。
  • 从模式,就是接收其他外设或者自身外设的一些信号,用于控制自身定时器的运行,也就是被别的信号控制,所以这部分叫从模式。
  • 触发源选择就是选择从模式的触发信号源的,你可以认为它是从模式的一部分。触发源选择指定的一个信号,得到TRGI,TRGI去触发从模式,从模式可以在这个列表里选择一项操作来自动执行。

5.输入捕获基本结构

在这里插入图片描述

6.PWMI基本结构

在这里插入图片描述

  • 配置为PWMI模式,同时测量频率和占空比。这个PWM模式就是PWM的输入模式,是专门为测量PWM频率和占空比设计的。
  • PWM模式和主从触发模式设计的非常巧妙,把这两个功能结合起来测量频率占空比,就是硬件全自动执行。软件不需要进行任何干预,也不需要进行中断,需要测量的时候直接读取CCR计算器,极大的减轻了软件的压力。

二、输入捕获模式测频率

1.接线图

在这里插入图片描述

2.代码

main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "PWM.h"
#include "IC.h"int main(void)
{/*模块初始化*/OLED_Init();		//OLED初始化PWM_Init();			//PWM初始化IC_Init();			//输入捕获初始化/*显示静态字符串*/OLED_ShowString(1, 1, "Freq:00000Hz");		//1行1列显示字符串Freq:00000Hz/*使用PWM模块提供输入捕获的测试信号*/PWM_SetPrescaler(720 - 1);					//PWM频率Freq = 72M / (PSC + 1) / 100PWM_SetCompare1(50);						//PWM占空比Duty = CCR / 100while (1){OLED_ShowNum(1, 6, IC_GetFreq(), 5);	//不断刷新显示输入捕获测得的频率}
}

IC.c

#include "stm32f10x.h"                  // Device header/*** 函    数:输入捕获初始化* 参    数:无* 返 回 值:无*/
void IC_Init(void)
{/*开启时钟*/RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);			//开启TIM3的时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);			//开启GPIOA的时钟/*GPIO初始化*/GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);							//将PA6引脚初始化为上拉输入/*配置时钟源*/TIM_InternalClockConfig(TIM3);		//选择TIM3为内部时钟,若不调用此函数,TIM默认也为内部时钟/*时基单元初始化*/TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;				//定义结构体变量TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;     //时钟分频,选择不分频,此参数用于配置滤波器时钟,不影响时基单元功能TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; //计数器模式,选择向上计数TIM_TimeBaseInitStructure.TIM_Period = 65536 - 1;               //计数周期,即ARR的值TIM_TimeBaseInitStructure.TIM_Prescaler = 72 - 1;               //预分频器,即PSC的值TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;            //重复计数器,高级定时器才会用到TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStructure);             //将结构体变量交给TIM_TimeBaseInit,配置TIM3的时基单元/*输入捕获初始化*/TIM_ICInitTypeDef TIM_ICInitStructure;							//定义结构体变量TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;				//选择配置定时器通道1TIM_ICInitStructure.TIM_ICFilter = 0xF;							//输入滤波器参数,可以过滤信号抖动TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;		//极性,选择为上升沿触发捕获TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;			//捕获预分频,选择不分频,每次信号都触发捕获TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;	//输入信号交叉,选择直通,不交叉TIM_ICInit(TIM3, &TIM_ICInitStructure);							//将结构体变量交给TIM_ICInit,配置TIM3的输入捕获通道/*选择触发源及从模式*/TIM_SelectInputTrigger(TIM3, TIM_TS_TI1FP1);					//触发源选择TI1FP1TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Reset);					//从模式选择复位//即TI1产生上升沿时,会触发CNT归零/*TIM使能*/TIM_Cmd(TIM3, ENABLE);			//使能TIM3,定时器开始运行
}/*** 函    数:获取输入捕获的频率* 参    数:无* 返 回 值:捕获得到的频率*/
uint32_t IC_GetFreq(void)
{return 1000000 / (TIM_GetCapture1(TIM3) + 1);		//测周法得到频率fx = fc / N,这里不执行+1的操作也可
}

IC.c

#ifndef __IC_H
#define __IC_Hvoid IC_Init(void);
uint32_t IC_GetFreq(void);#endif

3.相关API

1. void RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph, FunctionalState NewState);

功能:使能或禁用 APB1 总线上的外设时钟
参数

  • RCC_APB1Periph
    

    :选择 APB1 外设(x 为外设枚举值)

    • 可选值(部分):
      • RCC_APB1Periph_TIM2:TIM2 定时器
      • RCC_APB1Periph_TIM3:TIM3 定时器(输入捕获用)
      • RCC_APB1Periph_I2C1:I2C1 接口
  • NewState
    

    :时钟使能状态

    • 可选值:
      • ENABLE:使能时钟
      • DISABLE:禁用时钟
        返回值:无
2. void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);

功能:初始化 GPIO 引脚的模式、速度等参数
参数

  • GPIOx
    

    :选择 GPIO 端口(x 为端口字母)

    • 可选值:
      • GPIOAGPIOBGPIOC等(如 PA6 对应GPIOA
  • GPIO_InitStruct
    

    :指向 GPIO 配置结构体的指针

    • 结构体成员(部分):

      • GPIO_Mode
        

        :引脚模式

        • 可选值:
          • GPIO_Mode_IPU:上拉输入(输入捕获用)
          • GPIO_Mode_AF_PP:复用推挽输出
      • GPIO_Pin
        

        :引脚号

        • 可选值:
          • GPIO_Pin_0~GPIO_Pin_15(如 PA6 对应GPIO_Pin_6
      • GPIO_Speed
        

        :输出速度(输入模式无效)

        • 可选值:
          • GPIO_Speed_10MHzGPIO_Speed_50MHz
            返回值:无
3. void TIM_InternalClockConfig(TIM_TypeDef* TIMx);

功能:选择定时器的时钟源为内部时钟(默认配置)
参数

  • TIMx
    

    :选择定时器(x 为定时器编号)

    • 可选值:
      • TIM2TIM3(输入捕获用)、TIM4
        返回值:无
4. void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);

功能:配置定时器的时基参数(计数周期、分频等)
参数

  • TIMx
    

    :选择定时器

    • 可选值:
      • TIM3(输入捕获用)、TIM2TIM4
  • TIM_TimeBaseInitStruct
    

    :指向时基配置结构体的指针

    • 结构体成员(部分):

      • TIM_Period
        

        :自动重装值(ARR)

        • 可选值:
          • 0~65535(16 位计数器,如65535对应最大周期)
      • TIM_Prescaler
        

        :预分频值(PSC)

        • 可选值:
          • 0~65535(如71对应 72 分频,计数器时钟 1MHz)
      • TIM_CounterMode
        

        :计数模式

        • 可选值:
          • TIM_CounterMode_Up:向上计数(输入捕获用)
          • TIM_CounterMode_Down:向下计数
            返回值:无
5. void TIM_ICInit(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct);

功能:初始化定时器的输入捕获通道参数
参数

  • TIMx
    

    :选择定时器

    • 可选值:
      • TIM3(输入捕获用)、TIM2TIM4
  • TIM_ICInitStruct
    

    :指向输入捕获配置结构体的指针

    • 结构体成员(部分):

      • TIM_Channel
        

        :捕获通道

        • 可选值:
          • TIM_Channel_1:通道 1(输入捕获用)
          • TIM_Channel_2~TIM_Channel_4
      • TIM_ICPolarity
        

        :捕获极性

        • 可选值:
          • TIM_ICPolarity_Rising:上升沿捕获(输入捕获用)
          • TIM_ICPolarity_Falling:下降沿捕获
      • TIM_ICFilter
        

        :输入滤波器参数

        • 可选值:
          • 0x0~0xF(如0xF表示最强滤波,抗干扰)
            返回值:无
6. void TIM_SelectInputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_TS);

功能:选择定时器从模式的触发源
参数

  • TIMx
    

    :选择定时器

    • 可选值:
      • TIM3(输入捕获用)、TIM2TIM4
  • TIM_TS
    

    :触发源选择

    • 可选值(输入捕获相关):
      • TIM_TS_TI1FP1:使用通道 1 的滤波后信号(输入捕获用)
      • TIM_TS_TI2FP2:使用通道 2 的滤波后信号
        返回值:无
7. void TIM_SelectSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_SlaveMode);

功能:配置定时器的从模式行为(如复位、门控)
参数

  • TIMx
    

    :选择定时器

    • 可选值:
      • TIM3(输入捕获用)、TIM2TIM4
  • TIM_SlaveMode
    

    :从模式类型

    • 可选值:
      • TIM_SlaveMode_Reset:复位模式(输入捕获用,触发时计数器归零)
      • TIM_SlaveMode_Gated:门控模式(触发有效时计数器运行)
        返回值:无
8. void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState);

功能:启动或停止定时器计数
参数

  • TIMx
    

    :选择定时器

    • 可选值:
      • TIM3(输入捕获用)、TIM2TIM4
  • NewState
    

    :定时器使能状态

    • 可选值:
      • ENABLE:启动定时器(输入捕获用)
      • DISABLE:停止定时器
        返回值:无
9. uint16_t TIM_GetCapture1(TIM_TypeDef* TIMx);

功能:获取定时器通道 1 的捕获值(CCR1)
参数

  • TIMx
    

    :选择定时器

    • 可选值:
      • TIM3(输入捕获用)、TIM2TIM4
        返回值
  • 通道 1 的捕获寄存器值(0~65535,对应两次上升沿间的计数值)

现象:测量波形的输入口是PA6,用一根线把PA0和PA6连在一起,这样就能测量自己PWM模块产生波形的频率。

三、PWMI模式测频率占空比

1.接线图

在这里插入图片描述

2.代码

main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "PWM.h"
#include "IC.h"int main(void)
{/*模块初始化*/OLED_Init();		//OLED初始化PWM_Init();			//PWM初始化IC_Init();			//输入捕获初始化/*显示静态字符串*/OLED_ShowString(1, 1, "Freq:00000Hz");		//1行1列显示字符串Freq:00000HzOLED_ShowString(2, 1, "Duty:00%");			//2行1列显示字符串Duty:00%/*使用PWM模块提供输入捕获的测试信号*/PWM_SetPrescaler(720 - 1);					//PWM频率Freq = 72M / (PSC + 1) / 100PWM_SetCompare1(50);						//PWM占空比Duty = CCR / 100while (1){OLED_ShowNum(1, 6, IC_GetFreq(), 5);	//不断刷新显示输入捕获测得的频率OLED_ShowNum(2, 6, IC_GetDuty(), 2);	//不断刷新显示输入捕获测得的占空比}
}

IC.c

#include "stm32f10x.h"                  // Device header/*** 函    数:输入捕获初始化* 参    数:无* 返 回 值:无*/
void IC_Init(void)
{/*开启时钟*/RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);			//开启TIM3的时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);			//开启GPIOA的时钟/*GPIO初始化*/GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);							//将PA6引脚初始化为上拉输入/*配置时钟源*/TIM_InternalClockConfig(TIM3);		//选择TIM3为内部时钟,若不调用此函数,TIM默认也为内部时钟/*时基单元初始化*/TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;				//定义结构体变量TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;     //时钟分频,选择不分频,此参数用于配置滤波器时钟,不影响时基单元功能TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; //计数器模式,选择向上计数TIM_TimeBaseInitStructure.TIM_Period = 65536 - 1;               //计数周期,即ARR的值TIM_TimeBaseInitStructure.TIM_Prescaler = 72 - 1;               //预分频器,即PSC的值TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;            //重复计数器,高级定时器才会用到TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStructure);             //将结构体变量交给TIM_TimeBaseInit,配置TIM3的时基单元/*PWMI模式初始化*/TIM_ICInitTypeDef TIM_ICInitStructure;							//定义结构体变量TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;				//选择配置定时器通道1TIM_ICInitStructure.TIM_ICFilter = 0xF;							//输入滤波器参数,可以过滤信号抖动TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;		//极性,选择为上升沿触发捕获TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;			//捕获预分频,选择不分频,每次信号都触发捕获TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;	//输入信号交叉,选择直通,不交叉TIM_PWMIConfig(TIM3, &TIM_ICInitStructure);						//将结构体变量交给TIM_PWMIConfig,配置TIM3的输入捕获通道//此函数同时会把另一个通道配置为相反的配置,实现PWMI模式/*选择触发源及从模式*/TIM_SelectInputTrigger(TIM3, TIM_TS_TI1FP1);					//触发源选择TI1FP1TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Reset);					//从模式选择复位//即TI1产生上升沿时,会触发CNT归零/*TIM使能*/TIM_Cmd(TIM3, ENABLE);			//使能TIM3,定时器开始运行
}/*** 函    数:获取输入捕获的频率* 参    数:无* 返 回 值:捕获得到的频率*/
uint32_t IC_GetFreq(void)
{return 1000000 / (TIM_GetCapture1(TIM3) + 1);		//测周法得到频率fx = fc / N,这里不执行+1的操作也可
}/*** 函    数:获取输入捕获的占空比* 参    数:无* 返 回 值:捕获得到的占空比*/
uint32_t IC_GetDuty(void)
{return (TIM_GetCapture2(TIM3) + 1) * 100 / (TIM_GetCapture1(TIM3) + 1);	//占空比Duty = CCR2 / CCR1 * 100,这里不执行+1的操作也可
}

IC.h

#ifndef __IC_H
#define __IC_Hvoid IC_Init(void);
uint32_t IC_GetFreq(void);
uint32_t IC_GetDuty(void);#endif

现象:

  • 硬件连接:

PWM 输出(PA8) → 输入捕获引脚(PA6)
OLED 显示屏通过 I2C 接口连接(通常为 PB6/PB7)

  • 参数配置:

PWM 频率:72MHz / (720) / 100 = 1kHz
PWM 占空比:50 / 100 = 50%

  • 输入捕获配置:

TIM3 通道 1(PA6)配置为上升沿捕获,用于测量频率和占空比
从模式设为复位模式,确保每次上升沿触发计数器归零
2. 实时显示效果
OLED 显示内容:

Freq:00000Hz  
Duty:00%  

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词