Στον ATmega328 σε κάθε πόρτα υπάρχει μια διακοπή αλλαγής κατάστασης των πινς. Όταν η διακοπή αλλαγής κατάστασης της πόρτας είναι ενεργοποιημένη, κάθε αλλαγή στις καταστάσεις των πινς οδηγούν στη δημιουργία μιας διακοπής. Δες την ακόλουθη εικόνα. Ο καταχωρητής PCICR περιέχει τα bits ενεργοποίησης για τις πόρτες.
Για κάθε PCINT πιν της κάθε πόρτας ορίζεται και ένα bit ενεργοποίησης. Εάν το bit ενεργοποίησης γίνει 1, αλλαγές σε αυτό το πιν οδηγούν και σε μια διακοπή.
Χρησιμοποιώντας τις διακοπές αλλαγής κατάστασης των πιν
Για να χρησιμοποιήσουμε τις διακοπές αλλαγής κατάστασης πιν, τα επόμενα θα πρέπει να τεθούν σε 1.
(α) τα κατάλληλα bits των καταχωρητών PCMSKn
(β) τα PCIEn bits των σχετικών θυρών.
(γ) η σημαία Ι στον καταχωρητή κατάστασης SREG.
Παράδειγμα: Τα πιν ΡΒ0, ΡΒ2 και ΡΒ3 είναι συνδεμένα σε διακόπτες. Γράψε ένα πρόγραμμα που να κάνει το πιν PORTB.5 high όταν οποιοδήποτε από τους διακόπτες αλλάζει κατάσταση.
Απάντηση
Για να ενεργοποιήσουμε τις διακοπές που προκαλούνται με αλλαγή κατάστασης στα πινς ΡΒ0, ΡΒ2 και ΡΒ3 τα επόμενα θα πρέπει να τεθούν σε high:
(1) Tα bits 0, 2 και 3 του καταχωρητή PCMSK0 ( o PCMSK0 αντιστοιχεί στην PORTB)
(2) PCIE0 του PCICR (το PCIE0 αντιστοιχεί για την PORTB)
(3) Την σημαία Ι
.ORG 0 ;location for reset
JMP MAIN
.ORG 0x06 ;location for pin change interrupt 0
JMP PCINT0_ISR
MAIN: LDI R20, HIGH(RAMEND)
OUT SPH, R20
LDI R20, LOW(RAMEND)
OUT SPL, R20 ;initialize stack
SBI DDRB,5 ;PB5 as output
CBI PORTB, 5 ;PB5 = low
LDI R20, 0b00001101
STS PCMSK0, R20 ;enable PB0, PB2, and PB3 in PCMSK0
OUT PORTB, R20 ;enable pull-up resistors
LDI R20, (1<<PCIE0)
STS PCICR, R20 ;enable PORTB change interrupt
SEI ;enable interrupts
HERE: JMP HERE ;stay here
PCINT0_ISR:
SBI PORTB,5 ;PB5 = high
RETI ;return
Προτεραιότητα εξυπηρέτησης διακοπών
Στην επόμενη ενότητα θα συζητήσουμε τι θα συμβεί εάν ζητηθούν δυο διακοπές την ίδια στιγμή. Ποια από τις δυο διακοπές θα εξυπηρετηθεί πρώτα;
Προτεραιότητα διακοπών
Εάν δυο διακοπές ζητηθούν την ίδια στιγμή, η διακοπή με την μεγαλύτερη προτεραιότητα θα εξυπηρετηθεί πρώτη. Η προτεραιότητα κάθε διακοπής σχετίζεται με την διεύθυνση της διακοπής στο interrupt vector table. Η διακοπή που έχει την μικρότερη διεύθυνση έχει την μεγαλύτερη προτεραιότητα. Για παράδειγμα, η διεύθυνση της εξωτερικής διακοπής 0 έχει την υψηλότερη προτεραιότητα και εάν και οι δυο αυτές διακοπές ζητηθούν την ίδια στιγμή η εξωτερική διακοπή 0 εξυπηρετείται πρώτη.
Διακοπή μέσα σε διακοπή
Τι συμβαίνει όταν ο AVR εκτελεί μια ρουτίνα ISR εξυπηρέτησης διακοπής και μια άλλη διακοπή ζητηθεί; Όταν ο AVR ξεκινά να εκτελέσει μια ρουτίνα ISR απενεργοποιεί το bit I του καταχωρητή κατάστασης SREG που προκαλεί την απενεργοποίηση όλων των διακοπών και καμία άλλη διακοπή δεν θα εξυπηρετηθεί. Όταν η εντολή RETI εκτελείται ο AVR ενεργοποιεί το bit I προκαλώντας τις άλλες διακοπές να εξυπηρετηθούν. Εάν θέλεις μια άλλη διακοπή (με οποιαδήποτε προτεραιότητα) να εξυπηρετηθεί ενώ εκείνη τη στιγμή μια άλλη διακοπή εξυπηρετείται, θα πρέπει να θέσεις το bit Ι σε 1 με την εντολή SEI. Αλλά χρειάζεται προσοχή. Για παράδειγμα σε μια low-level-triggered εξωτερική διακοπή, ενεργοποιώντας το bit I, ενώ το πιν ΙΝΤ παραμένει ενεργό (κατάσταση LOW) θα προκαλέσει την ISR να εκτελείται ξανά και ξανά μέσα στην άλλη, προκαλώντας την κατάρρευση του σωρού.