Differences

This shows you the differences between two versions of the page.

Link to this comparison view

pm:lab:lab2 [2020/03/01 14:04]
alexandru.predescu
pm:lab:lab2 [2020/03/08 11:01] (current)
alexandru.predescu
Line 26: Line 26:
  
 O întrerupere hardware reprezintă un semnal sincron sau asincron de la un periferic ce semnalizează apariția unui eveniment care trebuie tratat de către procesor. Tratarea întreruperii are ca efect suspendarea firului normal de execuție al unui program și lansarea în execuție a unei **rutine de tratare a întreruperii (RTI)**. O întrerupere hardware reprezintă un semnal sincron sau asincron de la un periferic ce semnalizează apariția unui eveniment care trebuie tratat de către procesor. Tratarea întreruperii are ca efect suspendarea firului normal de execuție al unui program și lansarea în execuție a unei **rutine de tratare a întreruperii (RTI)**.
 +
 +<​hidden>​
 +Ar trebui mentionat si ce inseamna sincron si asincron.
 +</​hidden>​
  
 Întreruperile hardware au fost introduse pentru a se elimina buclele pe care un procesor ar trebui să le facă în așteptarea unui eveniment de la un periferic. Folosind un sistem de întreruperi,​ perifericele pot comunica cu procesorul, acesta din urma fiind liber să-și ruleze programul normal în restul timpului și să își întrerupă execuția doar atunci când este necesar. Întreruperile hardware au fost introduse pentru a se elimina buclele pe care un procesor ar trebui să le facă în așteptarea unui eveniment de la un periferic. Folosind un sistem de întreruperi,​ perifericele pot comunica cu procesorul, acesta din urma fiind liber să-și ruleze programul normal în restul timpului și să își întrerupă execuția doar atunci când este necesar.
  
 Înainte de a lansa în execuție o RTI, procesorul trebuie sa aibă la dispoziție un mecanism prin care să salveze starea în care se afla în momentul apariției întreruperii. Aceasta se face prin salvarea într-o memorie, de cele mai multe ori organizată sub forma unei stive, a registrului contor de program (Program Counter), a registrelor de stare precum și a tuturor variabilelor din program care sunt afectate de execuția RTI. La sfârșitul execuției RTI starea anterioară a registrelor este refăcută și programul principal este reluat din punctul de unde a fost întrerupt. Înainte de a lansa în execuție o RTI, procesorul trebuie sa aibă la dispoziție un mecanism prin care să salveze starea în care se afla în momentul apariției întreruperii. Aceasta se face prin salvarea într-o memorie, de cele mai multe ori organizată sub forma unei stive, a registrului contor de program (Program Counter), a registrelor de stare precum și a tuturor variabilelor din program care sunt afectate de execuția RTI. La sfârșitul execuției RTI starea anterioară a registrelor este refăcută și programul principal este reluat din punctul de unde a fost întrerupt.
 +
 +<​hidden>​
 +Salvarea si restaurarea registrilor poarta numele de prolog si epilog.
 +</​hidden>​
  
 Pentru a asocia o întrerupere cu o anumită rutină din program, procesorul folosește **tabela vectorilor de întrerupere** (TVI), ilustrată în figura de mai jos. În această tabelă, fiecărei întreruperi îi este asociată adresa rutinei sale de tratare, la care programul va face salt în cazul apariției acesteia. Aceste adrese sunt predefinite și sunt mapate în memoria de program într-un spatiu contiguu care alcătuiește TVI. Adresele întreruperilor în TVI sunt setate în funcție de prioritatea lor: cu cât adresa este mai mică cu atât prioritatea este mai mare. Pentru a asocia o întrerupere cu o anumită rutină din program, procesorul folosește **tabela vectorilor de întrerupere** (TVI), ilustrată în figura de mai jos. În această tabelă, fiecărei întreruperi îi este asociată adresa rutinei sale de tratare, la care programul va face salt în cazul apariției acesteia. Aceste adrese sunt predefinite și sunt mapate în memoria de program într-un spatiu contiguu care alcătuiește TVI. Adresele întreruperilor în TVI sunt setate în funcție de prioritatea lor: cu cât adresa este mai mică cu atât prioritatea este mai mare.
Line 431: Line 439:
 <​code>​ <​code>​
 // calculate the frequency of the interrupt (f) from the timer configuration and clock speed (f_clk) // calculate the frequency of the interrupt (f) from the timer configuration and clock speed (f_clk)
-= f_clk / (prescaler * (tc + 1))+f_int = f_clk / (prescaler * (tc + 1))
 // calculate the target timer count (tc) for the required interrupt frequency // calculate the target timer count (tc) for the required interrupt frequency
