0% found this document useful (0 votes)
2 views

Lab 08 Embedded System AVR

Lab 8 of the EE222 Embedded Systems course focuses on Timer Programming using the ATmega328p microcontroller. The lab covers the functionality and programming of AVR Timers, specifically Timer 0 and Timer 1, including their registers and modes, with an emphasis on achieving precise timing through the Clear Timer on Compare (CTC) mode. Students are required to complete tasks involving timer programming, including creating a digital stopwatch and calculating timer values for specific delays.

Uploaded by

mokishere
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views

Lab 08 Embedded System AVR

Lab 8 of the EE222 Embedded Systems course focuses on Timer Programming using the ATmega328p microcontroller. The lab covers the functionality and programming of AVR Timers, specifically Timer 0 and Timer 1, including their registers and modes, with an emphasis on achieving precise timing through the Clear Timer on Compare (CTC) mode. Students are required to complete tasks involving timer programming, including creating a digital stopwatch and calculating timer values for specific delays.

Uploaded by

mokishere
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 21

EE222: Embedded Systems

Lab 8: Timer Programming

Class: BESE-13-B

Lab instructor: Syed Zain-ul-hasan

MEMBER 1
AHMED BILAL
417936 | BESE-13-B

1
EE222: Embedded Systems

Lab 8: Timer Programming

Class: BESE-13-B

Lab instructor: Syed Zain-ul-hasan

MEMBER 2
ALI AMAR
426014 | BESE-13-B

2
EE222: Embedded Systems

Lab 8: Timer Programming

Class: BESE-13-B

Lab instructor: Syed Zain-ul-hasan

MEMBER 3
MUHAMMAD ZAID
416952 | BESE-13-B

3
EE222: Embedded Systems

Lab 8: Timer Programming

Class: BESE-13-B

Lab instructor: Syed Zain-ul-hasan

MEMBER 4
MUHAMMAD ZOHAIB
413441 | BESE-13-B

4
Lab 8: Timer Programming
EE222: Microprocessor Systems

Contents
1 Acknowledgements..........................................................................................................................2
2 Administrivia.....................................................................................................................................2
2.1 Learning Outcomes..........................................................................................................................2
2.2 Deliverable........................................................................................................................................2
2.3 Hardware Resources........................................................................................................................2
3 Introduction.......................................................................................................................................3
3.1 AVR Timers.......................................................................................................................................3
3.2 AVR Timer 0 programming.............................................................................................................3
3.2.1 Timer Counter Zero (TCNT0)......................................................................................................3
3.2.2 Timer Counter Control Register Zero (TCCR0)..........................................................................3
3.2.3 Output Compare Register Zero (OCR0)......................................................................................4
3.2.4 Timer 0 Interrupt Flag Register (TIFR0)....................................................................................4
3.3 AVR Timer 1 programming.............................................................................................................4
3.3.1 Timer Counter One (TCNT1).......................................................................................................4
3.3.2 Timer Counter Control Register One (TCCR1)...........................................................................4
3.3.3 Output Compare Register One (OCR1).......................................................................................5
3.3.4 Timer 1 Interrupt Flag Register (TIFR1)....................................................................................5
3.3.5 Timer 1 CTC Mode (Clear Timer on Compare)...........................................................................5
3.3.6 Timer 1 CTC Mode Example.........................................................................................................6
4 Lab Tasks............................................................................................................................................7
4.1 Task A................................................................................................................................................7
4.2 Task B................................................................................................................................................7
4.3 Task C................................................................................................................................................7

5
1 Acknowledgements
This lab exercise is prepared by Mohammad Azfar Tariq and Muhammad Usman under the
supervision of Dr. Rehan Ahmed for the course EE-222 Microprocessor Systems, focusing on the
ATmega16 microcontroller. Later on, the lab was revised for the ATmega328p Arduino Uno-
based microcontroller by Lab Engr. Shaiza. Reporting any errors or discrepancies found in the
text is appreciated.

2 Administrivia
2.1 Learning Outcomes
By the end of this lab you will be able to;

1. Use Timers/Counters features of ATmega328p.

2. Create calculated, precise delays through timers.

2.2 Deliverable
You are required to submit

• Appropriately Commented Code

• Explicit Calculations for Timer Values

• Issues in Developing the Solution and your Response in the beginning of next lab

2.3 Hardware Resources


• Arduino Uno board with ATmega328p microcontroller

• Seven Segment Display x2

• Resistance 47Ω x2

• Switches

