cancel
Showing results for 
Search instead for 
Did you mean: 

Strange values from HAL_TIM_ReadCapturedValue

iforce2d
Associate III

I'm using input capture with a 16 bit timer to read a 1.5ms pulse that occurs every 20ms. I can see on my scope that the input pulse conforms to this exactly. Here's the code for the interrupt callback:

uint16_t pwmVal0 =   0;
uint16_t pwmVal1 =   0;
uint16_t pwmLength = 0;
uint8_t whichEdge =  0;
 
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
	if ( htim == &htim3 && htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1 ) {
		if ( whichEdge == 0 ) {
			//HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET);
 
			pwmVal0 = HAL_TIM_ReadCapturedValue( htim, TIM_CHANNEL_1 );
			__HAL_TIM_SET_CAPTUREPOLARITY( htim, TIM_CHANNEL_1, TIM_INPUTCHANNELPOLARITY_FALLING );
			whichEdge = 1;
		}
		else {
			//HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);
 
			pwmVal1 = HAL_TIM_ReadCapturedValue( htim, TIM_CHANNEL_1 );
			__HAL_TIM_SET_CAPTUREPOLARITY( htim, TIM_CHANNEL_1, TIM_INPUTCHANNELPOLARITY_RISING );
			whichEdge = 0;
 
			pwmLength = pwmVal1 - pwmVal0;
		}
	}
}

Note the two commented lines. When I look at the pulses made by those on my scope, the detected waveform is exactly what I expect and is rock solid. So the interrupt is triggering just fine. The problem is that the values returned by HAL_TIM_ReadCapturedValue (and used to calculate my final goal value 'pwmLength') are only correct about 70% of the time. Here's the result:

0693W000004GTTAQA4.png

Every value in this array should be around 1500, but there are consistently values around 62941 showing up, with a regular repetition.

What's weird is I've used this method many times in the past with no such problems. Is it possible that the hardware is at fault maybe?

5 REPLIES 5
T J
Lead

65535 - 62941 = 2594 ?

do you have the auto-reload set to 65535 - 2594 +1500 = 64441 = 0xFBB9 ?

TDK
Guru

It's really unlikely that the hardware is at fault. I can't see any issues with the code you posted. You could define those variables as volatile but I doubt that's it.

If you feel a post has answered your question, please click "Accept as Solution".

> do you have the auto-reload set to 65535 - 2594 +1500 = 64441 = 0xFBB9 ?

No, to 4096.

And the "wrong" result comes exactly in 1500/4096*100% of cases, cca 37%.

The solution is called modulo arithmetics. There's also no need to use anything but the maximum ARR.

JW

PS Always start with stating, which STM32 is you question related to.

iforce2d
Associate III

Thanks for the tips, turns out you're correct.

Somehow despite spending almost 4 hours on this and double-checking everything a dozen times, I manage to miss this typo here every time I checked:

htim3.Init.Period = 0xfff-1;

It didn't help that I made the exact same typo in a second project I set up specifically to test the minimal case. I also noticed that when the pin was floating it would trigger interrupts at a similar rate to the 'wrong' values (50Hz possibly from mains AC?) which sent me down a pointless rabbit hole of suspecting hardware issues.

Anyway with the correct value of 0xffff-1 everything is fine. Maybe I shouldn't be coding so late into the night with a foggy brain...

The correct value is 0xFFFF, not 1 less than that.
If you feel a post has answered your question, please click "Accept as Solution".