Delay on PIC18F
c, delay, microcontroller, mplab, pic18
Solution
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).
Problem
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.