Timer - time is wrong

Hello,
I have a problem with a timer and i really dont get what the problem is.
It is an arduino Mega1280 board and i am using timer3 which i believe is a 16bit timer.

So i thought, well if the prescaler is set to 128 the countintervall is:
1/(16 000 000/128) = 0,000008 seconds = 8µs

then if the timer is resetted to 0 after the overflow to the 16 bit (65536)
so it should take the timer 8µs *65536 = 524,288 ms to the Overflow.

this is how i set the timer up:

 /* First disable the timer overflow interrupt while we're configuring */
  TIMSK3 &= ~(1<<TOIE3);  

  /* Configure timer2 in normal mode (pure counting, no PWM etc.) */
  TCCR3A &= ~((1<<WGM31) | (1<<WGM20));  
  TCCR3B &= ~(1<<WGM32);  

  /* Select clock source: internal I/O clock */
  ASSR &= ~(1<<AS2);  

  /* Disable Compare Match A interrupt enable (only want overflow) */
  TIMSK3 &= ~(1<<OCIE3A);  

  TCCR3B |= (1<<CS32)  | (1<<CS20); // Set bits  
  TCCR3B &= ~(1<<CS31);             // Clear bit  
  tcnt3 = 0;
  TCNT3 = tcnt3;
ISR(TIMER3_OVF_vect) {  
  /* Reload the timer */
  TCNT3 = tcnt3;  
  Serial.println(millis()-measure);
  measure = millis();
}

Now i get 4194 mS on the serial monitor…
what is wrong with this?

is the Clock really 16Mhz or do i have to measure it first du get real times in seconds?

Is this timer connected to any pin ? i dont need any connection of the timer to any pins, because i use every pin on the board for something else.
can i use timers, just without anything happing with pins?
-Flo

Can you show the whole thing and not just snippets?

 /* Configure timer2 in normal mode (pure counting, no PWM etc.) */
  TCCR3A &= ~((1<<WGM31) | (1<<WGM20));  
  TCCR3B &= ~(1<<WGM32);

How about:

 TCCR3A = 0;
 TCCR3B = 0;

Then we know it is all reset.

ISR(TIMER3_OVF_vect) {  
  /* Reload the timer */
  TCNT3 = tcnt3;  
  Serial.println(millis()-measure);
  measure = millis();
}

Don’t do serial prints in an ISR.

  TCCR3B |= (1<<CS32)  | (1<<CS20); // Set bits

This is Timer 3 so it should be CS30:

  TCCR3B |= (1<<CS32)  | (1<<CS30); // Set bits

See page 161 of the datasheet.

Those bits would give you a prescaler of 1024. There is no prescaler of 128 for Timer 3.

is the Clock really 16Mhz or do i have to measure it first du get real times in seconds?

It will be a code problem.