6
3 Introduction
3.1 AVR Timers
Timers are special registers in microcontrollers/microprocessors whose value increment
with every clock tick. In AVR, there are three timers, Timer 0, Timer 1 and Timer 2.

3.2 AVR Timer 0 programming


Timer 0 in AVR is manipulated using registers TCNT0, TCCR0A, TCCR0B, TIFR0, OCR0A and
OCR0B.

3.2.1 Timer Counter Zero (TCNT0)


TCNT0 is an 8-bit register which can count from 0 to 255. We can also load starting value in
this register from where the counter will start its counting.

3.2.2 Timer Counter Control Register Zero (TCCR0)


This register is used to configure the timer/counter. This register has two variants TCCR0A
and TCCR0B.

TCCR0A COM0A1 COM0A0 COM0B1 COM0B0 -- -- WGM01 WGM00

TCCR0B FOC0A FOC0B -- -- WGM02 CS02 CS01 CS00

For now only CS02:CS00 bits are of importance. These bits are used to apply prescalar to input
clock frequency
CS02:CS00 Function
000 Timer Counter Stopped
001 clk (No prescalar)
010 clk / 8
011 clk / 64
100 clk / 256
101 clk / 1024
WGM02:WGM00 Mode
000 Normal Mode
010 CTC Mode

7
3.2.3 Output Compare Register Zero (OCR0)
We can load some 8-bit value in this register, such that when the value in counter matches
it, the Output Compare Flag Zero (OCF0) is raised.
OCR0A: The output compare register A contains an 8-bit value that is continuously
compared with the counter value (TCNT0). A match can be used to generate a waveform
output on the OC0A pin.
OCR0B: The output compare register B contains an 8-bit value that is continuously
compared with the counter value (TCNT0). A match can be used to generate a waveform
output on the OC0B pin.
3.2.4 Timer 0 Interrupt Flag Register (TIFR0)
-- -- -- -- -- OCF0B OCF0A TOV0

TOV0 Timer 0 overflow flag


OCF0B Timer 0 output compare B match flag
OCF0A Timer 0 output compare A match flag

To clear a flag when it is set, write “1” to it.

3.3 AVR Timer 1 programming


Timer 1 in AVR is 16-bit wide which means it can count more than Timer 0. The range of
Timer 1 is 0-65535. Timer 1 in AVR is manipulated using TCNT1 = [TCNT1H:TCNT1L], TCCR1A,
TCCR1B, TCCR1C, OCR1A = [OCR1AH:OCR1AL], OCR1B = [OCR1BH:OCR1BL] and TIFR1.

3.3.1 Timer Counter One (TCNT1)

TCNT1 is a 16-bit register divided into two 8-bit chunks TCNT1H and TCNT1L. To load a 16-
bit value into it we must separate it into two 8-bit chunks, load the lower 8-bits in TCNT1L
and higher 8-bits in TCNT1H separately.

3.3.2 Timer Counter Control Register One (TCCR1)

TCCR1 has three variants TCCR1A, TCCR1B and TCCR1C.

TCCR1A COM1A1 COM1A0 COM1B1 COM1B0 -- -- WGM11 WGM10


TCCR1B ICNC1 ICESI -- WGM13 WGM12 CS12 CS11 CS10
TCCR1C FOC1A FOC1B -- -- -- -- -- --

8
CS12:CS10 Function
000 Timer Counter Stopped
001 clk (No prescalar)
010 clk / 8
011 clk / 64
100 clk / 256
101 clk / 1024

WGM13:WGM10 Mode

0000 Normal Mode


0100 CTC Mode

The lower two bits of WGM control are in TCCR1A and the higher two bits are in TCCR1B.

3.3.3 Output Compare Register One (OCR1)

For Timer 1, there are two outputs compare registers OCR1A and OCR1B, 16-bit each, with
compare match flag OCF1A and OCF1B in TIFR1.

3.3.4 Timer 1 Interrupt Flag Register (TIFR1)


-- -- ICF1 -- -- OCF1B OCF1A TOV1

TOV1 Timer 1 overflow flag


OCF1B Timer 1 output compare B match
OCF1A flag Timer 1 output compare A
ICF1 match flag Timer 1 Interrupt Capture
Flag

To clear a flag when it is set, write “1” to it.

3.3.5 Timer 1 CTC Mode (Clear Timer on Compare)


Usually when we have to toggle a pin of microcontroller with a specific frequency, using
timer delays, some inaccuracy is induced by control instructions (housekeeping). For
example, the instructions which load the timer, change the value of output ports, clear flags,
etc. in each iteration, add some unwanted time lag in our original delay and our toggling
frequency is disturbed.
To avoid this unwanted lag AVR provides a special timer operating mode “Clear Timer on
9
Compare”. In this mode when the value in TCNT register becomes equal to the value in OCR,

