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

Lab 10

This document outlines Lab 10 for the Embedded System course, focusing on AVR Hardware Interrupts. It includes acknowledgements, learning outcomes, deliverables, hardware resources, and detailed explanations of hardware interrupts in the ATmega328P microcontroller. Additionally, it provides example code for implementing interrupts to control LEDs and tasks involving a seven-segment display and an LCD.

Uploaded by

mokishere
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views

Lab 10

This document outlines Lab 10 for the Embedded System course, focusing on AVR Hardware Interrupts. It includes acknowledgements, learning outcomes, deliverables, hardware resources, and detailed explanations of hardware interrupts in the ATmega328P microcontroller. Additionally, it provides example code for implementing interrupts to control LEDs and tasks involving a seven-segment display and an LCD.

Uploaded by

mokishere
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 12

Embedded System

Lab 10
AVR Hardware Interrupts

Submitted By:
Asna Maqsood
426990
BESE13 B
Embedded System
Lab 10
AVR Hardware Interrupts

Submitted By:
Muhammad Ahsan
406267
BESE13 B
Embedded System
Lab 10
AVR Hardware Interrupts

Submitted By:
Muhammad Owais Khan
404262
BESE13 B
Embedded System
Lab 10
AVR Hardware Interrupts

Submitted By:
Umar Farooq
406481
BESE13 B
Lab 10: AVR Hardware Interrupts
EE222: Microprocessor Systems

Contents

1. Acknowledgements........................................................................................................................ 1

2. Administrivia................................................................................................................................... 1

2.1. Learning Outcomes.......................................................................................................................................... 2

2.2. Deliverable........................................................................................................................................................... 2

2.3. Hardware Resources....................................................................................................................................... 2

3. Interrupts........................................................................................................................................... 2

3.1. Hardware Interrupts....................................................................................................................................... 2

4. Tasks.................................................................................................................................................... 6

4.1. Task 1.................................................................................................................................................................. 6

1. Acknowledgements
This lab exercise is prepared by Lab Engr. Shaiza for the course EE-222 Microprocessor
Systems. 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;

• Code hardware interrupts for efficient scheduling in ATmega328p.

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

• Arduino USB cable

• Universal Programmer

• Seven Segment Display x2

• Resistance 47Ω x2

• Switch

3. Interrupts
In this lab, hardware interrupts are utilized to enable communication between
microcontrollers and external devices. Hardware interrupts allow the microcontroller to
respond immediately to external signals, pausing its current tasks to handle the interrupt
before resuming its normal operations.

3.1. Hardware Interrupts


The ATmega328P has two external hardware interrupts, which are:

1. INT0: Pin PD2 (PORTD.2)

2. INT1: Pin PD3 (PORTD.3)


In addition, the ATmega328P has an additional external interrupt source, but it is handled
differently compared to the dedicated INT0 and INT1 pins. Specifically:
• PCINT (Pin Change Interrupts) can be triggered on several pins in PORTB,
PORTC, and PORTD.
Upon activation of these pins, the AVR is interrupted in whatever it is doing and jumps to
the program memory location specified in the table below to perform the interrupt service
routine.
Interrupt Program Memory Location
External Interrupt request 0 0x0002
External Interrupt request 1 0x0004

To utilize these interrupts, they must be enabled in the External Interrupt Mask Register
(EIMSK). The EIMSK includes bits for enabling each interrupt:
_ _ _ _ _ _ INT1 INT0

EIMSK bit Function


INT0 When 1, Enables external interrupt 0
INT1 When 1, Enables external interrupt 1

In addition to setting the interrupt enable bits, the global interrupt enable (I) bit must also
be set to allow the microcontroller to respond to interrupts. This can be done using the
sei() function from the avr/interrupt.h library.

EICRA (External Interrupt Control Register A):


There are two types of activation for the external hardware interrupts:
(1) level triggered
(2) edge triggered
Both INT0 and INT1 can be level or edge triggered. Upon reset INT0 and INT1 are
lowlevel-triggered interrupts. The bits of the MCUCR register indicate the trigger options
of INT0 and INT1 as shown below:
_ _ _ _ ISC11 ISC10 ISC01 ISC00

ISC (Interrupt Sense Control bits) bits define the level or edge on the external pins that
activates the interrupt.
ISC01:ISC00 Description
00 The low level of INT0 generates an
interrupt request.
01 Any logical change on INT0 generates an
interrupt request
10 The falling edge of INT0 generates an
interrupt request.
11 The rising edge of INT0 generates an
interrupt request.
ISC11:ISC10 Description
00 The low level of INT1 generates an
interrupt request.
01 Any logical change on INT1 generates an
interrupt request
10 The falling edge of INT1 generates an
interrupt request.
11 The rising edge of INT1 generates an
interrupt request.

Example Code:
The code demonstrates the use of hardware interrupts to toggle two LEDs independently.
These LEDs are controlled via two external interrupts, INT0 and INT1. The INT0 interrupt
pin is connected to switch 0 (SW0), and the INT1 interrupt pin is connected to switch 1
(SW1). Whenever INT0 is triggered by a rising edge, the program toggles the LED
connected to PORTC.0, and whenever INT1 is triggered by a rising edge, the LED connected
to PORTB.0 toggles.
#include <avr/io.h>
#include <avr/interrupt.h>
int main(void)
{

DDRC=(1<<PORTC0);
DDRB=(1<<PORTB0);
EIMSK=(1<<INT0)|(1<<INT1); // Enable External Interrupt 0 and Interrupt 1
sei();
EICRA=(1<<ISC00)|(1<<ISC01)|(1<<ISC10)|(1<<ISC11);

/*making INT0 and INT1 as positive edge triggered*/


PORTC=(1<<PORTC0);
PORTB=(1<<PORTB0);
while (1);
}

