STM8S003F3P6定时器输入捕获和输出比较

输入捕获定时器初始化

#include "tim1.h"
#include "common.h"
#include "stm8s.h"
/**
  * @brief  Configure TIM1 16mhz
  * @param  None
  * @retval None
  */
void STM8_TIM1_Init(void) /* 定时器1初始化 ,配置为输入捕获 测频率和脉宽 */
{
    // 16分频         16M/(0x0f)=1M   CNTR计数一次为 1/1M=1us
    TIM1_TimeBaseInit( 0x0f, TIM1_COUNTERMODE_UP, 0xffff, 0 ); 
    TIM1_ICInit( TIM1_CHANNEL_1, TIM1_ICPOLARITY_RISING, TIM1_ICSELECTION_DIRECTTI, TIM1_ICPSC_DIV1, 0x0a );
    TIM1_ICInit( TIM1_CHANNEL_2, TIM1_ICPOLARITY_RISING, TIM1_ICSELECTION_DIRECTTI, TIM1_ICPSC_DIV1, 0x0a );
    TIM1_ICInit( TIM1_CHANNEL_3, TIM1_ICPOLARITY_RISING, TIM1_ICSELECTION_DIRECTTI, TIM1_ICPSC_DIV1, 0x0a );
    
    TIM1_ITConfig( TIM1_IT_CC1, ENABLE );
    TIM1_ITConfig( TIM1_IT_CC2, ENABLE );
    TIM1_ITConfig( TIM1_IT_CC3, ENABLE );
     
//    TIM1_ITConfig( TIM1_IT_UPDATE, ENABLE );
    
    TIM1_Cmd(DISABLE );
    
    TIM1_ClearITPendingBit( TIM1_IT_CC1 );
    TIM1_ClearITPendingBit( TIM1_IT_CC2 );
    TIM1_ClearITPendingBit( TIM1_IT_CC3 );
}

输入捕获定时器中断函数

捕获2个周期以获得频率、周期、占空比

