输入捕获定时器初始化
#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);
}
}