Skip to main content
Rogers.Gary
Senior II
December 17, 2018
Question

CubeMX Examples, Timers & No .ioc Files?

  • December 17, 2018
  • 3 replies
  • 2647 views

Hello:

I am trying to come to an understanding using timer configurations with CubeMX/HAL. I hope someone can point me in the right direction. This is specifically for timer capture, but is probably applicable to PWM generation, and/or PWM capture too. This is using the Nucleo-L476RG demo board.

In general, I am spinning my wheels on the relationship of these things that all seemingly affect the frequency of an interrupt an capture. In the newest CubeMX, there is an example in: "STM32Cube_FW_L4_V1.13.0\Projects\NUCLEO-L476RG\Examples\TIM\TIM_PWMInput"

In the readme file, it states that:

The minimum frequency value to measure is (TIM3 counter clock / CCR MAX)

                                        = (80 MHz)/ 65535

                                        = 1120 Hz

That's great. So what is the right way to change the required variables to count a frequency of, let's say, 100Hz? If someone gives me a specific example, that's great too, but I still have not become self-educated. Without a core understanding of the relationship of the variables, I may get it to work this time, but what about next time?

One of the most pressing issues is that ST has provided these examples, without the ".ioc" files - the CubeMX files - so a person can open it up and understand with the configuration parameters just how this file was generated. Why are they not given with the examples?

I have been using the STM32F4, and never used CubeMX to code gen on that processor. Yet, I was able to do this fairly easily, getting perfect sub-hz resolution on frequency counts. I look at the code, see how it is done, but cannot replicate it with the STM32L4. So far, I have had nothing but frustration trying to set up CubeMX to do the same thing. None of the clock parameters I change in "SystemClock_Config" seem to get correct results, but lots of spasmodic numbers.

So...please, hopefully someone from ST can answer my question (more like a frustrated plea right now) and help me to fully understand this. Are there example/training videos? I have not found any. Just a lot of segmented training videos that don't really help put it together to figure this out.

Thank you...

Gary

This topic has been closed for replies.

3 replies

raptorhal2
Lead
December 17, 2018

The example sets the timer counter prescaler to zero, so the 80 MHz is fed unchanged into the counter. Set the prescaler and counter preset value to get the frequency you need.

Cheers, Hal

Rogers.Gary
Senior II
December 17, 2018

Thanks for the answer, but pretty much what I said. That's a specific answer, but I am looking for more, as above.

1- Why do the examples not come with the CubeMX generator files (.ioc) ? Without these, it is difficult to understand the concept and specifics of how the person designing the example used CubeMX to get the code. ST wants people to use CubeMX, then why not provide these....I see others have noted this too.

Regarding your answer, which of the below is to be changed to get the frequency range, and what is the general concept or formula to determine what it should be for a value or range:

void SystemClock_Config(void)

{

 RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

 RCC_OscInitTypeDef RCC_OscInitStruct = {0};

 /* MSI is enabled after System reset, activate PLL with MSI as source */

 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI;

 RCC_OscInitStruct.MSIState = RCC_MSI_ON;

 RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_6;

 RCC_OscInitStruct.MSICalibrationValue = RCC_MSICALIBRATION_DEFAULT;

 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;

 RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_MSI;

 RCC_OscInitStruct.PLL.PLLM = 16;

 RCC_OscInitStruct.PLL.PLLN = 10;

 RCC_OscInitStruct.PLL.PLLR = 8;

 RCC_OscInitStruct.PLL.PLLP = 7;

 RCC_OscInitStruct.PLL.PLLQ = 8;

 if(HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)

 {

   /* Initialization Error */

   while(1);

 }

 /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2

    clocks dividers */

 RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);

 RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;

 RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;

 RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; 

 RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; 

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

 {

   /* Initialization Error */

   while(1);

 }

}

Thanks,

Gary

raptorhal2
Lead
December 17, 2018

I'm not a PWM expert, but from what I can see in the example, everything is in the main.c code. And, there is no need to change the system clock (which would affect everything) to get a lower frequency.

Take a look at the first figure in the General Timers section of the Reference Manual. It shows a timer counter prescalar register which can be used to generate lower frequency interrupts.

This is the code section in main.c that needs to be modified:

TimHandle.Init.Period           = 0xFFFF;

 TimHandle.Init.Prescaler        = 0;

 TimHandle.Init.ClockDivision    = 0;

 TimHandle.Init.CounterMode      = TIM_COUNTERMODE_UP;

 TimHandle.Init.RepetitionCounter = 0;

Check my math, but I believe the formula is:

Period * Prescalar = SysClock/Frequency

Usually the best solution is if Period and Prescaler are approximately equal, so 1000-1 and 800-1 should work well for 100 Hz.

Cheers, Hal

Rogers.Gary
Senior II
December 22, 2018

Hi,

Can anyone answer this question?

Why in the interrupt handler do I need to divide the return value by 799 to get the right frequency?

How can I accomplish this with modification of period and prescalar, if that is possible? Apparently it is supposed to be, but I cannot find values to accomplish this.

Gary