Syntax:
Repeat For time unit ... program code ... <condition> Exit Repeat ... End Repeat
Command Availability:
Available on PIC (12-bit, 14-bit, enhanced mid-range and PIC18) and AVR microcontrollers. Introduced in build 1654.
Explanation:
Repeat For runs a block of code over an exact length of time, instead of a fixed number
of times. The compiler counts the clock cycles the code takes, works out how many passes of
the code fit into the time requested, and adds padding so that every pass takes the same
time and the whole construct finishes exactly on time. It replaces the hand-counted Wait
and nop padding that is otherwise needed to make a timing window last an exact number of
clock cycles.
time is a whole-number constant: a plain number, or a name created with #define.
unit is one of the units used by Wait:
| Unit | Length of unit |
|---|---|
|
us (or usec) |
1 microsecond |
|
10us (or 10usec) |
10 microseconds |
|
ms (or msec) |
1 millisecond |
|
10ms (or 10msec) |
10 milliseconds |
|
s (or sec, second) |
1 second |
|
m (or min) |
1 minute |
|
h (or hour) |
1 hour |
The total time is exact in clock cycles at the clock speed given in #chip. On PIC chips
one instruction cycle is four clock cycles, as it is for Wait. Interrupts are not
included in the calculation: time spent in an interrupt handler makes the loop last
longer.
How the passes are chosen
The compiler fits as many passes as it can into the time (up to 65535), then shares the time left over equally between the passes as padding, so the passes are evenly spaced. Any remainder of a few clock cycles is added once, after the last pass.
This means the time from the start of one pass to the start of the next is the total time
divided by the number of passes - it is not simply the length of the code in the loop.
For example, Repeat For 100 ms around a body that contains Wait 5 ms and a pin toggle
runs 19 passes that are about 5.26 ms apart, because 20 passes of more than 5 ms cannot fit
into 100 ms. If the body is shortened slightly (Wait 4900 us), the compiler fits 20 passes
and pads each one out to exactly 5.000 ms. To space the passes by a particular period,
make the code in the loop a little shorter than that period.
If the code in the loop is very short compared with the total time, the padding in each
pass becomes very large. A time that needs more than 56,000,000 clock cycles of padding in
every pass is rejected; use a longer body, or wrap the Repeat For in an ordinary loop.
What can go inside the loop
The loop is timed by counting the instructions in it, so everything inside must take a fixed, known time. These are allowed:
- Assignments and arithmetic on
Byte,Word,IntegerandLongvariables, including bit operations, shifts and rotates, array elements and the hardware multiplier where the chip has one Set,Dir, port and bit writes, andPulseOutWaitwith a constant time in any unit, andWaitL1. The delay is built into the loop as an exact inline delay of up to 8,000,000 clock cycles perWait.Wait 10000 usandWait 10 mstherefore both workIf … Then … End Ifwith noElse. Only the test is counted. The statements inside theIfrun only when the condition is true and their time is not counted, so a pass in which the condition is true lasts a little longerExit Repeat, to leave the loop early, for example when a timeout is not needed any more. The loop then ends sooner than the time requested
These are not allowed, and produce a compiler error:
ElseandElse If, and conditions that need a library routine, such as comparingWordvariables, or twoBytevariables with>or<, or combining tests withAnd/OrGoto,Gosub,Select Case, calls to your ownSuborFunction,Exit SubandExit Function- Another
Repeat, or aFor,DoorWait While/Wait Untilloop Waitwith a variable timeIntOn,IntOff, and anything else that the compiler builds as a call to a library routine, such as string handling, division and modulus
The time itself must also be a constant. A variable, an expression such as 10*9, a number
with a fraction, zero, a negative number, or a time too short for even one pass of the loop
is rejected. See the
Constraints and Error Messages page for the
full list.
Example:
'This code keeps a pin high for exactly 100 ms.
#chip 16F1829, 8
#option explicit
#define OUTPIN PORTC.0
Dir OUTPIN Out
Set OUTPIN On
Repeat For 100 ms ' <<< the timed loop
Wait 5 ms ' a constant Wait is allowed inside the loop
End Repeat
Set OUTPIN OffKey line: Repeat For 100 ms — repeats the code up to End Repeat for exactly 100 ms. The compiler chooses the number of passes and the padding.
Example:
'This code toggles port A 20 times, 5.000 ms apart, over exactly 100 ms.
#chip 16F1829, 8
#option explicit
Dir PORTA Out
Repeat For 100 ms
Wait 4900 us ' shorter than 5 ms, so that 20 passes fit
PORTA = !PORTA
End RepeatKey line: Wait 4900 us — the Wait is made a little shorter than the 5 ms period, so the compiler fits exactly 20 passes and pads each to 5.000 ms.
Example:
'This code counts Timer1 overflows during a gate time of exactly 790047 us.
#chip 16F1829, 8
#option explicit
Dim Overflows As Byte
Repeat For 790047 us
Wait 1009 us
nop
If TMR1IF = 1 Then ' only the test is counted
Overflows = Overflows + 1
TMR1IF = 0
End If
End RepeatKey line: Repeat For 790047 us — the whole gate lasts exactly 790047 microseconds, whether or not the overflow flag was set, apart from the If body running on a pass in which the flag is set.
Example:
'This code waits up to 50 ms for a button press and leaves the loop at once when it happens.
#chip 16F1829, 8
#option explicit
#define BUTTON PORTB.4
Dir BUTTON In
Dim Pressed As Byte
Pressed = 0
Repeat For 50 ms
If BUTTON = On Then
Pressed = 1
Exit Repeat ' <<< leave early
End If
Wait 100 us
End RepeatKey line: Exit Repeat — leaves the timed loop as soon as the button is seen, so the loop lasts at most 50 ms.
See Also:
- Repeat — looping a fixed number of times
- Wait — the delay command, and its units, used inside
Repeat For - For — a counted loop that also exposes the current iteration number
- Do — an unbounded loop
- Constraints and Error Messages — the limits and error messages for
Repeat For

