Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[PIC] How can I generate delay in microseconds of any value for PIC18F4550?

Status
Not open for further replies.

SAMO6

Newbie level 5
Newbie level 5
Joined
Nov 14, 2016
Messages
10
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
139
I am trying to generate delay of variable length using delay function in MPLAB X IDE for PIC18F4550.
Crystal Frequency=20MHz.
Basically, I am trying to generate delay of value which will be given as a parameter to delay_us function as shown below:
Such as, delay_us(10) function will generate 10 microsecond delay.
Generally, I use 'for loop' for delay as shown below.
Code:
void delay()
{
for(i=0;i<10;i++)
   {
   for(j=0;j<1000;j++);
   }
}
I never understood actual meaning of those values written there in above code, I always used to write any value there, but now I am requiring 10 microsecond delay in my application.

So, Can anyone tell me how can I implement a program for 10 microsecond delay for PIC18f4550, Xtal frequency=20Mhz.
Plz, help.
 
Last edited by a moderator:

Disassemble (or generate asm listing) count how many clocks takes one iteration and you will know how the delay is.
 

You can use cycle delays defined in xc8 plib/delays.h

Or use stopwatch in MPLIB Simulator to measure the exact delay generated by your delay loops.
 
  • Like
Reactions: SAMO6

    SAMO6

    Points: 2
    Helpful Answer Positive Rating
hello,


example for 500 µS 16Mhz

to ajust for your case ..
at 20MHz => NOP= cycle=0,2µS



Code:
short N1;
      
 N1=100;  // initialise once the variable , to be reconized by compiler
 // tempo de 500,0µS
 // formula :   = 0,25+0,25 +(N1*(16*0,25+0,5+0,25))-0,25+(4*0,25)
 //  Load counter    N1 Loops  times ( 16 Nop + Decrement Counter + Branch loop) - Branch (skiped )+ final adjust by 4 nop.

 asm
 {        
        MOVLW 105 ;
        MOVWF _N1;   // 8 bit counter
 ici:        
        nop ;   //1
        nop ;
        nop ;
        nop ;
        nop ;
        nop ;
        nop ;
        nop ;
        nop ;
        nop ; //10
        nop ;
        nop ;
        nop ;
        nop ;
        nop ;
        nop ; //16
        decfsz _N1 ,F ;   //decr counter, skip over next instruction if equal to zero  
        bra ici   ;
        nop;
        nop;
        nop;
        nop;  // add 4x0.25=1µS to round tempo pile poil to 500µS
 }
  asm nop ;  // external nop final used as Break point to measure exact cycles and times . ...gives 500.0µS
 

One thing to be cautious of for future reference is that many compilers will optimise away what they see as empty 'for' loops. This is possible, even at low or no optimisation levels, because the compiler only has to create assembler code that is logically equivalent to your C code . Also they need have no concept of a 'delay' (other than the NOOP instruction which they typically generate for other reasons).
If you are using the MPLABx IDE then I would assume you are also using the XC8 compiler. Check out the 'delay.h' file and the XC8 User guide has discusses the options quite well.
If accuracy of the delay is important (and also independence of general interrupt processing causing delays etc.) then use a timer.
Susan
 

Most nowadays C compilers have native wizard tools which saves a lot of our time to configure the settings of the microcontrollers registers to achieve the specification of the design, and I would be a lot surprised if the one you're using has not such a similar feature. Even at this case, you can take a search on the Web for online calculators which provide the final code for you, as this one for example (not tested):



Once you're seeking for a delay in the range of microseconds, unfortunately any implementation in C would not be guaranteed to work as supposed, so that the code for that certainly would be generated in the assembly syntax.
 

One thing to be cautious of for future reference is that many compilers will optimise away what they see as empty 'for' loops.
Susan

gcc is not optimizing away empty loops.
 

If you are using MPLAB X IDE for generating delay two MACRO's are available

//*********from (MPLAB Compiler User’s Guide)*******

__DELAY_MS, __DELAY_US
Synopsis
__delay_ms(x) // request a delay in milliseconds
__delay_us(x) // request a delay in microseconds

Description
As it is often more convenient request a delay in time-based terms rather than in cycle counts, the macros __delay_ms(x) and __delay_us(x) are provided. These macros simply wrap around _delay(n) and convert the time based request into instruction cycles based on the system frequency. In order to achieve this, these macros require the prior definition of pre-processor symbol _XTAL_FREQ. This symbol should be defined as the oscillator frequency (in Hertz) used by the system. An error will result if these macros are used without defining oscillator frequency symbol or if the delay period requested is too large.
 
  • Like
Reactions: SAMO6

    SAMO6

    Points: 2
    Helpful Answer Positive Rating
Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top