This shows you the differences between two versions of the page.
pm:lab:lab2-2021 [2022/03/04 13:49] alexandru.predescu [2. Instrumente necesare] |
pm:lab:lab2-2021 [2022/03/04 14:00] (current) alexandru.predescu [5. Linkuri utile] |
||
---|---|---|---|
Line 22: | Line 22: | ||
* Depanare LED - verificarea stării true/false | * Depanare LED - verificarea stării true/false | ||
- | * **mesaje pe interfața serială / USART - depanare prin USART, bluetooth, etc** | + | * mesaje pe interfața serială / USART - depanare prin USART, bluetooth, etc |
* Debuggere avansate pentru afisarea si modificarea memoriei / registrelor (a se vedea JTAG de mai jos) | * Debuggere avansate pentru afisarea si modificarea memoriei / registrelor (a se vedea JTAG de mai jos) | ||
* Loopbacking (conectarea ieșirilor la intrări) poate oferi informații despre modul în care comenzile sunt trimise dispozitivelor externe. | * Loopbacking (conectarea ieșirilor la intrări) poate oferi informații despre modul în care comenzile sunt trimise dispozitivelor externe. | ||
Line 81: | Line 81: | ||
<note tip>**Baud rate** este numărul de simboluri/pulsuri pe secundă al semnalului. În esență, reprezintă viteza de transmisie și este foarte important ca și transmițătorul și receptorul să folosească același baud rate pentru transmisia corectă a datelor. Una dintre cele mai comune probleme cu USART este setarea diferită a baud rate-ului pe transmițător și pe receptor. Această neconcordanță se manifestă prin recepția unor date greșite (transmițătorul trimite caracterul 'a', receptorul primește caracterul '&')</note> | <note tip>**Baud rate** este numărul de simboluri/pulsuri pe secundă al semnalului. În esență, reprezintă viteza de transmisie și este foarte important ca și transmițătorul și receptorul să folosească același baud rate pentru transmisia corectă a datelor. Una dintre cele mai comune probleme cu USART este setarea diferită a baud rate-ului pe transmițător și pe receptor. Această neconcordanță se manifestă prin recepția unor date greșite (transmițătorul trimite caracterul 'a', receptorul primește caracterul '&')</note> | ||
- | |||
- | <note warning>Pentru ca cele două dispozitive, în cazul nostru PC-ul și placa de laborator, să poată comunica între ele prin USART, trebuie configurate **identic**. Dacă placa este configurată cu baud rate 115200, 9 biți de date, 1 bit de stop și fără paritate atunci PC-ul trebuie configurat **exact la fel** pentru a comunica.</note> | ||
- | |||
- | ==== 3.1 Registre ==== | ||
<note>Descrierea completă pentru: | <note>Descrierea completă pentru: | ||
- | * a celor trei registre de control | + | * cele trei registre de control |
- | * a registrului pentru baud rate | + | * registrul pentru baud rate |
- | * a celui pentru buffer-ele de transmisie/recepție | + | * registrele pentru buffer-ele de transmisie/recepție |
- | Se gaseste în {{:pm:doc8272.pdf|datasheet}} la <color red>capitolul 19. </color> | + | Se gaseste în {{:pm:atmel-7810-automotive-microcontrollers-atmega328p_datasheet.pdf|datasheet}} la <color red>capitolul 19. </color> |
- | Registrele au un 'n' la sfârșit care distinge între cele două periferice USART de pe microcontroller-ul nostru. 'n' va lua valoarea 0 pentru USART0, respectiv 1 pentru USART1. | + | Deoarece biblioteca Arduino vine cu suport foarte bun pentru comunicație serială, nu vom insista asupra lucrului direct cu registre. |
</note> | </note> | ||
- | === USART Data Register n (UDRn) === | ||
- | |||
- | {{ .:lab1:udr.png?nolink |Registrul UDR}} | ||
- | |||
- | |||
- | ''RXB'' și ''TXB'' sunt buffer-ele de recepție, respectiv transmisie. Ele folosesc //aceeași adresă de I/O//. Deci ''RXB'' este accesat citind din ''UDRn'', ''TXB'' scriind în ''UDRn''. Buffer-ul de transmisie poate fi scris numai atunci când bitul ''UDRE'' (//USART Data Register Empty//) din portul ''UCSRnA'' este 1. În caz contrar, scrierile vor fi ignorate. | ||
- | |||
- | === USART Control and Status Register n A (UCSRnA) === | ||
- | |||
- | {{ .:lab1:ucsra.png?nolink |Registrul de control UCSRnA}} | ||
- | |||
- | ''UCSRnA'' este registrul de stare al controller-ului de comunicație. Biții cei mai importanți sunt: | ||
- | * **RXCn** – **Receive Complete** – devine 1 când există date primite și necitite. Când buffer-ul de recepție este gol, bitul este resetat automat | ||
- | * **TXCn** – **Transmit Complete** – devine 1 când buffer-ul de transmisie devine gol | ||
- | * **UDREn** – **Data Register Empty** – devine 1 când buffer-ul de transmisie poate accepta noi date | ||
- | |||
- | === USART Control and Status Register n B (UCSRnB) === | ||
- | |||
- | {{ .:lab1:ucsrb.png?nolink |Registrul de control UCSRnB}} | ||
- | |||
- | |||
- | ''UCSRnB'' este un registru de control. Biții importanți: | ||
- | * **RXCIEn** – **Receive Complete Interrupt Enable** – când este 1, controller-ul de comunicație va genera o întrerupere când au fost primite date | ||
- | * **TXCIEn** – **Transmit Complete Interrupt Enable** – când este 1, controller-ul de comunicatie va genera o întrerupere când buffer-ul de transmisie devine gol | ||
- | * **UDRIEn** – **Data Register Empty Interrupt Enable** – când este 1, controller-ul de comunicație va genera o întrerupere când buffer-ul de transmisie mai poate accepta date | ||
- | * **RXENn** – **Receiver Enable** – dacă este 0, nu se pot recepta date | ||
- | * **TXENn** – **Transmitter Enabler** – dacă este 0, nu se pot transmite date | ||
- | * **UCSZn2** – împreună cu ''UCSZ1'' și ''UCSZ0'' din portul ''UCSRC'', selectează dimensiunea unui cuvânt de date | ||
- | |||
- | === USART Control and Status Register n C (UCSRnC) === | ||
- | |||
- | {{ .:lab1:ucsrc.png?nolink |Registrul de control UCSRnC}} | ||
- | |||
- | |||
- | ''UCSRnC'' este tot un registru de control. Biții importanți: | ||
- | * **UMSELn** – **Mode Select** – 0 pentru funcționare asincronă, 1 pentru funcționare sincronă | ||
- | * **UPMn1, UPMn0** – **Parity Mode** - Fiind vorba de doi biți, împreună pot avea 4 valori posibile, detaliate în tabelul ce urmează: | ||
- | {{ .:lab1:upm.png?nolink | Biții UPM}} | ||
- | |||
- | |||
- | * **USBSn** – **Stop Bit Select** – 0 pentru un bit de stop, 1 pentru doi biți de stop | ||
- | {{ .:lab1:usbs.png?nolink | Biții USBS}} | ||
- | * **UCSZn1, UCSZn0** – împreună cu ''UCSZn2'' din portul ''UCSRnB'', selectează dimensiunea cuvântului de date | ||
- | {{ .:lab1:ucsz.png?nolink |Biții UCSZ}} | ||
- | |||
- | |||
- | === USART Baud Rate Registers (UBRRn) === | ||
- | |||
- | {{ .:lab1:ubrr.png?nolink |Registrul UBRRn}} | ||
- | |||
- | ''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. | ||
- | |||
- | <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 ==== | ||
- | <file c> | ||
- | void USART0_init(unsigned int baud) { | ||
- | /* setează baud rate */ | ||
- | UBRR0 = baud; | ||
- | /* UBRR0 este un registru pe 16 biți, la nivel de compilator se vor face doua scrieri de 8 biti */ | ||
- | |||
- | /* pornește transmițătorul */ | ||
- | UCSR0B = (1<<TXEN0); | ||
- | |||
- | /* setează formatul frame-ului: 8 biți de date, 2 biți de stop, fără paritate */ | ||
- | UCSR0C = (1<<USBS0)|(3<<UCSZ00); | ||
- | } | ||
- | |||
- | void USART0_transmit(unsigned char data) { | ||
- | /* așteaptă până când buffer-ul e gol */ | ||
- | while(!(UCSR0A & (1<<UDRE0))); | ||
- | |||
- | /* pune datele în buffer; transmisia va porni automat în urma scrierii */ | ||
- | UDR0 = data; | ||
- | } | ||
- | </file> | ||
- | |||
- | |||
- | **Scrieri pe 16 biți:** | ||
- | |||
- | <hidden>Parerea mea: nu mai scriem assembly de mult la laborator, hai sa scoatem partea asta cu ordinea de scriere. | ||
- | |||
- | Pentru că scrierea în registre I/O are efecte imediate, scrierea în registre de 16 biți trebuie făcută cu grijă. Există o ordine prestabilită (și proprie fiecărui registru) în care trebuie făcută scrierea, altfel ne expunem la efecte tranzitorii nedorite. | ||
- | |||
- | De exemplu, registrul ''UBRR0'' (format din ''UBRR0H'' și ''UBRR0L'') se scrie întotdeauna cu byte-ul HIGH înaintea byte-ului LOW, pentru că scrierea byte-ului LOW este trigger-ul pentru schimbarea baud rate-ului. În cazul scrierii în C a locației ''UBRR0'', compilatorul va face automat cele două scrieri în ordinea corectă. | ||
- | |||
- | </hidden> | ||
- | |||
- | |||
- | ** (3 <nowiki><<</nowiki> x) ** | ||
- | |||
- | Pentru biți de configurație care se găsesc întotdeauna unul după altul se folosește și o mască cu mai mulți biți shiftați cu index-ul celui mai din dreapta: ''(3 <nowiki><<</nowiki> UCSZ00)'' înlocuiește astfel ''(1 <nowiki><<</nowiki> UCSZ01) | (1 <nowiki><<</nowiki> UCSZ00)'' | ||
- | |||
- | ** (1 <nowiki><<</nowiki> x) | (1 <nowiki><<</nowiki> y) ** | ||
- | |||
- | <hidden>Ce inseamna ca e mai eficient? E o operatie algebrica iar compilatorul poate si face simplificari algebrice. De asemenea, e evident ca nu amestec operatile intre ele. As scoate si asta. </hidden> | ||
- | |||
- | De cele mai multe ori o să facem măști compuse, pe care le vom aplica unui registru I/O în același timp. <hidden> Această metodă este mai eficientă decât a face aceste operații pe rând. </hidden> **Atenție!** Pot doar să compun măști pentru aceeași operație, nu pot aplica o mască //SAU// în același timp cu o mască //ȘI// pentru că rezultatul ar fi complet eronat! | ||
- | |||
==== Utilizarea interfetei seriale de pe Arduino UNO ==== | ==== Utilizarea interfetei seriale de pe Arduino UNO ==== | ||
Line 281: | Line 175: | ||
- | ===== 4. Exerciții ===== | + | ===== 5. Resurse ===== |
- | + | ||
- | **Capitole utile din {{:pm:doc8272.pdf | Datasheet ATmega324}}** | + | |
- | * 1. Pin Configurations - pag. 2 | + | |
- | * 19. USART - pag. 174 | + | |
- | * secțiunile 19.1 - 19.3 pentru overview | + | |
- | * secțiunea 19.4.1 pentru generarea ceasului | + | |
- | * secțiunile 19.5 - 19.8 pentru formatul frame-ului, modul de a programa inițializarea și funcționarea | + | |
- | * secțiunea 19.11 este referința pentru registrele I/O | + | |
- | + | ||
- | ** 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, 2 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 **(2p) | + | |
- | Comandați prin serială generarea in cod Morse a numelui vostru, folosind buzzer-ul. | + | |
- | <note> | + | |
- | Î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. | + | |
- | </note> | + | |
- | + | ||
- | + | ||
- | + | ||
- | ===== 4. Resurse ===== | + | |
* {{:pm:atmel-7810-automotive-microcontrollers-atmega328p_datasheet.pdf|Datasheet Atmega 328p}} | * {{:pm:atmel-7810-automotive-microcontrollers-atmega328p_datasheet.pdf|Datasheet Atmega 328p}} | ||
Line 311: | Line 181: | ||
* {{:pm:lab:uno.jpg?200|pinout Arduino UNO}} | * {{:pm:lab:uno.jpg?200|pinout Arduino UNO}} | ||
* Responsabili: [[Adrian.Mocanu@gmail.com | Adrian Mocanu]] | * Responsabili: [[Adrian.Mocanu@gmail.com | Adrian Mocanu]] | ||
- | ===== 5. Linkuri utile ===== | + | ===== 6. Linkuri utile ===== |
* {{https://cache.amobbs.com/bbs_upload782111/files_22/ourdev_508497.html | AVR Baud Rate Tables}} | * {{https://cache.amobbs.com/bbs_upload782111/files_22/ourdev_508497.html | AVR Baud Rate Tables}} |