STM32定时器捕获PWM脉冲频率

本文详细介绍了PWM输入捕获的工作原理及其在STM32上的实现方法。通过具体实例讲解了如何配置定时器来捕获PWM信号,计算其周期与占空比,并提供了完整的程序代码。

一、概念理解

PWM输入捕获模式是输入捕获模式的特例,自己理解如下

1. 每个定时器有四个输入捕获通道IC1、IC2、IC3、IC4。且IC1 IC2一组,IC3 IC4一组。并且可是设置管脚和寄存器的对应关系。

2. 同一个TIx输入映射了两个ICx信号。

3. 这两个ICx信号分别在相反的极性边沿有效。

4. 两个边沿信号中的一个被选为触发信号,并且从模式控制器被设置成复位模式。

5. 当触发信号来临时,被设置成触发输入信号的捕获寄存器,捕获“一个PWM周期(即连续的两个上升沿或下降沿)”,它等于包含TIM时钟周期的个数(即捕获寄存器中捕获的为TIM的计数个数n)。

6. 同样另一个捕获通道捕获触发信号和下一个相反极性的边沿信号的计数个数m,即(即高电平的周期或低电平的周期)

7. 由此可以计算出PWM的时钟周期和占空比了

    frequency=f(TIM时钟频率)/n。

    duty cycle=(高电平计数个数/n),

    若m为高电平计数个数,则duty cycle=m/n

    若m为低电平计数个数,则duty cycle=(n-m)/n

注:因为计数器为16位,所以一个周期最多计数65535个,所以测得的 最小频率= TIM时钟频率/65535。

 

二、程序设计与分析

1. 程序概述:选择TIM3作为PWM输入捕获。IC2设置为上升沿,并设置为有效的触发输入信号。所以IC2的捕获寄存器捕获PWM周期,

                   IC1的捕获寄存器捕获PWM的高电平周期。

2.程序代码如下:

 
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);      //时钟配置

 
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

 

 


  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;                               //GPIO配置
  PIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  GPIO_Init(GPIOA, &GPIO_InitStructure);

 

 

 

 
  NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;                     //NVIC配置 
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);

 

 

 

  TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;                   //通道选择
  TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;       //上升沿触发
  TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;    //管脚与寄存器对应关系
  TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;           //输入预分频。意思是控制在多少个输入周期做一次捕获,如果

//输入的信号频率没有变,测得的周期也不会变。比如选择4分频,则每四个输入周期才做一次捕获,这样在输入信号变化不频繁的情况下,

//可以减少软件被不断中断的次数。
  TIM_ICInitStructure.TIM_ICFilter = 0x0;                            //滤波设置,经历几个周期跳变认定波形稳定0x0~0xF

  TIM_PWMIConfig(TIM3, &TIM_ICInitStructure);                 //根据参数配置TIM外设信息

 
  TIM_SelectInputTrigger(TIM3, TIM_TS_TI2FP2);                //选择IC2为始终触发源

 
  TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Reset);//TIM从模式:触发信号的上升沿重新初始化计数器和触发寄存器的更新事件

 
  TIM_SelectMasterSlaveMode(TIM3, TIM_MasterSlaveMode_Enable); //启动定时器的被动触发

 
  TIM_Cmd(TIM3, ENABLE);                                 //启动TIM2

           
  TIM_ITConfig(TIM3, TIM_IT_CC2, ENABLE);     //打开中断 

 

中断处理函数

 

void TIM3_IRQHandler(void)
{
 
  TIM_ClearITPendingBit(TIM3, TIM_IT_CC2);                //清楚TIM的中断待处理位

 
  IC2Value = TIM_GetCapture2(TIM3);                         //读取IC2捕获寄存器的值,即为PWM周期的计数值

  if (IC2Value != 0)
  {
   
    DutyCycle = (TIM_GetCapture1(TIM3) * 100) / IC2Value;         //读取IC1捕获寄存器的值,并计算占空比

   
    Frequency = 72000000 / IC2Value;                                          //计算PWM频率。
  }
  else
  {
    DutyCycle = 0;
    Frequency = 0;
  }
}

 

 

