Lecture 8

Views:
 
Category: Education
     
 

Presentation Description

No description available.

Comments

Presentation Transcript

Lecture 8 : 

Lecture 8 Interrupt Subsystem

Interrupt Theory : 

Interrupt Theory Unscheduled, higher priority events are handled by Interrupt system. Upon Interrupt MC will complete the current instruction and then jump to Interrupt Service Routine (ISR). Each interrupt has its own ISR. After completing ISR MC will resume from it left off before the interrupt.

Interrupt Sources : 

Interrupt Sources Interrupt Sources in descending order of priority

Interrupt Sources : 

Interrupt Sources

The process : 

The process When Interrupt occurs, MC completes current instruction being executed. Stores the address of next instruction on Stack. Executes ISR related to the interrupt source. Turns off Interrupt system to prevent further interrupts while one is in progress. The AVR CPU will automatically disable the Global Interrupt Enable bit, to prevent the ISR from being itself interrupted. ISR is executed by loading the beginning address of ISR into the program counter. ISR is executed till “reti” is encountered.

Programming an Interrupt : 

Programming an Interrupt Ensure the ISR for a specific interrupt is tied to the correct interrupt vector address, which points to the starting address of the ISR. Ensure the interrupt system has been globally enabled. This is accomplished with the assembly language instruction SEI. Ensure the specific interrupt subsystem has been locally enabled. Ensure the registers associated with the specific interrupt have been configured correctly.

Conditions for ISR : 

Conditions for ISR For an ISR to be called, we need three conditions to be true: Firstly, the AVR's global Interrupts Enable bit (I) must be set in the MCU control register SREG. This allows the AVR's core to process interrupts via ISRs when set, and prevents them from running when cleared. It defaults to being cleared on power up, so we need to set it. Secondly, the individual interrupt source's enable bit must be set. Each interrupt source has a separate interrupt enable bit in the related peripheral's control registers, which turns on the ISR for that interrupt. This must also be set, so that when the interrupt event occurs the processor runs the associated ISR. Thirdly, The condition for the interrupt must be met

Linking ISR to Interrupt source : 

Linking ISR to Interrupt source Place a JMP or RJMP instruction to this function at the address specified in the table we just looked at. At the start of the AVR's FLASH memory space lies the Interrupt Vector Table, which is simply a set of hardwired addresses which the AVR's processor will jump to when each of the interrupts fire. By placing a jump instruction at each interrupt's address in the table, we can make the AVR processor jump to our ISR which lies elsewhere. Code: .org 0x{Vector Address} jmp MyISRHandler MyISRHandler: ; ISR code to execute here reti “reti” has the dual function of exiting the ISR, and automatically re-enabling the Global Interrupt Enable bit. This happens inside the C version too when the function returns, we just don't see it normally.

‘C’ definition : 

‘C’ definition Code: #include <avr/interrupt.h> ISR({Vector Source}_vect) {    // ISR code to execute here } E.g. vector source could be INT0, INT1 or INT2 for external Interrupts.

I-bit : 

I-bit I-bit: sei, which SEts the I flag cli, which CLears the I flag Code: sei ; Enable Global Interrupts While in C, we have to use special macros from our libc library's header. In the case of AVR-GCC and its avr-libc library, we just use the sei() and cli() macro equivalents defined in <avr/interrupt.h>: Code: sei(); // Enable Global Interrupts

Configuring external Interrupts : 

Configuring external Interrupts The external interrupts INT0 (pin 16), INT1 (pin 17), and INT2 (pin 3) trigger an interrupt within the ATmega16 when an external event occurs. Interrupts INT0 and INT1 may be triggered with a level or an edge signal, whereas interrupt INT2 is edge-triggered only.

Interrupt Registers : 

Interrupt Registers

Interrupt Pins : 

Interrupt Pins

Assembly Example : 

Assembly Example

Assembly Example : 

Assembly Example .include "m16def.inc" ; Interrupt service vectors .org $0000 rjmp Reset ; Reset vector .org INT0addr rjmp IntV0 ; INT0 vector (ext. interrupt from pin D2) .org INT1addr rjmp IntV1 ; INT1 vector (ext. interrupt from pin D3) ;--------------------------------------------------------------------------- ; ; Register defines for main loop .def TIME=r16 .def TEMP=r17 ;--------------------------------------------------------------------------- ; ; Reset vector - just sets up interrupts and service routines and ; then loops forever. Reset: ldi TEMP,low(RAMEND) ; Set stackptr to ram end out SPL,TEMP ldi TEMP, high(RAMEND) out SPH, TEMP ser TEMP ; Set TEMP to $FF to... out DDRB,TEMP ; ...set data direction to "out" out PORTB,TEMP ; ...all lights off! out PORTD,TEMP ; ...all high for pullup on inputs ldi TEMP,(1<<INT0)+(1<<INT1) ; int masks 0 and 1 set out GICR,TEMP ldi TEMP,$0f ; interrupt t0 and t1 on rising edge only out MCUCR,TEMP ldi TIME,$00 ; Start from 0 sei ; enable interrupts and off we go! loop: rjmp loop ; Infinite loop - never terminates ;--------------------------------------------------------------------------- ; ; Int0 vector - decrease count IntV0: dec TIME rjmp Int01 ; jump to common code to display new count ;--------------------------------------------------------------------------- ; ; Int1 vector - increase count IntV1: inc TIME ; drop to common code to display new count Int01: mov r0,TIME ; display on LEDs com r0 out PORTB,r0 reti

INT0 Initialization in ‘C’ : 

INT0 Initialization in ‘C’ void initialize_interrupt0(void) //initialize interrupt 0 { DDRD = 0xFB; //set PD2 (int0) as input PORTD &= ~0x04; //disable pullup resistor //PD2 GICR = 0x40; //enable int 0 MCUCR = 0x03; //set for positive edge //trigger sei(); // Enable Global Interrupts }

‘C’ Example : 

‘C’ Example #include <avr/io.h>//Do not forget to add this header file#include <avr/interrupt.h>  int main(void){ // Set PORTC is as output DDRC=0XFF; // Enable INT0 External Interrupt in GICR RegisterGICR |= 1<<INT0;// Falling-Edge Triggered INT0MCUCR |= 1<<ISC01;// Enable Interruptssei();  // Set Bit 0 of PORTC PORTC = 0x01;   while (1)    {   }}// External Interrupt 0 ISRISR(INT0_vect){ // Invert the Bit 0 of PORT C every time interrupt occurs   PORTC^=0x01;}

authorStream Live Help