Delay function with MCUXpresso and frdm-k64f does not work

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Delay function with MCUXpresso and frdm-k64f does not work

Jump to solution
10,256 Views
leandro_f_rocco
Contributor III

Hi,

I am using MCUXpresso IDE v10.2.1 [Build 795] to program a FRDM-K64F board.

I need a delay function to generate a delay of milliseconds and microseconds, for this I am writing the following codes:

#define SOURCE_CLOCK CLOCK_GetFreq(kCLOCK_CoreSysClk)

void delay_us(uint32_t value)
{
    uint32_t d = SOURCE_CLOCK / 1000000 * value;
    uint32_t i;
    for (i = 0U; i < d; ++i)
    {
        __asm("NOP");
    }
}

void delay_ms(uint32_t value)
{
    uint32_t d = SOURCE_CLOCK / 1000 * value;
    uint32_t i;
    for (i = 0U; i < d; ++i)
    {
        __asm("NOP");
    }
}

I am testing the functions to blink an LED. The problem is that no matter the configured SystemClock frequency, delay functions always blink the LED at a frequency around 10 times lower than the SystemClock, in other words, if I call the functions as follows:

delay_ms(1000); // Spected delay of 1 second

the delay I get is about 10 seconds.

What is the problem?

Regards.

NXP.png

Labels (1)
1 Solution
8,637 Views
Hui_Ma
NXP TechSupport
NXP TechSupport

Hi,

Using C code is hard to calculate the code execute time.

It need to check the assembly instruction of below code:

 for (i = 0U; i < d; ++i)
    {
        __asm("NOP");
    }

For example, we setting to get 1us delay with execute  (d = SOURCE_CLOCK / 1000000 * 1) times of "NOP" instruction.

While, the for loop also take time to calculate i variable value and compare with d value.

That's why we use timer to set delay and could get accuracy time interval.


Have a great day,
Mike

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

View solution in original post

14 Replies
8,637 Views
BlackNight
NXP Employee
NXP Employee

Hi Leandro,

You might have a look at the implementation in McuOnEclipseLibrary/McuWait.h at master · ErichStyger/McuOnEclipseLibrary · GitHub  and McuOnEclipseLibrary/McuWait.c at master · ErichStyger/McuOnEclipseLibrary · GitHub 

It uses the SystemCoreClock as base and then calculates the needed cycles to wait for a given real time.

I hope this helps,

Erich

0 Kudos
Reply
8,637 Views
gschelotto
Contributor V

Hi Erich,

Years ago I used the PE component of WAIT and I suppose this is a similar implementation for MCUxpresso. Is it possible to isolate the McuWait from the rest of the library? If so, how?

regards,
gaston

0 Kudos
Reply
8,637 Views
ErichStyger
Senior Contributor V

Hi gaston,

yes, McuOnEclipseLibrary/McuWait.c at master · ErichStyger/McuOnEclipseLibrary · GitHub  is exactly for this.

You can easily separate it from the rest of the library.

In that case you just need to have the global libary configuration macros removed or defined locally.

Erich

0 Kudos
Reply
8,637 Views
gschelotto
Contributor V

In that case you just need to have the global libary configuration macros removed or defined locally.

Please Erich, could provide some hint to do this? Sorry but I'm not familiar with this library.
gaston

0 Kudos
Reply
8,635 Views
ErichStyger
Senior Contributor V

see attached.

This is assuming Kinetis Cortex-M4 with no RTOS and MCUXpresso SDK, see McuLibConfig.h:

// global overrides
#define McuLib_CONFIG_SDK_VERSION_USED   McuLib_CONFIG_SDK_MCUXPRESSO_2_0
#define McuLib_CONFIG_SDK_USE_FREERTOS  (0)

Otherwise you need to set there your CPU, because waiting depends on the core capabilites (e.g. Cycle counter, see Cycle Counting on ARM Cortex-M with DWT | MCU on Eclipse ).

And you should call McuWait_Init() as part of your driver initialization before you use any functionality of the driver.

I hope this helps,

Erich

0 Kudos
Reply
8,635 Views
gschelotto
Contributor V

Thanks Erich for the clarification, excellent support as usual :-)
gaston

0 Kudos
Reply
8,637 Views
leandro_f_rocco
Contributor III

Hi Erich,

Thanks for your response.

Regards.

0 Kudos
Reply
8,637 Views
Hui_Ma
NXP TechSupport
NXP TechSupport

Hi,

SDK software provided delay function to using System Tick timer to generate the delay interval.

Please check the example code at <led_blinky> demo for the detailed info:

 /* Delay 1000 ms */
 SysTick_DelayTicks(1000U);

void SysTick_DelayTicks(uint32_t n)
{
    g_systickCounter = n;
    while(g_systickCounter != 0U)
    {
    }
}

Wish it helps.


Have a great day,
Mike

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos
Reply
4,809 Views
NVazquez
Contributor IV

I tried to use this delay, but my code gets struck here,

void SysTick_DelayTicks(uint32_t n)
{
    g_systickCounter = n;
    while(g_systickCounter != 0U)
    {
    }
}

 

It never enters the "void SysTick_Handler(void)".

0 Kudos
Reply
4,804 Views
ErichStyger
Senior Contributor V

Do you have interrupts enabled? Check the PRIMASK.

0 Kudos
Reply
8,637 Views
gschelotto
Contributor V

But what about if I need to implement a nano-second delay? it would lead to an interrupt overhead, right?

regards,
gaston

0 Kudos
Reply
8,637 Views
leandro_f_rocco
Contributor III

Hi Mike, thanks for your response.

The SysTick_DelayTicks function works fine, but now I would like to know what's wrong with my functions. I have the following questions:

1) In each cycle of SOURCE_CLOCK the processor is executing an instruction?

2) If the answer to the previous question is yes, my functions should be working, or not?

3) What is the reason why the delay I'm obtaining is about 10 times more than the delay I'm trying to get?

Thanks!!!

0 Kudos
Reply
8,638 Views
Hui_Ma
NXP TechSupport
NXP TechSupport

Hi,

Using C code is hard to calculate the code execute time.

It need to check the assembly instruction of below code:

 for (i = 0U; i < d; ++i)
    {
        __asm("NOP");
    }

For example, we setting to get 1us delay with execute  (d = SOURCE_CLOCK / 1000000 * 1) times of "NOP" instruction.

While, the for loop also take time to calculate i variable value and compare with d value.

That's why we use timer to set delay and could get accuracy time interval.


Have a great day,
Mike

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

8,637 Views
leandro_f_rocco
Contributor III

Thanks Mike. I think I have this clear now.

Regards.

0 Kudos
Reply