#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