Differences

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

Link to this comparison view

pm:lab:lab1 [2020/02/27 13:50]
ana.constantinescu [4. Exerciții]
pm:lab:lab1 [2020/03/03 14:31] (current)
daniel.berbece [5. Resurse]
Line 26: Line 26:
 Transmisia asincronă de date se face la nivel de **cadre**(frames),​ fiecare cadru fiind format din mai mulți biți, având formatul descris în figură. Transmisia asincronă de date se face la nivel de **cadre**(frames),​ fiecare cadru fiind format din mai mulți biți, având formatul descris în figură.
  
- {{ .:lab1:seriala.png | Transmisia serială }} + {{ .:lab1:uart_ctranca.png | Transmisia serială }} 
  
  
Line 101: Line 101:
 ''​UBRRn''​ este registrul care selectează **baud rate**-ul. Are 12 biți. Primii 4 se află în ''​UBRRnH'',​ ceilalți 8 în ''​UBRRnL''​. Valoarea pe care o scriem în ''​UBRRn''​ depinde de frecvența procesorului și de baud rate-ul dorit. În tabelul următor găsiți valorile pentru frecvența de 16 Mhz. ''​UBRRn''​ este registrul care selectează **baud rate**-ul. Are 12 biți. Primii 4 se află în ''​UBRRnH'',​ ceilalți 8 în ''​UBRRnL''​. Valoarea pe care o scriem în ''​UBRRn''​ depinde de frecvența procesorului și de baud rate-ul dorit. În tabelul următor găsiți valorile pentru frecvența de 16 Mhz.
  
