0

I am working on a small project which utilizes STM32F411RE. I am applying input pulses at a frequency of 100 Hz and am also measuring the applied pulses using a scope. My aim is to initiate a General Purpose Timer counter upon the detection/rising edge of the input pulse and stop the timer's counter upon the falling edge of the same pulse. I have everything configured and programmed accordingly. I am adding my code for everyone's reference:

Before that, This is my configuration in CubeMx: Clock Configuration = 80 MHz Internal Clock Division = 1 ( APB1 = APB2 = 80 MHz) TIM 2 enabled and sourced with the Internal clock.

I implemented this code and tried looking for formulas but everywhere they mention different formulas which leaves me in a confused state.

volatile uint32_t timerCountValue = 0;
uint32_t currentValue = 0;
uint32_t timeDifference = 0;
uint32_t counterMaxValue = 4294967295; //Timer's Counter max value

void HAL_GPIO_EXTI_Callback( uint16_t GPIO_Pin )
{
    if( GPIO_Pin == GATE1_Pin )
    {
        if( HAL_GPIO_ReadPin( GATE1_GPIO_Port, GATE1_Pin ) == GPIO_PIN_SET )
        {
            HAL_TIM_Base_Start( &htim2 );
            timerCountValue = TIM2->CNT;
            while( HAL_GPIO_ReadPin( GATE1_GPIO_Port, GATE1_Pin ) == GPIO_PIN_SET )
            {
                if( HAL_GPIO_ReadPin( GATE1_GPIO_Port, GATE1_Pin ) == GPIO_PIN_RESET )
                {
                    HAL_TIM_Base_Stop( &htim2 );
                    currentValue = TIM2->CNT;
                    break;
                }
            }
        }
        //Calculate the time difference
        if( currentValue >= timerCountValue )
        {
            timeDifference = currentValue - timerCountValue;
        }
        else
        {
            timeDifference = counterMaxValue - timerCountValue + currentValue + 1;
        }
    }
}

Now, based on the attached code, I do get some value inside the 'timeDifference' variable. But how do I validate if the value stored inside the 'timeDifference' variable matches with the pulse width value which I see on the scope.

From the Scope : Pulse width (fall time - rise time) = 4.16ms From the code : Timer counter value (timeDifference variable) holds 15764 then in the second instance holds 61454 and the value keeps on fluctuating.

Can someone please help me understand the conversion and validation part of this project? Also, how to calculate a good prescaler value? Currently I have set my Prescaler value to 39999 but not sure how to properly calculate it. Please advise.

Clifford
  • 88,407
  • 13
  • 85
  • 165
  • 80MHz divided by (39999+1) is 2000, i.e. two ticks per ms. That should yield results in timeDifference around 8; 15764 means around 8 seconds and 61454 around 30 seconds. How exactly do you observe timeDifference? Do you have some breakpoints set in the above code? – wek Aug 28 '23 at 22:16
  • If you expect others to read your code, it would be useful (to your aim) to format it conventionally with indentation. – Clifford Aug 29 '23 at 09:12
  • ... never mind - fixed it for you. – Clifford Aug 29 '23 at 09:20
  • @Clifford stack overflow made me remove the indentations. Sorry about that, this is my very first post and thank you for the indentations. – Ariarikta Aug 29 '23 at 23:52
  • @wek I am thinking of using the timer in output compare and then monitor it using a logic analyzer. – Ariarikta Aug 29 '23 at 23:53
  • Re SO removing indent - nonsense - not if you use the correct mark-up. – Clifford Aug 30 '23 at 22:12

1 Answers1

1

As the counter is a 32-bit, your timeDifference is unnecessarily over-complicated.

//Calculate the time difference
uint32_t timeDifference = currentValue - timerCountValue;

will work due to modulo-2 arithmetic. See How to deal with a wrapping counter in embedded C

HAL_GPIO_EXTI_Callback() is an interrupt handler, but your code has a busy-wait loop unsuited to interrupt handling. Your handler should run to completion quickly and deterministically with no delays or busy-wait loops. The handler in this case should operate as a state-machine, using a static flag or state variable to indicate whether it is waiting for the start or end of the pulse.

Your method of pulse capture is in any event sub-optimal. The timer hardware has input-capture capability where the timer/counter can be gated directly by a GPIO input, allowing the pulse to be measured directly (and accurately) with no software overhead. See https://controllerstech.com/input-capture-in-stm32/ for an example of pulse measurement using input-capture.

Clifford
  • 88,407
  • 13
  • 85
  • 165
  • Yes, over the period of time I realized I incorrectly implemented the callback function. I have fixed it and now I could see pulses getting generated at the output but it is just that they ain't synced with the input pulses. I will still look into the link you have shared. Thanks a lot for that! – Ariarikta Aug 29 '23 at 23:55
  • @Ariarikta cannot comment on your "corrected" code since you have not provided it. Post a new question with the new code. This has an answer now, so it would be bad form to change the question. It is not clear what you mean by "_ain't synced_". The code you presented is flawed probably in more ways than I have addressed, but it was so far from working, and also not the most appropriate solution, it seems pointless to address those issues. – Clifford Aug 30 '23 at 22:19