2022-12-31 03:24 PM
Good afternoon everyone....
I am trying to learn more about the stm32 and am using a nucleo L476 and an oscilloscope. In particular I want to understand more about the output compares of the timers. I have read many an app-note , user guide and data sheet regarding these and am now at the stage of testing stuff out.....I am running into complete confusion with respect to this...
I have a 26MHz clock with a prescaler of 26 -1 (should be a 1MHz Cnt clock). I have the ARR register loaded with 100 - 1 (should create an UIF event every 100us). I am using CubeMX to set this up. There are a few questions:
__HAL_TIM_ENABLE_IT(&htim3, TIM_IT_UPDATE);
The following below is my ISR.....My attempt was to have UIF interrupt me every 10khz (see above comment on this), turn the output on and arm the CCR with counter + 10. My thought was that after this expires (CNTR clock is 1MHz so my expectation was 10us later) I would get a CC1R interrupt and then clear the output using FORCED_ACTIVE and INACTIVE statements. There are a few things here:
void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef *htim)
{
if (htim == &htim3)
{
if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1)
{
if (__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC1))
{
__HAL_TIM_CLEAR_FLAG(htim, TIM_IT_CC1);
htim->Instance->SR &= ~TIM_SR_CC1IF;
htim->Instance->CCR1 = 0;
htim->Instance->CCMR1 = 0; //clears mode output bits --- freezes output
htim->Instance->CCMR1 |= TIM_OCMODE_FORCED_INACTIVE; //forces output to 0??
}
else if (__HAL_TIM_GET_FLAG(htim, TIM_FLAG_UPDATE))
{
__HAL_TIM_CLEAR_FLAG(htim, TIM_IT_UPDATE); //clear UIF Flag
htim->Instance->SR &= ~TIM_SR_UIF;
htim->Instance->CCR1 = htim->Instance->CNT + 10;
htim->Instance->CCMR1 = 0; //clears mode output bits --- freezes output
htim->Instance->CCMR1 |= TIM_OCMODE_FORCED_ACTIVE; //set output to 1 immediately
}
}
}
}
Solved! Go to Solution.
2023-01-05 01:25 AM
Yes, you are missing a lot.
The statement:
TIM->SR &= ~TIM_SR_UIF;
is actually executed as:
(1) temp = TIM->SR;
(2) temp &= ~TIM_SR_UIF;
(3) TIM->SR = temp;
where temp is an ARM processor register.
Now think what will happen if another timer event flag, like CC1IF, is set by timer hardware after (1) and before (3) is executed. This flag will be cleared by (3) because it has a value of 0 in temp and your software will have no chance to notice it being set - you will loose the CC1IF event in your ISR..
An old beginner's problem with STM32 timer flags... ;)