-tc = (1 / f) / (prescaler ​/ f_clk) - 1+tc = f_clk / (prescaler ​* f_int) - 1
 </​code>​ </​code>​
  
Line 479: Line 487:
 </​hidden>​ </​hidden>​
  
 +  - **(1p)**. Rulați exemplul din scheletul de laborator. Ce mod de funcționare folosește timer-ul? Dar prescaler?
 +    *Pe ecranul LCD-ului se pot vizualiza valorile ''​TCNT1''​ și ''​OCR1A''​.
 +    *Limita din dreapta ecranului reprezintă 0xFFFF.
   - **(2p)**. Activați întreruperea externă ''​PCINTn''​ necesară pentru butoanele legate la ''​PB2''​ și ''​PD6''​. În handler-ul de întrerupere,​ aprindeți LED-ul legat la ''​PB3''​ la apăsarea lui ''​PB2''​ și stingeți-l la apăsarea lui ''​PD6''​.   - **(2p)**. Activați întreruperea externă ''​PCINTn''​ necesară pentru butoanele legate la ''​PB2''​ și ''​PD6''​. În handler-ul de întrerupere,​ aprindeți LED-ul legat la ''​PB3''​ la apăsarea lui ''​PB2''​ și stingeți-l la apăsarea lui ''​PD6''​.
     * Hint: butonul este de tip normal deschis, cu rezistență de tip pull-up     * Hint: butonul este de tip normal deschis, cu rezistență de tip pull-up
Line 486: Line 497:
   - **(3p)**. Realizați un cronometru de tip "​countdown timer"   - **(3p)**. Realizați un cronometru de tip "​countdown timer"
     * La apăsarea butonului ''​PB2'',​ cronometrul va fi activat cu o durată de 10 secunde     * La apăsarea butonului ''​PB2'',​ cronometrul va fi activat cu o durată de 10 secunde
-    * La expirarea timpului se va stinge LED-ul legat la ''​PB2''​  +    * La expirarea timpului se va stinge LED-ul legat la ''​PB3''​  
-    *  La apăsarea butonului ''​PD6'',​ cronometrul va fi resetat +    *  La apăsarea butonului ''​PD6'',​ cronometrul va fi oprit și va fi reactivat doar la apăsarea lui ''​PB2''​ 
-    * Hint: Configurați Timer1 în mod //CTC// cu top la ''​OCR1A''​. Calculați prescaler-ul și valoarea lui ''​OCR1A''​ pentru a genera întreruperi cu perioada de o secundă. +    * Hint: Configurați Timer1 în mod //CTC cu top la OCR1A//. Calculați prescaler-ul și valoarea lui ''​OCR1A''​ pentru a genera întreruperi cu perioada de o secundă. 
-  - **(2p)**. Dorim ca led-ul conectat la ''​PB2''​ să funcționeze după următoarea regulă: dintr-o perioadă de o secundă, LED-ul va sta aprins 200 ms. Pentru a implementa acest comportament,​ vom avea nevoie de al doilea registru de comparație al Timer1, OCR1B. Calculați valorile care ar trebui scrise în registrele ''​OCR1A''​ și ''​OCR1B''​ și implementați/​modificați rutinele de tratare a întreruperilor astfel încat să obținem acest comportament.+    * <​hidden>​Nu este prea clara cerinta in ceea ce priveste butonul PD6. Cronometrul isi reia executia la apasarea lui PB2 si nu mai fuctioneaza la apasarea PD6? R: Da (actualizat)</​hidden>​ 
 +  - **(2p)**. Dorim ca LED-ul conectat la ''​PB2''​ să funcționeze după următoarea regulă: dintr-o perioadă de o secundă, LED-ul va sta aprins 200 ms. Pentru a implementa acest comportament,​ vom avea nevoie de al doilea registru de comparație al Timer1, ​''​OCR1B''​. Calculați valorile care ar trebui scrise în registrele ''​OCR1A''​ și ''​OCR1B''​ și implementați/​modificați rutinele de tratare a întreruperilor astfel încat să obținem acest comportament.
   - **(3p)**. Realizați o alarmă pentru cronometrul de la exercițiul anterior ​   - **(3p)**. Realizați o alarmă pentru cronometrul de la exercițiul anterior ​