//TIM1_CH1-CH3通道捕获
void TIM1_ISR_Capture( void )
{
  static uint16_t overload=0;  //定时器溢出计数
  /* 输入捕获 */
  if (TIM1_GetITStatus(TIM1_IT_CC1) != RESET)
  {/* CH1 */
      static uint8_t ch1_cc_bz = 0;
      uint16_t  ch1_ICValue = 0;
      uint16_t  ch1_ICValue1 = 0;
      static uint16_t ch1_num1;
      static uint16_t ch1_num2;
      static uint16_t ch1_num3;
      static uint16_t ch1_num4;
      switch(ch1_cc_bz)
      {
           case 0:
               //  TIM1_SetCompare1( 0 );
               ch1_num1 = TIM1_GetCapture1();
               TIM1->CCER1 &= (uint8_t)(~TIM1_CCER1_CC1P);//设为上升沿捕获
              
               ch1_cc_bz = 1;
               break;
           case 1:
               ch1_num2 = TIM1_GetCapture1();
               if( ch1_num2 > ch1_num1 )
               {
                   ch1_ICValue = ch1_num2 - ch1_num1;
               }
               else
               {
                   ch1_ICValue = (0xffff - ch1_num1) + ch1_num2 ;
               }
               TIM1_CH1_Data.Low_Time = ch1_ICValue;
               TIM1->CCER1 |= TIM1_CCER1_CC1P;  //设为下降沿捕获
               ch1_cc_bz = 2;
               break;
           case 2:
               ch1_num3 = TIM1_GetCapture1();
               ch1_cc_bz = 3;
             break;
           case 3:
               ch1_num4 = TIM1_GetCapture1();
               if( ch1_num4 > ch1_num3 )
               {
                   ch1_ICValue1 = ch1_num4 - ch1_num3;
               }
               else
               {
                   ch1_ICValue1 = (0xffff - ch1_num3) + ch1_num4 ;
               }
               TIM1_CH1_Data.Pluse_Period = ch1_ICValue1;           //晶振1M 计数一次刚好是1us
               TIM1_CH1_Data.High_Time = TIM1_CH1_Data.Pluse_Period - TIM1_CH1_Data.Low_Time;
               TIM1_CH1_Data.CaptOK_Flag = TRUE;
               ch1_cc_bz = 0;
             break;
      }
      TIM1_ClearITPendingBit( TIM1_IT_CC1 );
      TIM1_ClearFlag( TIM1_FLAG_CC1 );
  }
  else if(TIM1_GetITStatus(TIM1_IT_CC2) != RESET)
  {/* CH2 */
      static uint8_t ch2_cc_bz = 0;
      uint16_t  ch2_ICValue = 0;
      uint16_t  ch2_ICValue1 = 0;
      static uint16_t ch2_num1;
      static uint16_t ch2_num2;
      static uint16_t ch2_num3;
      static uint16_t ch2_num4;
      switch(ch2_cc_bz)
      {
           case 0:
               ch2_num1 = TIM1_GetCapture2();
               TIM1->CCER1 &= (uint8_t)(~TIM1_CCER1_CC2P);//设为上升沿捕获            
               ch2_cc_bz = 1;
               break;
           case 1:
               ch2_num2 = TIM1_GetCapture2();
               if( ch2_num2 > ch2_num1 )
               {
                   ch2_ICValue = ch2_num2 - ch2_num1;
               }
               else
               {
                   ch2_ICValue = (0xffff - ch2_num1) + ch2_num2 ;
               }
               TIM1_CH2_Data.Low_Time = ch2_ICValue;  
               TIM1->CCER1 |= TIM1_CCER1_CC2P;  //设为下降沿捕获
               ch2_cc_bz = 2;
               break;
           case 2:
               ch2_num3 = TIM1_GetCapture2();
               ch2_cc_bz = 3;
             break;
           case 3:
               ch2_num4 = TIM1_GetCapture2();
               if( ch2_num4 > ch2_num3 )
               {
                   ch2_ICValue1 = ch2_num4 - ch2_num3;
               }
               else
               {
                   ch2_ICValue1 = (0xffff - ch2_num3) + ch2_num4 ;
               }
               TIM1_CH2_Data.Pluse_Period = ch2_ICValue1;           //晶振1M 计数一次刚好是1us
               TIM1_CH2_Data.High_Time = TIM1_CH2_Data.Pluse_Period - TIM1_CH2_Data.Low_Time;
               TIM1_CH2_Data.CaptOK_Flag = TRUE;
               ch2_cc_bz = 0;
             break;
      }
      TIM1_ClearITPendingBit( TIM1_IT_CC2 );
      TIM1_ClearFlag( TIM1_FLAG_CC2 );
  }
  else if(TIM1_GetITStatus(TIM1_IT_CC3) != RESET)
  {/* CH3 */
      static uint8_t ch3_cc_bz = 0;
      uint16_t  ch3_ICValue = 0;
      uint16_t  ch3_ICValue1 = 0;
      static uint16_t ch3_num1;
      static uint16_t ch3_num2;
      static uint16_t ch3_num3;
      static uint16_t ch3_num4;
      switch(ch3_cc_bz)
      {
           case 0:
               //  TIM1_SetCompare1( 0 );
               ch3_num1 = TIM1_GetCapture3();
               TIM1->CCER2 &= (uint8_t)(~TIM1_CCER2_CC3P);//设为上升沿捕获
              
               ch3_cc_bz = 1;
               break;
           case 1:
               ch3_num2 = TIM1_GetCapture3();
               if( ch3_num2 > ch3_num1 )
               {
                   ch3_ICValue = ch3_num2 - ch3_num1;
               }
               else
               {
                   ch3_ICValue = (0xffff - ch3_num1) + ch3_num2 ;
               }
               TIM1_CH3_Data.Low_Time = ch3_ICValue;
               TIM1->CCER2 |= TIM1_CCER2_CC3P;  //设为下降沿捕获
               ch3_cc_bz = 2;
               break;
           case 2:
               ch3_num3 = TIM1_GetCapture3();
               ch3_cc_bz = 3;
             break;
           case 3:
               ch3_num4 = TIM1_GetCapture3();
               if( ch3_num4 > ch3_num3 )
               {
                   ch3_ICValue1 = ch3_num4 - ch3_num3;
               }
               else
               {
                   ch3_ICValue1 = (0xffff - ch3_num3) + ch3_num4 ;
               }
               TIM1_CH3_Data.Pluse_Period = ch3_ICValue1;           //晶振1M 计数一次刚好是1us
               TIM1_CH3_Data.High_Time = TIM1_CH3_Data.Pluse_Period - TIM1_CH3_Data.Low_Time;     
               TIM1_CH3_Data.CaptOK_Flag = TRUE;
               ch3_cc_bz = 0;
             break;
      }
      TIM1_ClearITPendingBit( TIM1_IT_CC3 );
      TIM1_ClearFlag( TIM1_FLAG_CC3 );
  }
  
//  if(TIM1_GetITStatus(TIM1_IT_UPDATE) != RESET)
//  {
//      overload++;
//      TIM1_ClearITPendingBit( TIM1_IT_UPDATE );
//  } 
}

