Interrupt Subsystem

  • We have two strategies for getting input from an external device:
    • Polling – continually watch for completion of an event.
    • Interrupts – hardware generated subroutine call.
  • Polling with the ADC involved a tight loop that watched for a change in the ADSC flag:
poll:
      sbic  ADCSRA, ADSC  ; skip if bit clear (ADC complete)
      rjmp  poll
      in    r16, ADCH
  • Using interrupts allows the microcontroller to continue executing useful instructions.
  • When an interrupt occurs:
    • Completes current instruction.
    • Saves program counter (PC) on the stack.
    • Executes interrupt jump vector instruction (typically loads PC with the location of the Interrupt Service Routinue starting location).
    • Executes Interrupt Service Routine (ISR).
    • Returns to program when ISR encounters RETI instruction.

Interrupt Sources

The Interrupt Subsystem on the ATmega32 can receive interrupts from internal and external sources.

Internal Interrupt Sources

  • Power Subsystem:
    • Power on
    • Reset
    • Voltage low
  • Timer/Counter Subsystem:
    • Timer expired
    • Counter match
  • Analog to Digital Converter Subsystem:
    • ADC complete
  • Serial Communication Subsystem:

External Interrupt Sources

  • Anything that can generate an “on/off” signal.
  • ATmega32 has 3 pins (PD2, PD3, PB2) that the controller “listens” for an external trigger.

Interrupt Vector Table

.cseg
.org 0x00
     rjmp  start

; Interrupt Vector Table

.org 0x2a
start:
; ....
  • The ATmega32 has approximately 20 interrupts.
  • Each interrupt has a program memory location that stores a RJMP instruction that jumps to the ISR for the particular interrupt.
  • The m32def.inc file has labels associated with each interrupt type
  • Setting up the location of the ISR for the ADC, looks like this:
.org 0x00
     rjmp  start
.org ADCCaddr
     rjmp  adcISR
.org 0x2a
start:
     ; ...

; ISR for ADC subsystem
adcISR:
     ; ...

The ATmega32 interrupt subsystem supports twenty one different kinds of interrupts:

Vector No. Program Address Label Source Interrupt
1 0×00 RESET Power-on Reset, etc…
2 0×02 INT0addr INT0 External Interrupt Request 0
3 0×04 INT1addr INT1 External Interrupt Request 1
4 0×06 INT2addr INT2 External Interrupt Request 2
5 0×08 OC2addr TIMER2 COMP Timer/Counter2 Compare Match
6 0x0A OVF2addr TIMER2 OVF Timer/Counter2 Overflow
7 0x0C ICP1addr TIMER1 CAPT Timer/Counter1 Capture Event
8 0x0E OC1Aaddr TIMER1 COMP A Timer/Counter1 Compare Match A
9 0×10 OC1Baddr TIMER1 COMP B Timer/Counter1 Compare Match B
10 0×12 OVF1addr TIMER1 OVF Timer/Counter1 Overflow
11 0×14 OC0addr TIMER0 COMP Timer/Counter0 Compare Match
12 0×16 OVF0addr TIMER0 OVF Timer/Counter0 Overflow
13 0×18 SPIaddr SPI STC Serial Transfer Complete
14 0x1A URXCaddr USART RXC USART, Rx Complete
15 0x1C UDREaddr USART UDRE USART, Data Register Empty
16 0x1E UTXCaddr USART TXC USART, Tx Complete
17 0×20 ADCCaddr ADC ADC Conversion Complete
18 0×22 ERDYaddr EE_RDY EEPROM Ready
19 0×24 ACIaddr ANA_COMP Analog Comparator
20 0×26 TWIaddr TWI Two-wire Serial Interface
21 0×28 SPMRaddr SPM_RDY Store Program Memory Ready

