As the general timer input capture

Recommended for you: Get network issues from WhatsUp Gold. Not end users.

General use as input capture timer. We will use the TIM5 channel 1 (PA0) to do the input capture, capture PA0 pulse width and high level (with the WK_UP button input high level), through the serial port to print high level pulse width time

Input capture

Input capture mode can be used to measure pulse width and frequency measurement. STM32 timer, in addition to TIM6 and TIM7, there are other timer input capture function. STM32 input capture, simply by the edge detection on the TIMx_CHx, on the edge of the signal jump (such as rising / falling edge) time, the current timer value (TIMx_CNT) stored in the corresponding channel capture / compare register (TIMx_CCRx), complete a capture. At the same time also can trigger the interrupt /DMA configuration is captured.

We use TIM5_CH1 to capture high level pulse width, also is to first set the input capture for the rising edge detection, recorded the rising edge of the TIM5_CNT value. Then configure the capture signal to decrease along the capture, when down came, trapping occurs, and record the TIM5_CNT value. So, before and after the two TIM5_CNT difference, is the pulse width and high level, at the same time, counting the frequency of TIM5 we know, which can calculate the accurate time of high level pulse width.

Input capture configuration steps:

1)Open the TIM5 clock and the GPIOA clock, configure P A0 pull-down input.

To use TIM5, we must first open the TIM5 clock. Here we will configure P A0 pull-down input, because the high level pulse width we want to capture TIM5_CH1 above, and the TIM5_CH1 is connected to the PA0.

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE); //Enable TIM5 clock

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);   //Enable GPIOA clock

2)Initialize TIM5, set the TIM5 ARR and PSC.

Then open the TIM5 clock, we need to set the ARR and PSC two register value is automatically reloaded input capture load and count frequency. This is implemented using the TIM_TimeBaseInit function in the library functions in the

  1.    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
  2.    TIM_TimeBaseStructure.TIM_Period = arr; //Set the counter and automatic reload value
  3.    TIM_TimeBaseStructure.TIM_Prescaler =psc; //Set the pre frequency value
  4.    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; // TDTS = Tck_tim
  5.    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM up counting mode
  6.    TIM_TimeBaseInit(TIM5, &TIM_TimeBaseStructure);

3)Set the TIM5 input parameter, to open the input capture

The input parameters including mapping, filtering, frequency and the capture mode. Here we need to set the channel 1 to input mode, and the IC1 is mapped to the TI1 (channel 1) above, and do not use filter (to improve response speed), the rising edge capture. Library function through the TIM_ICInit function to initialize the input parameters:

void TIM_ICInit(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct),

Similarly, we come to have a look to define the parameters setting structure TIM_ICInitTypeDef:

  1.    typedef struct
  2.    {
  3.        uint16_t TIM_Channel; //Set channel
  4.        uint16_t TIM_ICPolarity; //Set the effective capture polarity input signal
  5.        uint16_t TIM_ICSelection; //Set the mapping relationship
  6.        uint16_t TIM_ICPrescaler; //Set the input capture frequency coefficient
  7.        uint16_t TIM_ICFilter; //Set the filter length
  8.    } TIM_ICInitTypeDef;

The configuration code is:

  1.    TIM_ICInitTypeDef TIM5_ICInitStructure;
  2.    TIM5_ICInitStructure.TIM_Channel = TIM_Channel_1; //Select the input IC1 is mapped to TI1
  3.    TIM5_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; //Rising along the capture
  4.    TIM5_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //Mapping to the TI1
  5.    TIM5_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; //Configure input frequency, regardless of the frequency
  6.    TIM5_ICInitStructure.TIM_ICFilter = 0x00;//The IC1F=0000 configuration input filter without filter
  7.    TIM_ICInit(TIM5, &TIM5_ICInitStructure);

4)That can capture and update interrupt (TIM5 DIER register)

Because we want to capture the pulse width, high level signals so, first capture is rising, the second captured falling after rising, must capture, capture edge is set down, at the same time, if the pulse duration is long, then the timer will overflow, overflow must do treatment on, otherwise the result would not be allowed to the. These two things, we are all in the interrupt inside, so must be open to capture interrupt and update interrupt.

