You are on page 1of 13

Experiment No 10

(a) Execute Timer programming in Atmel Studio 7


AVR Timer programming

Basics
Timers come in handy when you want to set some time interval like your alarm. This can be very
precise to a few microseconds.

Timers/Counters are essential part of any modern MCU. Remember it is the same hardware unit
inside the MCU that is used either as Timers or Counter. Timers/counters are an independent unit
inside a micro-controller. They basically run independently of what task CPU is performing. Hence
they come in very handy, and are primarily used for the following:
 Internal Timer: As an internal timer the unit, ticks on the oscillator frequency. The
oscillator frequency can be directly feed to the timer or it can be pre-scaled. In this mode
it used generate precise delays. Or as precise time counting machine.
 External Counter: In this mode the unit is used to count events on a specific external pin
on a MCU.
 Pulse width Modulation(PWM) Generator: PWM is used in speed control of motors and
various other applications.

Timer 0 Basics

Timer 0 is a 8 bit timer. It basically means it can count from 0 to 2^8 255. The operation of timer
0 is straight forward. The TCNT0 register hold the timer Count and it is incremented on ever y
timer "tick". If the timer is turned on it ticks from 0 to 255 and overflows. If it does so, a Timer
OverFlow Flag(TOV) is set.
You can as well load a count value in TCNT0 and start the timer from a specific count. Another
interesting feature is that a value can be set in the Output Compare Register (OCR0), and whenever
TCNT0 reaches that value, the Output Compare Flag (OCF0) flag is Set.
Timer/Counter 0

The configuration of the Timer can be set using the TCCR0 register shown below. With this you
can basically select two things:
1. The Frequency of the Clock Source with CS02, CS01, CS00 bits.
2. The mode of the timer. For the first example we will use it in normal mode where it ticks
from zero to the highest value (255)
Timer Counter Control Register 0
The Timer/counter Interrupt Flag Register (TIFR) holds the two basic flags we need the TOV and
OVF. Other bits correspond to the timer interrupts, which we will look at in another tutorial.
Timer/Counter 0 Flag Register

Example Code:
#include<avr/io.h>
#define LED PD4

int main()
{
uint8_t timerOverflowCount=0;
DDRD=0xff; //configure PORTD as output
TCNT0=0x00;
TCCR0 = (1<<CS00) | (1<<CS02);

while(1)
{
while ((TIFR & 0x01) == 0);
TCNT0 = 0x00;
TIFR=0x01; //clear timer1 overflow flag
timerOverflowCount++;
if (timerOverflowCount>=6)
{
PORTD ^= (0x01 << LED);
timerOverflowCount=0;
}
}
}
Timer 1 Basics
The Timer 1 is 16 bit, that means it can count from 0 to $$2^{16} = 65536$$. Hence the
Timer/Counter 1 is a 16 bit registered formed out of TCNT1H and TCNT1L as shown below.
Timer/Counter 1

Timer 3 also has 2 control registers which allow us to configure it and use it in any mode you wish.
Timer Counter Control Register 1A

Timer Counter Control Register 1B

Yes, and indeed we have a Flag register which will tell us the status of Timer 1 as shown below.
Timer/Counter 1 Flag Register

Example code:
#include<avr/io.h>
#include <util/delay.h>
#define LED PD4
int main()
{
DDRD |= (1<<LED) ; //configure led as outpout
TCCR1B = (1<<CS10) | (1<<CS12); //set the pre-scalar as 1024
OCR1A = 1562; //100ms delay
TCNT1 = 0;
while(1)
{
//If flag is set toggle the led
while((TIFR & (1<<OCF1A)) == 0);// wait till the timer overflow flag is SET
PORTD ^= (1<< LED);
TCNT1 = 0;
TIFR |= (1<<OCF1A) ; //clear timer1 overflow flag
}
}

Timer 2
Well, timer 2 is pretty similar to the timers covered above. Give it a shot, should you've any
questions do comment below.
Timers are independent units from the CPU. Hence if we use timers with Interrupts, it can make
the CPU free from polling the flags every-time. This is the way they are used normally

(b) Execute serial port programming in Atmel Studio 7.


