Timer Counter w/ Atmel Studio 7 & UNO Serie (Episode#06)
Let’s start with a new peripheral: Timer Counter!
But now let’s toggle LED at every 5 milliseconds using Timer Counter Zero or One.
We are going to start off where we were in previous episode#05 (we have an interruption generated when we push the button attached on Arduino Pin 7:)
Step#01→ Timer Zero. On page 101 of the Atmega328p data sheet we encounter ( 12.7.2 Clear Timer on Compare Match (CTC) Mode).
The waveform frequency (f) is defined by the following equation:
foc = foc_CPU/2*N[1+OCRnx]The N variable represents the prescale factor (1, 8, 64, 256, or 1024);
foc is the frequency output on compare match;
foc_CPU is the frequency of our Arduino(16 MHz) cpu;
OCRnx is the , the OC0A output that can be set to toggle its logical level on each compare match.
Good!
Step#02→ If we calculate what is the highest frequency we can get with 8-bits counter (Timer0) we have…
foc = 16000000/2*1024*[1+255]
foc = 30,5175781252⁸= 256–1=255 (zero base count)
note: The counter will pop up 30 times per second; It is great for operations with communication, but very fast for interactions with humans:/
Step#03→ Let’s try out Timer One! (16-bit log:) on page 131 of the Atmega328p data sheet;
Let’s scale down a bit our prescale to 256:
foc = 16000000/2*256*[1+65535]
foc = 0,4768371582031252¹⁶ = 65536–1= 65535 (zero base too)
note: This will works quite nicely for us; It will overflow pretty much twice a second:)
Step#04→ Now coding! First thing to do is comment the sleep mode; so leave it so that we can have a sequence in our code.
The counting sequence is determined by the setting of the Waveform Generation mode bits (WGM13:0) located in the Timer/Counter Control Registers A and B (TCCR1A and TCCR1B).
There is nothing for us on TCCR1A (we want normal mode operation) so we’re going to TCCR1B register straight away (page 136):
TCCR1B |= (1 << CS12);note: this set the Clock Select Bit Description is equal to 256 prescaler (0b100 )
Step#05→ Go to this part of data sheet (page 136 ):
13.11.8 TIMSK1 — Timer/Counter1 Interrupt Mask Register
And set this code:
TIMSK1 |= (1 << TOIE1);note: Bit 0 — TOIE1: Timer/Counter1, Overflow Interrupt Enable:)
Step#06→ Go to the top of our code (already there!):
#include <avr/interrupt.h>Step#07→ Enable interrupts (already there!):
sei();
while() {...}Step#08→ Implement our Interrupt Service Routine (ISR):
Head over 12.1 Interrupt Vectors (page 137) in ATmega48A and ATmega48PA of ATMega238p data sheet and find the vector of interest out.
Write it down:
ISR(TIMER1_OVF_vect)
{
LedToggle;
}note: Now the LED is toggle automatically at roughtly each 5 secs :) and there you have it!
In the next post we’re gonna control the timer that toggle the LED a little bit precisely using the output compare mode.
Stay tuned! Bye!
Here is the code till here:
https://github.com/giljr/avr/tree/master/atmel
Look for Episode #06 ;)
References & Credits
Follow along with the entire ‘Getting Started with AVR’ series: http://bit.ly/GettingStartedwithAVR
→Goto Episode#07
Complete Serie:
#00 HowTo-Load-Into-Arduino-AS7
#06_Timer Counter
#08
#09
#10
