cancel
Showing results for 
Search instead for 
Did you mean: 

stm32f051 discovery systick inaccurate

Jo-Jo Smith
Associate II
Posted on September 16, 2017 at 02:34

I need a timer that is accurate to 1us for a project I am working on. I bought some stm32f051 discovery boards to get going. I noticed all the timers seemed to be slow by about 0.75% (I checked them with a scope). That means I lose 7.5ms every second, which is huge for a real-time system. I tried to set-up a 1ms systick, and that is slow also.

I got the systick timer example working from the STM32F0-Discovery peripheral examples and changed the main loop as follows:

while (1)

  {

    /* Toggle LED4 */

    STM_EVAL_LEDToggle(LED4);

    /* Insert 50 ms delay */

    Delay(500);

    /* Toggle LED3 */

    //STM_EVAL_LEDToggle(LED3);

    /* Insert 100 ms delay */

    //Delay(500);

  }

The LED is blinking slow by the same amount, so I don't think it's my firmware.

I thought something might be wrong with my board, so I tried the same project on a different board, and that one is even slower. It is off by about 0.85%, so I don't think it's the board either.

Can anyone tell me why the boards all run so slow even when I use STMicro's systick example?

1 ACCEPTED SOLUTION

Accepted Solutions
Jo-Jo Smith
Associate II
Posted on September 18, 2017 at 22:50

I figured out what was wrong with my code. I'll post it here in case anyone else runs into this.

The example uses the internal RC oscillator, which isn't very accurate, of course. There is a macro called PLL_SOURCE_HSI in system_stm32f0xx.c which selects the RC oscillator as the clock source. There are two other macros right under it that you can use to select the more accurate HSE or HSE bypass.

View solution in original post

5 REPLIES 5
AvaTar
Lead
Posted on September 18, 2017 at 11:22

I noticed all the timers seemed to be slow by about 0.75% (I checked them with a scope).

You are running the core from HSI, which is based on a RC oscillator ?

It would be helpful to present the clock initialization code.

...

The LED is blinking slow by the same amount, so I don't think it's my firmware.

I cannot see any specific relation to SysTick in your main code, or how the error is supposed to depend on the SysTick.

Perhaps you can enlighten us what you mean.

Posted on September 18, 2017 at 19:13

 ,

 ,

Thanks for the reply.

If you read my post again, I state that I am using STM's example code that can be downloaded from their site. I didn't write it. STM wrote it.

Here it is in full:

/**

 ,

 , ******************************************************************************

 ,

 , * @file , , , SysTick/main.c

 ,

 , * @author , MCD Application Team

 ,

 , * @version V1.0.0

 ,

 , * @date , , , 23-March-2012

 ,

 , * @brief , , Main program body

 ,

 , ******************************************************************************

 ,

 , * @attention

 ,

 , *

 ,

 , * <,h2>,<,center>,&,copy, COPYRIGHT 2012 STMicroelectronics<,/center>,<,/h2>,

 ,

 , *

 ,

 , * Licensed under MCD-ST Liberty SW License Agreement V2, (the 'License'),

 ,

 , * You may not use this file except in compliance with the License.

 ,

 , * You may obtain a copy of the License at:

 ,

 , *

 ,

 , * , , , , , , ,

https://community.st.com/external-link.jspa?url=http%3A%2F%2Fwww.st.com%2Fsoftware_license_agreement_liberty_v2

 ,

 , *

 ,

 , * Unless required by applicable law or agreed to in writing, software

 ,

 , * distributed under the License is distributed on an 'AS IS' BASIS,

 ,

 , * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

 ,

 , * See the License for the specific language governing permissions and

 ,

 , * limitations under the License.

 ,

 , *

 ,

 , ******************************************************************************

 ,

 , */

/* Includes ------------------------------------------------------------------*/

 ,

♯ include 'main.h'

/** @addtogroup STM32F0_Discovery_Peripheral_Examples

 ,

 , * @{

 ,

 , */

/** @addtogroup SysTick_Example

 ,

 , * @{

 ,

 , */

/* Private typedef -----------------------------------------------------------*/

 ,

/* Private define ------------------------------------------------------------*/

 ,

/* Private macro -------------------------------------------------------------*/

 ,

/* Private variables ---------------------------------------------------------*/

 ,

GPIO_InitTypeDef GPIO_InitStructure,

 ,

static __IO uint32_t TimingDelay,

/* Private function prototypes -----------------------------------------------*/

 ,

void Delay(__IO uint32_t nTime),

/* Private functions ---------------------------------------------------------*/

/**

 ,

 , * @brief , , Main program

 ,

 , * @param , None

 ,

 , * @retval None

 ,

 , */

 ,

int main(void)

 ,

