Skip to main content
yang hong
Associate III
April 10, 2018
Question

timer 3 setting

  • April 10, 2018
  • 9 replies
  • 1533 views
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.

    This topic has been closed for replies.

    9 replies

    waclawek.jan
    Super User
    April 10, 2018
    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

    yang hong
    yang hongAuthor
    Associate III
    April 11, 2018
    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?

    waclawek.jan
    Super User
    April 11, 2018
    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

    henry.dick
    Associate II
    April 11, 2018
    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.

    yang hong
    yang hongAuthor
    Associate III
    April 13, 2018
    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?

    henry.dick
    Associate II
    April 13, 2018
    Posted on April 13, 2018 at 19:02

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