====== Välised katkestused ====== Välised katkestused (inglise keeles //external interrupt//) on ühed lihtsamad perifeeria funktsioonid. AVR-idel on tavaliselt 1 kuni 8 spetsiaalset viiku, mille loogilise väärtuse muutumisel või kindlal olekul tekitatakse programmis katkestus. Kuna enamasti kasutatakse seda funktsiooni kontrolleriväliste loogikasignaalide jälgimiseks, siis nimetataksegi vastavaid viike välise katkestuse viikudeks. Välise katkestuse kasutamiseks tuleks viik seadistada tavalise IO sisendrežiimi (võib ka väljundrežiimis kasutada, aga siis saab katkestust tekitada vaid kontroller ise). Välise katkestuse seadistusregistrites tuleb ära märkida katkestuste tekitamise lubamine ja tingimus, mille peale seda teha. Võimalikke tekitajaid on neli: * Loogiline null (pinge on 0V) * Loogilise väärtuse muutus * Langev front - loogiline muutus ühest nulli. * Tõusev front - loogiline muutus nullist ühte. Katkestuse tekitamiseks loogilise nulli valimisel tekitatakse katkestust järjest senikaua, kuni viigu väärtus on null. Põhiprogrammi töö on samal ajal peatatud. Lähtudes tööpõhimõttelt, on väliseid katkestusi kahte liiki: kontrolleri taktiga sünkroniseeritud ja asünkroonsed. Sünkroniseeritud katkestused toimivad sisendite väärtuse meelespidamise teel, mis tähendab, et loogilised muutused leitakse kahel erineval taktil saadud väärtuste võrdlemise teel. Kui välise signaali loogilised muutused toimuvad kiiremini, kui käib töötakt, siis katkestused, kas ei teki õigesti või jäävad üldse vahele. Asünkroonsed katkestused ei sõltu kontrolleri taktist ja võimaldavad tuvastada ka kiiremini muutuvat välist signaali - loogilist nivood peab signaal hoidma vähemalt 50 ns. ATmega128-l on 4 sünkroniseeritud ja 4 asünkroonset välist katkestust. Atmeli xmega seeria kontrolleritel on välised katkestused realiseeritud natuke erinevalt võrreldes tavaliste 8-bitiste kontrolleritega. Atmeli xmega seerial on igale siinile omistatud kaks välist katkestust INT0 ja INT1, mis on võimalik kasutades biti maski ühendada suvalise siini viiguga (või mitmega korraga). Vaja on panna ATmega128 viik number 9 ehk siini E viik 7 tekitama katkestust, kui selle väärtus muutub. Sellele viigule vastab väline katkestus INT7, mis on sünkroonne. #include // Välise katkestuse programm ISR(INT7_vect) { // Tee midagi } // Põhiprogramm int main(void) { // Siini E viigu 7 muutmine sisendiks biti 7 nullimise teel DDRE &= ~(1 << PIN7); // Siini E viigule 7 pull-up takisti määramine sisendi ujumise vastu PORTE |= (1 << PIN7); // Väliste katkestuste seaderegistris katkestuse 7 // tekitajaks loogilise muutuse määramine EICRB = (1 << ISC70); // Välise katkestuse 7 lubamine EIMSK |= (1 << INT7); // Globaalne katkestuste lubamine sei(); // Lõputu programmitsükkel while (1) continue; } Xmega puhul otsime sisendi muutust viigul PORTE0: #include // Välise katkestuse programm ISR(PORTE_INT0_vect) { // Tee midagi } // Põhiprogramm int main(void) { // Siini E viigu 0 muutmine sisendiks biti 0 nullimise teel PORTE.DIR &= ~(PIN0_bm); // Siini E viigule 0 pull-up takisti määramine sisendi ujumise vastu PORTE.PIN0CTRL = (PORT_OPC_PULLUP_gc); // Siini E viigu 0 katkestuse töörežiimi määramine PORTE.PIN0CTRL |= (PORT_ISC_BOTHEDGES_gc); // Siini E INT0 katkestuse prioriteedi määramine PORTE.INTCTRL |= (PORT_INT0LVL_MED_gc); // Viigu määramine siini E INT0 sisendiks PORTC.INT0MASK = (PIN0_bm); // Keskmise prioriteediga katkestuste lubamine PMIC.CTRL |= PMIC_MEDLVLEN_bm; // Globaalne katkestuste lubamine sei(); // Lõputu programmitsükkel while (1){}; } Lisaks üksikute viikude tekitatavatele katkestustele on suurematel AVR-idel võimalik kasutada ka tervete gruppide viikude loogiliste väärtuste muutuste katkestusi. Neid katkestusi nimetatakse lihtsalt viigu muutuse katkestusteks (inglise keeles //pin change interrupt//). Need rakenduvad siis, kui vähemalt ühe viigu väärtus grupis muutub.