CNT

Register: System Counter register.

((PUBPRI))
  CNT

Returns: Current 32-bit System Counter value.

Explanation

The CNT register contains the current value in the global 32-bit System Counter. The System Counter serves as the central time reference for all cogs; it increments its 32-bit value once every System Clock cycle.

Upon power-up/reset, the System Counter starts with an arbitrary value and counts upwards from there, incrementing with every System Clock cycle. Since the System Counter is a read-only resource, every cog can read it simultaneously and can use the returned value to synchronize events, count cycles and measure time.

Using CNT

Read CNT to get the current System Counter value. The actual value itself does not matter for any particular purpose, but the difference in successive reads is very important. Most often, the CNT register is used to delay execution for a specific period or to synchronize an event to the start of a window of time. The next examples use the WAITCNT instruction to achieve this.

waitcnt(3_000_000 + cnt)   'Wait for 3 million clock cycles 

The above code is an example of a "fixed delay" It delays the cog's execution for 3 million system clock cycles (about ¼ second when running with the internal fast oscillator).

In Spin code, when using CNT inside of a WAITCNT command as shown above, make sure to write the expression in the form "offset + cnt" as opposed to "cnt + offset" and make sure offset is at least 381 to account for Spin Interpreter overhead and avoid unexpectedly long delays. See the WAITCNT command's Fixed Delays section on page for more information.

The next is an example of a "synchronized delay." It notes the current count at one place and performs an action (toggles a pin) every millisecond thereafter with accuracy as good as that of the oscillator driving the Propeller chip.

PUB Toggle | TimeBase, OneMS
  dira[0]~~                      'Set P0 to output
  OneMS := clkfreq / 1000        'Calculate cycles per 1 millisecond
  TimeBase := cnt                'Get current count
  repeat                         'Loop endlessly
    waitcnt(TimeBase += OneMS)   ' Wait to start of next millisecond
    !outa[0]                     ' Toggle P0 

Here, I/O pin 0 is set to output. Then the local variable OneMS is set equal to the current System Clock frequency divided by 1000; i.e., the number of System Clock cycles per 1 millisecond of time. Next, the local variable TimeBase is set to the current System Counter value. Finally, the last two lines of code repeat endlessly; each time waiting until the start of the next millisecond and then toggling the state of P0.

For more information, see the WAITCNT section's Fixed Delays on page and Synchronized Delays on page .

The CNT register is read-only so it should not be assigned a value (i.e., should not be to the left of a := or other assignment operator).

Unless otherwise noted, content on this site is licensed under the
Creative Commons Attribution-ShareAlike 4.0 International License.