Sonsivri

Electronics => Pic C Languages => Topic started by: sughoi on July 08, 2008, 07:02:07 19:02



Title: delay routines
Post by: sughoi on July 08, 2008, 07:02:07 19:02
In order to use with PIC12F controllers (with Hi-Tech PICC compiler) I need delay routines. And I hope they can be used at low frequence (such as 125KHz). Does anybody have?


Title: Re: delay routines
Post by: aj49m on July 09, 2008, 05:14:53 17:14
using general proposite register and timer module combination, incrementing or decrementing register both, counting time that waiting every cycle and sumatory all in loop.







Title: Re: delay routines
Post by: sughoi on July 09, 2008, 06:13:14 18:13
Thank you. But I need ready and tested routines for slow frequence (31kHz, 125kHz, 250kHz etc.).


Title: Re: delay routines
Post by: TomJackson69 on July 12, 2008, 04:22:59 04:22
Thank you. But I need ready and tested routines for slow frequence (31kHz, 125kHz, 250kHz etc.).

What do you mean by "slow frequence (31kHz, 125kHz, 250kHz etc.)"?

You can use DelayUs (...) from the build-in function that comes with HTC18. Make sure you include delay.h and delay.c.

If you want to have a pin HI for #of uS and LOW for #of uS than just convert your whatever KHz to uS and call for DelayUs(...).

Hope that help,

Tom



Title: Re: delay routines
Post by: sughoi on July 12, 2008, 06:29:45 06:29
#include   "delay.h"

void
DelayMs(unsigned char cnt)
{
#if   XTAL_FREQ <= 2MHZ
   do {
      DelayUs(996);
   } while(--cnt);
#endif

#if    XTAL_FREQ > 2MHZ   
   unsigned char   i;
   do {
      i = 4;
      do {
         DelayUs(250);
      } while(--i);
   } while(--cnt);
#endif
}

This is original  delay.c  code file (hi-tech). I already use this rounies and also I change the frequence with

#undef XTAL_FREQ
#define XTAL_FREQ 125KHZ

but this is not precise. For 30 seconds delay it makes approximately 6 seconds extra delay. Because this routine was written for 4MHZ XTAL and the more faster xtal you use the more mistakes it makes. It is the same for slower XTAL..

Thank you for response


Title: Re: delay routines
Post by: TomJackson69 on July 12, 2008, 05:50:52 17:50
#include   "delay.h"

void
DelayMs(unsigned char cnt)
{
#if   XTAL_FREQ <= 2MHZ
   do {
      DelayUs(996);
   } while(--cnt);
#endif

#if    XTAL_FREQ > 2MHZ   
   unsigned char   i;
   do {
      i = 4;
      do {
         DelayUs(250);
      } while(--i);
   } while(--cnt);
#endif
}

This is original  delay.c  code file (hi-tech). I already use this rounies and also I change the frequence with

#undef XTAL_FREQ
#define XTAL_FREQ 125KHZ

but this is not precise. For 30 seconds delay it makes approximately 6 seconds extra delay. Because this routine was written for 4MHZ XTAL and the more faster xtal you use the more mistakes it makes. It is the same for slower XTAL..

Thank you for response

Hello,

The following are files that I used and modified and was running good for 20MHz.

delay.c and delay.h for Hi-Tech

;===============================
delay.c

/*
 --- Delay functions
   --- This is delay.c ---

See delay.h for details   
Make sure this code is compiled with full optimization!!!
 */



#include   "delay.h"



void DelayMs(unsigned char cnt)
{
   
   unsigned char i;

   while (cnt--)
   {

      i=4;

      while(i--)
      {

         DelayUs(uS_CNT);   /* Adjust for error */

      } ;

   } ;

}

;=================================
delay.h
/*
 *--- Delay functions for HI-TECH C on the PIC18
 ---

Functions available:      
DelayUs(x)   Delay specified number of microseconds
      
DelayMs(x)   Delay specified number of milliseconds   

Note that there are range limits:
 *   
- on small values of x (i.e. x<10), the delay becomes less
accurate. DelayUs is accurate with xtal frequencies in the
range of 4-16MHZ, where x must not exceed 255.
For xtal frequencies > 16MHz the valid range for DelayUs
is even smaller - hence affecting DelayMs.
To use DelayUs it is only necessary to include this file.
To use DelayMs you must include delay.c in your project.
Set the crystal frequency in the CPP predefined symbols list

on the PICC-18 commmand line, e.g.

picc18 -DXTAL_FREQ=4MHZ

or
picc18 -DXTAL_FREQ=100KHZ


Note that this is the crystal frequency, the CPU clock is
divided by 4.

MAKE SURE this code is compiled with full optimization!!!
*/



