Precise delay for Embedded Systems required? I may think so!!!
Started by 9 years ago●4 replies●latest reply 9 years ago●1512 viewsWell, its been a fact about defining delay in Embedded Systems. The approach may vary from person to person but at the end of the day the goal is to provide an accurate 1ms delay.
General methods involved in defining a delay are:
1. Using For loop
2. Using inbuilt delay function
I know many people will use the first methodology for defining delay. But, my question is ‘Is it an accurate delay?’. You may ask me a straight forward question, ‘Why you want an accurate delay?’
The reason is pretty simple and it depends on the use case. When you were using the delay for glowing an LED, then For loop methodology is more than enough. But, if your intention is to use the delay for strobing clock, then it will no longer help you !
Consider the following code:
void _delay_ms(uint8_t Val) { uint8_t i; while(Val>0) { for(i=0;i<104;i++); Val--; } }
In the above code, For loop is used to create 1ms delay. In most of the cases, this delay is based on Trial and error approach. As said before this method is ill suited for strobing clcok.
How did I get there?
I was also using for loop delay in most cases until I understand the real scenario. While working as an intern in Automation based firm, I was given a task of interfacing AT93C46 EEPROM with MSP430F5418 controller. It’s a 3 wire serial EEPROM which means by SPI protocol we can communicate with this. Initially, I thought it will be quite easy since because I had interfaced many devices in SPI protocol prior to this. But, to my surprise the project manager told me to interface this via software SPI. I simply said OK and worked on that.
I didn’t have worked with software SPI before, but I took it as a challenge. The first thing I did was inspecting the datasheet of the EEPROM and noted down he timing requirements. After writing the code, I got no response whatsoever form the device. But, I’m sure that I have written all the code in correct manner and reached my Project Manager for advice.
After inspecting my code he simply asked me, “Is this strobing clock got accurate timing?”. I said, “Yes. I have been using this delay for quite a long time and it was accurate”. Later on he explained me that the ‘For Loop’ in which I was using for 1ms delay in strobing clock was inaccurate and so only I was getting no response from the device.
Strobing clock function:
void strobe_sck(void) { P4OUT |= (SCK); delay_ms(1); P4OUT &= ~(SCK); }
As you can see that the code above uses ‘_delay_ms()’ function, which is the For Loop delay mentioned above. Then, I put a separate function for 1ms delay and after deploying the code, I was able to read and write from EEPROM.
For proper working of any sequential device, it is important to give accurate clock. If the clock’s timing was not accurate then you will get unexpected results.
Standard 1ms delay function:
inline void delay_ms(uint8_t count) { uint8_t i; for(i=0;i<count;i++) { _delay_cycles(4000); } }
Here, I used ‘_delay_cycles()’ function which comes with the standard library of Texas Instruments #MSP430 controller. It just carry outs the NOP (No Operation) task. The reason for making the function as inline is to avoid the overhead caused by the function call.
Though, when you examine the timing of the above function with the help of Oscilloscope, it will not 100% accurate due to the usage of looping statement, as this will consume few machine cycles. In order to compensate for that, I had slightly increased the delay count and it worked like a charm.
I hope this post will give you some info of using the precised delay for the better working of Embedded Systems. If you got some other options better than my method, just portray it in comments. Because, as I told earlier the motive of this post is to produce the accurate delay.
Don't ever rely on a for loop in C to achieve precise delays. The exact timing will depend on the compiler command-line settings and even the version of the compiler; if you upgrade there may be a new optimization that affects timing.
The only reliable ways to achieve a delay are
- usage of a library function to spin-wait and achieve the same intent as the for loop, but using assembly code that has been carefully constructed and tested.
- usage of a timer overflow flag or interrupt, so that the delay comes from hardware peripherals rather than a software loop. (This is generally better, anyway, since you can do something else useful with your CPU power than just waiting in a loop.)
Another point probably worth mentioning is that the code may be hard to port from one project to another, even though they all use the same or similar microcontroller brands/models, for similar reasons as the ones texane mentioned. When code is moved around, it may be hard to know/infer what is the run time clock frequency only based on compile-time information.
Moreover, the relationship between the clock frequency and the 'magic' number to put in delay_ms is likely non-linear, hence it may be difficult to come out with accurate, parametric code.