I want to use “nop” to realize a delay function. I set core clock frequency 180Mhz,so I use 180 "nop"
to realize a microseconds delay,unfortunately,it can't get my expected.Strangly,when I use 90 “nop”
it can close to the right answer.I use LPC54618 official development board.
my code:
/** Pure delay NOP */
#define RUN_NOP {__asm volatile ("nop\n\t");}
#define RUN_4_NOPS {RUN_NOP; RUN_NOP; RUN_NOP; RUN_NOP;}
#define RUN_16_NOPS {RUN_4_NOPS; RUN_4_NOPS; RUN_4_NOPS; RUN_4_NOPS;}
#define RUN_64_NOPS {RUN_16_NOPS; RUN_16_NOPS; RUN_16_NOPS; RUN_16_NOPS;}
#define RUN_90_NOPS {RUN_64_NOPS; RUN_16_NOPS;\ RUN_16_NOPS;RUN_4_NOPS;RUN_4_NOPS;RUN_NOP;RUN_NOP}
#define RUN_180_NOPS {RUN_64_NOPS; RUN_64_NOPS;\ RUN_16_NOPS;RUN_16_NOPS;RUN_16_NOPS;RUN_4_NOPS;}
this question confused me for a long times,I hope someone can answer me.
thank you!
Solved! Go to Solution.
Hello ,
The MATCH value in MR register should be less one than your match data, just like PCVAL register.
BR
Alice
I'm not sure of the exact details for the LPC546xx parts, but flash is not zero wait-state. There is a flash accelerator that mitigates this, but you cannot consistently fetch and execute 1 instruction per cycle from flash (you *may* be able to do this from RAM).
The best way to get accurate delays is to use a timer/counter.
Thank you for your replay!I used the ctimer1 to get delay,but I get same result.I set prescale value equal 180-1,matchvalue equal 1 to delay 1 millisecond,unfortunately,it delays 2 millisecond actually. when I set prescale value equal 90-1,matchvalue equal 1 to delay 1 millisecond,it can get right result.I don't know what make that happed?
thank you!
As converse said, Cortex M3/4 devices are more complex than simple 8-bit MCUs. Instruction execution time is not predictable to this degree.
> I used the ctimer1 to get delay,but I get same result.I set prescale value equal 180-1,matchvalue equal 1 to delay 1 millisecond,
I suppose you meant microsecond not millisecond.
Use a timer, toggle a GPIO pin in the timer interrupt, and measure the difference. Reduce the timer count to make up for the interrupt latency.
Higher priority interrupts could throw you off.
Do you have a good justification for an exact 1us delay ? You most probably don't need that accuracy.
thank you for your reply!I use a timer, toggle a GPIO pin in the timer interrupt,but have no difference.
my code :
/*******************************************************************************
* Function : MAINCTIMR_INIT
* @param : None
* @return : None
* Instruction : None
* Remark : None
* date : 2021.2.19
*******************************************************************************/
void MAINCTIMR_INIT(void)
{
ctimer_config_t config;
ctimer_match_config_t matchConfig;
CTIMER_GetDefaultConfig(&config);
config.prescale = MAIN_CTIMER_PRE-1;//MAIN_CTIMER_PRE = 90 or 180
CTIMER_Init(MAIN_CTIMER, &config);
matchConfig.enableCounterReset = true;
matchConfig.enableCounterStop = false;
matchConfig.matchValue = MAIN_CTIMER_MACHVLA; // MAIN_CTIMER_MACHVLA =1
matchConfig.outControl = kCTIMER_Output_NoAction;
matchConfig.outPinInitState = false;
matchConfig.enableInterrupt = true;
CTIMER_SetupMatch(MAIN_CTIMER, MAIN_CTIMR_MATCH, &matchConfig) //MAIN_CTIMER = CTIMER1
CTIMER_EnableInterrupts(MAIN_CTIMER,kCTIMER_Match1InterruptEnable);
CTIMER_StartTimer(MAIN_CTIMER);
}
/*******************************************************************************
* Function : MAINTIMR_IRQHandler
* @param : None
* @return : None
* Instruction : None
* Remark : None
* date : 2021.2.19
*******************************************************************************/
void MAIN_CTIMER_ISR(void) //MAIN_CTIMER_ISR = CTIMER1_IRQHandler
{
if(MAIN_CTIMER->IR & MAIN_CTIMERMACH_FLAG){
// time_stick++;
GPIO_PortToggle(GPIO,0X03,0X4000);
MAIN_CTIMER->IR = MAIN_CTIMERMACH_FLAG;
}
}
Is something wrong with core clock ?
thank you!
Hello ,
The MATCH value in MR register should be less one than your match data, just like PCVAL register.
BR
Alice
Thank you for your reply! As you said,I need set PCVAL register is not equal to (180 -1)forever becase the MR register can't set (1-1)to get 1us interrupt ! Thank you very much!
Thank you!
> config.prescale = MAIN_CTIMER_PRE-1;//MAIN_CTIMER_PRE = 90 or 180
I think you might need to check the user manual, especially the clock chain section. For many Cortex M MCUs I dealt with, the maximal peripheral clock was core_clock/2, i.e. 90 MHz in your case. The scope pictures look like that.
I don't have very much experience with the LPC54xxx series myself.
Thank you for your reply! The LPC54618 max frequency is 180Mhz,I have solute this question,the biggest reason is MR register value is error!
thank you!