void setup() {
  Serial.begin(115200);
  //TIMER EINRICHTEN
  
  /* First disable the timer overflow interrupt while we're configuring */
  TIMSK3 &= ~(1<<TOIE3);  

  /* Configure timer2 in normal mode (pure counting, no PWM etc.) */
  TCCR3A &= ~((1<<WGM31) | (1<<WGM20));  
  TCCR3B &= ~(1<<WGM32);  

  /* Select clock source: internal I/O clock */
  ASSR &= ~(1<<AS2);  

  /* Disable Compare Match A interrupt enable (only want overflow) */
  TIMSK3 &= ~(1<<OCIE3A);  

  /* Now configure the prescaler to CPU clock divided by 128 */
  TCCR3B |= (1<<CS32)  | (1<<CS30); // Set bits  
  TCCR3B &= ~(1<<CS31);             // Clear bit  

  
...
  

  tcnt3 = 0;
  /* Finally load end enable the timer */
  TCNT3 = tcnt3;  
}
/* 
ISR(TIMER3_OVF_vect) {  
  /* Reload the timer */
  TCNT3 = tcnt3;  
  /* Write to a digital pin so that we can confirm our timer */
  PORTK = outputs;   
  clock = true;  
  done = false;
 
  Serial.println(millis()-measure);
  measure = millis();
}  
/*

Thank you!
Cool now it works, the problem was that I assumed it to be an 128 Prescaler.

What about the pins, can i use all timers without any relation to the pins?

-Flo

Just for understanding the whole thing better :

TIMSK3 $= ~(1<<TOIE3);

means

the byte TIMSK3 which is 0000 0000 after initializing it

should be set to itself connected by the AND Operator with the following:

the BIT TOIE3 is the last bit of TIMSK3 so it is zero.

this means the decimal number 1 which is 0000 0001 gets shifted 0 to the left.
after this it will be negated so it is
1111 1110
which again is AND conncted to TIMSK3
so

0000 0000 & 1111 1110 = 0000 0000;

super … = )

now the next bit operator :

TCCR3A &= ~((1<<WGM31) | (1<<WGM30));

TCCR3A is the initial byte (0000 0000)

WMG31 is the second bit (bit 1) of this byte it has the value 0
WMG30 is the first bit (bit 0) of the same byte, its value is also 0

now the operations beggining from the right

the number 1 (0000 0001) gets shifted 0 positions (value of WGM30) to the left → 0000 0001
then the same with WGM31 → 0000 0001

these two bytes are connected by OR which leads to this byte : 0000 0001
this byte is negated → 1111 1110
and the byte TCCR3A is set to itself connected by and with this byte so:
0000 0000 & 1111 1110 → 0000 0000;

now the next operator :

TCCR3B &= ~(1<<WGM32);

TCCR3B is again a byte with the values 0000 0000

WGM32 is the fourth bit (bit 3) of this byte and has the value 0

the number one gets shifted 0 positions to the left → 0000 0001
and is negated ->1111 1110
then TCCR3B is set to itself and connected with it:

0000 0000 & 1111 1110 = 0000 0000

next operator :

ASSR &= ~(1<<AS2);
ASSR is a byte with the initial values 0000 0000

AS2 is the 6th bit (bit 5) of it and has the value 0
the number 1 gets shifted 0 positions to the left and is negated → 1111 1110
ASSR is set to itself and connected with this
0000 0000 & 1111 1110 = 0000 0000

next operator :

TIMSK3 &= ~(1<<OCIE3A);

TIMSK3 is a byte (0000 0000)
OCIE3A is its second bit (bit 1) with the value 0
number one is shifted 0 to the left and negated then TIMSK3 is set to itself & connected with it again

we get 0000 0000 again.

next operator:

TCCR3B |= (1<<CS32) | (1<<CS30);

TCCR3B is a byte (0000 0000) (initialized)
CS32 and CS30 are bits if it with the initial value 0

then it is 0000 0001 | 0000 0001 = 0000 0001
and TCCR3B is set to itself OR connected to it :
0000 0000 | 0000 0001 = 0000 0001

next operator :
TCCR3B &= ~(1<<CS31);

TCCR3B is 0000 0001

CS31 is the second bit(bit 1) and is 0 - > the number one gets shifted 0 to the left and is negated → 1111 1110
TCCR3B is set to itself & connected with it:

0000 0001 & 1111 1110 = 0000 0000;

NOW What do i missinterpret here? = )

You mustn't call Serial.print in an interrupt routine! That's going to block all the other interupts for several milliseconds...

okay, but what about those bits and bytes?

  TIMSK3 &= ~(1<<TOIE3);

This is just a standard way of clearing a bit. You take a bit (in this case 1 << 0, namely 1) so it looks like this:

0b000000001

Then you take the 1’s complement, giving:

0b11111110

Then you bit-wise “and” it to the original field (TIMSK3) so that all the other 7 bits are unchanged, but the target bit is cleared:

0bxxxxxxx0

Where “x” is “unchanged”.

Personally I would just do this, as I said, as it makes it clearer you are starting afresh with the timer:

TCCR3A = 0;
TCCR3B = 0;
TIMSK3 = 0;

All this other stuff is just waffle - unless you are planning to flick bits on and off midstream.

So ditto for the remaining 2/3 of your question. It’s the same thing again. And you can see how much more complicated it is than the 3 lines I posted.


TCCR3B |= (1<<CS32)  | (1<<CS30);

That’s just setting those two bits (since we are “or” ing them in, not inverted).

There is macro that does the bit shifting, it makes it look a bit neater:

TCCR3B |= _BV (CS32) | _BV (CS30);

HI,
thanks for your answer!
I got it now. The main thing i didnt know is that

TOIE3 and those other bits which are used to shift the number one are constants with the value of their bitposition,

so if to if it is the first bit from the right TOIE3 is equal to 0
if it is the fifth then it is equal to 6,
so it all makes sense because i always get a bitmask for the specific bit i want to do something with.

so it s like this for example (dont mind the syntax)
define TOIE3 = 3;

1<<TOIE3 = 0000 1000

now again the last thing to understand about those timers is still if they are connected to any pins or not,
I dont want them to be, because i use every pin.

Only if you want them to be. Connecting them to a pin takes a particular bit. Causing an interrupt takes a different bit. So you can connect them to a pin, have an interrupt, or neither.

cool, thank you.
Do you know if Timer4 is used for something else and if it is also an 16 bit timer?
is there a possibilty to do an interrupt when the timers count number is at a certain point?

EDIT

  noInterrupts();
  //TIMER3 EINRICHTEN
  TIMSK3 = 0;
  TCCR3A = 0;
  TCCR3B = 0;
  OCR3A = 10;   
  ASSR &= ~(1<<AS2);  
  TIMSK3 |= (1<<OCIE3A);  
  /* Setze Prescaler auf 64 */ 
  TCCR3B |= ((1<<CS31) | (1<<CS30));  // Setze bit CS32   
  TCCR3B &= ~(1<<CS32); // Setze Bit CS31 und Bit CS30 auf 0
  interrupts();

the Compare Match interrupt, does not work

the comparte match interrupt routine is not called :

ISR(TIMER3_COMPA_vect)                                       // Interrupt service run when Timer/Counter2 reaches OCR2A
{  
  PORTK=0b00000000;
}

i cannot see anthing wrong here

I could solve the problem;

The OCR3A register is actuallay a package of two 8 bit registers:
OCR3AH (high byte) and OCR3AL (lowbyte)

so i have to set those two bytes so that they form together a 16bit number which is bigger then the
TCNT3.
Now it works fine.