cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F302R8 TImer 6 Clock Speed / Time BAse

glenn0010
Associate III

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

1 ACCEPTED SOLUTION

Accepted Solutions

This is probably the late interrupt clear problem. Move

> TIM6->SR = ~TIM_SR_UIF; // Clear interrupt

to the beginning of the ISR.

JW

View solution in original post

6 REPLIES 6
TDK
Guru

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.

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

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

Work in steps. Disconnect the DAC and simply toggle a pin in the interrupt to convince yourself it's running at the right rate. Once that is solved, add in the DAC. Could be you're transferring 32 bits instead of 16 or something like that, or just have a factor of 2 mistake in the sine wave generation, or something similar. I don't think the bug is in the code you've provided.
If you feel a post has answered your question, please click "Accept as Solution".

This is probably the late interrupt clear problem. Move

> TIM6->SR = ~TIM_SR_UIF; // Clear interrupt

to the beginning of the ISR.

JW

> 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​ 

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