Programming the timer/counter(s)

Hello!

Some time ago I got my new Arduino Mega 2560 for experimenting. Immediately I had an question in mind:

Q: Is it possible to load a new TCNT into a counter on ATmega2560 while it is is counting up/down the previous TCNT without affecting the current counting? So is there something like a preload register from where a new TCNT will be automatically loaded into the timer?

I Have used the old famous Z80 processor and it's peripherals in automatic wood lathes. Particularly the properties of the CTC, counter timer circuit, have been essential accomplishing that. The Z80 CTC can receive a new time constant into a preload register (or how was it called) and after zero count the new constant is loaded into the counter without losing a nano second so to say.. So it is easy to achieve a perfect synchronization that I need.

One more Q: Where can I find an Assembler for the micro controller if I need it?

Thanks, Juha Immonen

Is it possible to load a new TCNT into a counter

What is a TCNT?

The data sheet for the processor is here:- www.atmel.com/Images/doc2549.pdf That will tell you.

Or put another way: yes you can update a TCNTn register on the fly, but it can be tricky to get this right (because for some counters its a 16 bit register and such updates take more than one instruction and the counter is still counting under your feet).

And of course it affects the current counting, its the count register!

Is it possible to load a new TCNT into a counter on ATmega2560 while it is is counting up/down the previous TCNT without affecting the current counting?

First of all, why do you want to load something into the counter without affecting its counting? That doesn't make sense to me.

Secondly, the classic way of loading an offset to a counter is

TCNTx += OFFSET;

That will work most of the times, but has some issues:

1) In between the reading and adding, TCNTx has advanced, usually by two ticks. So usually you want to do TCNTx += OFFSET + ERROR_TERM; instead; 2) In the case of roll-over in between the reading / adding, this approach can be materially off. This happens with 8-bit or 16-bit timers.

More reliable approach is a) a double read; or b) stop the timer, revised its count factoring the stopage, and reactivate the timer. Then there is the issue of interrupts.

And if we knew what you wanted to achieve it might suggest an alternative way to do it that doesn't have issues like this.

Thanks everybody and sorry that I have not been able to reply to your messages. Ok then..My application is such that the counter's down count frequency is typically about 60kHz, but it can be over 100kHz, not so terribly high. After the counter reaches zero a new and usually different value has to be loaded into it without loss of any count(s). Z80 CTC (Counter Timer Circuit) has a preload register. You first load a time constant to the counter which starts to count down and then you load another time constant to the preload register. Now after the register reaches zero the value from the preload register is automatically loaded into the counter and an interrupt is generated so you can load a new value to the preload register in an interrupt subroutine etc..No ticks lost or added!! I think that if I make an interrupt subroutine for an arduino counter (needs to be only 8bits) it might be possible to do the job without loosing (or adding unwanted) counts...Arduino is still so new to me that it might take some time to do the test needed..for ex. how do I know if there has been extra counts? Well these problems usually always have a solution sooner or later.

I want to explain what I am actually trying to achieve. I have made 5 processor controlled wood lathes so far. Actually they are not like the usual lathes because the pieces the make don't need to have rotational symmetry, they can have any shape that the geometry of the cutting blade can reach. There are 3 axis in the lathes. One for pushing a stick (about 2m max.) of raw material, another for rotating it and third that moves the cutting blades up and down. Everything has to work in absolute synchrony of course unless one wants to lathe a wooden corkscrew, hehee!! My initial question in mind a more accurate description of the 3:rd axis is in place: Every rotation of raw material is divided into certain number of intervals ( i have used 12400 to 40000). The part of my program that controls the 3:rd axis simply put reads data that can be simplified so it basically looks like this: del0 com0, del1 com1, del2 com2.........deln comn, where deli means a delay (part of the above mentioned interval) which actually is a value to be loaded into a counter and comi is a command for the stepper motor that moves the cutting blades and it can have three "values" 0=step cw, 1=step ccw and 2=no step. So the problem or question here is: how to reproduce this using arduino so that i don't loose synchrony.

it might be possible to do the job without loosing (or adding unwanted) counts.

It is very doable, but with limitations. Unlike a double-buffered mechanism, on an avr, writing to the CTC counter is transparent and immediate. That usually isn’t an issue when your new CTC is sufficiently long so that the timer has not advanced beyond it during the isr latency period. Otherwise, your actual roll-over will be too long.

Don't you want to count up? Eg. using CTC mode? You will get an interrupt when the counter is reached (eg. OCR0A), the counter is cleared and it keeps counting. Then you have plenty of time to load a new value into OCR0A (or whatever register for the timer, eg. OCR1A).

You won't miss any counts them.

In other words, I wouldn't fiddle with the TCNT register, but with what it is counting up to.

Hi Nick!

Do you mean that if i load a new value to eg. OCR0A even if it has counted up a bit after reaching the former value, it will count to the new value without starting from 0?

So, is the following a correct sequence of event?:
1.) I load a value, let’s call it TC0 to the counter
2.) counter reaches TC0, generates an interrupt and keeps on counting
3.) because of some delay it counts up to N before a new value, TC1 is loaded
4.) after the value TC1 is loaded the counter counts to that value starting from N+1 (N<TC1 of course)

Thanks,
Juha

Yes, I believe so. In particular because the datasheet says:

If the new value written to OCR0A is lower than the current value of TCNT0, the counter will miss the compare match. The counter will then have to count to its maximum value (0xFF) and wrap around starting at 0x00 before the compare match can occur.

That suggests that you can change the limit on the fly, and it is warning you that if the new limit is lower than the current count it will overshoot. But if you quickly change the limit, before it is reached, it will stop at the new limit.

Well..after reading the specs more carefully i think: Problem solved!! Thanks a lot Nick! I have to test for this, please reply if you have anything else Juha