in Teensy 4 there is a counter/register named ARM_DWT_CYCCNT which increases on the count of each system clock tick. This can be read and reset to 0. It also rolls over on it's own. I think it is 32 bits long.
Is there something similar for the atmega chips that allows me to count system clock ticks without having to resort to using the timers to do it?
The millis() is used for that. Since Timer0 does not run at 1kHz, there is a correction for millis(). The resulting millis() value is just as accurate as the 16MHz crystal or resonator, but with a little jitter because of the correction.
Arduino uses only Timer0 for millis(), the other timers can be used for precise timing.
Do you want a precise delay in clock cycles ? Some use a inline assembly "NOP" for a clock delay. There is also a function __builtin_avr_delay_cycles() to make the compiler generate "NOP" instructions (the compiler uses other instructions and loops for longer delays).
Ah, it uses Timer0. I guess i will just have to use a timer as well. I was hoping there might already be a system clock counter somewhere in the ATMega chips which i wasn't aware of yet.
Can you tell what your project is and what you need the timer for ?
We all use millis() in every situation.
It can calculate time up to 50 days.
If you have a board with a crystal (instead of a resonator) that is 1 minute inaccurate after a year, then you can make a clock with millis() and it will have exactly the same accuracy as the crystal.
i want to test the time it takes (in clock ticks) for a particular piece of code to run. Partly as a way to refine the speed of my code but also to learn how long it takes for some common pieces of code to run. E.g. is an IF/ELSE statement faster than using a SWITCH/CASE statement. How much slower is it to divide than multiply etc
How about toggling a spare pin to take timing measurements in your code?
Say we use pin 3 as a test-point, and allow 3 cycles to toggle using PORTD ^= (1 << PD3); then here we should measure 6.25μs and 62.5μs respectively...
@nuttymonk Why would you need a hardware timer ? I don't get it.
@dlloyd That is not the single clock cycle pin toggle command.
The micros() is accurate at 4µs on a Arduino Uno.
I prefer to use millis() to measure time. If the function is very short, then I let it run thousand times.
unsigned long t1 = millis();
... piece of code ...
unsigned long t2 = millis();
unsigned long elapsed time = t2 - t1;
This is the single clock cycle pin toggle command:
// This is only for ATmega microcontrollers.
// They have a pin toggle command that uses a single clock cycle.
//
// In Wokwi:
// Right click this text for Command Pallette or press F1.
// then search for 'assembly' en click to View the generate assembly code.
// A new tab was created with "sketch.lst" with the assembly code.
void setup()
{
pinMode(3, OUTPUT);
}
void loop()
{
PIND = bit(PD3); // or (1 << PD3);
__builtin_avr_delay_cycles(99);
PIND = bit(PD3);
__builtin_avr_delay_cycles(999);
PIND = bit(PD3);
}
Yeah, I know (I didn't say that) ... it toggles correctly and I allowed for the cycles. It embeds the bit location in the test-point width (in 62.5ns increments) which might be handy to identify multiple test points on a logic trace.
Timing:
I like micros() for the improved resolution (4μs) which doesn't have the jitter of millis().
When measuring time, millis() skips a beat at the meaning of life (42).