cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F767ZI Timer Interrupt

Mehmood Nurmohamed
Associate II
Posted on October 11, 2017 at 23:35

Hello,

I am having some difficulties wrapping my head around what's happening with my TIM3 interrupt.  I am creating a timer class for my application.  It needs a 1 microsecond resolution.  For some reason I can only achieve a 2 microsecond resolution.  I started with the STM32F7Cube TIM_Base example for this Nucleo board.  The system core clock is 216MHz.  I have hopefully followed the instructions for configuring the timer using the method from the MCU documentation:

Update_event = TIM_CLK/((PSC + 1)*(ARR + 1)*(RCR + 1))  

My code is as follows:

// Initialize TIMx peripheral as follows for a 1us tick (1MHz):

// + Period = SystemCoreClock/1000000 - 1

// + ClockDivision = 0

// + Counter direction = Up

TimHandle.Init.Period = (SystemCoreClock/TICK_RATE_HZ) - 1; // TICK_RATE_HZ = 1x10^6

TimHandle.Init.Prescaler = 0;

TimHandle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;

TimHandle.Init.CounterMode = TIM_COUNTERMODE_UP;

TimHandle.Init.RepetitionCounter = 0;

TimHandle.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;

if (HAL_TIM_Base_Init(&TimHandle) != HAL_OK)

{

/* Initialization Error */

Error_Handler();

}

//##-2- Start the TIM Base generation in interrupt mode ####################

if (HAL_TIM_Base_Start_IT(&TimHandle) != HAL_OK)

{

/* Starting Error */

Error_Handler();

}

0690X00000608aLQAQ.png

Many thanks in advance!

1 ACCEPTED SOLUTION

Accepted Solutions
Posted on October 17, 2017 at 21:13

If the clock runs at 108 MHz then the period needs to be 107 ie 108-1 to get to 1us (or 1 MHz)

Interrupting at MHz rates is not recommended, it will burn a ridiculous number of cycles, more so with HAL.

If you want clock signals, use the TIM to generate the signal in HW, not with interrupts.

1 MHz 0.5us width, Prescaler = 0, Period = 107, Pulse = 54 (50/50 Duty), PWM Mode

500 KHz 1us width, Prescaler = 0, Period = 215, Pulse = 108 (50/50 Duty), PWM Mode

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

View solution in original post

9 REPLIES 9
S.Ma
Principal
Posted on October 13, 2017 at 04:36

On a general note, check the top level clock tree feeding the timer block diagram to see if there is a div2 prescaler not shown at the timer block diagram level.

Joerg Wagner
Senior III
Posted on October 15, 2017 at 13:25

Like KIC8462852 EPIC2024278916 wrote, check the clock source.

But you measured 50% only of the period. So in your case it is 1/4 of the desired frequency

and not a div2 prescaler.

- Joerg -

Mehmood Nurmohamed
Associate II
Posted on October 16, 2017 at 19:58

0690X00000608NhQAI.png

Hello,

Thank you both for the analysis.  I took the existing example for TIM3 from the STM32CubeF7 example project and verified the clock source for TIM3.  In this case TIM3CLK = PCLK1*2 where PCLK1=HCLK/4.  Using that information TIM3CLK = HCLK/2 = SystemCoreClock/2.  For this target the SystemCoreClock is 216 MHz.  As a result TIM3CLK is 108 MHz.

Is there something I'm missing?  I've played with all sorts of permutations of the Prescaler and Period but can't seem to achieve the 1us period I need.  I even found a clock calculator from Mikroelectronica.  Their ARR and PSC values correspond with what I calculated (PSC = 0, ARR = 215) but I still don't have the right 1 us clock rate desired.

Many thanks for any other tips.

Joerg Wagner
Senior III
Posted on October 17, 2017 at 15:51

To reproduce I wrote a simple app with Timer 3 using your values.

This is my init code created with CubeMX:

/* TIM3 init function */

static void MX_TIM3_Init(void)

{

TIM_ClockConfigTypeDef sClockSourceConfig;

TIM_MasterConfigTypeDef sMasterConfig;

htim3.Instance = TIM3;

htim3.Init.Prescaler = 0;

htim3.Init.CounterMode = TIM_COUNTERMODE_UP;

htim3.Init.Period = 216;

htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;

htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;

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__);

}

}

To test the frequency:

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)

{

if (htim->Instance == TIM3) {

HAL_GPIO_TogglePin(dbgpin_GPIO_Port, dbgpin_Pin);

}

}

The results are in the attached PDF. Almost perfect.

What are you looking for?

________________

Attachments :

document.pdf : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006HyN0&d=%2Fa%2F0X0000000b6h%2FBb9RnZkSZliJLwuQCN6g9JoAnS9024K.aJpnbTzht8Y&asPdf=false
Mehmood Nurmohamed
Associate II
Posted on October 17, 2017 at 19:02

Hi Joerg,

Thank you for providing the report.  I too was able to get a 2us pulse width, originally.  My desire is to get a 1us resolution (ie pulse width).  If this is not possible then is there an explanation for that?  The best I can seem to do is this:

0690X00000608c3QAA.png

Many thanks for taking the time for your above analysis.

Posted on October 17, 2017 at 21:13

If the clock runs at 108 MHz then the period needs to be 107 ie 108-1 to get to 1us (or 1 MHz)

Interrupting at MHz rates is not recommended, it will burn a ridiculous number of cycles, more so with HAL.

If you want clock signals, use the TIM to generate the signal in HW, not with interrupts.

1 MHz 0.5us width, Prescaler = 0, Period = 107, Pulse = 54 (50/50 Duty), PWM Mode

500 KHz 1us width, Prescaler = 0, Period = 215, Pulse = 108 (50/50 Duty), PWM Mode

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on October 17, 2017 at 21:25

Hi Mehmooed, It is a 1us resolution!

When you toggle the state of a signal every 1us you will get the half of the frequency, 2us.

Do you need the signal for software events or an extenal signal? PWM like

Turvey.Clive.002

mentioned

is a better choice for external signal generation.

- Joerg-

Posted on October 17, 2017 at 22:35

Thank you to you both, Clive and Joerg.  Clive provided exactly the solution I am seeking:

500 KHz 1us width, Prescaler = 0, Period = 215, Pulse = 108 (50/50 Duty), PWM Mode

Posted on October 17, 2017 at 22:47

There is also a very useful YouTube video I found that explains how the PSC and ARR are assigned for a desired frequency:

https://www.youtube.com/watch?v=_3vDf2suINI