Page 1 of 2

C Based Delay - with and Without Timers

Posted: Wed Dec 10, 2025 5:53 pm
by jay_dee
Hi,
Side task whilst debugging my test rig. :)

How can I create a micro second delay in C code. I wish to avoid the FC Delay function, to exclude that from my investigation.

A) One method that uses the PIC timer.

B) Second method that avoid the using Timers.
Maybe a known loop count of 100 or similar.

With both methods, how can I back out the time of the delay, given an known Crystall Freq?
I assume if the FOSC is 20Mhz, then the instuction cycle is (Fcy) 5MHz.

Any ideas appreciated. :) Thanks. J.

Re: C Based Delay - with and Without Timers

Posted: Wed Dec 10, 2025 6:21 pm
by Steve-Matrix
At 5MHz, 5 NOPs in a delay would be 1us delay.

Re: C Based Delay - with and Without Timers

Posted: Wed Dec 10, 2025 8:34 pm
by jay_dee
Thanks Steve, I got 1uS (998ns) on a single "NOP();" so there is potentially something funky going on. J.

Re: C Based Delay - with and Without Timers

Posted: Wed Dec 10, 2025 9:00 pm
by LeighM
How are you measuring it?
If you are toggling an output pin then you need to factor in those instruction times, and any loop/jump, as well.

Re: C Based Delay - with and Without Timers

Posted: Wed Dec 10, 2025 9:06 pm
by mnfisher
Can i ask how you are timing this?

In theory you can get a 1us delay using a timer (with interrupt) or with some nop instructions.

So something like:

LATA0 = 1; // Set RA0 high
DELAY(); // delay also has function call overhead.
LATA0 = 0; // Set ra0 low

Will take longer than 1us due to the function call overhead.

If you use Flowcode to toggle a pin then there is also overhead for this (if you use any output block or a property and do pin=1 in a calculation it does st_bit(port, bit) again with some overhead - i believe it sets the direction bits, output and the bit)

If you test for 1ms delay then the overhead becomes much less significant..

Martin

Re: C Based Delay - with and Without Timers

Posted: Wed Dec 10, 2025 9:07 pm
by mnfisher
Leigh beat me to it...

Re: C Based Delay - with and Without Timers

Posted: Thu Dec 11, 2025 9:11 am
by jay_dee
Hi, Thanks Martin, Leigh,
As you both stated the method used signiicantly effects the duration of very short pulses.
A) toggling single bit of Port C, using the FC output command and delay using a single NOP(); in a C code box. Result a Pulse of : 998nS
B) toggling a bit using "LATC6" and Delay from a Single NOP(); all in a C code box. Result a pulse of : 399nS
C) toggling a single bit of Port C, using the FC output commands and FC delay of 10uS. Result a Pulse of : 16uS

This is the simple test FC, I disable different sections to acheive each test above.
FC11_PIC18F2585_DelayTest_WIP1.fcfx
(16.02 KiB) Downloaded 10 times
This test was started as I was having issues with Software/Timer driven UART comms. The Bits from the Software UART would be longer than required for a given Baud.

I am now wondering if a PIC at 20Mhz (5Mhz Fcy), allowing for instruction overhead, is actually capable of driving a software UART above 9600 Baud. I thought 19200 Baud would be quite achieveable but all testing results in Bit pulses that are too long.

1/9600 = 104 uS per Bit
1/19200 = 52 uS per bit.

Using simple commands, I tried to create a simple 52 uS pulse but I cannot get this PIC, using delays, timers or interrupts to create a 52 uS pulse. So I guess what hope has the FC commands got of achiving this. am I just asking to much of a moderatly slow PIC ? :)
J.

Re: C Based Delay - with and Without Timers

Posted: Thu Dec 11, 2025 9:53 am
by jay_dee
I'm going down this rabbit hole a bit further to improve my understanding and I 'think' I'm getting there!
This needs two instuction cycles, which may explain the larger value I got previously.

Code: Select all

LATC6 = 1;
NOP();
LATC6 = 0; 
I think this is closer to a single instruction delay and is my TRUE minimum pulse length.

Code: Select all

LATC6 = 1;
LATC6 = 0; 
Taking this info in hand...
The PIC 18F2585 has a Max operating frequency of 40Mhz. But I also have a 8 MHz XTAL.
HS 8Mhz / 4 = Fcy = 2Mhz. 1/2000000 = 0.0000005 = 500 nS.
Using my second method above and an 8MHz XTAL, I measure 499nS with the scope. SO I think this all makes sense.

I can also PLL 8 Mhz into 32MHz.
HS + PLL 32Mhz / 4 = Fcy = 8MHz. 1/8000000 = 0.0000001 = 100nS.
Using my second method above, I measure 124nS with the scope. near enough for me, allowing for tollerances etc.

OK, Now I'm going to go back to my Software UART using 32MHz and see if I get any improvement. :)

Re: C Based Delay - with and Without Timers

Posted: Thu Dec 11, 2025 10:33 am
by jay_dee
Well, I still can't get any Software driven UART type to send out anything with the correct Bit timing for 19200 or above.
I would have though a PIC running at 32MHz should have been able to do that?

Running in HS PLL mode is painful since I'm not sure if the FC internal delays/timers/calculations know its running at 32Mhz.
The settings in the Intrurupt component, think its set on 8Mhz. (Project Option is set to 32MHz)
I get approximately the right bit timing but not close enough for an external Terminal program to accept it.
Hmm. J.

Re: C Based Delay - with and Without Timers

Posted: Thu Dec 11, 2025 10:38 am
by mnfisher
I think in theory - you could get 115200 baud using C at 32MHz - you have 69 instruction cycles per bit (@8.7uS)

It would take some careful coding though...

Using the EUSART hardware is easier!

Martin