PWM输入模式

Posted forup

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PWM输入模式相关的知识,希望对你有一定的参考价值。

pwm输入模式基础

该模式是输入捕获模式的一个特例,除下列区别外,操作与输入捕获模式相同:

● 两个ICx信号被映射至同一个TIx输入。

● 这2个ICx信号为边沿有效,但是极性相反。

● 其中一个TIxFP信号被作为触发输入信号,而从模式控制器被配置成复位模式。

pwm输入模式其实属于特殊的输入捕获,参考讲到很好,遗憾的时很难具体记住哪个寄存器导致来回翻找,主模式从模式听的一塌糊涂,看图

技术图片

 

记住三点

1 pwm输入模式只有TIMX_CH1/TIMX_CH2使用,别忘了相应的初始化

2只用初始化一个引脚,IC1 IC2复用

如果设置ch1为触发模式,那么ch2 会成为一个从控制模式,当CH1连续采集到两个触发沿,那么CH2就会自动采集在相同时间内极性相反的触发沿的个数,如果IC1使用上边沿检测 IC2就自动使用下边沿检测。让检测更加准确。

2捕获寄存器中捕获的为TIM的计数个数n,另一个捕获通道捕获触发信号和下一个相反极性的边沿信号的计数个数m(即高电平的周期或低电平的周期)

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

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

    duty cycle=(高电平计数个数/n,大于0.5时除以2 ,小于0.5时乘以2

相关函数

void TIM_PWMIConfig(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct)   初始化函数

内容与TIM_IC一致注意通道选择

void TIM_SelectInputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource)

#define TIM_TS_ITR0 ((uint16_t)0x0000)
#define TIM_TS_ITR1 ((uint16_t)0x0010)
#define TIM_TS_ITR2 ((uint16_t)0x0020)
#define TIM_TS_ITR3 ((uint16_t)0x0030)
#define TIM_TS_TI1F_ED ((uint16_t)0x0040)

 这里我们只是用这两个
#define TIM_TS_TI1FP1 ((uint16_t)0x0050)   TI1 TI2 为 触发模式通道
#define TIM_TS_TI2FP2 ((uint16_t)0x0060)  
#define TIM_TS_ETRF ((uint16_t)0x0070)

作用:选择TIMx输入触发源

void TIM_SelectSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_SlaveMode)

#define TIM_SlaveMode_Reset ((uint16_t)0x0004)    选中触发信号(TRGI)的上升沿重初始化计数器并触发寄存器的更新
#define TIM_SlaveMode_Gated ((uint16_t)0x0005)    当触发信号(TRGI)为高电平计数器时钟使能
#define TIM_SlaveMode_Trigger ((uint16_t)0x0006)    计数器在触发(TRGI)的上升沿开始
#define TIM_SlaveMode_External1 ((uint16_t)0x0007)   选中触发(TRGI)的上升沿作为计数器时钟·

作用 :选择TIMx从模式

void TIM_SelectSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_SlaveMode)

TIM_MasterSlaveMode_Enable         TIM主/从模式使能

TIM_MasterSlaveMode_Disable        TIM主/从模式失能

作用:设置主从模式


注意!!!

  如果用CH2测量频率CH1测量占空比的话,只需要设置CH2,开启CC2中断即可,

  TIM_ITConfig(TIM4, TIM_IT_CC2|TIM_IT_Update, ENABLE);

  TIM_TS_TI2FP2,TIM_SelectInputTrigger(TIM4, TIM_TS_TI2FP2);     //选择有效输入端

  设置函数为: TIM_PWMIConfig(TIM4, &TIM4_ICInitStructure);而不是TIM_ICInit(TIM4, &TIM4_ICInitStructure);如果选择这个函数初始化的话还需要设置CH1。

 示例代码

功能 测频   测占空比

#include "timer.h"
#include "led.h"
#include "sys.h"
#include "usart.h"

