Delay function with MCUXpresso and frdm-k64f does not work

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 
已解决

Delay function with MCUXpresso and frdm-k64f does not work

跳至解决方案
10,255 次查看
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

标签 (1)
1 解答
8,636 次查看
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.
-------------------------------------------------------------------------------

在原帖中查看解决方案

14 回复数
8,636 次查看
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 项奖励
回复
8,636 次查看
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 项奖励
回复
8,636 次查看
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 项奖励
回复
8,636 次查看
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 项奖励
回复
8,634 次查看
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 项奖励
回复
8,634 次查看
gschelotto
Contributor V

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

0 项奖励
回复
8,636 次查看
leandro_f_rocco
Contributor III

Hi Erich,

Thanks for your response.

Regards.

0 项奖励
回复
8,636 次查看
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 项奖励
回复
4,808 次查看
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 项奖励
回复
4,803 次查看
ErichStyger
Senior Contributor V

Do you have interrupts enabled? Check the PRIMASK.

0 项奖励
回复
8,636 次查看
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 项奖励
回复
8,636 次查看
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 项奖励
回复
8,637 次查看
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,636 次查看
leandro_f_rocco
Contributor III

Thanks Mike. I think I have this clear now.

Regards.

0 项奖励
回复