#define   MHZ   *1


#ifndef   XTAL_FREQ

#define   XTAL_FREQ   4MHZ      /* Crystal frequency in MHz */

#endif



#if   XTAL_FREQ < 8MHZ

#define   uS_CNT    238         /* 4x to make 1 mSec */

#endif



#if   XTAL_FREQ == 8MHZ

#define uS_CNT  244
#endif



#if   XTAL_FREQ > 8MHZ

#define uS_CNT  246

#endif



#define FREQ_MULT   (XTAL_FREQ)/(4MHZ)



#define   DelayUs(x)   
{ unsigned char _dcnt; \
          
   if(x>=4) _dcnt=(x*(FREQ_MULT)/2); \
          
   else _dcnt=1; \
          
   while(--_dcnt > 0) \
            
   {\
            
      asm("nop");\
            
      asm("nop");\
            
   continue; }\
      
}



extern void DelayMs(unsigned char cnt);      // prototype

;==================================

The following is delay rutine I used with Microchip MCC18:

;==================================

delay_Mcc18.h


#ifndef DELAY_H
#define DELAY_H

#define   FOSC   29490L       /* Internal clock freq in KHZ*/
#define   MHZ      *1000L       /* number of kHz in a MHz */
#define   KHZ      *1          /* number of kHz in a kHz */

//===============================
//  //_dcnt = ((x* FOSC)/(12MHZ)); \

#define   DelayMicroS(x) { unsigned char _dcnt; \
            _dcnt = ((x* FOSC)/(20MHZ)); \       //-- change 20MHz to your frequency --
           while(--_dcnt != 0) \
             continue; }


//===============================
// --- cho them Delay_uS (x) ---

void DelayuS(unsigned int cnt)
{
   unsigned char   i;
   do {
      i = 2;
      do {
         DelayMicroS(2);
      } while(--i);
   } while(--cnt);
}

//===============================
void DelayMs(unsigned int cnt)
{
   unsigned char   i;
   do {
      i = 20;
      do {
         DelayMicroS(50);
      } while(--i);
   } while(--cnt);
}

//===============================

// use this function when need a delay loop from an ISR
// should not usually delay within an ISR but if you have too.....
void ISR_DelayMs(unsigned char cnt)
{
   unsigned char   i;
   do {
      i = 20;
      do {
         DelayMicroS(50);
      } while(--i);
   } while(--cnt);
}
//===============================

char kill_delay;

void DelayMsKill(unsigned char cnt)
{
   unsigned char   i;
   do {
      i = 20;
      do {
         DelayMicroS(50);
      } while(--i && !kill_delay);
   } while(--cnt && !kill_delay);
}

//
// Noted: I use only two functions
extern void DelayMs(unsigned int cnt);
extern void DelayuS(unsigned int cnt);


#endif
;===============================

You should look deep into the routine above and try to modify to feed your need.

The "delay_Mcc18.h" is only header need for using Microchip MCC18. This header should work with Hi-Tech also with little syntech change. I only work with Hi-Tech compiler for about a month or so, so I don't know much about this compiler. C is new for me; I am an assembly men. I use MCC18 on only one project so my knowledge is only limited.

I have noted that you say for 30 sec delay you get 6 extra sec of de lay. I suggest you to change the following in your delay.h

#if   XTAL_FREQ <= 2MHZ
   do {
      DelayUs(996);    // --- change this number to lower value and experiment with it
   } while(--cnt);       // --- until you get exact 30 seconds  ----------------
#endif


Good luck,

Tom


Title: Re: delay routines
Post by: Buddy on July 30, 2008, 02:47:50 14:47
Dear Sughoi,

You can use any delay code generator (for assembler language) then in HitechC, use the assembler directives: "#asm" to use the assembler language delay routines. Doing it this way can be quite accurate in timing!