注(一):若想改变测量的PWM频率范围,可将TIM时钟频率做分频处理

 TIM_TimeBaseStructure.TIM_Period = 0xFFFF;     //周期0~FFFF
  TIM_TimeBaseStructure.TIM_Prescaler = 5;       //时钟分频,分频数为5+1即6分频
  TIM_TimeBaseStructure.TIM_ClockDivision = 0;   //时钟分割
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//模式
  TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);//基本初始化
注注(二):定时器TIM的倍频器X1或X2。在APB分频为1时,倍频值为1,否则为2。



笔记:之前调试的时候,想检测低频,按照上面方法进行分频处理时,怎么都不行,后来才搞明白,由于检测时要进行计数,印记预装载值TIM_Period还是要设置成0xffff,而TIM_Prescaler是进行分频用的,也就是说,如果定时器时钟为72M,则将TIM_Prescaler设置成5后,TIM的时钟为14.4M,此时可以检测的最小频率=14.4M/0xffff,也就是说最小检测频率= 14.4M/TIM_Period;

    之前关于这个TIM_Period自动重载值没有理解好,怎么都调试不同,终于搞定了,记录一下,以便后期查阅

STM32使用定时器PWM脉冲进行计数是一种常见的应用场景,通常可以通过配置定时器的输入捕获功能或使用外部时钟模式来实现。以下是实现这一功能的关键点和配置方法: ### 使用外部时钟模式对PWM脉冲进行计数 STM32定时器支持外部时钟源输入,可以将外部信号作为计数器的时钟源,从而实现对PWM脉冲的计数。具体配置步骤如下: - 将外部PWM信号连接到定时器的某个通道(例如TIMx_CH1)。 - 配置该通道为**外部时钟模式1**(External Clock Mode 1),此时定时器的计数器会在每个PWM上升沿或下降沿(取决于配置)递增。 - 设置定时器为**向上计数模式**(Up Counting Mode),并根据需要设定自动重载值(ARR)以实现计数范围的限制。 - 启动定时器后,其计数器寄存器(TIMx_CNT)将随着每个PWM脉冲递增,从而实现对脉冲数量的计数[^1]。 ### 使用输入捕获功能进行脉冲计数 另一种方法是使用**输入捕获功能**来统计PWM脉冲的数量。这种方法通常用于需要记录脉冲边沿事件的场合: - 将PWM信号输入到某个定时器通道(例如TIMx_CH1)。 - 配置该通道为**输入捕获模式**,并在捕获中断中记录边沿事件。 - 每次捕获到指定边沿(如上升沿),可以手动增加一个计数变量,从而实现脉冲计数。 - 这种方式虽然不直接使用计数器寄存器,但可以提供更灵活的控制,例如检测脉冲宽度或频率变化[^2]。 ### 示例代码(基于外部时钟模式) 以下是一个简化的代码示例,展示如何配置STM32定时器使用外部时钟源对PWM脉冲进行计数: ```c void TIM2_Config(void) { // 使能TIM2时钟 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); TIM_TimeBaseInitTypeDef TIM_TimeBaseStruct; TIM_ICInitTypeDef TIM_ICStruct; // 初始化定时器基础参数 TIM_TimeBaseStruct.TIM_Prescaler = 0; // 不分频 TIM_TimeBaseStruct.TIM_Period = 0xFFFF; // 最大计数值 TIM_TimeBaseStruct.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStruct.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStruct); // 配置外部时钟模式 TIM_SelectInputTrigger(TIM2, TIM_TS_TI1FP1); // 选择TI1作为触发源 TIM_SelectSlaveMode(TIM2, TIM_SlaveMode_External1); // 外部时钟模式1 TIM_SelectMasterSlaveMode(TIM2, TIM_MasterSlaveMode_Enable); // 启动定时器 TIM_Cmd(TIM2, ENABLE); } // 获取当前计数值 uint16_t getPWMCount(void) { return TIM_GetCounter(TIM2); } ``` ### 注意事项 - 在使用外部时钟源时,需确保外部信号的频率不超过定时器的最高允许时钟频率。 - 如果PWM信号的边沿频率过高,可能会导致计数器溢出,因此建议设置合适的自动重载值(ARR)或使用DMA进行数据搬运。 - 若需要精确测量脉冲宽度或频率,推荐使用输入捕获模式,并结合中断或DMA进行处理[^4]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值