Hi, I want to use the 16-bit timer in the UNO (ATMEGA328), so I can use the 16MHz resolution, ie, I need to count in 62.5nsec. I found all these timer functions, but I still don't see how can can access the "hardware" counter directly, so I capture it's value based on an external interrupt.
I need to reset the timer, and let it go on some event, and then stop it (at 62.5nsec resolution) on some interrupt and capture its value. I would appreciate any hints or referrals to documentation that may explain to me how to do this. Thank you.
Jorge
I'm not entire sure what you want here. clear some counter, enable some external interrupt source and then when the interrupt source triggers, see how many clock "ticks" have happened?
The simplest method would be to use micros(), but that only have a resolution of 4usec on an Uno. If you move to A Teensy board, you can get 1usec resolution.
If that is not sufficient and you ned to 62.5nsec resolution, then the "hardware" is simply the Timer1/Counter1 register TCT1. All the registers in the datasheet are defined in the IDE so you just read/write them like a pre-defined variable. But this may be much more difficult to implement correctly.
what do you mean why? Because my application requires it. I'm measuring events that are in hundreds of nanoseconds and the mill() or micro() won't do. The AVR on the UNO is running at 16MHz, so that is the best I can hope for. If it were running at 32MHz, I'd want that resolution instead.
Thanks @JohnRob. Would the resolution of this method be the system clock, ie, 16MHz? I'll dig into it.
To follow up on my question, though, if I were programming the AVR in assembler, I think I would be able to reset the 16-bit timer (not necessarily use the PWM function), and start it counting based on 16MHz clocks. The ISR from the edge interrupt from pin 2, for example, would then stop the timer, disable interrupts, capture its value, and reset it back to 0. I would then restart the timer sometime later, and repeat the whole thing.
I'm "newish" to using the Arduino, and I am not sure how to use the abstraction the Arduino language provides to access the low level registers in the micro so that I can use its resources beyond what Arduino language provides (or maybe the Arduino language already does provide this mechanism).
Anyway, what I'm trying to do is pretty straightforward. There is an external circuit that is enabled after the internal 16-bit timer is enabled followed by the interrupts. When the external circuit detects an event, it drives pin 2 high triggering its ISR. In that ISR, I want to capture the value of the timer/counter. I want the counter to increment at the 16MHz rate. Is this possible with the Arduino?
Is the micro not running at 16MHz? then the timer should be able to be clocked at that rate - or am I missing something?
That's the point, there is no coding --I"m trying to use the hardware timer in the micro. The only timing error should be due to the interrupt latency.
@johnwasser -- I think this code will help understand how to program the Arduino --it will help me a lot- thank you.
Did you have to import some library so that the compiler could "understand" the register names?
What is _BV? Is that an Atmel instruction or an Arduino instruction?
Can you point me to any reference material where I could see how to access the ATMEGA328 at the the register level with the Arduino language? I'll keep looking through their documentation. Thanks again.
the repeat interval can be as slow as I want, but the minimum interval from starting the timer to the external event occuring can be a minimum of around 9microseconds, but can vary by 100s of nanoseconds and I'm interested in that variation-- thus the need for the 62.5nsec/count granularity ot the counter.
great...Thank you. I'm familiar with the data sheet and the timers in AVR assembler, but was unsure about accessing the low level registers of the micro with the Arduino "higher level" language . It is the Arduino side of things that I was most unsure about.