USART Serial Data Communication in AVR Microcontroller
The USART stands for universal synchronous and asynchronous receiver and transmitter. It is a
serial communication of two protocols. This protocol is used for transmitting and receiving the
data bit by bit with respect to clock pulses on a single wire. The AVR microcontroller has two
pins: TXD and RXD, which are specially used for transmitting and receiving the data serially. Any
AVR microcontroller consists of USART protocol with its own features.
USART Communication in AVR Microcontroller
The Main Features of AVR USART
 The USART protocol supports the full-duplex protocol.
 It generates high resolution baud rate.
 It supports transmitting serial data bits from 5 to 9 and it consists of two stop bits.
USART Pin Configuration
The USART of AVR consists of three Pins:
 RXD: USART receiver pin (ATMega8 PIN 2; ATMega16/32 Pin 14)
 TXD: USART transmitter pin (ATMega8 PIN 3; ATMega16/32 Pin 15)
 XCK: USART clock pin (ATMega8 PIN 6; ATMega16/32 Pin 1)
Modes of Operation
The AVR microcontroller of USART protocol operates in three modes which are:
 Asynchronous Normal Mode
 Asynchronous Double Speed Mode
 Synchronous Mode

Modes of Operation
Asynchronous Normal Mode
In this mode of communication, the data is transmitted and received bit by bit without clock pulses
by the predefined baud rate set by the UBBR register.
Asynchronous Double Speed Mode
In this mode of communication, the data transferred at double the baud rate is set by the UBBR
register and set U2X bits in the UCSRA register. This is a high-speed mode for synchronous
communication for transmitting and receiving the data quickly. This system is used where accurate
baud rate settings and system clock are required.
Synchronous Mode
In this system, transmitting and receiving the data with respect to clock pulse is set UMSEL=1 in
the UCSRC register.
USART Configuration In AVR microcontroller
USART can be configured using five registers such as three control registers, one data register and
baud-rate-selection register, such as UDR, UCSRA, UCSRB, UCSRC and UBRR.

7 Steps for Composing the Program


Step1: Calculate and Set the Baud Rate
The baud rate of USART/UART is set by the UBRR registrar. This register is used to generate the
data transmission at the specific speed. The UBRR is a 16-bit register. Since the AVR is a 8-bit
microcontroller and its any register size is 8-bit. Hence, here the 16-bit UBRR register is composed
of two 8-bit registers such as UBRR (H), UBRR(L).
The formula of the baud rate is
BAUD= Fosc/(16*(UBBR+1))
The formula of the UBRR register is
UBRR= Fosc/( 16*(BAUD-1))
The frequency of the AVR microcontroller is 16MHz=16000000; Let us assume the baud rate as
19200Bps, then
UBRR= 16000000/(16*(19200-1))
UBRR= 16000000/(16*(19200-1))
UBRR= 51.099
Eventually find the baud rate
BAUD= 16000000/( 16*(51+1))
UBRR= 19230bps
Step2: Data Mode Selection
The data transmission mode, start bit and stop bit and the character size is set by the control and
status register UCSRC.

Data Mode Selection


Step3: Data Transmission Mode Selection
The synchronous and asynchronous mode is selected by the UMSEL bit of the control status
register. If we give UMSEL=0, then the USART operates in asynchronous mode, otherwise
operates in synchronous mode.

Data Transmission Mode Selection


Step4: Start Bit and Stop Bit
The start bit and stop bits are a way for sending and receiving the data serially. Generally any data
fame consists of one stat bit and one stop bit, but the AVR microcontroller has one start bit and
two stop bits for processing the data. The extra stop bit can be useful for adding a little extra receive
processing time. It is especially useful for high data transfer rates, whereas the data transfer speed
is very high, so we don’t get proper data. Thus, we can increase the processing time by using two
stop bits to get the proper data.

Start Bit and Stop Bit


The number of stop bits is selected by the USBS bit of UCSRC – the control status register. The
USBS=0, for one stop bit, and USBS=1, for two stop bits.
Step5: Set the Character Size
As in case with the basic microcontrollers sending and receiving the byte of data(8-bits) at a time,
whether in a AVR microcontroller, we can choose a data frame format in each frame by the UCSZ
bit of the UCSRC register.

Data Frame Format


Step6: Store the Received Data
The AVR microcontroller consists of a UDR buffer register for transmitting and receiving data.
The UDR is a 16-bit buffer register wherein 8-bits are used for receiving (RXB) the data and other
bits are used for transmitting the data (TXB). Transmitting data buffer register will be the
destination to UDR register for the written data on its location. Receiving data buffer register will
be returning the content of the UDR register.
Step7: Transmitter and Receiver Enabling
The transmitted and received data will be allowed by the RXC and TXC pins of the microcontroller
which are set by the UCSRA register of the microcontroller. This flag bit set by the microcontroller
for the data is completed by receiving and transmitting (TXC=RXC=1).

