cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F4 TIMER INTERRUPT NOT HAPPENİNG

yasinbjk50
Associate III

Hı everyone, ı was trying to design basic timer project in register level about toggling on related led pin every 1 second. However, the led is on a few seconds after that it is off and never becoming on. When ı do the same project in HAL library, it worked well. By the way, I use APB1 as 84 MHz. Is there anything i missed out ?

 

 

/* Includes */
#include "stm32f4xx.h"
#include "stm32f4_discovery.h"

void RCC_Config()
{
	RCC->CR |= 0x00030000;										// HSEON and HSEONRDY enable
	while(!(RCC->CR & 0x00020000));								// HSEON Ready Flag wait
	RCC->CR |= 0x00080000;										// CSS Enable
	RCC->CR |= 0x01000000;										// PLL ON
	RCC->PLLCFGR |= 0x00400000;									// PLL e HSE seçtik
	RCC->PLLCFGR |= 0x00000004;									// PLL M = 4
	RCC->PLLCFGR |= 0x00005A00;									// Pll N = 168
	RCC->PLLCFGR |= 0x00000000;									// PLL p = 2
	RCC->CFGR |= 0x00000000;									// AHB Prescaler = 1
	RCC->CFGR |= 0x00080000;									// APB2 Prescaler = 2
	RCC->CFGR |= 0x00001400;									// APB1 Prescaler = 4
	RCC->CIR |= 0x00080000;										// HSERDY Flag clear
	RCC->CIR |= 0x00800000;										// CSS Flag clear
}

void GPIO_Config()
{
	RCC->AHB1ENR |= 0x00000008; 		// GPIOD active
	GPIOD -> MODER |= 0x55000000;		// 12-13-14-15 output
	GPIOD->PUPDR = 0x00000000;			// no pull-up, pull-down

}


void TIM_Config()
{
	RCC->APB1ENR |= 1 << 0;		// TIM2 clock enable
	TIM2->CR1 |= 0 << 4;		// Counter mode is upcounter (DIR)
	TIM2->CR1 |= 0 << 5;		// Center aligned mode edge-aligned mode (CMS)
	TIM2->CR1 |= 0 << 8;		// Set the clock divisixon to 1 (CKD)
	//TIM2->CR1 |= 1 << 2;		// only under ve overflow generate interrupt
	TIM2->SMCR |= 0 << 0;		// Internal clock source (SMS)
	TIM2->EGR |= 1 << 0;		// Tımer Update Generation ( UG: Update generation)
	TIM2->DIER |= (1 << 0);
	TIM2->PSC |= 41999;			// 84000 MHz / (41999+1) = 2000 ( PSC[15:0]: Prescaler value) -> The counter clock frequency CK_CNT is equal to fCK_PSC / (PSC[15:0] + 1)
	TIM2->ARR |= 1999;			// 2000/2000 = 1 saniye => 1 saniyede bir 2000 (ARR=autoreload değeri) saydirmis oluruz.
	//TIM2->CR1 &= ~(1<<0);		// Tımer2 Counter Disable for now (CEN:Counter enable)
	TIM2->CR1 |= (1<<0);		//
}

void EXTI_Config()
{
	NVIC_EnableIRQ(TIM2_IRQn);
}


void TIM2_IRQHandler(void)
{

	if(TIM2->SR & (1<<0))
  	{
		TIM2->SR &= ~(1<<0);
		GPIOD->ODR ^= (1 << 12);
  	}
}

int main(void)
{
  RCC_Config();
  GPIO_Config();
  TIM_Config();
  EXTI_Config();

  while (1)
  {

  }
}


void EVAL_AUDIO_TransferComplete_CallBack(uint32_t pBuffer, uint32_t Size){
  /* TODO, implement your code here */
  return;
}


uint16_t EVAL_AUDIO_GetSampleCallBack(void){
  /* TODO, implement your code here */
  return -1;
}

 

1 ACCEPTED SOLUTION

Accepted Solutions
TDK
Guru

An easy way to figure it out is to compare the register values using HAL with the register values you're setting in your own program.

> TIM2->ARR |= 1999;

Don't use bit-wise modification here. If you want to set the value, set the value:

TIM2->ARR = 1999;

The default value for ARR is 0xFFFF, which means your statement has no effect and your timer is updating at 84 MHz / 42000 / 65536 = 0.03 Hz.

 

Also, using CMSIS defines will make your code a lot more readable and will cut down on typos. For example, instead of "TIM2->CR1 |= (1<<0);", do

TIM2->CR1 |= TIM_CR1_CEN;

 

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

View solution in original post

4 REPLIES 4
AA1
Senior II

It is missing enable global interrupts with __enable_irq().

 

gbm
Lead II

The errors in your code result from using magic numbers instead of bit names and using operators |=, &= instead of assignments. Without checking if the magic numbers are correct, I can easily see few problems.

1. ARR is set to 65535, so the timer period is > 32 s.

2. You reset the timer interrupt flag incorrectly, using &= instead of =. This works with your simple case but would cause problems if you use some other sources of timer interrupt.

3. PLL is enabled before setting the divisors. It's hard to guess what clock frequency will be used.

TDK
Guru

An easy way to figure it out is to compare the register values using HAL with the register values you're setting in your own program.

> TIM2->ARR |= 1999;

Don't use bit-wise modification here. If you want to set the value, set the value:

TIM2->ARR = 1999;

The default value for ARR is 0xFFFF, which means your statement has no effect and your timer is updating at 84 MHz / 42000 / 65536 = 0.03 Hz.

 

Also, using CMSIS defines will make your code a lot more readable and will cut down on typos. For example, instead of "TIM2->CR1 |= (1<<0);", do

TIM2->CR1 |= TIM_CR1_CEN;

 

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

thx the problem was below

TIM2->PSC |= 41999;
TIM2->ARR |= 1999;

 

these must have been what you explained

TIM2->PSC = 41999;
TIM2->ARR = 1999;