Here we use the timer off function TIM_ITConfig can make can capture and update interrupt:

TIM_ITConfig( TIM5,TIM_IT_Update|TIM_IT_CC1,ENABLE);//Allow updates to interrupt and capture interrupt

5)Set the interrupt packet, write interrupt service function

Set the interrupt packet is mainly through the function NVIC_Init () to complete the. The packet is completed, we also need to interrupt function inside the completion of data processing and the capture setting key operation, so as to realize the high level pulse width statistics. In the interrupt service function, with the previous external interrupt and timer interrupt experiment, we want to interrupt type judgment when interrupt began, to clear the interrupt flag at the end of the interrupt. The function used to respectively the TIM_GetITStatus () function and TIM_ClearITPendingBit () function.

if (TIM_GetITStatus(TIM5, TIM_IT_Update) != RESET){}//To determine whether the update interrupt

if (TIM_GetITStatus(TIM5, TIM_IT_CC1) != RESET){}//To determine whether the captured events

TIM_ClearITPendingBit(TIM5, TIM_IT_CC1|TIM_IT_Update);//Clear interrupt and capture the flag

6)Enable timer (TIM5 CR1 register)

Finally, counter switch must open the timer, counter to start TIM5, input capture.

TIM_Cmd(TIM5,ENABLE );    //Enable the timer 5



