poll:
sbic ADCSRA, ADSC ; skip if bit clear (ADC complete)
rjmp poll
in r16, ADCH
The Interrupt Subsystem on the ATmega32 can receive interrupts from internal and external sources.
.cseg
.org 0x00
rjmp start
; Interrupt Vector Table
.org 0x2a
start:
; ....
.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 |
Setup:
When the interrupt occurs:
push r0
in r0, SREG
push r0
; ...
pop r0
out SREG, r0
pop r0
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
com temp
out PORTB, temp
sbi ADCSRA, ADSC ; Start ADC again
pop temp
out SREG, temp ; Restore status register
pop temp
reti