/* Lowlevel delay routines For Microchip 18Fxxx or 18Cxxx and Hi-Tech C Designed by Shane Tolmie of www.microchipC.com corporation. Freely distributable. Questions and comments to webmaster@microchipC.com. Lots of Hi-Tech C FAQ and sample source code at http://www.microchipC.com/. Example C: #define PIC_CLK 4000000 unsigned int timeout_int, timeout_char; DelayUs(40); //do NOT do DelayUs(N) of N<5 @ 4Mhz or else it executes DelayUs(255) !!!! DelayUs(255); //max dly250n; //delay 250ns dly1u; //delay 1us timeout_char=timeout_char_us(1147); while(timeout_char-- && (RA1==0)); //wait up to 1147us for port RA1 to go high // - this is the max timeout timeout_int=timeout_int_us(491512); while(timeout_int-- && (RA1==0)); //wait up to 491512us for port RA1 to go high // - this is the max timeout */ #ifndef __DELAY_H #define __DELAY_H #define PIC_CLK 48000000 extern unsigned char delayus_variable; /* #if (PIC_CLK == 4000000) #define dly125n please remove; for 32Mhz+ only #define dly250n please remove; for 16Mhz+ only #define dly500n please remove; for 8Mhz+ only #define dly1u asm("nop") #define dly2u dly1u;dly1u #elif (PIC_CLK == 8000000) #define dly125n please remove; for 32Mhz+ only #define dly250n please remove; for 16Mhz+ only #define dly500n asm("nop") #define dly1u dly500n;dly500n #define dly2u dly1u;dly1u #elif (PIC_CLK == 16000000) #define dly125n please remove; for 32Mhz+ only #define dly250n asm("nop") #define dly500n dly250n;dly250n #define dly1u dly500n;dly500n #define dly2u dly1u;dly1u #elif (PIC_CLK == 20000000) #define dly200n asm("nop") #define dly400n dly250n;dly250n #define dly2u dly400n;dly400n;dly400n;dly400n;dly400n #elif (PIC_CLK == 32000000) #define dly125n asm("nop") #define dly250n dly125n;dly125n #define dly500n dly250n;dly250n #define dly1u dly500n;dly500n #define dly2u dly1u;dly1u #else #error delay.h - please define pic_clk correctly #endif */ //***** //delay routine #if PIC_CLK == 4000000 #define DelayDivisor 4 #define WaitFor1Us asm("nop") #define Jumpback asm("goto $ - 4") //on PIC18F, it is asm("goto $ - 4") and on PIC16F core it is asm("goto $ - 2") #elif PIC_CLK == 8000000 #define DelayDivisor 2 #define WaitFor1Us asm("nop") #define Jumpback asm("goto $ - 4") #elif PIC_CLK == 16000000 #define DelayDivisor 1 #define WaitFor1Us asm("nop") #define Jumpback asm("goto $ - 4") #elif PIC_CLK == 20000000 #define DelayDivisor 1 #define WaitFor1Us asm("nop"); asm("nop") #define Jumpback asm("goto $ - 6") #elif PIC_CLK == 32000000 #define DelayDivisor 1 #define WaitFor1Us asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop") #define Jumpback asm("goto $ - 12") #elif PIC_CLK == 48000000 #define DelayDivisor 1 #define WaitFor1Us asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop") #define Jumpback asm("goto $ - 20") #else #error delay.h - please define PIC_CLK correctly #endif #define DelayUs(x) { \ delayus_variable=(unsigned char)(x/DelayDivisor); \ asm("movlb (_delayus_variable) >> 8"); \ WaitFor1Us; } \ asm("decfsz (_delayus_variable)&0ffh,f"); \ Jumpback; /* timeouts: C code for testing with ints: unsigned int timeout; timeout=4000; PORT_DIRECTION=OUTPUT; while(1) { PORT=1; timeout=8000; while(timeout-- >= 1); //60ms @ 8Mhz, opt on, 72ms @ 8Mhz, opt off PORT=0; } Time taken: optimisations on: 16cyc/number loop, 8us @ 8Mhz optimisations off: 18cyc/number loop, 9us @ 8Mhz with extra check ie: && (RB7==1), +3cyc/number loop, +1.5us @ 8Mhz C code for testing with chars: similar to above Time taken: optimisations on: 9cyc/number loop, 4.5us @ 8Mhz with extra check ie: && (RB7==1), +3cyc/number loop, +1.5us @ 8Mhz Formula: rough timeout value = (/) * (PIC_CLK/4.0) To use: //for max timeout of 1147us @ 8Mhz #define LOOP_CYCLES_CHAR 9 //how many cycles per loop, optimizations on #define timeout_char_us(x) (unsigned char)((x/LOOP_CYCLES_CHAR)*(PIC_CLK/4.0)) unsigned char timeout; timeout=timeout_char_us(1147); //max timeout allowed @ 8Mhz, 573us @ 16Mhz while((timeout-- >= 1) && ()); //wait To use: //for max 491512us, half sec timeout @ 8Mhz #define LOOP_CYCLES_INT 16 //how many cycles per loop, optimizations on #define timeout_int_us(x) (unsigned int)((x+/LOOP_CYCLES_INT)*(PIC_CLK/4.0)) unsigned int timeout; timeout=timeout_int_us(491512); //max timeout allowed @ 8Mhz while((timeout-- >= 1) && ()); //wait */ #define LOOP_CYCLES_CHAR 9 //how many cycles per loop, optimizations on #define timeout_char_us(x) (long)(((x)/LOOP_CYCLES_CHAR)*(PIC_CLK/1000000/4)) #define LOOP_CYCLES_INT 16 //how many cycles per loop, optimizations on #define timeout_int_us(x) (long)(((x)/LOOP_CYCLES_INT)*(PIC_CLK/1000000/4)) //if lo byte is zero, faster initialization by 1 instrucion #define timeout_int_lobyte_zero_us(x) (long)(((x)/LOOP_CYCLES_INT)*(PIC_CLK/4.0)&0xFF00) //function prototypes void DelayBigUs(unsigned int cnt); void DelayMs(unsigned char cnt); void DelayMs_interrupt(unsigned char cnt); void DelayBigMs(unsigned int cnt); void DelayS(unsigned char cnt); #endif