CTC mode in ATmega168

Go To Last Post
8 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I tried to use Timer1 in ATmega168 in CTC mode, but it's not working as intended.

The code fragments are given below.

//Timer intialisation

TCCR1B |= (1 << CS12) |(1 << CS10); 

TCCR1B &= ~(1 << CS11);

TCCR1B |= (1<<WGM12);

TCCR1A &= ~((1<<WGM11)|(1<<WGM10));

TIMSK1 |= (1<<OCIE1A);

TCNT1 = 0;

OCR1A = 7200;

sei();

//Interrupt function

ISR(TIMER1_OVF_vect){

}

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Embedded Freak wrote:
it's not working as intended

 

What where you expecting to happen?

 

What is actually happening?

How are you observing that? (Oscilloscope? Debugger with breakpoint in ISR? Or...?)

 

At what clock frequency is your ATmega168 running?

How have you proved that?

 

Do not post code fragments. Post a minimal but complete program that builds and runs and demonstrates the problem.

 


 

Also: Learn how to post code so that it comes out neatly when showed in a post:

 

"He used to carry his guitar in a gunny sack, or sit beneath the tree by the railroad track. Oh the engineers would see him sitting in the shade, Strumming with the rhythm that the drivers made. People passing by, they would stop and say, "Oh, my, what that little country boy could play!" [Chuck Berry]

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

"TIMER1_OVF_vect" is wrong.
Correctly it is "TIMER1_COMPA_vect".

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes, I have tried both ISR. Still, the interrupt function is not executing. 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I was just trying to run the CTC mode. The original program is too long that's why I posted only the fragments. I was developing a code and was trying to create a delay of 0.5 sec. The clock frequency is 14.7456 MHz and I have used a pre-scalar of /1024. I am trying to light up an led in the ISR function. I don't know if the timer is working properly. Is the initializing correct. I think something is wrong in it, but I couldn't find it. 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Did you verify the smallest code you represented?
I simulated it and confirmed that there was no problem except that the interrupt vector number was incorrect.

The problem will be elsewhere.

 

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/cpufunc.h>

int main(void)
{
	TCCR1B |= (1 << CS12)| (1 << CS10); 
	TCCR1B &= ~(1 << CS11);
	TCCR1B |= (1 << WGM12);
	TCCR1A &= ~((1 << WGM11)| (1 << WGM10));
	TIMSK1 |= (1 << OCIE1A);
	TCNT1 = 0;
	OCR1A = 7200;
	sei();
    while (1) 
    {
		_NOP();
    }
}

ISR(TIMER1_OVF_vect){
	_NOP();  // It is not executed here.
}

ISR(TIMER1_COMPA_vect){
	_NOP();  // If not, the program counter will be 0.
}	

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
TCCR1B |= (1 << CS12) |(1 << CS10); 
TCCR1B &= ~(1 << CS11);
TCCR1B |= (1<<WGM12);
TCCR1A &= ~((1<<WGM11)|(1<<WGM10));
TIMSK1 |= (1<<OCIE1A);
TCNT1 = 0;
OCR1A = 7200;

//the above is a bit clumsy

TCCR1B = 0;
TCCR1A = 0;
TCNT1 = 0;
OCR1A = 7200- 1;
TCCR1B = (1 << CS12) | (1 << CS10) | (1<<WGM12); 
TIMSK1 |= (1<<OCIE1A);
...
...

ISR(TIMER1_COMPA_vect)
{
 
}

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
TCCR1B = (1 << CS12)| (1 << CS10) | (1 << WGM12);

is surely more "readable" than three separate RMWs?

 

Only use |= and &~= for later bit setting once everything is configured. During configuration use = direct assignment.