-{{ .:lab1:baud_rate.png?nolink |}}+<note tip> 
 +Pentru valorile UBRR pentru 12MHz cautati valorile in acest {{https://​cache.amobbs.com/​bbs_upload782111/​files_22/​ourdev_508497.html | link}} 
 +</​note>​ 
 +{{ pm:lab:lab1:pm-lab01-baudrate.png?nolink |}}
  
 ==== 2.2 Exemplu de utilizare ==== ==== 2.2 Exemplu de utilizare ====
Line 107: Line 110:
 void USART0_init(unsigned int baud) { void USART0_init(unsigned int baud) {
     /* setează baud rate */     /* setează baud rate */
-    ​UBRR0H ​(unsigned char)(baud>>​8);​ +    ​UBRR0 = baud; 
-    UBRR0L = (unsigned char)baud; +    /* UBRR0 este un registru pe 16 biți, la nivel de compilator se vor face doua scrieri de 8 biti */
-    /* UBRR0 este un registru pe 16 biți +
-    Alternativ se poate scrie UBRR0 = baudpentru că la nivel de compilator ​ +
-    ​se vor face două scrieri de 8 biți */+
  
     /* pornește transmițătorul */     /* pornește transmițătorul */
Line 342: Line 342:
       * secțiunea 19.11 este referința pentru registrele I/O       * secțiunea 19.11 este referința pentru registrele I/O
  
-==== USART ==== +** Task 0  **(1p)
-** Task 0  **(xp)+
 Rulați exemplul pentru USART. Pentru configurările serialei, vedeți fisierul usart.c din schelet. Rulați exemplul pentru USART. Pentru configurările serialei, vedeți fisierul usart.c din schelet.
  
-**Task 1 **(xp+**Task 1 **(3p
-Configurați USART0 cu următorii parametri: baud rate 19200, 8 biți de date, bit de stop, paritate ​pară. Transmiteți către PC câte un mesaj pentru fiecare eveniment de apăsare/​lăsare a unui buton (ex: se apasă PD6, se transmite “PD6 apăsat”, se lasă PD6, se transmite “PD6 lăsat”, câte o singură dată pe apăsare).+Configurați USART0 cu următorii parametri: baud rate 19200, 8 biți de date, bit de stop, fara paritate. Transmiteți către PC câte un mesaj pentru fiecare eveniment de apăsare/​lăsare a unui buton (ex: se apasă PD6, se transmite “PD6 apăsat”, se lasă PD6, se transmite “PD6 lăsat”, câte o singură dată pe apăsare).
  
-**Task 2 **(xp)+**Task 2 **(2p)
 Comandați prin serială generarea in cod Morse a numelui vostru, folosind buzzer-ul. ​ Comandați prin serială generarea in cod Morse a numelui vostru, folosind buzzer-ul. ​
 <​note>​ <​note>​
Line 355: Line 354:
 </​note>​ </​note>​
  
-**Task 3**Bonus USART (xp+**Task 3 **(1p)  
-Configurați printf astfel încât să printeze direct pe USART0. Refaceți exercițiul 1 folosind printf.+Rulați exemplul pentru LCD.
  
-** Tips pentru printf ​(click to show)** +**Task 4** (3p)  
-<​spoiler>​ +Implementați funcțiile din bibliotecă: 
-<note tip> +  * LCD_putCharAt ​ 
-După cum știți de la programare, printf este echivalent cu fprintf(stdout,​... ), cu alte cuvinte, folosește stdout ca fișier în care să scrie. Pentru a putea utiliza printf corect pe AVR, trebuie ca stdout trebuie să pointeze către o **structură validă FILE**. +  * LCD_printAt ​ 
- +Puteți folosi funcțiile LCD_writeInstr și LCD_writeData. 
-<​code>​ +  ​- Utilizați funcțiile implementate pentru a afișa un mesaj pe prima linie a LCD-ului. ​ 
-struct __file { +  ​- Folositi implementarea anterioara pentru a afisa un mesaj trimis pe USART
- char *buf;​ /​* buffer pointer */ +<note 
- unsigned char unget; /* ungetc() buffer */ +Mesajul ​trebuie să poată fi deplasat la stânga ​cu butonul PB2 și la dreapta cu butonul PD6Limitați deplasarea mesajului astfel încât acesta ​să nu iasă de pe ecran.
- uint8_t flags;​ /​* flags, see below */ +
-#define __SRD  0x0001 /OK to read */ +
-#define __SWR  0x0002 /OK to write */ +
-#define __SSTR 0x0004 /* this is an sprintf/​snprintf string */ +
-#define __SPGM  0x0008 /* fmt string is in progmem */ +
-#define __SERR  0x0010 /* found error */ +
-#define __SEOF 0x0020 /* found EOF */ +
-#define __SUNGET 0x040 /* ungetc() happened */ +
-#define __SMALLOC 0x80 /* handle is malloc()ed */ +
- int size;​ /​* size of buffer */ +
- int len;​ /​* characters read or written so far */ +
- int (*put)(char,​ struct __file *); /* function to write one char to device */ +
- int (*get)(struct __file *); /* function to read one char from device */ +
- void *udata;​ /​* User defined and accessible data*/ +
-}; +
- +
-#typedef struct __file FILE +
- +
-</code+
- +
-Pentru un fișier în care trebuie ​doar să scriem, nu ne trebuie decât câmpul ''​flags''​ și câmpul ''​put''​. ''​put''​ este un pointer către o funcție care scrie un caracter, iar ''​flags''​ este un câmp cu flag-uri, printre care există ​și un flag care spune că putem scrie în fișier, ''​__SWR''​Este suficient să faceți o structură cu ''​put''​ și flags corecte și să pointeze stdout către ea ca să vă meargă ''​printf''​.+
 </​note>​ </​note>​
-</​spoiler>​ 
- 
- 
- 
- 
-==== LCD ==== 
- 
-**Task 0 **(xp) ​ 
-Rulați exemplul pentru LCD. 
- 
-**Task 1** (xp)  
-Implementați funcțiile LCD_putCharAt și LCD_printAt din bibliotecă. Puteți folosi funcțiile LCD_writeInstr și LCD_writeData. Utilizați funcțiile implementate pentru a afișa un mesaj pe prima linie a LCD-ului. Mesajul trebuie să poată fi deplasat la stânga cu butonul PB2 și la dreapta cu butonul PD6. Limitați deplasarea mesajului astfel încât acesta să nu iasă de pe ecran. 
  
 <note tip> <note tip>
  ​Trebuie să folosiți o instrucțiune a LCD-ului (apelată cu ''​LCD_writeInstr''​) pentru a poziționa cursorul la poziția dorită, apoi să scrieți datele către LCD (cu ''​LCD_writeData''​). Codul instrucțiunilor LCD le puteți vedea fie în <tabref instructiuni_lcd>,​ fie în fișierul ''​lcd.h''​ prezent în scheletul de laborator.  ​Trebuie să folosiți o instrucțiune a LCD-ului (apelată cu ''​LCD_writeInstr''​) pentru a poziționa cursorul la poziția dorită, apoi să scrieți datele către LCD (cu ''​LCD_writeData''​). Codul instrucțiunilor LCD le puteți vedea fie în <tabref instructiuni_lcd>,​ fie în fișierul ''​lcd.h''​ prezent în scheletul de laborator.
 </​note>​ </​note>​
-==== USART ==== 
  
-<​hidden>​ 
-------------Exercitii vechi 
-<​spoiler>​Pentru partea de UART: recomand sa lasam exercitile 0 (relevant pentru ca pe orice placa te vei conecta mai intai cu UART pana sa ai ssh sau mai stiu eu ce), 1 si 2 (faciliteaza ENORM debuggingul). Totusi, la exercitiul 1 haideti sa schimbam formatul cadrelor uart (si baud rate-ul), ca sa nu serveasca din anii trecuti. 
  
 +**Task 5: **Bonus USART (1p)
 +Configurați printf astfel încât să printeze direct pe USART0. Refaceți exercițiul 1 folosind printf.
  
-3 ar trebui sa fie scos. +** Tips pentru ​printf ​(click to show)**
-</​spoiler>​ +
- +
-** Task 0** (1p). Rulați exemplul ​pentru ​USART. Pentru configurările serialei, vedeți fisierul ''​usart.c''​ din schelet. +
- +
-** Task 1** (3p). Configurați //USART0// cu următorii parametri: baud rate 19200, 8 biți de date, 1 bit de stop, paritate pară. Transmiteți către PC câte un mesaj pentru fiecare eveniment de apăsare/​lăsare a unui buton (ex: se apasă PB2, se transmite "PB2 apăsat",​ se lasă PB2, se transmite "PB2 lăsat", ​**câte o singură dată pe apăsare**). +
- +
-<note tip> +
- +
-Switch-urile mecanice suferă de un efect numit "​bounce"​. Linia nu va avea o tranziție clară de la 1 la 0 sau invers, ci va oscila un pic (este un efect pur mecanic). Pentru a nu afișa de multiple ori o secvență de apăsat -> lăsat -> apăsat etc. pentru o singură apăsare, trebuie să aplicăm o tehnică de **debouncing**:​ +
-  * Fie ignorăm orice tranziție după prima pentru o perioadă mică de timp, de ex 10-20ms (varianta simplă) +
-  * Fie măsurăm cât de lung este un puls continuu și luăm o apăsare doar dacă apare pentru mai mult de câteva ms (de exemplu, cu o buclă cu delay de 10ms, dacă am măsurat 0 de 4 ori consecutiv consider că este cu adevărat o apăsare) +
- +
-{{ .:​lab1:​bounce.jpg?​400 |}} +
-</​note>​ +
- +
-** Task 2** (3p). Comandați prin serială generarea de cod Morse folosind buzzer-ul. În scheletul de laborator găsiți variabila morse_alphabet ce conține literele alfabetului în cod Morse. Pe serială veți trimite caractere ASCII litere mici (ex: '​a',​ '​b',​ '​c',​ etc.). Placa va citi caractere de pe serială și va reda semnalul Morse corespunzător de fiecare dată când citește un caracter valid. +
- +
-<​spoiler>​** Task 3 (Bonus)** (1p). Configurați //printf// astfel încât să printeze direct pe //USART0//. Refaceți exercițiul 1 folosind //​printf//​.</​spoiler>​ +
 <​spoiler>​ <​spoiler>​
-** Tips pentru printf (click to show)** 
 <note tip> <note tip>
 După cum știți de la programare, printf este echivalent cu fprintf(stdout,​... ), cu alte cuvinte, folosește stdout ca fișier în care să scrie. Pentru a putea utiliza printf corect pe AVR, trebuie ca stdout trebuie să pointeze către o **structură validă FILE**. După cum știți de la programare, printf este echivalent cu fprintf(stdout,​... ), cu alte cuvinte, folosește stdout ca fișier în care să scrie. Pentru a putea utiliza printf corect pe AVR, trebuie ca stdout trebuie să pointeze către o **structură validă FILE**.
Line 464: Line 408:
 </​note>​ </​note>​
 </​spoiler>​ </​spoiler>​
-</​hidden>​ 
  
-==== LCD ==== 
- 
-<​hidden> ​ 
-----Exercitii vechi 
-<​spoiler>​ 
-Pentru partea de LCD: cred ca 0 si 1 sunt relevante (sa vada cum folosesc un API + ca laburile viitoare vor necesita sa stie sa lucreze cu LCD-ul), deci 0 si 1 ar trebui sa ramana. 
- 
-2 este masturbare intelectuala,​ nu aduce plus valoare: cum sa transmita pe UART se face in prima parte a laboratorului,​ cum sa afiseze la exercitile 0 si 1. In conlzie, 2 ar trebui sa fie scos. 
- 
-Pe 3 oricum nu il face nimeni si nici nu ii prea vad sensul (daca ne gandim la scopul laboratorului). Si 3 ar trebui sa fie scos. 
-</​spoiler>​ 
- 
-**Task 0** (0p). Rulați exemplul pentru LCD. 
- 
-**Task 1** (3p). Implementați funcțiile //​LCD_putCharAt//​ și //​LCD_printAt//​ din bibliotecă. Puteți folosi funcțiile //​LCD_writeInstr//​ și //​LCD_writeData//​. Utilizați funcțiile implementate pentru a afișa un mesaj pe prima linie a LCD-ului. Mesajul trebuie să poată fi deplasat la stânga cu butonul PB2 și la dreapta cu butonul PD6. Limitați deplasarea mesajului astfel încât acesta să nu iasă de pe ecran. 
- 
-<note tip> Trebuie să folosiți o instrucțiune a LCD-ului (apelată cu ''​LCD_writeInstr''​) pentru a poziționa cursorul la poziția dorită, apoi să scrieți datele către LCD (cu ''​LCD_writeData''​). Codul instrucțiunilor LCD le puteți vedea fie în <tabref instructiuni_lcd>,​ fie în fișierul ''​lcd.h''​ prezent în scheletul de laborator. 
-</​note>​ 
- 
- 
-<​spoiler>​**Task 2** (2p). Afișați pe ecranul LCD-ului caracterele primite pe interfața seriala USART0. Utilizați ambele linii ale ecranului astfel: afișați caracterele secvențial,​ pe prima linie, apoi pe linia a doua, și reveniți la prima linie suprascriind vechile caractere în momentul umplerii ecranului. 
- 
-**Task 3 (Bonus)** (2p + bragging rights). Implementați și afișati caracterul custom din <imgref lcd_chuck>​. Inițial Chuck se află pe linia de jos a LCD-ului. El trebuie să poată fi mutat cu o poziție la stânga/​dreapta pentru fiecare apasare a butoanelor PB2/PD6. Cât timp ambele butoane sunt apăsate, Chuck își va folosi puterea specială și se va muta pe aceeași coloană a liniei de sus. 
- 
-<​imgcaption lcd_chuck center | Courageous Chuck>​{{.:​lab1:​lcd_chuck.png|}}</​imgcaption>​ 
-</​spoiler>​ 
-</​hidden>​ 
  
  
 ===== 5. Resurse ===== ===== 5. Resurse =====
  
-  * {{.:lab1:lab1_skel.zip | Schelet laborator}}+  * {{:pm:lab:​lab1_skel2020.zip | Schelet laborator}}
 <​hidden> ​ * {{.:​lab1:​lcd_schema.zip| Schemă simulare}} ({{.:​lab1:​lcd_schema_2012.zip| varianta 2012}}, cu ATmega16, pentru versiunile de Proteus vechi)</​hidden>​ <​hidden> ​ * {{.:​lab1:​lcd_schema.zip| Schemă simulare}} ({{.:​lab1:​lcd_schema_2012.zip| varianta 2012}}, cu ATmega16, pentru versiunile de Proteus vechi)</​hidden>​
   * {{.:​lab1:​hd44780_datasheet.pdf| Datasheet Hitachi 44780}}   * {{.:​lab1:​hd44780_datasheet.pdf| Datasheet Hitachi 44780}}
   * {{:​pm:​doc8272.pdf | Datasheet ATmega324}}   * {{:​pm:​doc8272.pdf | Datasheet ATmega324}}
 +  * {{https://​cache.amobbs.com/​bbs_upload782111/​files_22/​ourdev_508497.html | AVR Baud Rate Tables}}
 <​hidden> ​ * <​html><​a class="​media mediafile mf_pdf"​ href="/​wiki/​pm/​lab/​lab1?​do=export_pdf">​PDF laborator</​a></​html></​hidden>​ <​hidden> ​ * <​html><​a class="​media mediafile mf_pdf"​ href="/​wiki/​pm/​lab/​lab1?​do=export_pdf">​PDF laborator</​a></​html></​hidden>​
   * Responsabili:​ [[dorin_marian.ionita@cs.pub.ro | Dorin Ionita]] [[ Ana Dragan ]]   * Responsabili:​ [[dorin_marian.ionita@cs.pub.ro | Dorin Ionita]] [[ Ana Dragan ]]
  
pm/lab/lab1.1582804203.txt.gz · Last modified: 2020/02/27 13:50 by ana.constantinescu
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