This shows you the differences between two versions of the page.
pm:lab:lab2-2021 [2022/03/04 13:45] alexandru.predescu [2.2 Exemplu de utilizare] |
pm:lab:lab2-2021 [2022/03/04 14:00] (current) alexandru.predescu [5. Linkuri utile] |
||
---|---|---|---|
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> | ||
- | |||
- | ==== 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> | ||
- | |||
- | <note tip> | ||
- | **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 279: | Line 175: | ||
- | ===== 4. Resurse ===== | + | ===== 5. Resurse ===== |
* {{:pm:atmel-7810-automotive-microcontrollers-atmega328p_datasheet.pdf|Datasheet Atmega 328p}} | * {{:pm:atmel-7810-automotive-microcontrollers-atmega328p_datasheet.pdf|Datasheet Atmega 328p}} | ||
Line 285: | 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}} |