-    * Configurați Timer2 în mod //CTC// și activați întreruperea corespunzătoare pentru a genera un sunet cu frecvența de 500Hz folosind speaker-ul de pe placă (folosiți ISR-ul pentru a comuta pinul ''​PD4''​). +    * Configurați Timer2 în mod //CTC cu top la OCR2A// și activați întreruperea corespunzătoare pentru a genera un sunet cu frecvența de 625Hz folosind speaker-ul de pe placă (folosiți ISR-ul pentru a comuta pinul ''​PD4''​). 
-    * La expirarea timpului se va emite o alarmă folosind speaker-ul conectat la pinul ''​PD4'' ​+    * La expirarea timpului se va emite o alarmă folosind speaker-ul conectat la pinul ''​PD4''​, cu o durată de 2 secunde ​
     * La apăsarea butonului ''​PD6'',​ cronometrul și alarma vor fi dezactivate     * La apăsarea butonului ''​PD6'',​ cronometrul și alarma vor fi dezactivate
-  ​- **(2p)**. Afișați pe LCD starea cronometrului (timp rămas, activat/​dezactivat)+    * <​hidden>​Nu inteleg de unde a rezultat valoarea de 186 pentru OCR2A din solutii. Din ce am calculat eu, frecventa intreruperii ar fi de 1250Hz (jumatate din perioada) si pentru aceasta valoare obtin OCR2A = 149. R: Asa este, am schimbat frecventa ca sa dea exact. Am actualizat solutia. </​hidden>​ 
 +  ​- **(1p)** Bonus. Afișați pe LCD starea cronometrului (timp rămas, activat/​dezactivat)
     * Afișarea pe LCD se va realiza în bucla principală,​ la fel ca în [[pm:​lab:​lab1|laboratorul 1]]     * Afișarea pe LCD se va realiza în bucla principală,​ la fel ca în [[pm:​lab:​lab1|laboratorul 1]]
     * Obs. Afișarea pe LCD este "​independentă"​ și nu afectează redarea sunetului sau precizia cronometrului.     * Obs. Afișarea pe LCD este "​independentă"​ și nu afectează redarea sunetului sau precizia cronometrului.
  
-/*+ 
 +<​hidden>​
   - **(1p)**. Rulați exemplul din scheletul de laborator. Ce mod de funcționare folosește timer-ul? Dar prescaler?   - **(1p)**. Rulați exemplul din scheletul de laborator. Ce mod de funcționare folosește timer-ul? Dar prescaler?
     * Pe ecranul LCD-ului se pot vizualiza valorile ''​TCNT1''​ și ''​OCR1A''​.     * Pe ecranul LCD-ului se pot vizualiza valorile ''​TCNT1''​ și ''​OCR1A''​.
Line 519: Line 533:
     * Ce observați că se întampla cu LED-ul? De ce?     * Ce observați că se întampla cu LED-ul? De ce?
     * Ce valoarea trebuie sa îi atribuim lui ''​ICR1''​ pentru a obține comportamentul dorit în enunț?     * Ce valoarea trebuie sa îi atribuim lui ''​ICR1''​ pentru a obține comportamentul dorit în enunț?
 +    * [AP] este gresit enuntul sau este "​misleading",​ deoarece nu poate genera overflow cu ICR1 = 50000
   - **(1p + bragging rights)**. În directorul scheletului se generează fișierul ''​lab2.lss'',​ reprezentând codul ASM asociat laboratorului. Numărați ciclii de procesor necesari rulării codului din handler-ul întreruperii de overflow a timer-ului 1. Modificați codul sursă C și folosiți ''​ISR_NAKED''​ pentru a reduce durata handler-ului.   - **(1p + bragging rights)**. În directorul scheletului se generează fișierul ''​lab2.lss'',​ reprezentând codul ASM asociat laboratorului. Numărați ciclii de procesor necesari rulării codului din handler-ul întreruperii de overflow a timer-ului 1. Modificați codul sursă C și folosiți ''​ISR_NAKED''​ pentru a reduce durata handler-ului.
-    ​* Explorați secțiunea de [[#​linkuri-utile|link-uri utile]] +</​hidden>​ 
-*/+ 
 +   /​* ​* Explorați secțiunea de [[#​linkuri-utile|link-uri utile]]*/ 
 ===== 4. Resurse ===== ===== 4. Resurse =====
  
   * {{.:​lab2:​lab2_skel.zip|Schelet laborator}}   * {{.:​lab2:​lab2_skel.zip|Schelet laborator}}
 +
 +<​hidden>​
 +* {{.:​lab2:​lab2_sol.zip|Soluție laborator}}
 +</​hidden>​
  
  /* * <​html><​a class="​media mediafile mf_pdf"​ href="​lab2?​do=export_pdf">​PDF laborator</​a></​html>​*/​  /* * <​html><​a class="​media mediafile mf_pdf"​ href="​lab2?​do=export_pdf">​PDF laborator</​a></​html>​*/​
pm/lab/lab2.1583064295.txt.gz · Last modified: 2020/03/01 14:04 by alexandru.predescu
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0