Routine:

  1. #include "timer.h"
  2. #include "led.h"
  3. #include "usart.h"

  4. /**
  5.  * 5 channel 1 input capture timer configuration
  6.  */
  7.  void TIM5_Cap_Init(u16 arr,u16 psc)
  8. {
  9.     GPIO_InitTypeDef GPIO_InitStructure;
  10.     TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
  11.     TIM_ICInitTypeDef TIM5_ICInitStructure;
  12.     NVIC_InitTypeDef NVIC_InitStructure;
  13.     
  14.     RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5,ENABLE);    /*Enable TIM5 clock*/
  15.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); /*Enable GPIOA clock*/
  16.     
  17.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; /**/
  18.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; /*PA0 input*/
  19.     GPIO_Init(GPIOA,&GPIO_InitStructure);
  20.     GPIO_ResetBits(GPIOA,GPIO_Pin_0); /*PA0 drop-down*/
  21.     
  22.     /*Initialize the timer 5 TIM5*/
  23.     TIM_TimeBaseStructure.TIM_Period = arr; /*Set the counter and automatic reload value */
  24.     TIM_TimeBaseStructure.TIM_Prescaler = psc; /*The prescaler */
  25.     TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; /*Set the clock division: TDTS = Tck_tim*/
  26.     TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; /*TIM up counting mode*/
  27.     TIM_TimeBaseInit(TIM5,&TIM_TimeBaseStructure); /*According to the TIM_TimeBaseInitStruct specified in the TIMx parameter initialization time base unit*/
  28.             
  29.     /* Initialize the TIM5 input capture parameters */
  30.     TIM5_ICInitStructure.TIM_Channel = TIM_Channel_1; /*CC1S=01     Select the input IC1 is mapped to TI1*/    
  31.     TIM5_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; /*Rising along the capture*/
  32.     TIM5_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; /*Mapping to the TI1*/
  33.     TIM5_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; /*Configure input frequency, regardless of the frequency*/
  34.     TIM5_ICInitStructure.TIM_ICFilter = 0; /*The IC1F=0000 configuration input filter without filter*/
  35.     TIM_ICInit(TIM5,&TIM5_ICInitStructure);
  36.     
  37.     /*Interrupt packet initialization*/
  38.     NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn;    /*TIM5 interrupt*/
  39.     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; /*Preemptive priority level 2*/
  40.     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; /*From the priority level 0*/
  41.     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; /*The IRQ channel is enabled*/
  42.     NVIC_Init(&NVIC_InitStructure);
  43.     
  44.     TIM_ITConfig(TIM5,TIM_IT_Update|TIM_IT_CC1,ENABLE);/*Allow updates to interrupt, allows the CC1IE to capture interrupt*/
  45.     TIM_Cmd(TIM5,ENABLE); /*Enable the timer 5*/    
  46. }

  47. u8 TIM5CH1_CAPTURE_STA=0;    //Input capture state                         
  48. u16    TIM5CH1_CAPTURE_VAL;    //Input capture value

  49. /**
  50.  * Timer 5 interrupt service routine    
  51.  */
  52. void TIM5_IRQHandler(void)
  53. {
  54.     if((TIM5CH1_CAPTURE_STA&0X80)==0)//Not successfully capture    
  55.     {
  56.         if(TIM_GetITStatus(TIM5,TIM_IT_Update) != RESET)
  57.         {
  58.             if(TIM5CH1_CAPTURE_STA&0X40)//Has captured to a high level
  59.             {
  60.                 if((TIM5CH1_CAPTURE_STA&0X3F)==0X3F)//The high level is too long
  61.                 {
  62.                     TIM5CH1_CAPTURE_STA|=0X80;//Marker successfully captured a
  63.                     TIM5CH1_CAPTURE_VAL=0XFFFF;
  64.                 }else TIM5CH1_CAPTURE_STA++;
  65.             }
  66.         }
  67.         
  68.         if(TIM_GetITStatus(TIM5,TIM_IT_CC1) !=RESET)
  69.         {
  70.             if(TIM5CH1_CAPTURE_STA & 0x40)
  71.             {
  72.                 TIM5CH1_CAPTURE_STA|=0X80;        //Marker successfully captures a rising edge
  73.                 TIM5CH1_CAPTURE_VAL = TIM_GetCounter(TIM5);
  74.                 TIM_OC1PolarityConfig(TIM5,TIM_ICPolarity_Rising); //CC1P=0 is set to rise along the capture
  75.             }
  76.             else
  77.             {
  78.                 TIM5CH1_CAPTURE_STA=0;            //Empty
  79.                 TIM5CH1_CAPTURE_VAL=0;
  80.                 
  81.                 TIM_SetCounter(TIM5,0);
  82.                 TIM5CH1_CAPTURE_STA|=0X40;        //Mark captured the rising edge
  83.                 TIM_OC1PolarityConfig(TIM5,TIM_ICPolarity_Falling);        //CC1P=1 is set to decrease along the capture
  84.             }
  85.         }
  86.         
  87.     }
  88.     TIM_ClearITPendingBit(TIM5,TIM_IT_CC1|TIM_IT_Update); /*Clear interrupt flag*/
  89. }

  1. extern u8 TIM5CH1_CAPTURE_STA;        //Input capture state                         
  2. extern u16    TIM5CH1_CAPTURE_VAL;    //Input capture value    
  3.  int main(void)
  4.  {        
  5.      u32 temp=0;
  6.     delay_init();          //The delay function to initialize    
  7.     NVIC_Configuration();      //Setting NVIC 2:2 interrupt packet priority, 2 priority response
  8.     uart_init(9600);     //Serial communication is initialized to 9600
  9.      LED_Init();             //LED port initialization
  10.  
  11.      TIM5_Cap_Init(0XFFFF,72-1);    //The frequency count 1Mhz
  12.        while(1)
  13.     {
  14.          delay_ms(10);
  15.                  
  16.          if(TIM5CH1_CAPTURE_STA&0X80)//The successful capture to a rising edge
  17.         {
  18.             temp=TIM5CH1_CAPTURE_STA&0X3F;
  19.             temp*=65536;//Overflow time sum
  20.             temp+=TIM5CH1_CAPTURE_VAL;//High level of total time
  21.             printf("HIGH:%d us\r\n",temp);//Print the total high level time
  22.             TIM5CH1_CAPTURE_STA=0;//Open the next acquisition
  23.         }
  24.     }
  25.  }

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download

Posted by Dunn at May 26, 2014 - 5:18 AM