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),

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

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

相关函数

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 \r\n",TIM_GetCapture1(TIM2),TIM_GetCapture2(TIM2));                
        
                 printf("TIM2 frequency=%d , duty=%lf\r\n",(100000/TIM_GetCapture1(TIM2)),(my_abs((double)TIM_GetCapture1(TIM2)/(double)TIM_GetCapture2(TIM2))));
        TIM_ClearITPendingBit(TIM2,TIM_IT_CC1);
    }
   

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

猜你喜欢

转载自www.cnblogs.com/forup/p/12785847.html
PWM