Differences

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

Link to this comparison view

pm:lab:lab2-2023 [2024/03/18 09:08]
florin.stancu add #include <avr/interrupt.h> to timer ISR example
pm:lab:lab2-2023 [2026/03/09 10:53] (current)
jan.vaduva [2.4. Lucrul cu Timer-ul]
Line 371: Line 371:
 { {
   TIMSK1 |= (1 << OCIE1A);   TIMSK1 |= (1 << OCIE1A);
 +  // ...
 } }
 int main() int main()
 { {
-  sei(); ​         // activăm primirea întreruperilor 
   init_timer1(); ​ // apelăm funcția de inițializare   init_timer1(); ​ // apelăm funcția de inițializare
 +  sei(); ​         // activăm primirea întreruperilor
   // ...   // ...
 } }
Line 419: Line 420:
 ===== 3. Exerciții ===== ===== 3. Exerciții =====
  
-**Task 1.1**+**Task 1. (2p)** 
 +Implementați o funcție ''​uptime_ms()''​ care returnează numărul de milisecunde scurse de la pornirea microcontrolerului.
  
-  * Implementați o funcție asemănătoare cu ''​millis()''​ din biblioteca Arduino. Aceasta ar trebui să returneze intervalul de timp trecut de la pornirea (sau ultimul reset) al uC-ului. Configurați interfața USART0 cu aceeași parametri folosiți în laboratorul trecut și transmiteți către PC un mesaj ales de voi la intervale de 1 secundă. 
  
-HINTS:+  * folosiți un timer și întreruperi pentru a genera un tick periodic de aproximativ 1 ms 
 + 
 +  * la fiecare întrerupere incrementați un contor global 
 + 
 +  * funcția ''​uptime_ms()''​ trebuie să returneze valoarea acestui contor 
 + 
 +<note tip>
   * Frecvența de ceas a uC-ului este de 12MHz. Folosiți formulele prezentate anterior pentru a obține valorile potrivite pentru prescaler și registrul de comparație ale timer-ului ales astfel încât întreruperile generate de acesta să se declanșeze la intervalul de timp dorit.   * Frecvența de ceas a uC-ului este de 12MHz. Folosiți formulele prezentate anterior pentru a obține valorile potrivite pentru prescaler și registrul de comparație ale timer-ului ales astfel încât întreruperile generate de acesta să se declanșeze la intervalul de timp dorit.
   * Timer2 poate fi utilizat cu un număr mai mare de valori ale prescaler-ului.   * Timer2 poate fi utilizat cu un număr mai mare de valori ale prescaler-ului.
 +</​note>​
 +
 +Configurați ''​USART0''​ cu aceiași parametri ca în laboratorul anterior și transmiteți către PC mesajul:
 +<​code>​
 +Uptime: <​valoare>​ ms
 +</​code>​
 +
 +Mesajul trebuie trimis la fiecare **1 secundă**.
 +
 +
 +
 +<​note>​ Funcția ''​USART0_transmit(char data)''​ este blocantă (blochează executia restul instrucțiunilor din main). Determinați limita minimă a intervalului de timp dintre mesaje pentru care acestea pot fi transmise corect, în funcție de BAUD rate și de numărul de caractere din mesaj. </​note>​
 +
 +
 +**Task 2.1 BTN Interrupt (2p)**
 +
 +Configurați ​ **pin change interrupt** pentru butonul BTN1 (PB2).
 +
 +Implementați rutina de tratare a întreruperii ''​ISR(PCINT<​n>​_vect)''​. In ISR setați un flag atunci când butonul este apăsat. In ''​main()''​ detectați flag-ul și transmiteți pe USART mesajul: "​**PRESS**"​.
  
-**Task ​1.2** +**Task ​2.2 Debouncing (1p)**
-  * Pentru a putea citi în mod corect apăsări scurte ale butoanelor este necesară o metodă de debouncing. Cum ar putea fi rezolvată problema citirilor eronate cu ajutorul funcției ''​millis()''?​ Concepeți o funcție (în pseudocod) care să ilustreze soluția găsită.+
  
-**Task 2.**+Când se apasă un buton, generați un eveniment "**PRESS**" o singură dată, chiar dacă contactul bounce-uiește. 
 +Implementați debouncing cu o fereastră de 30–50 ms bazată pe ''​uptime_ms()''​ (din Task 1), dar fără să blocați execuția în main.
  
-  * Reluați exercițiul 3 din primul laborator și implementați-l folosind timer-e și întreruperi pentru citirea butoanelor și efectul de clipire al LED-urilor. 
  
-<​spoiler ​**Reminder Ex3, lab 0**> +**Task 3. (3p)**
-  * La apăsarea succesivă a BTN1, LED-ul RGB trebuie să își schimbe culoarea ​(Red -> Green -> Blue -> Red) +
-  ​BTN2 trebuie să controleze efectul de clipire al LED-ului aprins +
-</​spoiler>​+
  
-**Task 3.** +Folosiți buzzer-ul ​și butoanele:
-  * Folosiți ​butoanele ''​PD6''​ și ''​PB2''​ pentru a controla ​buzzer-ul: +
-    * Unul dintre butoane selectează frecvența sunetului generat de buzzer (dintre 3 valori, de ex. 100Hz, 200Hz, 300Hz) +
-    * Buzzer-ul funcționează doar când mențineți al doilea buton apăsat +
-    * Puteți folosi LED-ul RGB pentru a indica frecvența aleasă+
  
-**Task 4. (BONUS)**+  ​BTN1 (''​PB2''​) schimbă frecvența sunetului generat de buzzerFrecvența poate avea 3 valori diferite ​(200 Hz, 400 Hz, 800 Hz).  
 +  ​BTN2 (''​PD6''​) este „gate”: buzzerul sună doar cât timp BTN2 este ținut apăsat.
  
-  * Funcția implementată la primul exercițiu va acumula o anumită eroare din cauza faptului că frecvența de ceas nu poate fi divizată perfect. +(generați semnalul pentru buzzer folosind un timer șîntreruperi)
-    * Încercați să calculațdupă câte cicluri de funcționare a timer-ului eroarea devine semnificativă (peste 1 ms)+
-    * Propuneți o metodă prin care se poate reduce această eroare +
-    * Încercați implementarea metodei propuse+
  
  
 +**Task 4. Mini scheduler (2p)**
  
 +Folosiți funcția ''​uptime_ms()''​ pentru a implementa un mini-scheduler cooperativ care execută mai multe taskuri periodice. Implementați în bucla principală un mecanism care verifică periodic momentul curent (''​now = uptime_ms()''​) și execută următoarele taskuri:
  
 +  *  T1 – Heartbeat (periodă 1000 ms) - Comută starea LED-ului albastru.
 +  *  T2 – Logger (periodă 500 ms) - Transmite pe USART mesajul: **t=<​uptime_ms>​ ms**
 +  *  T3 – Status (periodă 3000 ms) - Comută starea LED-ului roșu.
pm/lab/lab2-2023.1710745695.txt.gz · Last modified: 2024/03/18 09:08 by florin.stancu
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