Skip to main content
stephen5489
Associate
October 18, 2013
Question

Timer

  • October 18, 2013
  • 14 replies
  • 2614 views
Posted on October 18, 2013 at 04:13

Hi, I am makin a encoder interface on the et-arm stamp stm32, my problem is that maximun frequency I can get from the encoder is 30Hz and I just can measure at less 1190Hz (based in PWM_IN example) I am measuring the time betwen falling and rising voltage and this is my code. The code doesn't work could anyone please help me?

void RCC_ExIT_Configuration(void){

/* TIM2 clock enable */

 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

}

void GPIO_ExIT_Configuration(void){

//GPIO_InitTypeDef GPIO_InitStructure;

/* TIM2 channel 2 pin (PA.01) configuration */

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(GPIOA, &GPIO_InitStructure);

}

void EXTI_Exp(void)

{

    // System Clocks Configuration

    //

RCC_ExIT_Configuration();

    //

    // Configure the GPIO ports

    //

    GPIO_ExIT_Configuration();

    /* TIM2 configuration: PWM Input mode ------------------------

       The external signal is connected to TIM2 CH2 pin (PA.01),

       The Rising edge is used as active edge,

       The TIM2 CCR2 is used to compute the frequency value

       The TIM2 CCR1 is used to compute the duty cycle value

    ------------------------------------------------------------ */

    TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;

    TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;

    TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;

    TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;

    TIM_ICInitStructure.TIM_ICFilter = 0x0;

    TIM_PWMIConfig(TIM2, &TIM_ICInitStructure);

    /* Select the TIM2 Input Trigger: TI2FP2 */

    TIM_SelectInputTrigger(TIM2, TIM_TS_TI2FP2);

    /* Select the slave Mode: Reset Mode */

    TIM_SelectSlaveMode(TIM2, TIM_SlaveMode_Reset);

    TIM_SelectSlaveMode(TIM4, TIM_SlaveMode_Reset);

    /* Enable the Master/Slave Mode */

    TIM_SelectMasterSlaveMode(TIM2, TIM_MasterSlaveMode_Enable);

    /* TIM enable counter */

    TIM_Cmd(TIM2, ENABLE);

    /* Enable the CC2 Interrupt Request */

    //TIM_ITConfig(TIM2, TIM_IT_CC2 | TIM_IT_Trigger, ENABLE);

}