double  my_abs(double a);
/*我们只需配置触发通道即可*/
void TIM2_Int_Init( u16 arr,u16 psc ){

    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
    NVIC_InitTypeDef NVIC_InitStructure;
        GPIO_InitTypeDef  GPIO_InitStructure;
        TIM_ICInitTypeDef   TIM_ICInitStruct;
        NVIC_InitTypeDef    NVIC_InitStructe;
        /*GPIO初始化PA.0 */
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); 
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;               
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;            
    GPIO_Init(GPIOA, &GPIO_InitStructure);     
    
        /*定时器初始化*/
    TIM_TimeBaseStructure.TIM_Period = arr;     
    TIM_TimeBaseStructure.TIM_Prescaler =psc; 
    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;         //预分频系数
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //计数方式
    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); 
        /*中断初始化*/
         NVIC_InitStructe.NVIC_IRQChannel = TIM2_IRQn;                     
     NVIC_InitStructe.NVIC_IRQChannelPreemptionPriority = 0;
     NVIC_InitStructe.NVIC_IRQChannelSubPriority = 1;
     NVIC_InitStructe.NVIC_IRQChannelCmd = ENABLE;
     NVIC_Init(&NVIC_InitStructe);  
        /*pwm输入初始化*/
        TIM_ICInitStruct.TIM_Channel=TIM_Channel_1;        //选择通道
        TIM_ICInitStruct.TIM_ICFilter=0x0;                            //滤波系数
        TIM_ICInitStruct.TIM_ICPolarity=TIM_ICPolarity_Rising;//触发模式    
        TIM_ICInitStruct.TIM_ICPrescaler=TIM_CKD_DIV1;    //预分频选择
        TIM_ICInitStruct.TIM_ICSelection=TIM_ICSelection_DirectTI;//端口映射
        TIM_PWMIConfig(TIM2,&TIM_ICInitStruct);
        
     TIM_SelectInputTrigger(TIM2, TIM_TS_TI1FP1);     //选择有效输入端        
     TIM_SelectSlaveMode(TIM2, TIM_SlaveMode_Reset);  //配置为主从复位模式
     TIM_SelectMasterSlaveMode(TIM2, TIM_MasterSlaveMode_Enable);                                       
     TIM_ITConfig(TIM2, TIM_IT_CC1|TIM_IT_Update, ENABLE);          //中断配置
 
     TIM_ClearITPendingBit(TIM2, TIM_IT_CC1|TIM_IT_Update); //清除中断标志位

    TIM_Cmd(TIM2, ENABLE);  

}

void TIM2_IRQHandler(void)
{
  
    if(TIM_GetITStatus(TIM2,TIM_IT_Update)!=RESET)//定时器中断清零
    {

        TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
    }

    else if(TIM_GetITStatus(TIM2,TIM_IT_CC2)!=RESET)//通道1触发清零
    {

        TIM_ClearITPendingBit(TIM2,TIM_IT_CC2);
    }

   else if(TIM_GetITStatus(TIM2,TIM_IT_CC1)!=RESET)//通道2触发清零
    {

        printf("TIM2 HIGH=%d , LOW=%d 
",TIM_GetCapture1(TIM2),TIM_GetCapture2(TIM2));                
        
                 printf("TIM2 frequency=%d , duty=%lf
",(100000/TIM_GetCapture1(TIM2)),(my_abs((double)TIM_GetCapture1(TIM2)/(double)TIM_GetCapture2(TIM2)))/2);
        TIM_ClearITPendingBit(TIM2,TIM_IT_CC1);
    }
   

}
double  my_abs(double a)
{
    if(a<0)
    a=-a;
    else
    a=a;
    return a ;
}

 

以上是关于PWM输入模式的主要内容,如果未能解决你的问题,请参考以下文章

[pwm]PWM的输入捕捉模式

stm32通用定时器pwm输入模式

请教STM32 定时器PWM输入捕获 引脚通道配置

[STM32F103]定时器PWM输入

stm32cubemx PWM

stm32cubemx PWM