cancel
Showing results for 
Search instead for 
Did you mean: 

timer 3 setting

yang hong
Associate II
Posted on April 10, 2018 at 20:15

Hello,

I am using STM32F429ZI, I would like to use timer 3 to generate a timer with high resolution something like 4000Hz  My Timer 3 setting is following:

static void MX_TIM3_Init(void)

{

TIM_ClockConfigTypeDef sClockSourceConfig;

TIM_MasterConfigTypeDef sMasterConfig;

htim3.Instance = TIM3;

htim3.Init.Prescaler = 419;

htim3.Init.CounterMode = TIM_COUNTERMODE_UP;

htim3.Init.Period =49;

htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;

htim3.Init.RepetitionCounter=0;

if (HAL_TIM_Base_Init(&htim3) != HAL_OK)

{

_Error_Handler(__FILE__, __LINE__);

}

sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;

if (HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig) != HAL_OK)

{

_Error_Handler(__FILE__, __LINE__);

}

sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;

sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;

if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)

{

_Error_Handler(__FILE__, __LINE__);

}

}

I use global interrupt event TIM3_IRQHandler to handle event update

void TIM3_IRQHandler(void)

{

/* USER CODE BEGIN TIM3_IRQn 0 */

/* USER CODE END TIM3_IRQn 0 */

HAL_TIM_IRQHandler(&htim3);

/* USER CODE BEGIN TIM3_IRQn 1 */

printf('timer 3 update: %d\n',timer_counter);

if (timer_counter>=10000)

{

HAL_TIM_Base_Stop_IT(&htim3);

}

else

{

HAL_GPIO_TogglePin(NOMIGBT_GPIO_PORT,NOMIGBT_PIN);

__HAL_TIM_CLEAR_FLAG(&htim3,TIM_IT_UPDATE);

timer_counter++;

}

/* USER CODE END TIM3_IRQn 1 */

}

I trigger digital output to verify my timer. It looks my timer locked by 3Hz. Does anybody knows what is happen?

Thank you so much.

9 REPLIES 9
Posted on April 10, 2018 at 23:29

- verify your system clock is set as you expect, outputting it to MCO

- read out and check/post the timer registers content

JW

Posted on April 11, 2018 at 21:17

Hello, 

I did some bug and get system clock information as followed:

0690X0000060AYgQAM.png

Do you think it is ok?

henry.dick
Senior II
Posted on April 11, 2018 at 23:17

You are doing a slow task (print) from within the isr.

Make the isr as short as possible and see where you go from there.

Posted on April 11, 2018 at 21:31

I don't know. There are too many things that may go wrong between setting a structure and actually having the regsiters set up - including the oscillator may be running or not.

Why don't you output the system clock onto a MCO pin, and measure it? That's a sure way to know what is its frequency.

JW

Posted on April 13, 2018 at 18:21

Hello, 

I have simplified the isq code, so now only toggle output, it looks faster now, but it is still slower than what I want. I did some calculations, for example, prescale=29 and autoload=30, I got 8.5khz output, so it looks I have 8MHz timer clock. it is pretty strange because I thought I should have APB1 (84MHz). I am using NUCLEO-F429ZI and I use STM32CUBEMX to generate a code for my demo project. 

I read systme clock, hclk, pclk1 and pclk2 frequency. all of them are 16M. 

I attach my system clock code below:

void SystemClock_Config(void)

{

RCC_OscInitTypeDef RCC_OscInitStruct;

RCC_ClkInitTypeDef RCC_ClkInitStruct;

/**Configure the main internal regulator output voltage

*/

__HAL_RCC_PWR_CLK_ENABLE();

__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

/**Initializes the CPU, AHB and APB busses clocks

*/

RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;

RCC_OscInitStruct.HSIState = RCC_HSI_ON;

RCC_OscInitStruct.HSICalibrationValue = 16;

RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;

RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;

RCC_OscInitStruct.PLL.PLLM = 8;

RCC_OscInitStruct.PLL.PLLN = 168;

RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;

RCC_OscInitStruct.PLL.PLLQ = 7;

if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)

{

_Error_Handler(__FILE__, __LINE__);

return ;

}

/**Initializes the CPU, AHB and APB busses clocks

*/

RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK

|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;

RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;

RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;

RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;

RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;

RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;

if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)

{

_Error_Handler(__FILE__, __LINE__);

return;

}

/**Configure the Systick interrupt time

*/

HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);

/**Configure the Systick

*/

HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);

/* SysTick_IRQn interrupt configuration */

HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);

}

void TIM3_IRQHandler(void)

{

TIM3->SR &= ~(TIM_SR_UIF);

NOMIGBT_GPIO_PORT->ODR ^= NOMIGBT_PIN;

}

What I want is to set one timer for 1 micro second interval (this interval is the best I want, of course, if it is impossible, I can have 10 micro second or 5 micro second), every 1 micro second to trigger interrupt timer event, then according to preset timing to trigger on/off some digital outputs. Do I need use assemble program for fast irq event?

Posted on April 13, 2018 at 19:02

Sure, so long as you make sure that the isr is quick and short.

Posted on April 13, 2018 at 19:42

right now, I only have 1/10 interrupt frequency I need, for example, I suppose to have 600Hz, I only get 60Hz, my sysclk, hclk, plclk1, and plclk2 are the same value, 160M. Do you think it is correct?

Posted on April 13, 2018 at 20:05

If your system clock is 160Mhz and you want to get 600hz interrupt, use a Pressler to decide down the clock and then set the period or output match. 

So take a look at your timer and pick the right Pressler and period register or compare register and go from there.

Posted on April 13, 2018 at 21:47

Hello, 

Thank you for your reply. I regenerate code from stm32cubemax, it seems working now.