void TIM2_IRQHandler(void){

int IC2Value=0;

// Clear TIM2 Capture compare interrupt pending bit

//TIM_ClearITPendingBit(TIM2, TIM_IT_CC2);

if (TIM_GetITStatus(TIM2, TIM_IT_CC2)== SET){

if(count!=0){

// Get the Input Capture value

IC2Value = TIM_GetCapture2(TIM2);

if ((IC2Value != 0))

{

// Frequency computation

Frequency = SystemCoreClock / IC2Value;

count+=(1/Frequency);

//Frequency2 = SystemCoreClock / IC2Value2;

}

else

{

//DutyCycle = 0;

Frequency = 0;

//Frequency2 = 0;

}

TIM_ClearITPendingBit(TIM2, TIM_IT_CC2);

count=0;

}

}

else if(TIM_GetITStatus(TIM2, TIM_IT_Trigger)== SET){

count+=1/1190;

}

}

    This topic has been closed for replies.

    14 replies

    Tesla DeLorean
    Guru
    October 18, 2013
    Posted on October 18, 2013 at 05:03

    Not sure I can help you with this, the code doesn't look complete, there is a Format Code Block tool (Paintbrush [< >] icon) for pasting code into the forum, please use it. I'm also a bit confused about what supposed to be going on in the IRQ Handler.

    Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
    stephen5489
    Associate
    October 18, 2013
    Posted on October 18, 2013 at 05:36

    void RCC_ExIT_Configuration(void){
    /* TIM2 clock enable */
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
    }
    void GPIO_ExIT_Configuration(void){
    //GPIO_InitTypeDef GPIO_InitStructure;
    /* TIM2 channel 2 pin (PA.01) configuration */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    }
    void EXTI_Exp(void)
    {
    // System Clocks Configuration
    //
    RCC_ExIT_Configuration();
    //
    // Configure the GPIO ports
    //
    GPIO_ExIT_Configuration();
    /* TIM2 configuration: PWM Input mode ------------------------
    The external signal is connected to TIM2 CH2 pin (PA.01),
    The Rising edge is used as active edge,
    The TIM2 CCR2 is used to compute the frequency value
    The TIM2 CCR1 is used to compute the duty cycle value
    ------------------------------------------------------------ */
    TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;
    TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
    TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
    TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
    TIM_ICInitStructure.TIM_ICFilter = 0x0;
    TIM_PWMIConfig(TIM2, &TIM_ICInitStructure);
    /* Select the TIM2 Input Trigger: TI2FP2 */
    TIM_SelectInputTrigger(TIM2, TIM_TS_TI2FP2);
    /* Select the slave Mode: Reset Mode */
    TIM_SelectSlaveMode(TIM2, TIM_SlaveMode_Reset);
    /* Enable the Master/Slave Mode */
    TIM_SelectMasterSlaveMode(TIM2, TIM_MasterSlaveMode_Enable);
    /* TIM enable counter */
    TIM_Cmd(TIM2, ENABLE);
    /* Enable the CC2 Interrupt Request */
    //TIM_ITConfig(TIM2, TIM_IT_CC2 | TIM_IT_Trigger, ENABLE);
    }
    void TIM2_IRQHandler(void){
    int IC2Value=0;
    // Clear TIM2 Capture compare interrupt pending bit
    //TIM_ClearITPendingBit(TIM2, TIM_IT_CC2);
    if (TIM_GetITStatus(TIM2, TIM_IT_CC2)== SET){
    if(count!=0){
    // Get the Input Capture value
    IC2Value = TIM_GetCapture2(TIM2);
    if ((IC2Value != 0))
    {
    // Frequency computation
    Frequency = SystemCoreClock / IC2Value;
    count+=(1/Frequency);
    //Frequency2 = SystemCoreClock / IC2Value2;
    }
    else
    {
    //DutyCycle = 0;
    Frequency = 0;
    //Frequency2 = 0;
    }
    TIM_ClearITPendingBit(TIM2, TIM_IT_CC2);
    count=0;
    }
    }
    else if(TIM_GetITStatus(TIM2, TIM_IT_Trigger)== SET){
    count+=1/1190;
    }
    }

    and in the IRQ I'm trying to count how much times the timer overflow before that next rising or falling edge came. And why the code is incomplete?
    stephen5489
    Associate
    October 22, 2013
    Posted on October 22, 2013 at 14:04

    Clive, colud you please tell me what's the flag used in overflow?

    Tesla DeLorean
    Guru
    October 22, 2013
    Posted on October 22, 2013 at 15:46

    And why the code is incomplete?

    You use variables you don't define, and will not compile? Static analysis requires enough context to review the internal correctness, dynamic analysis requires it to run.

    Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
    stephen5489
    Associate
    October 22, 2013
    Posted on October 22, 2013 at 21:28

    #include ''stm32f10x_gpio.h''
    #include ''stm32f10x_rcc.h''
    #include ''stm32f10x_usart.h''
    #include ''stm32f10x_tim.h''
    #include ''stm32f10x_flash.h''
    #include ''misc.h''
    #include ''stm32f10x_exti.h''
    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
    TIM_ICInitTypeDef TIM_ICInitStructure;
    TIM_OCInitTypeDef TIM_OCInitStructure;
    GPIO_InitTypeDef GPIO_InitStructure;
    EXTI_InitTypeDef EXTI_InitStructure;
    #define EXTI9_5_IRQChannel ((u8)0x17)
    uint16_t PrescalerValue = 0;
    //int DutyCycle = 0;
    int Frequency = 0;
    int Frequency2 = 0;
    float count;
    void RCC_ExIT_Configuration(void){
    /* TIM2 clock enable */
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
    }
    void GPIO_ExIT_Configuration(void){
    //GPIO_InitTypeDef GPIO_InitStructure;
    /* TIM2 channel 2 pin (PA.01) configuration */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    }
    void EXTI_Exp(void)
    {
    // System Clocks Configuration
    //
    RCC_ExIT_Configuration();
    //
    // Configure the GPIO ports
    //
    GPIO_ExIT_Configuration();
    /* TIM2 configuration: PWM Input mode ------------------------
    The external signal is connected to TIM2 CH2 pin (PA.01),
    The Rising edge is used as active edge,
    The TIM2 CCR2 is used to compute the frequency value
    The TIM2 CCR1 is used to compute the duty cycle value
    ------------------------------------------------------------ */
    TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;
    TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
    TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
    TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
    TIM_ICInitStructure.TIM_ICFilter = 0x0;
    TIM_PWMIConfig(TIM2, &TIM_ICInitStructure);
    /* Select the TIM2 Input Trigger: TI2FP2 */
    TIM_SelectInputTrigger(TIM2, TIM_TS_TI2FP2);
    /* Select the slave Mode: Reset Mode */
    TIM_SelectSlaveMode(TIM2, TIM_SlaveMode_Reset);
    /* Enable the Master/Slave Mode */
    TIM_SelectMasterSlaveMode(TIM2, TIM_MasterSlaveMode_Enable);
    /* TIM enable counter */
    TIM_Cmd(TIM2, ENABLE);
    /* Enable the CC2 Interrupt Request */
    //TIM_ITConfig(TIM2, TIM_IT_CC2 | TIM_IT_Update, ENABLE);
    }

    void TIM2_IRQHandler(void){
    int IC2Value=0;
    // Clear TIM2 Capture compare interrupt pending bit
    //TIM_ClearITPendingBit(TIM2, TIM_IT_CC2);
    if (TIM_GetITStatus(TIM2, TIM_IT_CC2)== SET){
    if(count!=0){
    // Get the Input Capture value
    IC2Value = TIM_GetCapture2(TIM2);
    if ((IC2Value != 0))
    {
    // Frequency computation
    Frequency = SystemCoreClock / IC2Value;
    count+=(1/Frequency);
    //Frequency2 = SystemCoreClock / IC2Value2;
    }
    else
    {
    //DutyCycle = 0;
    Frequency = 0;
    //Frequency2 = 0;
    }
    TIM_ClearITPendingBit(TIM2, TIM_IT_CC2);
    count=0;
    }
    }
    else if(TIM_GetITStatus(TIM2, TIM_IT_Trigger)== SET){
    count+=1/1190;
    }
    }
    /*****************************************************************************************************/
    void Send_Data(void){
    extern char Data_Tx[31];
    extern int Frequency = 0;
    char *Tx=Data_Tx;
    extern float count;
    sprintf(Data_Tx, ''%s%f%c'', ''kk'', count, '#');
    GPIO_SetBits(LED_PORT,GPIO_Pin_10);
    while(*Tx){
    while(USART_GetFlagStatus(USART1, USART_FLAG_TXE)==RESET);
    USART_SendData(USART1, *Tx++);
    }
    while((USART_GetFlagStatus(USART1, USART_FLAG_TC)!=SET)){
    }
    GPIO_ResetBits(LED_PORT,GPIO_Pin_10);
    }

    code compile without any warning or error but it's not working just how I like to do, for example when the microprocessor send the ''count'' variable I just can see kk on hyperterminal. this is all the code I can gave you hope it being enough.
    Tesla DeLorean
    Guru
    October 22, 2013
    Posted on October 22, 2013 at 22:12

    What is the target frequency range you are looking to measure?

    Having the counter wrap is problematic, you might want to adjust the timebase, and consider if input capture would be and option instead of PWM capture.

    Most of the time you are writing zero to count, the only time it isn't is for a ''Trigger'' interrupt that is not enabled, and should probably be ''Update''

    72 MHz / 65536 is 1098.633

    Does %f work here? Do you have the right library linked? What's the tool chain?
    Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
    stephen5489
    Associate
    October 23, 2013
    Posted on October 23, 2013 at 18:48

    Does %f work here? Do you have the right library linked? What's the tool chain?

    the toolchain is arm-none-eabi-c++, about the library I use (#include <stdio.h>) and I'm sure it works because I used the same function before for send different variables e.g int, char and string.

    What is the target frequency range you are looking to measure?

    the frequency range I'm capturing is 14-30Hz.

    Most of the time you are writing zero to count, the only time it isn't is for a ''Trigger'' interrupt that is not enabled, and should probably be ''Update''

    About those mistakes in the code, you were totaly right I changed the code but it still doesn't works.

    I going to try make it by input capture instead PWM capture, and could you please explain what do you mean about? (Having the counter wrap is problematic) I don't understand it

    Tesla DeLorean
    Guru
    October 23, 2013
    Posted on October 23, 2013 at 19:02

    The counter is 16-bit wide, you have it clocking at 72 MHz, it will wrap ~1100 times a second.

    You might want to configure the time base to something more appropriate for the range you wish to measure. Perhaps 500 KHz?

    14 Hz would be ~35714 ticks, 30 Hz would be ~16667 ticks

    Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
    stephen5489
    Associate
    October 25, 2013
    Posted on October 25, 2013 at 02:34

    Hi Clive.

    I've been programming and change the configuration from PWM input to input capture but I still can't get it works. what I need is measure the frequency of a input square signal which can have any frequency in a range from 15 to 30 hz. below I'll show you how I configured timer and handler funtion.

    
    void
    RCC_ExIT_Configuration(
    void
    ){
    
    
    /* TIM2 clock enable */
    
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
    
    }
    
    
    void
    GPIO_ExIT_Configuration(
    void
    ){
    
    
    //GPIO_InitTypeDef GPIO_InitStructure;
    
    
    /* TIM2 channel 2 pin (PA.01) configuration */
    
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
    
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    
    
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    
    
    
    }
    
    
    void
    NVIC_TimeConfiguration(
    void
    )
    
    {
    
    NVIC_InitTypeDef NVIC_InitStructure;
    
    
    //
    
    // Enable the TIM2_HandlerIRQ Interrupt
    
    //
    
    NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
    
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
    
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    
    NVIC_Init(&NVIC_InitStructure);
    
    }
    
    
    void
    EXTI_Exp(
    void
    )
    
    {
    
    
    // System Clocks Configuration
    
    //
    
    RCC_ExIT_Configuration();
    
    
    //
    
    // Configure the GPIO ports
    
    //
    
    GPIO_ExIT_Configuration();
    
    
    NVIC_TimeConfiguration();
    
    
    /* Time base configuration */
    
    TIM_TimeBaseStructure.TIM_Period = 0xffff;
    
    TIM_TimeBaseStructure.TIM_Prescaler = 0xffff;
    
    TIM_TimeBaseStructure.TIM_ClockDivision = 0;
    
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    
    
    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
    
    
    TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;
    
    TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
    
    TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
    
    TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
    
    TIM_ICInitStructure.TIM_ICFilter = 0x0;
    
    
    TIM_ICInit(TIM2,&TIM_ICInitStructure);
    
    
    /* Select the TIM2 Input Trigger: TI2FP2 */
    
    TIM_SelectInputTrigger(TIM2, TIM_TS_TI2FP2);
    
    
    /* Select the slave Mode: Reset Mode */
    
    TIM_SelectSlaveMode(TIM2, TIM_SlaveMode_Reset);
    
    
    /* Enable the Master/Slave Mode */
    
    TIM_SelectMasterSlaveMode(TIM2, TIM_MasterSlaveMode_Enable);
    
    
    /* TIM enable counter */
    
    TIM_Cmd(TIM2, ENABLE);
    
    
    /* Enable the CC2 Interrupt Request */
    
    TIM_ITConfig(TIM2, TIM_IT_CC2 | TIM_IT_Update, ENABLE);
    
    }
    
    
    
    void
    TIM2_IRQHandler(
    void
    ){
    
    
    int
    IC2Value=0;
    
    
    if
    (TIM_GetITStatus(TIM2, TIM_IT_Update)==SET){
    
    count+=1/163;
    
    TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
    
    }
    
    else
    if
    (TIM_GetITStatus(TIM2, TIM_IT_CC2)==SET){
    
    IC2Value = TIM_GetCapture2(TIM2);
    
    if
    ((IC2Value != 0))
    // | (IC2Value2 != 0))
    
    {
    
    // Frequency computation
    
    Frequency = SystemCoreClock / IC2Value;
    
    count+=1/Frequency;
    
    }
    
    else
    
    {
    
    Frequency = 0;
    
    }
    
    TIM_ClearITPendingBit(TIM2, TIM_IT_CC2);
    
    }
    
    }
    
    
    void
    Send_Data(
    void
    ){
    
    
    extern
    char
    Data_Tx[31];
    
    char
    *Tx=Data_Tx;
    
    
    sprintf(Data_Tx, 
    ''%s%0.4f%c''
    , 
    ''kk''
    , count, 
    '#'
    );
    
    GPIO_SetBits(LED_PORT,GPIO_Pin_10);
    
    while
    (*Tx){
    
    while
    (USART_GetFlagStatus(USART1, USART_FLAG_TXE)==RESET);
    
    USART_SendData(USART1, *Tx++);
    
    }
    
    while
    ((USART_GetFlagStatus(USART1, USART_FLAG_TC)!=SET)){
    
    }
    
    GPIO_ResetBits(LED_PORT,GPIO_Pin_10);
    
    }

    and I replaced the toolchain fromarm-none-eabi-gcc-4.5.1 toarm-none-eabi-gcc-4.6.2 From: clive1 Posted: Wednesday, October 23, 2013 7:02 PM Subject: Timer

    The counter is 16-bit wide, you have it clocking at 72 MHz, it will wrap ~1100 times a second.

    You might want to configure the time base to something more appropriate for the range you wish to measure. Perhaps 500 KHz? 14 Hz would be ~35714 ticks, 30 Hz would be ~16667 ticks
    Tesla DeLorean
    Guru
    October 25, 2013
    Posted on October 25, 2013 at 17:16

    Ok, that's pretty hopeless, try this, it's a complete worked example, adapt to the specifics of your board.

    // STM32 VLDiscovery TIM2 Frequency Measurement 18-30 Hz - sourcer32@gmail.com
    #include <
    stdio.h
    >
    #include ''stm32F10x.h''
    /**************************************************************************************/
    void USART_Configuration(void)
    {
    GPIO_InitTypeDef GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    /* Configure USART Tx as alternate function push-pull */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; // PA.09 USART1.TX
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    /* Configure USART Rx as input floating */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; // PA.10 USART1.RX
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    /* USART resources configuration (Clock, GPIO pins and USART registers) ----*/
    /* USART configured as follow:
    - BaudRate = 115200 baud
    - Word Length = 8 Bits
    - One Stop Bit
    - No parity
    - Hardware flow control disabled (RTS and CTS signals)
    - Receive and transmit enabled
    */
    USART_InitStructure.USART_BaudRate = 115200;
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    USART_InitStructure.USART_StopBits = USART_StopBits_1;
    USART_InitStructure.USART_Parity = USART_Parity_No;
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
    /* Enable UART clock */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
    /* USART configuration */
    USART_Init(USART1, &USART_InitStructure);
    /* Enable the USART1 */
    USART_Cmd(USART1, ENABLE);
    }
    /**************************************************************************************/
    void USART_PutString(char *s)
    {
    while(*s)
    {
    while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
    USART_SendData(USART1, *s++);
    }
    while((USART_GetFlagStatus(USART1, USART_FLAG_TC) != SET));
    }
    /**************************************************************************************/
    void NVIC_Configuration(void)
    {
    NVIC_InitTypeDef NVIC_InitStructure;
    NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
    }
    /**************************************************************************************/
    void TIM2_Configuration(void)
    {
    GPIO_InitTypeDef GPIO_InitStructure;
    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
    TIM_ICInitTypeDef TIM_ICInitStructure;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; // PA1 TIM2_CH2
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    TIM_TimeBaseStructure.TIM_Prescaler = (uint16_t)(SystemCoreClock / 500000) - 1; // 500 KHz Time Base
    TIM_TimeBaseStructure.TIM_Period = 65535; // Maximal
    TIM_TimeBaseStructure.TIM_ClockDivision = 0;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
    TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;
    TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
    TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
    TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
    TIM_ICInitStructure.TIM_ICFilter = 0x0;
    TIM_ICInit(TIM2, &TIM_ICInitStructure);
    TIM_Cmd(TIM2, ENABLE);
    /* Enable the CC2 Interrupt Request */
    TIM_ITConfig(TIM2, TIM_IT_CC2, ENABLE);
    }
    /**************************************************************************************/
    volatile uint16_t TIM2CH2Measurement = 0;
    void TIM2_IRQHandler(void)
    {
    if (TIM_GetITStatus(TIM2, TIM_IT_CC2) == SET)
    {
    static uint16_t ICValue1 = 0, ICValue2 = 0;
    static int CaptureNumber = 0;
    TIM_ClearITPendingBit(TIM2, TIM_IT_CC2);
    if (CaptureNumber == 0)
    {
    ICValue1 = TIM_GetCapture2(TIM2);
    CaptureNumber = 1;
    }
    else
    {
    ICValue2 = TIM_GetCapture2(TIM2);
    TIM2CH2Measurement = ICValue2 - ICValue1; // Delta Ticks @ 500 KHz
    ICValue1 = ICValue2;
    }
    }
    }
    /**************************************************************************************/
    void TIM3_Configuration(void)
    {
    GPIO_InitTypeDef GPIO_InitStructure;
    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
    TIM_OCInitTypeDef TIM_OCInitStructure;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO, ENABLE); // AFIO required for remapping
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; // PC6 TIM3_CH1
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
    GPIO_Init(GPIOC, &GPIO_InitStructure);
    GPIO_PinRemapConfig(GPIO_FullRemap_TIM3, ENABLE);
    TIM_TimeBaseStructure.TIM_Prescaler = (uint16_t)(SystemCoreClock / 1000000) - 1; // 1 MHz Time Base
    TIM_TimeBaseStructure.TIM_Period = (uint16_t)(1000000 / 20) - 1; // 20 Hz
    TIM_TimeBaseStructure.TIM_ClockDivision = 0;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
    // channel 1 configuration (PC.06) Remapped
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_Pulse = (TIM_TimeBaseStructure.TIM_Period + 1) / 2; // 50% Duty
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
    TIM_OC1Init(TIM3, &TIM_OCInitStructure);
    TIM_Cmd(TIM3, ENABLE);
    }
    /**************************************************************************************/
    void GPIO_Configuration(void)
    {
    GPIO_InitTypeDef GPIO_InitStructure;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; // PC.08 BLUE LED
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOC, &GPIO_InitStructure);
    }
    /**************************************************************************************/
    int main(void)
    {
    USART_Configuration(); // For DEBUG
    NVIC_Configuration();
    TIM2_Configuration(); // Measurement Channel
    TIM3_Configuration(); // Test Source
    GPIO_Configuration(); // LED
    while(1) // Infinite Loop
    {
    char String[30];
    while(TIM2CH2Measurement == 0); // Wait for measurement
    sprintf(String, ''%7.4lf Hz
    '', 500000.0 / (double)TIM2CH2Measurement); // 500 KHz Ticks
    GPIO_SetBits(GPIOC, GPIO_Pin_8); // BLUE LED
    USART_PutString(String);
    GPIO_ResetBits(GPIOC, GPIO_Pin_8);
    TIM2CH2Measurement = 0; // Clear measurement
    }
    }

    Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..