Timer in CTC mode in Atmega-16

Timers in CTC Mode

Till now, we were dealing with the basic modes of timer 0 and timer 1. In this article, we are going to dig deeper about the timer and understand about timer in CTC mode. This is important for PWM(Pulse Width Modulation). For this tutorial, we need you to know about the timer and its operation.

CTC mode

In timer, what we have done until now is setting the value of it and waiting for it to overflow. A timer in CTC mode allows us to compare a value which lies in the middle of timer initialization value and timer overflow. When the value of timer and our desired value becomes equal, we can do an action say- turning off an LED. I know, what are you thinking, we can do this by simple if-else condition and compare each value of timer with our desired value and when the match occurs, you can do things. Well, we can do that, but that is not why you are here for. In this article, you are going to learn about timer in CTC mode and about different ways to use it. This is going to a bit long article than I usually write, but there are a lot of things to talk about in this article.

CTC Mode using Status Register

We can monitor a bit in a status register to know if a particular event occurred or not. These bits are called flag. So, flags are essentially the bits of the status registers that changes its value on some particular event.

Now you may think why it is better than the above-suggested method?

Well, as you are coding the comparison value in the microcontroller itself, it saves up the unnecessary usage of machine cycle which lead to the accurate generation of the waveform, which is basically the requirement. So, when this flag “set”, the timer resets automatically and thus goes the name- Clear on Timer Comparison-CTC. Here I am using this mode on Timer 1 of Atmega-16.

Registers to know about

TCCR1A and TCCR1B Registers

Timer in ctc mode - avr

ctc interrupt timer

In TCCR1B and TCCR1A register, there are bits like WGM13: WGM10. Sure, you need more bit to set up a timer but I am assuming that you already have an idea about the timers. If you don’t please read this article first. Below is the table that gives us the values of these bits.

OCR1A and OCR1B Registers

Learn timer in ctc mode

These guys store the value to compare. We can use any one of them or both of them because, in Atmega-16, there are two CTC channels.

TIFR Register

Timer in atmega 16

This is a common register for all the timer in Atmega-16. The bits of our interesting is OCF1A and OCF1B. These bits set high whenever the timer value and the compared value are equal, these flags are “set”. We need to monitor these flags in our code. This method is a polling method because we are continuously checking the status of the flag bit.

The Program

So for CTC mode, I have to set the bit for WGM12 and also, in that register, you have to select the prescaler, so select your bits accordingly. Next is initializing the counter and give the desired value to OCR1A. In the while loop, check if the OCF1A bit is set or not. If it is set, you can do whatever you want to do-like turning on the LED(stuff like that), after the task, you have to clear the flag as it doesn’t clear automatically. Please click on this link if you want to know about prescalers, I have discussed it in my earlier post.

#include <avr/io.h>

void timerinctcinit()
{
	TCCR1B=(1<<WGM12)|//select your prescaler;
	TCNT1=0;
	OCR1A=40000;//insert the comparision value.
	
}

int main(void)
{
	timerinctcinit();
	
    while (1) 	
    {
		if(TIFR&(1<<OCF1A))
		{
			//do your stuff, like blink an LED
			//clear the flag now, by writing 1 to it.
		}
		
}

Well, the above method is good but there is another way to do that which is elegant. An Interrupt method. There is an interrupt in an AVR for you so that you don’t need to check the value for every execution cycle. Whenever a match occurs, an ISR(Interrupt Service Routine) is executed which you have written. Let us now learn on how we can do that.

Interrupt method for Timer in CTC mode

TIMSK Register

As I am using timer 1, therefore the bit we need to “set” is OCIE1A or B, depending upon the timer channel you are using. Because there is two CTC channel, we have two bits for their activation. On setting these bits, whenever the value becomes equal, the OCF1 flag is high and thus, an interrupt is fired for which you have to write an Interrupt Service Routine.

The Program using ISR

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

void timerinctcinit()
{
	TCCR1B=(1<<WGM12)|//select your prescaler;
	TCNT1=0;
	OCR1A=40000;//insert the comparision value. I have selected a random value between - to 65536
	TIMSK=(1<<OCIE1A);  //enabling the compare match interrupt
        sei();
}

int main(void)
{
	timerinctcinit();
	
    while (1) 	
    {
		// do nothing as the comparision event is managed in interrupt.
	}
		
}
ISR(TIMER1_COMPA_vect)
{
	// Do your stuff here like blinking an LED.
}

As you can see, you are not checking the flag every time instead, an interrupt is fired which is doing your work. This method is more accurate and elegant than the previous one because that method is a polling method and this is an-yes you guessed it right Interrupt Method. For more differences between these two.

That’s it for this article, there are still two more ways to discuss. But I will discuss those in upcoming articles. Until then, do follow us on the social media, share this article with your friend who is into electronics and peace out!

Leave a Comment

Your email address will not be published. Required fields are marked *

Share This