Enabling Interrupts

  • Must enable the global interrupt flag.
    • SREG has an I flag.
  • Ways to set I flag (enable interrupts):
    • SEI – Set Enable Interrupt.
    • RETI – RETurn from Interrupt service routine (automatically sets the I flag.
  • Ways to clear I flag (disable interrupts):
    • CLI – clears the interrupt flag.
    • Whenever the ATmega32 is reset, the I flag is cleared.
    • Whenever an interrupt occurs, the I flag is cleared.

Interrupt Processing Steps

Setup:

  • Must initialize the stack.
  • Must set up the interrupt jump table.
  • Must enable the global interrupt flag.
  • Must enable particular local interrupt we are interested in.

When the interrupt occurs:

  • Finish current instruction.
  • Push current PC onto the stack.
  • Clear I flag.
  • Execute RJMP instruction in the Interrupt Vector Table.
  • Execute the interrupt service routine.
  • Execute RETI at end of ISR.
  • Set I flag.
  • Pop saved PC into the PC.

Interrupt Service Routine Guidelines

  • Make it as short as possible.
  • Push/Pop any registers that must be preserved onto the stack.
  • Push/Pop SREG onto the stack.
    push   r0
    in     r0, SREG
    push   r0
; ...
    pop    r0
    out    SREG, r0
    pop    r0

Sample Code

Here is a simple program that makes use of the interrupt subsystem to display the results of the ADC conversion on the LEDs.

; Author: t a y l o r@msoe.edu
; Date: 4-23-2007
; Filename: adcIntDemo.asm
;
; This program uses the ADC subsystem and the interrupt subsystem
;  to take the analog signal on ADC channel 0 and display its digital
;  representation on the LEDs.
; Hardware configuration:
;  - PORTB connected to LEDs.
;  - PORTA pin 0 connected to analog source.

.nolist
.include "m32def.inc"
.list

.def temp = r16  ; Use r16 as a temp register

.cseg
.org 0x00
     rjmp  stackInit
.org ADCCaddr     ; Jump vector for ADC interrupts
     rjmp  adcISR

.org 0x2a
stackInit:
     ldi   temp, HIGH(RAMEND-0x20)
     out   SPH, temp
     ldi   temp, LOW(RAMEND-0x20)
     out   SPL, temp

start:
     ldi   temp, 0xff   ; Configure PORTB as output
     out   DDRB, temp
     cbi   DDRA, 0      ; Configure PORTA as input
     rcall adcIntInit0
     sbi   ADCSRA, ADSC ; Start AD conversion

; Program just loops forever doing nothing (until interrupted)
forever:
     rjmp  forever

; Initialize ADC for single ended conversion on ADC channel 0
;  with interrupt subsystem enabled.
adcIntInit0:
.def temp = r16
     push  temp

     ; Set ADC reference voltage, put in 8-bit mode and select channel 0
     ldi   temp, 0b01100000
     out   ADMUX, temp

     ; Enable ADC and ADC interrupts, prescale factor = 128
     ldi   temp, 0b10001111
     out   ADCSRA, temp
     sei                ; Enable global interrupt flag

     pop   temp
     ret

; Interrupt Service Routine for ADC subsystem
; Takes result of ADCH and sends compliment of the result
;  (since LED are active low) to the LEDs on PORTB and then
;  starts the ADC all over again.
; Assumptions:
;  - ADC and Interrupt subsystems have been initialized.
;  - Using ADC channel 0.
;  - Using only 8 MSB of ADC result.
;  - PORTB is configured as output.
; Hardware configuration:
;  - Analog input source is connected to PORTA pin 0.
;  - PORTB connected to active low LEDs.
adcISR:
     push  temp
     in    temp, SREG   ; Capture status register
     push  temp

     in    temp, ADCH
     out   PORTB, temp
     sbi   ADCSRA, ADSC ; Start ADC again

     pop   temp
     out   SREG, temp   ; Restore status register
     pop   temp
     reti
ce2800/interrupts.txt · Last modified: 2009/06/03 11:22 (external edit)
 

This website is not owned or managed by the Milwaukee School of Engineering.

© 2003-2010 Dr. Christopher C. Taylor, et. al. • Office: L-343 • Phone: 277-7339 • npǝ˙ǝosɯ@ɹolʎɐʇ • -> RSS <-