ISR(INT0_vect)
{
PORTC ^=(1<<PORTC0);
}
ISR(INT1_vect)
{
PORTB^=(1<<PORTB0);
}

Let us understand the code below:


The sei() function, defined in avr/interrupt.h, sets the global interrupt enable bit, which
allows the microcontroller to respond to interrupts. Enabling the INT0 and INT1 bits in the
External Interrupt Mask Register (EIMSK) activates external interrupts 0 and 1. The
program runs in an infinite while(1) loop, waiting for a low-to-high transition on either
INT0 or INT1.

When INT0 or INT1 detect a low-to-high transition, the corresponding flag in the External
Interrupt Flag Register (EIFR) is set. This triggers an interrupt, and the AVR
microcontroller jumps to the appropriate interrupt service routine: ISR(INT0_vect) or
ISR(INT1_vect). These routines toggle the state of the LEDs connected to PORTC.0 and
PORTB.0, respectively.
While the processor is executing an interrupt service routine (ISR), the flag that caused
the interrupt (such as INTF0 and INTF1) is automatically cleared by the processor.
The GIFR register layout includes flags for each interrupt:

- - - - - - - INTF1 INTF0
4. Lab tasks:
4.1. Task1:

1. Connect a seven-segment display (SSD) to your ATmega328p and ensure it displays a


continuous counting sequence from 0-9 with a 1-second delay between each digit.
Once it reaches 9, the sequence should restart at 0.
2. Connect a switch (SW) to generate an interrupt signal. When the switch is pressed
(interrupt triggered), the SSD counting should pause. Instead of interacting with an
LED, a 16x2 LCD should display your name (e.g., "Syed Zain Ul Hassan") scrolling
from right to left across the screen.
3. The scrolling name on the LCD should continue until the switch is pressed again, at
which point the LCD display should stop, and the SSD should resume counting
from where it was paused.
4. Both tasks (SSD counting and LCD scrolling) must run independently and in parallel
to avoid lag when switching between functionalities.

Code:
#include <avr/io.h>
#include <avr/delay.h>
#include <avr/interrupt.h>
#include <stdbool.h>
#include <LiquidCrystal.h> // Includes the LiquidCrystal Library

// Initialize the LCD. Parameters: (rs, enable, d4, d5, d6, d7)
LiquidCrystal lcd(1, 2, 4, 5, 6, 7);
// Global flag to indicate interrupt
volatile bool interruptFlag = false;

void setup() {
lcd.begin(16, 2); // Initialize the LCD screen with dimensions 16x2
DDRB = 0xFF; // Set PORTB as output for the seven-segment display
enableINT0(); // Enable INT0 interrupt
}

void loop() {
// Only update LCD when interrupt has been triggered
if (interruptFlag) {
String text = "Ahsan Owais Umar Asna"; // Text to scroll
int textLength = text.length(); // Length of the text
// Scroll the text horizontally
for (int position = 0; position < textLength + 16; position++) {
lcd.clear(); // Clear the display
lcd.setCursor(16 - position, 0); // Set the cursor position for scrolling
lcd.print(text); // Display the text
delay(200); // Adjust delay for scrolling speed
}

// Reset the interrupt flag after updating LCD


interruptFlag = false;
}
}

void enableINT0() {
sei(); // Enable global interrupts
EIMSK |= (1 << INT0); // Enable INT0 external interrupt
MCUCR &= ~((1 << ISC01) | (1 << ISC00)); // Clear both ISC01 and ISC00 for low-level
trigger
}

// Interrupt Service Routine for INT0


ISR(INT0_vect) {
interruptFlag = true; // Set the flag when INT0 interrupt occurs
}

// Seven segment display function


char SevenSegment(char number)
{
// - a b c d e f g
if (number == 0) return 0x7E; // 0 0 0 0 0 0 0 1
else if (number == 1) return 0x30; // 0 1 0 0 1 1 1 1
else if (number == 2) return 0x6D; // 0 0 0 1 0 0 1 0
else if (number == 3) return 0x79; // 0 0 0 0 0 1 1 0
else if (number == 4) return 0x33; // 0 1 0 0 1 1 0 0
else if (number == 5) return 0x5B ; // 0 0 1 0 0 1 0 0
else if (number == 6) return 0x5F; // 0 0 1 0 0 0 0 0
else if (number == 7) return 0x70; // 0 0 0 0 1 1 1 1
else if (number == 8) return 0x7F ; // 0 0 0 0 0 0 0 0
else if (number == 9) return 0x7B; // 0 0 0 0 1 1 0 0
else return 0x00;
}

int main(void) {
// This function does nothing in this case because the main loop
// is driven by interrupts and flags
DDRC = 0xFF;
DDRB = 0x01;
// enableINT0();
while (1) {
// The `loop()` function will handle LCD display updates when needed.
for (int i=0;i<10;i++)
{

PORTC=SevenSegment(i);
bool v = (SevenSegment(i)>>6)<<7;

if (v) { // Check if PC6 is high


PORTB =0x01; // Set PB0 high if PC6 is high
}
else {
PORTB = 0x00; // Set PB0 low if PC6 is low
}
_delay_ms(1000);

}
}
}

Output:

You might also like