{

 ,

 , /*!<, At this stage the microcontroller clock setting is already configured,

 ,

 , , , , , , this is done through SystemInit() function which is called from startup

 ,

 , , , , , , file (startup_stm32f0xx.s) before to branch to application main.

 ,

 , , , , , , To reconfigure the default setting of SystemInit() function, refer to

 ,

 , , , , , , system_stm32f0xx.c file

 ,

 , , , , */ , , ,  ,

 ,

 , , , , ,  ,

 ,

 , /* Initialize Leds mounted on STM32F0-discovery */

 ,

 , STM_EVAL_LEDInit(LED3),

 ,

 , STM_EVAL_LEDInit(LED4),

 , /* Turn on LED3 and LED4 */

 ,

 , STM_EVAL_LEDOn(LED3),

 ,

 , STM_EVAL_LEDOn(LED4),

 , /* Setup SysTick Timer for 1 msec interrupts.

 ,

 , , , , ------------------------------------------

 ,

 , , , 1. The SysTick_Config() function is a CMSIS function which configure:

 ,

 , , , , , , - The SysTick Reload register with value passed as function parameter.

 ,

 , , , , , , - Configure the SysTick IRQ priority to the lowest value (0x0F).

 ,

 , , , , , , - Reset the SysTick Counter register.

 ,

 , , , , , , - Configure the SysTick Counter clock source to be Core Clock Source (HCLK).

 ,

 , , , , , , - Enable the SysTick Interrupt.

 ,

 , , , , , , - Start the SysTick Counter.

 ,

 , ,  ,

 ,

 , , , 2. You can change the SysTick Clock source to be HCLK_Div8 by calling the

 ,

 , , , , , , SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8) just after the

 ,

 , , , , , , SysTick_Config() function call. The SysTick_CLKSourceConfig() is defined

 ,

 , , , , , , inside the stm32f0xx_misc.c file.

 , , , 3. You can change the SysTick IRQ priority by calling the

 ,

 , , , , , , NVIC_SetPriority(SysTick_IRQn,...) just after the SysTick_Config() function

 ,

 , , , , , , call. The NVIC_SetPriority() is defined inside the core_cm0.h file.

 , , , 4. To adjust the SysTick time base, use the following formula:

 ,

 , , , , , , , , , , , , , , , , , , , , , , , , , ,  ,

 ,

 , , , , , , , , Reload Value = SysTick Counter Clock (Hz) x , Desired Time base (s)

 ,

 , ,  ,

 ,

 , , , , , , - Reload Value is the parameter to be passed for SysTick_Config() function

 ,

 , , , , , , - Reload Value should not exceed 0xFFFFFF

 ,

 , , */

 ,

 ,  ,

 ,

 , if (SysTick_Config(SystemCoreClock / 1000))

 ,

 , {

 ,

 , , , /* Capture error */

 ,

 , , , while (1),

 ,

 , }

 , while (1)

 ,

 , {

 ,

 , , , /* Toggle LED4 */

 ,

 , , , STM_EVAL_LEDToggle(LED4),

 , , , /* Insert 50 ms delay */

 ,

 , , , Delay(500),

 , , , /* Toggle LED3 */

 ,

 , , , //STM_EVAL_LEDToggle(LED3),

 , , , /* Insert 100 ms delay */

 ,

 , , , //Delay(500),

 ,

 , }

 ,

}

/**

 ,

 , * @brief , Inserts a delay time.

 ,

 , * @param , nTime: specifies the delay time length, in milliseconds.

 ,

 , * @retval None

 ,

 , */

 ,

void Delay(__IO uint32_t nTime)

 ,

{

 ,

 , TimingDelay = nTime,

 , while(TimingDelay != 0),

 ,

}

/**

 ,

 , * @brief , Decrements the TimingDelay variable.

 ,

 , * @param , None

 ,

 , * @retval None

 ,

 , */

 ,

void TimingDelay_Decrement(void)

 ,

{

 ,

 , if (TimingDelay != 0x00)

 ,

 , {

 ,

 , , , TimingDelay--,

 ,

 , }

 ,

}

♯ ifdef , USE_FULL_ASSERT

/**

 ,

 , * @brief , Reports the name of the source file and the source line number

 ,

 , * , , , , , , , , where the assert_param error has occurred.

 ,

 , * @param , file: pointer to the source file name

 ,

 , * @param , line: assert_param error line source number

 ,

 , * @retval None

 ,

 , */

 ,

void assert_failed(uint8_t* file, uint32_t line)

 ,

{

 ,

 , /* User can add his own implementation to report the file name and line number,

 ,

 , , , , ex: printf('Wrong parameters value: file %s on line %d\r\n', file, line) */

 , /* Infinite loop */

 ,

 , while (1)

 ,

 , {

 ,

 , }

 ,

}

 ,

♯ endif

/**

 ,

 , * @}

 ,

 , */

/**

 ,

 , * @}

 ,

 , */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

Why does the tick seem to be slow?

Posted on September 18, 2017 at 20:09

Why does the tick seem to be slow?

This question suggests you have not yet fully grasped how the Systick interrupt works, and what it's supposed to do.

The code supplied by ST here is a simple example.

But how does that relate to 'Systick is slow' ?

Posted on September 18, 2017 at 20:48

OK, I'll try to explain it again in more detail.

Look in the main loop. There is a 500ms timer. Every 500ms the LED4 pin should toggle. That should give me a 1Hz square wave on that pin, but it doesn't give me a 1Hz square wave. It is toggling almost 1% slower than it should be. If the frequency is less than it should be, I can only assume Systick is slower than it should be.

Why does this code not toggle the pin at 1Hz?

Jo-Jo Smith
Associate II
Posted on September 18, 2017 at 22:50

I figured out what was wrong with my code. I'll post it here in case anyone else runs into this.

The example uses the internal RC oscillator, which isn't very accurate, of course. There is a macro called PLL_SOURCE_HSI in system_stm32f0xx.c which selects the RC oscillator as the clock source. There are two other macros right under it that you can use to select the more accurate HSE or HSE bypass.