Double the Baud Rate


We can double the transfer rate of the USART communication of the AVR microcontroller from
16 bits to 8-bits effectively by the U2X –bit in the UCSRA register. This bit effects only on
asynchronous operation. If we can set this bit (U2X=1), it will reduce the baud rate from 16-bit to
8-bit effectively doubling the transfer rate for synchronous communication.
This is an advanced feature of the AVR microcontroller for speedy processing of the data.
Example code:
Write an 8051 C program to transfer the message “yes” serially at 9600 baud, 8-bit data, 1 stop
bit. Do this continuously.
(c) Execute interrupt programming in Atmel Studio 7.

Basics of AVR Interrupts


Interrupts, are perhaps one of the most important pieces that you need to understand for completing
most of your micro-controller projects. Interrupts allow micro-controllers to continue doing their
main job and provide mechanism to handle all other tasks which need the controller attention.

Before we go ahead with the examples here, are a few situations where you may want to use these:
 Let's say you have a device like GSM interfaced to your Micro-controller using UART or
other serial interface. You simple do not know when you'll receive a new text message or
a call. One way to handle this is continuously monitor for the even to occur. The other way
is to configure a serial interrupt. Yes, you guessed it right, this is a Software Interrupt
indeed.
 Now let's say you're building a music player. The main task of the processor is to read and
play back the audio file. However the player should be able to play/pause/forward/rewind.
And this could happen any time. How about connecting the switches to hardware interrupt
pins? The processor will be notified any time the events happen.
Steps to configure the Interrupts:
 Set INT1 and INT0 bits in the General Interrupt Control Register (GICR)
 Configure MCU Control Register (MCUCR) to select interrupt type.
 Set Global Interrupt(I-bit) Enable bit in the AVR Status Register(SREG)
 Handle the interrupt in the Interrupt Service Routine code.

Interrupt Sources
With AVR Micro-controllers, you can configure interrupts on various sources such as:
 Port Pins : INT0, INT1 and INT2
 Timers
 UART
 SPI
 ADC
 EEPROM
 Analog Comparator
 TWI or I2C
The vector table below shows the mapping of various interrupts. Notice that the RESET interrupt
has an address of $000, the first address of the program memory indeed.
Also notice that the next interrupt starts at an offset of 2 words(AVR Memory is word addressable
1 Word = 2 Bytes). Indeed no program can be stored in 4 bytes. What it will hold is a Jump
instruction to actual Interrupt service routine(ISR) in the memory. ISR, the name might sound
fancy, but it is nothing more than a program that executes once the interrupt is generated.

Interrupt Priority
Now you might wonder, what is I configure various interrupts and two or more interrupts happen
at the same time, which will get executed? The answer is it depends on the interrupt priority. For
AVR architecture it is simple. The lower the vector address, the higher the priority. Have a look
again RESET has the highest priority as might expect and other units later.
Example code:
#include<avr/io.h>
#include<avr/interrupt.h>
#include<util/delay.h>
#include "lcd.h"
volatile int cnt_zero,cnt_one;
ISR (INT0_vect) //External interrupt_zero ISR
{
cnt_zero++;
}
ISR (INT1_vect) //External interrupt_one ISR
{
cnt_one++;
}

int main()
{
DDRC=0xff; //Configure PORTC(Lcd databus) as output
DDRD=0xe0; //Configure INT0,INT1 as input and PORTD5-
PORTD7(rs,rw,en) as output

LCD_SetUp(PB_0,PB_1,PB_2,P_NC,P_NC,P_NC,P_NC,PB_4,PB_5,PB_6,PB_7)
;
LCD_Init(2,16);

GICR=0xc0; //Enable External Interrupts INT0 and INT1


MCUCR=0x08; //Configure INT0 active low level triggered and INT1
as falling edge

sei(); // Enable global interrupts by setting global interrupt


enable bit in SREG

while(1)
{
LCD_Printf("EINT0:%4u\n",cnt_zero);
LCD_Printf("EINT1:%4u\n",cnt_one);
}
}

You might also like