1
0
the hardware clears the timer, raises OCF and start timer again all by its own in the same
Machine Cycle. No software instructions are needed in the process and a higher timing
accuracy is achieved.

3.3.6 Timer 1 CTC Mode Example


Suppose we wish to read pin 0 of port C every 500ms and send the ASCII of letter ‘L’ on port
D if its value is 0 else send ASCII of letter ‘H’ with high time precision.
If the clock frequency is 16MHz and prescalar we wish to use is clk/256 then,

Time for one tick = 256/16M = 16µs

Ticks for 500ms = 500m/16µ = 31250 = 0x7A12


#include <avr/io.h>
int main( )
{
DDRC = 0x00 ; // Set port C as
input DDRD = 0xFF; // Set port D
as output TCNT1 = 0;
//Initialize timer 1
OCR1A = 31250;// Set output compare register
TCCR1A = 0x00 ; // WGM13:WGM10 = 0100 , CS12:CS10
= 100 TCCR1B = 0x0C;
TCCR1C = 0x00;
unsigned char data ;
while (1)

{
if ( (TIFR1 & 0x02) != 0 ) // Check OCF1A flag bit
{
TIFR1 |= 0x02 ; // Clear
flag data = PINC; // Read
port C if ( ( data & 0x01)
== 0) PORTD = 'L' ;
else
PORTD= 'H' ;
}
}
}

In the example above, the time consumed by if-else statement and other instructions inside
while(1) loop will not affect the timer count because the timer has been restarted by
hardware after compare match and is running in parallel with these instructions.

Why have we used or-equals in line 16 and not simple equal? Find the answer.

1
1
4 Lab Tasks
4.1 Task A
Implement the code in example 2.3.6, just to get familiar with timer programming and paste
proper screenshots of output.

4.2 Task B
Calculate and determine the value of compare match and prescalar for timer 1 such that it
produces a precise 1 second delay for 16MHz clock. Include your calculations in the report.

4.3 Task C
In this task you are required to create a “Digital Stop Watch” that records the time in
seconds precisely (use CTC mode).
1. Connect two 7-segment-Displays with your ATmega328p.
2. Connect two switches (say Sw1 and Sw2) with your ATmega328p.
3. If Sw1 is high, the Stop Watch must get reset to zero, no matter what is the state of Sw2.
4. If Sw2 is high and Sw1 is low, the Stop Watch must display the seconds passed.
5. If Sw2 is low and Sw1 is also low, the Stop Watch must pause its time and if Sw2 is
raised again, it should resume from where it was paused.
Hint: Using timer-1 is same as using timer-0. The difference is in size of the TCNTx. The
example provided in Section 2.3.6 serves as the code template for this task. You basically
need to enhance it with your functionality.

1
2
Solution

Introduction:
This lab focuses on Timer Programming in the ATmega328p microcontroller. The lab introduces
us to AVR timers, specifically Timer 0 and Timer 1, and their various programming modes, with
special emphasis on the Clear Timer on Compare (CTC) mode for precise timing operations.
Objectives
 Learn to use Timers/Counters features of ATmega328p
 Create calculated, precise delays through timers
 Understand and implement CTC mode for accurate timing operations
Hardware used:
Arduino Uno board with ATmega328p microcontroller, Two Seven Segment Displays, Resistors
Software used:
Atmel Studio 7, AVRDUDES, Timer programming registers (Timer 0, Timer 1)

Task 1

#include <avr/io.h>
int main( )
{
DDRC = 0x00 ; // Set port C as input
DDRD = 0xFF; // Set port D as output
TCNT1 = 0; //Initialize timer 1
OCR1A = 31250;// Set output compare register
TCCR1A = 0x00 ; // WGM13:WGM10 = 0100 , CS12:CS10 = 100
TCCR1B = 0x0C;
TCCR1C = 0x00;
unsigned char data ;
while (1)
{
if ( (TIFR1 & 0x02) != 0 ) // Check OCF1A flag bit
{
TIFR1 |= 0x02 ; // Clear flag
data = PINC; // Read port C
if ( ( data & 0x01) == 0)
PORTD = 0b00111000 ;
else
PORTD= 0b01110110 ;
}
}}

1
3
Hardware Implmentation:

1
4
Task 2
Code:

#include <avr/io.h>

