[ Log In ]
Thumbnail: quad buffer line driver 74HC126E

Quad Buffer Line Driver (Through Hole)

Image of the Atmega324p


Serial to USB converter with Micro USB cable

USB to Serial Converter

Thumbnail: Crystal Oscillator 18.432 MHz for UART

18.432 MHz Crystal Oscillator 18pf 30ppm

Thumbnail: 22 pF Capacitor

22 pF Multilayer Ceramic Capacitor

Thumbnail: Quartz crystal oscillator - 16 MHz

16 MHz Crystal Oscillator 20 pF Through Hole

Thumbnail: 4x4 keypad top view.

4x4 Keypad with Adhesive Backing

USB AVR programmer

USB AVR Programmer

3 pin slide switch

SPDT Slide Switch 3 pin 30V

Handheld auto range multimeter

Handheld Auto Ranging Digital Multimeter

Skip Navigation Links

Microcontroller - A Beginners Guide - Basic and Default Usage of a Timer and Counter and The Microcontroller Clock

Timers and counters are so important that you will find many examples throughout this tutorial series. As the name implies, timers can tell the time and count. Counting and timing allows for some really cool things, like controlling the brightness of LEDs, controlling the angle of servo shafts, receiving sensor data that transmit in PWM (Pulse Width Modulation - more on that in another tuorial), making a timer (like on the stove), or just simply adding a time variable to your microcontroller project.

But first, it's important to know that there is a clock inside (or outside) the AVR microcontrollers. In fact, all microcontrollers have clocks in them (or use one that resides outside of a microcontroller). Microcontrollers need clocks so the our programs can be executed in rythm with the clock. This is the basic function of microcontrollers. A basic instruction is processed when a tick from the clock passes. Just like these programs we are writing, as clock ticks pass, instructions are processed in time with the ticks of the clock.

The timer and counter functions in the microcontroller simply count in sync with the microcontroller clock. However, the counter can only count up to either 256 (8-bit counter), or 65535 (16-bit counter). That's far from the 1,000,000 ticks per second that the standard AVR microcontroller provides. The microcontroller provides a very useful feature called prescaling. Prescaling is simply a way for the counter to skip a certain number of microcontroller clock ticks. The AVR microcontrollers allow prescaling (skipping) numbers of: 8, 64, 256 and 1024. That is, if 64 is set as the prescaler, then the counter will only count every time the clock ticks 64 times. That means, in one second (where the microcontroller ticks one million times) the counter would only count up to 15,625. you could see that if the counter counts up to that number, then you would be able to blink an LED every second.

Mainly, timers have a register for control, and a register that holds the count number. The control register contains some switches to turn on and off features. And you guessed it... one of the features is which prescaling to select. The control register is called TCCR0 or TCCR1 (Timer/Counter Control Register). The TCCR0 is the 8-bit control register and only has an 8-bit control register, so there is only 8 switches to turn on and off. TCCR1 is 16-bit, so it has 16 switches to turn on and off, but it comes in two 8-bit registers labeled A and B (TCCR1A and TCCR1B). The switches are as follows: FOC (force Output Compare), WGM (Waveform Generation Mode), COM (Compare Match Output Mode) and CS (Clock Select).

The register that holds the count is called the TCNT register. And there is an 8-bit version (TCNT0) and a 16-bit version (TCNT1). The TCNT1 register actually gets its number from two other 8-bit registers to create a complete 16-bit number, but that is all done behind the scenes (abstracted) so you don't need to worry about how the TCNT1 gets this ability to have 16-bit, just think it's magic.

In the video, two programs were shown: one that just shows a single LED blinking at approximately 1 second, and another program that has one row of 7 LEDs chasing every second, and another row of 7 LEDs chasing each at 1 second. The latter program is shown here since it has the most features used with the 16-bit timer.

Without being repetitive from previous posts, the program initializes the ports for the LEDs and sets the timer/counter #1 (the 16-bit timer). The TCCR1B control register is used to set the prescaling factor of 64 with the CS10 and CS11 switches.

Since we want one of the 7 LEDs to chase 1/7th of a second each, we take the number 15,625 (1000000/64 - remember the 1000000 is the 1 mhz clock of the micrcontroller) and divide it by 7 to get ~2,232.143. Now, you're saying, but you use only 2232 in the pogram!! that's because TCNT1 will only accept integer (no decimals). Now you're saying, the timing will be off by the amount of the decimal!! True, but the AVR internal clock is +/- 10% inaccurate anyway. If an external crystal is used, you sould use a perfect number that represents the appropriate count.

You will notice that the TCNT1 is also reset to zero manually. This is needed otherwise the TCNT1 will keep counting past the 2232 condition that was set. There are other control features that has an automatic zeroing of this number, but we will get to that in another tutorial. The remaining parts of the program is using stuff we learned i previous tutorials (LED turning on and off and arrays).

#include <avr/io.h>
int main(void)
DDRB = 0b01111111;
PORTB = 0b00000000;
DDRD = 0b01111111;
PORTD = 0b00000000;
TCCR1B |= 1<<CS10 | 1<<CS11;
int LEDNumber[2];
if (TCNT1 > 2232)
TCNT1 = 0;
PORTB = 1<<LEDNumber[0];
LEDNumber[0] ++;
if (LEDNumber[0] > 6)
LEDNumber[0] = 0;
PORTD = 1<<LEDNumber[1];
LEDNumber[1] ++;
if (LEDNumber[1] > 6)
LEDNumber[1] = 0;