Strange values from HAL_TIM_ReadCapturedValue
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2020-09-18 10:00 AM
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:
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?
- Labels:
-
TIM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2020-09-18 2:50 PM
65535 - 62941 = 2594 ?
do you have the auto-reload set to 65535 - 2594 +1500 = 64441 = 0xFBB9 ?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2020-09-18 3:05 PM
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2020-09-18 3:53 PM
> 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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2020-09-18 10:11 PM
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...
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2020-09-18 10:13 PM