int main() {
// Set Port D as output
DDRD = 0xFF;

// Initialize Timer 1
TCNT1 = 0; // Start count from 0
OCR1A = 62499; // Set compare match value for 1-second
delay
TCCR1A = 0x00; // WGM13:WGM10 = 0100 (CTC mode)
TCCR1B = 0x0C; // WGM12 = 1, CS12:CS10 = 100 (prescalar =
256)

while (1) {
if (TIFR1 & 0x02) { // Check OCF1A flag
TIFR1 |= 0x02; // Clear flag by writing '1'
PORTD ^= 0xFF; // Toggle PORTD
}
}
return 0;

Calculations:
Given
 Clock Frequency (F_CPU) = 16 MHz = 16,000,000 Hz
 Required Delay = 1 second
 Prescalar = 256

Calculate Timer Tick Period:


Timer Tick Period = Prescalar / F_CPU
Timer Tick Period = 256 / 16,000,000
Timer Tick Period = 0.000016 seconds = 16 microseconds

1
5
Calculate Required Number of Ticks for 1 second:
Number of Ticks = Required Delay / Timer Tick Period
Number of Ticks = 1 / 0.000016
Number of Ticks = 62,500

Compare Match Value:


OCR1A = Number of Ticks - 1
OCR1A = 62,500 - 1
OCR1A = 62,499
The reason we subtract 1 is because the timer counts from 0, so to get 62,500 ticks, we
need to count from 0 to 62,499.

With these settings:


 Each timer tick takes 16 microseconds (due to prescalar of 256)
 The timer will count up to 62,499
 Total time = 62,500 ticks × 16 microseconds = 1 second exactly

This gives us a precise 1-second delay using Timer 1 in CTC mode.

Task 3
#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>

// Seven segment display patterns for digits 0-9


const uint8_t SEGMENT_PATTERNS[] = {
0x7E, // 0
0x30, // 1
0x6D, // 2
0x79, // 3

1
6
0x33, // 4
0x5B, // 5
0x5F, // 6
0x70, // 7
0x7F, // 8
0x7B, // 9
};

void init_ports(void)
{
// Set PORTB (pins 8-13) as output for tens digit
DDRB = 0xFF;
// Set PORTD (pins 0-7) as output for ones digit
DDRD = 0xFF;
// Initialize both ports to 0
PORTB = 0x00;
PORTD = 0x00;
DDRC = 0x00;
}

void display_digit(uint8_t digit, uint8_t port_select)


{
if (digit > 9)
return; // Validate input

// Get the segment pattern for the digit


uint8_t pattern = SEGMENT_PATTERNS[digit];

// Display on selected port


if (port_select == 0)
{
PORTD = (PORTD & 0b10000000) | (pattern & 0x7F);
}
else
{
if (digit == 4 || digit == 1)
{
PORTD = 0x00;
}
else
{
PORTD = 0x80;

1
7
}
PORTB = pattern; // Tens digit on PORTB
}
}

void display_number(uint8_t number)


{
if (number > 59)
return; // Validate input

uint8_t tens = number / 10;


uint8_t ones = number % 10;

// Display tens digit on PORTB


display_digit(tens, 1);
// Display ones digit on PORTD
display_digit(ones, 0);
}

int main(void)
{
uint8_t seconds = 0;

// Initialize ports
init_ports();
TCNT1 = 0; //Initialize timer 1
OCR1A = 62500;// Set output compare register
TCCR1A = 0x00 ; // WGM13:WGM10 = 0100 , CS12:CS10 = 100
TCCR1B = 0x0C;
TCCR1C = 0x00;

while (1)
{
// Display current seconds

if ( (TIFR1 & 0x02) != 0 ) // Check OCF1A flag bit


{
TIFR1 |= 0x02 ; // Clear flag
// Increment seconds and reset if necessary

if (PINC & 0x01) {


seconds = 0;

1
8
} else if (PINC & 0x02) {
seconds++;
if (seconds > 59)
{
seconds = 0;
}
}

display_number(seconds);
}

return 0;
}

Configuration:
 Defined display patterns for digits 0-9 using segment patterns
 Initialized ports: PORTB and PORTD for display output, PORTC
for switch inputs
 Switch 1 (PINC & 0x01): Resets the counter to zero
 Switch 2 (PINC & 0x02): Controls start/pause functionality
 Configured Timer 1 in CTC mode with appropriate compare value
(62500) for 1-second timing
 display_digit(): Manages individual digit display
 display_number(): Handles two-digit number display
 Used separate ports for tens and ones digits

Hardware:

1
9
2
0
2
1

You might also like