Multitasking și întrerupere Arduino, robotosha
Multitasking și întrerupere a Arduino
Ce este o întrerupere?
Întrerupere - este un semnal care spune procesorul care trebuie să se oprească imediat ce se face în prezent, și să facă unele intervenții chirurgicale, având o prioritate ridicată. Această prelucrare se numește un manipulator de întrerupere cu prioritate ridicată (handler de întrerupere).
Dacă vom pune în aplicare o funcție și de conectarea acestuia de a întrerupe această funcție de fiecare dată când semnalul de întrerupere va fi declanșat. La întoarcerea sa din rutina de tratare a întreruperii, procesorul va continua să proceseze ceea ce făcea înainte de întrerupere.
Întreruperile pot fi generate de mai multe surse:
- Unul dintre timer-ul Arduino. formând o întrerupere timer;
- Schimbarea statului uneia dintre intrare de întrerupere externă;
- Schimbarea în stare a unuia dintre grupurile de pini.
Când se utilizează o întrerupere, nu este nevoie de a scrie cod în bucla (). verificarea în mod constant starea unei întrerupere cu prioritate ridicată. Nu este nevoie să vă faceți griji cu privire la răspuns lent sau butoanele care lipsesc sunt presate din cauza rutine prea lungi de funcționare.
Procesorul se va opri automat ce face la momentul întreruperii și cauza întreruperii handler de dumneavoastră. Trebuie doar să scrie cod pentru a răspunde la o întrerupere ori de câte ori apare.
Cronometrul întrerupe Arduino
Contor de timp și cronometrul întrerupere ne permite să facem doar asta. Putem seta un cronometru pentru a ne întrerupe o dată pe milisecundă. Cronometrul va, de fapt, să ne spună că este timpul pentru a verifica ceasul!
Arduino are trei cronometre: Timer0. Timer1 și Timer2. Timer0 deja configurat pentru generarea de milisecundă întrerupere, actualizarea milisecunde contra transmise în Millis (). Aceasta este exact ceea ce avem nevoie!
Cronometre - un contor simplu care contează cu o anumită frecvență, obținute de la sistemul de 16MHz. Putem configura divizor de frecvență pentru a produce frecvența dorită și diferite moduri de cont. Putem de asemenea, le personaliza pentru a genera o întrerupere atunci când cronometrul ajunge la unele valori prestabilite.
Timer0 este de 8 biți, contează la 0 la 255, și generează o întrerupere atunci când deversor (depășirea valorii 255). Acesta folosește un separator de ceas 64 în mod implicit, pentru a ne permite să 976.5625 frecvență Hz întrerupere (suficient de aproape 1 kHz, pentru scopurile noastre). Nu vom schimba frecvența de Timer0, deoarece aceasta este încalcă exact Millis () la locul de muncă!
compara registre
În registrele de comparație sunt stocate datele care sunt în mod constant în comparație cu starea contra / timer-ul. Stabilirea registrului comparație (OCR0A) pentru a genera o altă întrerupere undeva în mijlocul de numărare. Codul de mai jos va TIMER0_COMPA genera o întrerupere de fiecare dată când valoarea contorului trece 0xAF.
Biblioteca de a lucra cu întreruperi
Rețeaua poate fi găsit câteva biblioteci pentru a lucra cu cronometre. Mulți doar sondaj în mod constant Millis () în același mod ca și am făcut ultima oară. Dar sunt unii care vă permit să ajustați cronometrele pentru a genera întreruperi.
Excelent bibliotecă și TimerOne TimerThree de Paul Stoffregan oferă multe caracteristici de nivel scăzut pentru configurarea unui cronometru întrerupere. TimerThree bibliotecă nu funcționează pe ONU Arduino. Acesta poate fi folosit cu Leonardo. Mega 2560 si unele placi Teensy.
Arduino UNO are doar două intrări de întrerupere externe. Dar dacă vrei mai mult de două intrări? Din fericire Arduino UNO suportă întreruperi «schimbare PIN» (pentru a schimba intrarea) pentru toate pini.
Întrerupe schimbare de intrare - aceasta este la fel ca întrerupere externă. Diferența este că primul este generat de o schimbare de stare pe oricare dintre PIN-ul respectiv 8. Ele sunt un pic mai dificil de manevrat, deoarece trebuie să țină evidența ultima stare cunoscută de toate cele 8 pini, pentru a afla care dintre cele 8 PIN-ul a cauzat întreruperea.
PinChangeInt biblioteca implementeaza interfata user-friendly pentru a întrerupe schimbarea intrări.
Reguli pentru a face cu întreruperi
Pentru ca totul să funcționeze fără probleme, cel mai bine este să nu folosiți mai mult de 10 întreruperi diferite.
Dacă totul are o prioritate mai mare, atunci prioritatea ridicată nu este prezent la acea
stivuitoare de întrerupere trebuie să fie utilizate numai pentru o prioritate de prelucrare, sensibile la calendarul de evenimente. Amintiți-vă că întreruperile sunt dezactivate în timp ce vă aflați într-un handler de întrerupere. Dacă încercați să faceți prea mult la nivelul de întrerupere, veți obține un răspuns mai rău la alte întreruperi.
O întrerupere la un moment dat
Atunci când programul este în funcția de întrerupere, celelalte întreruperile sunt dezactivate. Acest lucru are două consecințe importante:
- Munca efectuată în funcțiile de manipulare de întrerupere trebuie să fie scurt, astfel încât să nu piardă mai mult de o întrerupere.
- Cod care rulează în funcții de procesare de întrerupere nu trebuie să cauzeze ceva care ar necesita ca întreruperea a fost activ (de exemplu, întârzierea (). Sau ceva care utilizează magistrala I 2 C). Se va prăbuși programul.
Pune bucla de prelucrare lungi ()
Dacă aveți nevoie pentru a efectua o prelucrare intensă ca răspuns la o întrerupere, utilizați handler de întrerupere pentru a face ceea ce este necesar, și apoi setați variabila volatilă a statului. indicând faptul că nu este necesară o prelucrare ulterioară. Când apelați funcția de actualizare () a buclei () verifica variabila de stat pe această temă dacă este necesar un tratament follow-up.
Verificați înainte de reconfigurare temporizator
Cronometre sunt o resursă limitată. Pe Arduino UNO sunt doar 3, iar acestea sunt folosite pentru multe lucruri. Dacă pui cu configurația timer, unele lucruri nu ar putea să funcționeze. De exemplu, în ONU Arduino:
schimbul de date securizate
Deoarece întrerupere suspendăm toate procesorul este de a face, trebuie să vă faceți griji cu privire la schimbul de date între procesoare și codul de întrerupere în bucla ().
Uneori, compilatorul va încerca să optimizeze codul dvs. pentru a îmbunătăți performanța. Uneori, ca urmare a acestei optimizări, copii ale variabilelor utilizate în mod frecvent vor fi stocate într-un registru pentru acces rapid la acestea. Problema este că, dacă una dintre aceste variabile este partajat de gestionare a întreruperilor și codul în bucla (). apoi, în cele din urmă, poate apărea copie stătut în locul valorilor reale. Marcarea unei variabile ca voltatile spune compilatorului că nu este necesar să se producă aceste optimizare potențial periculoase.
Chiar și etichetarea variabilă ca volatile nu va fi suficientă dacă variabila este mai mare decât un număr întreg (de exemplu, string, matrice, structura, etc.). Mai multe variabile irebuetsya mai multe cicluri de instrucțiuni pentru actualizarea și în cazul în care are loc o întrerupere în mijlocul acestei actualizări, datele pot fi deteriorate. Dacă aveți mai multe variabile sau structuri care sunt partajate cu handler de întrerupere, ar trebui să dezactivați întrerupe atunci când upgrade de la bucla (). Rețineți că întreruperile sunt dezactivate în rutina de tratare a întreruperii este deja implicit.
Cum apreciați această publicație? (57 voturi, scor mediu: 4.86 din 5)