Hi to everybody here
Please, hints needed.
I want to implement precise delays from few us to 100us.This is for squeezing consumption optimization in some peripheral ,following directives of a co-worker.
Of course it is not a disaster if i would wait 5us instead of 3us in some sequence.But it is mostly for me ,to learn to use the timer correctly.
Now i'm using a Freedom Board KL05Z,with core,bus and TPM clock=20.97 MHz,global optimization level=0
NB:the TPM0 prescaler is set to 0
I did a simple C function acting on TPM0 registers:
void Mydelay_usec(unsigned int del) { TPM0_MOD=del; TPM0_CNT =0x00;//clean counter TPM0_SC |=TPM_SC_CMOD(0x01)|TPM_SC_TOF_MASK ;//inc. on every edge,clean overflow flag,up while(!(TPM0_SC & TPM_SC_TOF_MASK) );//wait for overflow TPM0_SC &=~(TPM_SC_CMOD_MASK);//stop the timer }
I measure the delay by reading a pulse width on a pin on the oscilloscope :
GPIOB_PDOR &=~0x200; Mydelay_usec((test_var);//<<<<< GPIOB_PDOR |=0x200;
I leave the function empty ,just to measure the time needed to call it ,and to switch the test pin.The pulse width is 1.5us
void Mydelay_usec(unsigned int del){}
...i expected something less
With the function complete,if i call it with input parameter=1, the resulting time is about 4.1us that lowers to 3us with global optimization level=3
I don't have experience of ARM assembly.Looking the content of my function not far form assembly level, i expected less assembly instructions(see the alleged file).
Another issue is that incrementing the MOD value by 1,does not correspond to a progressive increment of the pulse width-
It looks,that the overflow,and the related pulse width are varying only when the MOD increases by 8 (?) units.
I guess this is because of the time between two checks of the TOF flag in the while(..) loop,that is too long to resolve a count of few units.
So a loop shorter than a TPM count is needed, but this is impossible unless i slow the count with a prescaler.
What is the right approach in this case?Interrupt?I should ever check some flag changed by the ISR..
Thank you all.
Diego
Original Attachment has been moved to: assembly.txt.zip
Hi Diego,
I'm not sure that whether I've figured out the problem. Could you please upload your project? If I have your project, it's convenience to me for confirm the problem is right or not.
I'm looking forward to your reply.
Have a nice day!
Best regards,
Ping
Thank you for working on it,Ping.
I'll'do it as soon as possible,once i have cleaned up the unnecessary parts just to focus on the item.
Thanks again
Hi Diego,
I'm glad to hear your news and I'm also looking forward to your demo code.
Have a nice day!
Best regards,
Ping
Sorry i just found the time to resume the code today ,in the very early morning-
In ProcessorExpert.c i call the delay function ,i check on the oscilloscope the duration of the pulses
PinScope_SetVal();
McuWaitUs(50);
PinScope_ClrVal();
McuWaitUs(80);
PinScope_SetVal();
McuWaitUs(10);
PinScope_ClrVal();
i don't pretend to have actually the duration in microseconds,even in this case i would need a macro to calculate the right value of the parameter eg:
McuWaitUs(CONVERT_FOR_REAL_US_VALUE(14)) depending by clock frequency ,prescalers etc
Furtermore time is neede to call the function and passing the parameter.
But i would like to be able to measure increments of 1us of the delay time.
This looks possible,i need to increase the parameter from 50 to 80 to see someting more than 1us increase,not bad.
Anyway many intermediate values gives the same delay,i guess this is becaus the loops that checks the flag
while(!(TPM0_SC & TPM_SC_TOF_MASK) );//wait for overflow
is much longer than the increses in TPM count,so a shorter loop would be needed-I'm i right?
Wich is the best way (in assembly?) to obtain it?
Thank you again and i apologize for my late reply to this topic
Diego
McuWaitUs(14);
Hi Diego,
Thanks for your reply. I also aggree with your opinion the loops that checks the overflow flag cost much longer than the increses in TPM count.
So 1us can't be calculated just by clock frequency and prescale parameter and I'd like to suggest two methods for you.
One method is using interrupt which could avoid the loop, another method is using systick to implement precise delay as the replacement of TPM.
You could chck the detail describtion of systick for KL through the thread as follow.
Have a great day,
Ping
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Hi Diego,
I've been working on your now and I'll reply as soon as possible if I work it out.
So be patient.
Best regards,
Ping