2021-01-01 11:42 AM
HI,
So I cannot seem to get the time base that I expect out of Timer 6. I have got timer working wiht the right freqnecy however I cannot seem to get timer 6 to work at the expected freqency. It seems to be running twice as fast to what I set it to.
I am running a 16 MHz internal, in the diagram attached you should find the rest of the RCC settings.
This is the code that goes with that diagram. I have checked it and it should all be good but maybe I missed something.
RCC->CR |= RCC_CR_HSEON; //HSE on
while((RCC->CR & RCC_CR_HSERDY) != RCC_CR_HSERDY); // Waiting for HSE to be ready
RCC->CR &= ~RCC_CR_PLLON; // Disable PLL
while((RCC->CR & RCC_CR_PLLRDY)== RCC_CR_PLLRDY); // Wait for pll to turn off
RCC->CFGR = RCC_CFGR_PLLSRC_HSE_PREDIV | RCC_CFGR_PLLMUL9 | RCC_CFGR_HPRE_DIV1 | RCC_CFGR_PPRE1_DIV2 | RCC_CFGR_PLLXTPRE_HSE_PREDIV_DIV2;//PLLSCR = HSE/2 , PLLMUL = x9 (72Mhz),AHB prescaler not devided, APB1 Clock /2 = 36MHz (Max=36MHz)
RCC->CR |= 0x01000000; // Turn on PLL on
while((RCC->CR & RCC_CR_PLLRDY) != RCC_CR_PLLRDY); // Waiting for PLL to be ready
FLASH->ACR |= FLASH_ACR_LATENCY_1; // Adjust flash speed for new frequency
RCC->CFGR |= RCC_CFGR_SW_PLL; // Set PLL as system clock
while((RCC->CFGR & RCC_CFGR_SWS_PLL) != RCC_CFGR_SWS_PLL); // Wait fpr pll to be used as system clock
RCC->CR &= ~RCC_CR_HSION; //Turning of HSI
while((RCC->CR & RCC_CR_HSIRDY) == RCC_CR_HSIRDY); // Wait for HSI to be off
This is the code for TIMER 6
RCC->APB1ENR |= RCC_APB1ENR_TIM6EN; // Enabling timer 6 clock, running at 72 MHz
TIM6->CR1 |= TIM_CR1_URS ; // Only Counter Overflow/Underflow generates an update interrupt or DMA reqwst
TIM6->PSC = 65535; // 72 MHz / 65535+1 = 1098.6 Hz = CK_CNT = Max output freuqnecy
TIM6->ARR = 101;
TIM6->DIER |= TIM_DIER_UIE; // TIM6 update interrupt enabled
NVIC_EnableIRQ(TIM6_DAC_IRQn); // enabling TIM6 global and DAC underrun error Interrupt
TIM6->CR1 |= TIM_CR1_CEN; // TIM6 Clock Enable
According to this, I should have a 72 MHz clock / 65536 = CK_CNT = 1098 Hz / 101 ticks =10.87 Hz
I then have an interrupt whihc goes through the values of a lookup table with 101 samples. Therefore = 10.87 Hz /101 = 0.1076 Hz =9.29 s. I however seem to be running twice as fast through this.
void TIM6_DAC_IRQHandler(void)
{
//Duty Cycles
TIM1->CCR1 = tableU[i];
TIM1->CCR2 = tableV[i];
TIM1->CCR3 = tableW[i];
i++;
//if we reached end of array
if (i == 101)
{
i = 0;
}
TIM6->SR = ~TIM_SR_UIF; // Clear interrupt
}
Can anyone spot any obvious errors?
Cheers
GG
Solved! Go to Solution.
2021-01-01 02:42 PM
This is probably the late interrupt clear problem. Move
> TIM6->SR = ~TIM_SR_UIF; // Clear interrupt
to the beginning of the ISR.
JW
2021-01-01 12:11 PM
Well your timer can't be running faster than the core clock. How are you measuring the frequency? Is UIF set every time the interrupt fires? Seems like you may be running the DAC as well, which may be firing the interrupt.
> According to this, I should have a 72 MHz clock / 65536 = CK_CNT = 1098 Hz / 101 ticks =10.87 Hz
Note that the frequency is timer clock / (PSC + 1) / (ARR + 1), not simply ARR. Counter starts at 0. This wouldn't explain things, of course.
2021-01-01 01:20 PM
So I'm generating a sine wave via the look up table. I am using a scope on peak detect and measuring from the first pulse of the sine wave which then does the positive half cyle then is low for the negative half cyle as the complemnary is high then it goes high again to start the positive half cycle again. So I am measuring the time between the 2 high points i.e. one cycle
2021-01-01 01:41 PM
2021-01-01 02:42 PM
This is probably the late interrupt clear problem. Move
> TIM6->SR = ~TIM_SR_UIF; // Clear interrupt
to the beginning of the ISR.
JW
2021-01-01 02:45 PM
> Well your timer can't be running faster than the core clock.
Actually, in 'F3, it can, (up to) twice the core clock, i.e. 144MHz. Not TIM6, and it's not the case here, but I thought this is an interesting piece of information.
JW
@TDK
2021-01-02 02:02 AM
Thanks to both of you for your help.
Jan, you were spot on. I am clearing the interrupt flag first thing in the ISR adn this fixed my issue.
Nice to know of this little quirk
Cheers
Glenn