输入捕获频率计算

/**
  * @brief  Clacuate_FreqAndDutyCyle
  * @param  None
  * @retval bool
  */
bool Clacuate_FreqAndDutyCyle(void) 
{
    if(TIM1_CH1_Data.CaptOK_Flag)
    {
      TIM1_CH1_Data.CaptOK_Flag = FALSE;
      TIM1_CH1_Data.Pluse_Freq = 1000000 / TIM1_CH1_Data.Pluse_Period; //TIM CLK = 1M 计算频率
      TIM1_CH1_Data.Pulse_Duty = TIM1_CH1_Data.High_Time * 1.0f / TIM1_CH1_Data.Pluse_Period * 100;
    }
    else if(TIM1_CH2_Data.CaptOK_Flag)
    {
      TIM1_CH2_Data.CaptOK_Flag = FALSE;
      TIM1_CH2_Data.Pluse_Freq = 1000000 / TIM1_CH2_Data.Pluse_Period; 
      TIM1_CH2_Data.Pulse_Duty = TIM1_CH2_Data.High_Time * 1.0f / TIM1_CH2_Data.Pluse_Period * 100;
    }
    else if(TIM1_CH3_Data.CaptOK_Flag)
    {
      TIM1_CH3_Data.CaptOK_Flag = FALSE;
      TIM1_CH3_Data.Pluse_Freq = 1000000 / TIM1_CH3_Data.Pluse_Period; 
      TIM1_CH3_Data.Pulse_Duty = TIM1_CH3_Data.High_Time * 1.0f / TIM1_CH3_Data.Pluse_Period * 100;
    }else
    {
      return FALSE;
    }
    return TRUE;
}

输出比较定时器初始化

#include "tim2.h"
#include "common.h"

const uint16_t TIM2_CH1_Freq = 1000;  /*10000时100hz*/
const uint16_t TIM2_Out_Pluse_Num = 150;  /* The number of pulses required by the Div  */

/**
  * @brief  Configure TIM2  16mhz
  * @param  None
  * @retval None
  */
void STM8_TIM2_Init(void) /* 定时器初始化 */
{
    /* Time base configuration */
  TIM2_TimeBaseInit(TIM2_PRESCALER_16, 0xffff);

  /* Prescaler configuration */
  TIM2_PrescalerConfig(TIM2_PRESCALER_16, TIM2_PSCRELOADMODE_IMMEDIATE);

  /* Output Compare Active Mode configuration: Channel1 */
  /*
	  TIM2_OCMode = TIM2_OCMODE_INACTIVE
       TIM2_OCPolarity = TIM2_OCPOLARITY_HIGH
       TIM2_Pulse = CCR1_Val
	*/
  TIM2_OC1Init(TIM2_OCMODE_TOGGLE,TIM2_OUTPUTSTATE_ENABLE,TIM2_CH1_Freq,TIM2_OCPOLARITY_HIGH); 
  
  /* DISABLE ccr Preload */
  TIM2_OC1PreloadConfig(DISABLE);
  
  /* TIM IT enable */
  TIM2_ITConfig(TIM2_IT_CC1, DISABLE);
    
  /* TIM2 enable counter */
  TIM2_Cmd(DISABLE); 
}

输出比较定时器中断函数


void TIM2_ISR_Compare(void)
{
   /* 输出比较 */
   static int count = 0;
   static int pwm_tmp = 0;
   if (TIM2_GetITStatus(TIM2_IT_CC1) != RESET)
   {
      /* Clear TIM2 Capture Compare1 interrupt pending bit*/
      TIM2_ClearITPendingBit(TIM2_IT_CC1);
      count ++;
      if(count % 2 == 0) /* 一个周期进来两次 */
      {  /* 脉冲个数计数 */
          pwm_tmp++;
          Mcu_Pwm_Out_TOG;
          if(pwm_tmp >= TIM2_Out_Pluse_Num)  /* 判断是否达到指定脉冲数 */
          {
              pwm_tmp = 0;
              TIM2_ITConfig(TIM2_IT_CC1, DISABLE);
              system_data.Fuze_Status = Fuze_Pluse_Out_Finish;
          }
      }
       /*获取当前计数*/
       uint16_t g_count_val = TIM2_GetCounter();
       
       TIM2_SetCompare1((g_count_val + TIM2_CH1_Freq)%0xffff); 
   }  

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值