I'm using a PIC18F14K50 with HiTech ANSI C Compiler and MPLAB v8.43. My PIC code is finally up and running and working, with the exception of the delay function. This is crucial for my application - I need it to be in certain states for a given number of milliseconds, seconds, or minutes.
I have been trying to find a solution for this for about 2 weeks but have been unsuccessful so far. I gave up and wrote my own delay function with asm("nop");
in a loop, but this gives very unpredictable results. If I tell it to wait for half a second or 5 seconds, it works accurately enough. But as soon as I tell it to wait for longer - like for 10 minutes, the delay only lasts about 10 - 20 seconds, and 2 minutes ands up being a blink shorter than a 500ms delay.
Here are my config fuses and wait()
function:
#include <htc.h>
__CONFIG(1, FOSC_IRC & FCMEN_OFF & IESO_OFF & XINST_OFF);
__CONFIG(2, PWRTEN_OFF & BOREN_OFF & WDTEN_OFF);
__CONFIG(3, MCLRE_OFF);
__CONFIG(4, STVREN_ON & LVP_OFF & DEBUG_OFF);
__CONFIG(5, 0xFFFF);
__CONFIG(6, 0xFFFF);
__CONFIG(7, 0xFFFF);
void wait(int ms)
{
for (int i = 0; i < ms; i++)
for (int j = 0; j < 12; j++)
asm("nop");
}
Like I said, if I call wait(500)
up to wait(30000)
then I will get half a second to 30 second delay to within the tolerence I'm interested in - however if I call wait(600000)
then I do not get a 10 minute delay as I would expect, but rather about 10-15 seconds, and wait(120000)
doesn't give a 2 minute delay, but rather a quick blink.
Ideally, I'd like to get the built-in __delay_ms()
function working and being called from within my wait()
, however I haven't had any success with this. If I try to #include <delay.h>
then my MPLAB complains there is no such file or directory. If I look at the delay.h in my HiTech samples, there is a DelayUs(unsigned char)
defined and an extern void DelayMs(unsigned char)
which I haven't tried, however when I try to put the extern directly into my C code, I get an undefined symbol error upon linking.
The discrepancy between the short to medium delays and the long delays makes no sense. The only explanation I have is that the compiler has optimised out the NOPs or something.
Like I said, it's a PIC18F14K50 with the above configuration fuses. I don't have a great deal of experience with PICs, but I assume it's running at 4MHz given this set-up.
I'm happy with an external function from a library or macro, or with a hand-written function with NOPs. All I need is for it to be accurate to within a couple of seconds per minute or so.
Is the PIC a 16-bit microcontroller? My guess is that you're getting overflow on the value of wait, which would overflow after 2^15 (32,767 is the max value of a signed 16 bit int).