Sunteți pe pagina 1din 18

Ministerul Educației al Republicii Moldova

Universitatea Tehnică a Moldovei


Facultatea Calculatoare Informatică și Microelectronică
Departamentul Microelectronică și Inginerie Biomedicală

RAPORT
La lucrarea de laborator Nr:1
La disciplina Proiectarea Microsistemelor
Tema: Interfața serială USART.
Activarea librăriei STDIO pentru MCU AVR

A efectuat: st. gr. IBM-172 Rotari Nicu

A verificat: Verjbitchi Valeriu

Chișinău 2020
Scopul lucrării: Să se studieze interfața serială USART. Să se conecteze librăria STDIO la
modulul periferic USART. Să se realizeze aplicații, utilizînd librăria STDIO.
Sarcina lucrării: Să se dezvolte o aplicație cu MCU care ar permite dirijarea unui
LED prin terminalula atașat la interfața USART.
Noțiuni teoretice:
Un program C+ este alcatuit din una sau mai multe funcții, din care una este rădăcina
sau funcție principală și execuția începe automat cu ea. Aceasta se numește main. Funcțiile
apelate pot fi funcții predefinite descrise în fișiere header predefinite sau pot fi funcții definite
de către programator. Acestea din urmă pot fi definite în fișierul sursă care conține programul
principal sau în alt fișier numit header utilizator și cu care se creează legatura în perioada de
linkeditare prin directiva preprocesor # include.
În cazul în care programatorul își creează propriile fișiere header numele fișierului va
fi inclus între ghilimele ( " " ). Fișierul va fi conținut de directorul setat ca fiind director de
lucru.
Interfața serială USART (Universal synchronous/asynchronous receiver/transmitter)
reprezintă un standard de comunicare serială între diverse dispozitive cum ar fi comunicarea
între calculator (prin portul serial COM) şi alte dispozitive. Comunicarea serială presupune
folosirea unei singure legături dacă ea este unidirecţională, adică există un trasmiţător şi un
receptor sau invers. Dacă este bidirecţională este nevoie de două legături, pe o legătură
realizându-se transmisia iar pe alta recepţia. Dacă se foloseşte modul sincron pe lîngă
legăturile de transmisie a datelor se mai foloseşte o legătură prin care se stabileşte acelaşi
semnal de tact între dispozitive. Schema de principiu este reprezentată în figura1:

Figura 1. Schema de principiu a comunicării seriale între două dispozitive

Dispozitivul care transmite date se numeşte master iar cel care primeşte se numeşte
slave. De obicei masterul stabileşte formatul cuvântului şi frecvenţa ceasului iar datele
furnizate se vor obţine la pinul TX. Slave-ul va trebui configurat astfel încât să primească
cuvinte care au acelaş format cu cele generate de master şi să funcţioneze la aceeaşi frecvenţă.
Pinul prin care un dispozitiv primeşte date este pinul RX.
Viteza de transmisie a datelor se măsoară în BAUD , unitate care reprezintă numărul de biţi
transmişi într-o secundă. Această viteză trebuie să fie egală între dispozitivele care comunică
serial. La transmisia asincronă pot apărea diverse erori deoarece frecvenţele de tact pot fi
puţin diferite chiar dacă ele sunt setate aparent egal. Acest neajuns este înlăturat la transmisia
sincronă deoarece semnalul de tact generat de master este transmis slave-ului prin legătura
XCK.
Transmisia asincronă
Pentru ca transmisia să fie bidirecţională trebuie să se utilizeze două conexiuni, una
prin care se vor trimite datele şi una prin care aceste date vor fi primite. Cuvântul care este
trimis este format din două părţi, o parte care reprezintă datele iar altă parte care reprezintă
codul de verificare.
Tabelul 1.Biții de lucru a USART

Start Data Data Data Data Data Data Data Data Stop
0 1 2 3 4 5 6 7
Orice cuvânt începe cu un bit de start care trebuie să fie 0. Următorii biţi sunt biţii de
date care pot avea o lungime între 5 şi 8 biţi iar la sfârşit este un bit de stop care întodeauna
trebuie să fie 1.

Figura 2. Formatul cuvîntului în AVR


Primul bit St reprezintă bitul de start.Lungimea cuvântului de date poate fi cuprinsă
între 5 şi 9 biţi. Pentru o mai bună securitate în transmisie se poate seta la sfârşitul cuvântului
de date un bit de paritate care verifică paritatea biţilor de date. Sfârşitul cuvântului poate fi
reprezentat de unul sau doi biţi care trebuie să aibă valoarea 1. Transmiţătorul sau receptorul
sunt libere doar atunci când s-au transmis biţii de stop şi sunt în stare Idle, stare care este
reprezentată de 1 logic pe linile de conexiune.
Schimbul de date se face prin doi regiştri, unul în care se înscriu datele şi unul de
shiftare prin care se transmite cuvântul. În ATMega32 datele se scriu sau se citesc din
registrul UDR. De exemplu pentru transmiterea unui caracter char pe 8 biţi trebuie să se scrie
caracterul în UDR. USART-ul va trece automat conţinutul lui UDR în registrul serial apoi îl
va transmite pe linia de legătură celuilalt dispozitiv care va prelua datele tot în registrul serial
al cărui conţinut va fi transmis registrului UDR. Registrul serial,dacă dispozitivul este
configurat ca transmiţător, va pune pe lângă date şi bitul de start , bitul de paritate şi bitul/biţii
de final. Dacă dispozitivul este configurat ca receptor, registrul serial va verifica dacă
transmisia este corectă şi dacă da datele cuvântului vor fi copiate în UDR.
Regiştrii folosiţi în ATMega32 pentru comunicarea serială sunt reprezentați în mai jos:
-Registrul UDR care are rolul de a stoca datele necesare pentru transmisie sau
recepţie:

Figura 2.Transmisia(Tx) și recepția datelor(Rx)


Dacă se realizează transmisia, datele sunt stocate în TXB iar dacă se realizează
recepţia datele se găsesc în RXB.
-Registrul UCSRA:

Figura 3. Biții de lucru ai registrului UCSRA


Bitul 7 –RXC- indică starea registrului de recepţiei.Dacă încă se mai primesc date
valoarea lui este 1 iar dacă recepţia a fost efectuată complet valoarea lui este 0.
Bitul 6 –TXC- indică starea registrului de transmisie.Dacă încă se mai transmit date
valoarea lui este 1 iar dacă transmisia a fost efectuată complet valoarea lui este 0.
Bitul 5 – UDRE – indică dacă UDR poate fi citit sau scris.Dacă este 1 UDR poate fi
scris, dacă este 0 nu se pot efectua operaţii cu acest registru.
Bitul 4 – FE – Detectează dacă există erori la transmiterea cuvântului verificând
bitul/biţii de final.Dacă acest/aceşti biţi au o valoare diferită de 1 atunci bitul FE ia valoarea
1.Dacă totul este în regulă atunci valoarea lui FE va fi 0.
Bitul 3 –DOR - Detectează dacă există erori de suprascrierea USAR-tului.De exemplu
la recepţie poate apărea o astfel de eroare dacă UDR şi registrul serial este plin şi alt caracter
este pe cale de a fi primit.FE este 1 dacă s-a semnalat o astfel de eroare şi 0 dacă nu avem o
eroare de acest fel.
Bitul 2 – PE – are rolul de a detecta eroarea de paritate.Dacă s-a detectat o astfel de
eroare ia valoarea 1 iar dacă nu valoarea lui va fi 0.
Bitul 1 – U2X – Acest bit este 1 dacă dorim să dublăm viteza de transmisie în modul
asicron şi 0 dacă se foloseşte viteza normală.Acest bit trebuie să aibă întotdeauna valoarea 0
dacă este folosit modul sincron.
Bitul 0 – U2X- Se setează 1 dacă se foloseşte comunicarea multiprocesor şi 0 dacă se
foloseşte comunicarea uniprocesor.
-Registrul UCSRB:

Figura 4. Biții de lucru ai registrului UCSRB


-Bitul 7-RXCIE – 1 setează generarea unei întreruperi la terminarea recepţiei,0
întreruperea nu este folosită.
-Bitul 6-TXCIE – 1 setează generarea unei întreruperi la terminarea transmisiei,0
întreruperea nu este folosită.
-Bitul 5-UDRIE – 1 setează generarea unei întreruperi atunci când registrul UDRIE
poate fi folosit,0 întreruperea nu este folosită.
-Bitul 4- RXEN – 1 setează USART-ul ca receptor.
-Bitul 3- TXEN – 1 setează USART-ul ca Transmiţător.
-Bitul 2- UCSZ2 – se foloseşte împreună cu o parte din biţii registrului UCSRC .
-Bitul 1 – RXB8 – este al 9-lea bit din schimbul de date pe 9 biţi şi se foloseşte la
recepţie.
-Bitul 0 – TXB8 – este al 9-lea bit din schimbul de date pe 9 biţi şi se foloseşte la
transmisie.
-Registrul UCSRC:

Figura 5. Biții de lucru ai registrului UCSRC


-Bitul 7 –URSEL- se foloseşte pentru selecţia regiştrilor astfel:1 dacă se lucrează cu
registrul UCSRC şi 0 dacă se lucrează cu registrul UBBRH.
-Bitul 6 –UMSEL-Prin acest bit se setează modul de funcţionare al USART-ului:1
dacă funcţionează în modul sincron şi 0 dacă funcţionează în modul asincron.
-Bitul 5 şi 4 –UPM1 şi UPM0 – Se folosesc pentru selecţia parităţii:
UPM1 UPM0
00 - Nu se foloseşte bitul de paritate.
01 - Combinaţie rezervată.
10 - Se foloseşte bitul de paritate ca bit par.
11 - Se foloseşte bitul de paritate ca bit impar.
-Bitul 3 –USBS- se foloseşte pentru a seta numărul biţilor care reprezintă sfârşitul
cuvântului: 1- se setează doi biţi de stop,0-se setează un singur bit de stop.
-Biţii 2 şi 1– UCSZ1 şi UCSZ0- se folosesc împreună cu UCSZ2 din UCSRB pentru a
seta lungimea cunvântului de date:
UCSZ2 UCSZ1 UCSZ0 Lungimea Cuvântului
000 – 5 biţi;
001 – 6 biţi;
010 – 7 biţi;
011 – 8 biţi;
100 – Combinaţie rezervată;
101 – Combinaţie rezervată;
110 – Combinaţie rezervată;
111 – 9 biţi;
-Bitul 0 – UCPOL-Se foloseşte pentru modul sincron şi setează ce front al semnalului
de pe linia XCK va fi folosit în transmisie.În modul asincron acesta se setează 0.Valorile pe
care le poate lua sunt următoarele:0 – se foloseşte frontul crescător, 1 se foloseşte frontul
descrescător.
-Registrul UBRR – Acest registru se foloseşte pentru a seta viteza de transmisie a
datelor.

Figura 6. Biții de lucru ai registrului UBRR


-Bitul 15 – URSEL – trebuie să fie 0 atunci când se efectuează operaţii cu acest
registru.
-Biţii 12,13,12 sunt nişte biţi rezervaţi nefolosiţi în acest microcontroler.
-Biţii 11:0 sunt folosiţi pentru a seta viteza de transmisie a datelor.Totuşi setarea se
face doar cu biţii cei mai semnificativi,11:8.Viteza de transmisie a datelor se calculează după
formula 1:

(1)
Unde BAUD reprezintă viteza de transmisie măsurată în Baud,f_int reprezită frecvenţa
internă a procesorului iar UBBR este valoarea setată în registru.
Eroarea la transmisie se calculează după formula 2:

(2)

În tabelul 2 se poate observa ce influenţă are frecvenţa asupra erorii la transmisie:


Tabelul 2. Exemple de setări ale registrului UBRR pentru frecvențe de oscilator
utilizate frecvent

Mersul lucrării:

1) Pentru început s-a realizat schema flux de date a circuitului din figura 7, 8 și
schema bloc a programului sursă din figura 9, 10.

Figura 7. Schema flux de date a circuitului


stdio.h led.c led.h

main.c

usart.h usart.c util/delay.h

Figura 8. Schema interconectărilor în program

Figura 9.Schema bloc a funcției principale main


Figura 10.Schema bloc a funcției de scanare a tastaturii

Figura 11. Schema bloc a funcției de a) aprindere, b) stingere a LED-ului


Figura 12. Schema bloc a funcției de licărire a LED-ului

Figura 13. Schema bloc a funcției de a) inițializare a Usart-ului, b) transmitere, c)recepție a


datelor
2) S-a scris programul conform schemelor din figurile 8 și 9 în AVR Studio.
Au fost create fișierele header în realizarea programului principal.
 Fișierul led.h
#include <avr/io.h> //Includem fisierul de adrese periferice pentru Atmega32
#ifndef LED_H //daca constanta LED_H nu este definita
#define LED_H // atunci se defineste
#ifndef LED_PORT PORTA
#define LED_PORT PORTA // LED_PORT are valoarea portului A
#endif LED_PORT PORTA
#ifndef LED_DDR DDRA
#define LED_DDR DDRA
#endif LED_DDR DDRA
#ifndef LED_PIN PA1 //LED_PIN are valoarea pinului 1 din portul A
#define LED_PIN PA1
#endif LED_PIN PA1
void LED_ON(void); //Prototipul functiei LED_ON
void LED_OFF(void); //Prototipul functiei LED_OFF
void licarire_LED(void); //Prototipul functiei licarire_LED
#endif /*LED_H*/ // dacă LED_H a fost găsită atunci se termină if-ul
 Fișierul usart.h
#ifndef USART_H //daca constanta USART_H nu este definita
#define USART_H // atunci se defineste

void USART_Init(unsigned int baud); //Prototipul functiei USART_Init


void USART_Transmit(unsigned char data);//Prototipul functiei
USART_Transmit
unsigned char USART_Receive(void); //Prototipul functiei USART_Receive

#endif /*USART_H*/ // dacă USART_H a fost găsita atunci se termina if-ul

Au fost create fișierele sursă ale programului principal.


 Fișierul led.c
#include "led.h" //includem fișierul header pentru lucru cu led-ul
#include <util/delay.h> //includem fișierul standart pentru lucrul cu functia
delay_ms

void LED_ON(void) //functia pentru aprinderea led-ului


{
LED_PORT |=(1<<LED_PIN); // aprinderea led-ului
}

void LED_OFF(void) // functia pentru stingerea led-ului

LED_PORT &= ~(1<<LED_PIN); // stingerea led-ului


}
void licarire_LED(void) //functia de licarire a ledului

char i = 0; //definim un caracter de tip char

for(i=0; i<30; i++) //pentru i<30 atunci


{
PORTA |= (1<<PA1); //aprindem ledul

_delay_ms(100);

PORTA &= ~(1<<PA1); //stingem ledul

_delay_ms(100);

}
}

 Fișierul main.c
#include <avr/io.h>//Includem fisierul de adrese periferice pentru Atmega32
#include "led.h" //includem fișierul header pentru lucru cu led-ul
#include "usart.h"//includem fișierul header pentru lucru cu Usart-ul
#include <stdio.h>//includem libraria pentru functiile de intrare/iesire

void Port_Init(void); //Prototipul functiei Port_Init


void Scanare_Tastatura(void); //Prototipul functiei Scanare_Tastatura
void licarire_LED(); //Prototipul functiei licarire_LED

void Port_Init(void) //functia pentru initializarea porturilor

{
//Configurarea porturilor A,B,C pe intrare
PORTA = 0x00;
DDRA = 0xFF;

PORTB = 0x00;
DDRB = 0xFF;

PORTC = 0x00;
DDRC = 0xFF;

PORTD = ~0x82; //Pinul 7 este “0”logic, iar restul pinilor “1”

DDRD = 0x82; //Configuram pinii 7 si 1 pe iesire, restul pe intrare


}
int main(void) //functia principala main
{
Port_Init(); //Prototipul functiei Port_Init
USART_Init(12); //Prototipul functiei USART_Init
printf("Pentru a stinge LED-ul tastati 0, iar pentru a aprinde LED-ul tastati 1");

while (1) //ciclu infinit in care se realizeaza aprinderea si stingerea


led-ului
Scanare_Tastatura(); //Prototipul functiei Scanare_Tastatura
}
void Scanare_Tastatura() //functia Scanare_Tastatura realizeaza schimbarea
starii led-ului si afiseaza la terminal in cazul cind se apasa orice tasta.
{
char ch; //se declara ch de tip char
scanf("%c",&ch); //realizeaza citirea caracterului de la tastatura
if (ch=='1') //daca ch=1
{
LED_ON(); //atunci se cheama functia de aprindere a led-ului
printf("Led_aprins\r");//afiseaza la terminal mesajul Led_aprins dupa
apasarea tastei”1” si cind led-ul a fost aprins
}
else //daca nu
{
if(ch=='0'){ atunci verifica daca ch=”0”
LED_OFF(); //atunci se cheama functia de stingere a led-ului
printf("Led_stins\r");//afiseaza la terminal mesajul Led_stins dupa
apasarea tastei”0” si cind led-ul a fost stins
}
else{ //daca nu
if(ch=='2'){//atunci verifica dac ch=”2”
licarire_LED(); //daca da cheama functia de licarire a led-ului
printf("Led_intermitent\r");//afiseaza la terminal mesajul
Led_intermitent dupa apasarea tastei”2”
}
else //daca nu

{
printf("Tasta_gresita \r");//atunci la apasarea oricare alte taste va aparea
mesajul:”Tasta_gresita”
}
}
}
}

 Fișierul usart.c
#include <avr/io.h>//Includem fisierul de adrese periferice pentru Atmega32
#include <stdio.h>//includem libraria pentru functiile de intrare/iesire
#include "usart.h"//includem fișierul header pentru lucru cu Usart-ul
static FILE mystdout = FDEV_SETUP_STREAM(USART_Transmit,USART_Receive,
_FDEV_SETUP_RW);//se defineste fluxul de lucru cu interfata seriala

void USART_Init(unsigned int baud) //functia pentru initializarea Usart-ului


{
stdout=&mystdout;//output printf
stdin=&mystdout;//input scanf

UBRRH=(unsigned char)(baud>>8);
UBRRL=(unsigned char) baud;
UCSRA = (1<<U2X); //viteza de transmisie da datelor este 9600 biti/s
UCSRB=(1<<RXEN)| (1<<TXEN);//se activeaza receptia si transmisia
UCSRC=(1<<URSEL)| (1<<USBS)| (3<<UCSZ0);//lucrul cu
UBRRH,setarea a 2 biti de stop si lungimea cuvintului de date este de 8 biti
}

void USART_Transmit(unsigned char data)//functia de transmitere a datelor


{
while(!(UCSRA& (1<<UDRE))) //se asteapta sa se elibereze buffer-ul de
transmitere
;
UDR=data; //se pun datele in buffer
}

unsigned char USART_Receive(void) // functia de receptie a datelor


{
while(!(UCSRA& (1<<RXC))) //se asteapta pina cind datele vor fi primite
;
return UDR;//datele primite de la buffer se iau si se returneaza
}

3) S-a construit schema electrică a circuitului în ISIS Proteus.


Figura 14.Schema electrică a circuitului
4) A fost efectuată simularea în Proteus,astfel a fost verificată corectitudinea programului
cît și funcționalitatea sa,observîndu-se executarea comenzilor de microcontroler.

Figura 15. Simularea schemei electrice,afișarea primului mesaj nici o tastă apăsată,
LED stins
Figura 16.Simularea schemei electrice, tasta 1 apăsată, led aprins

Figura 17. Simularea schemei electrice, tasta 0 apăsată, led stins


Figura 18. Simularea schemei electrice, tasta 2 apăsată, led este stins după licărire

Figura 19. Simularea schemei electrice, orice altă tastă apăsată, led este stins
Concluzie:
In urma efectuarii lucrarii de laborator nr #1 am reușit să înțeleg că interfața cu
utilizatorul este un subsistem specializat ce permite comunicarea între mai multe dispozitive.
Astfel am aflat că .la configurarea a două dispozitive care vor comunica serial asicron trebuie
să se ia în considerație ca viteza de transfer să fie egală la transmisie şi recepţie şi să fie
aceeaşi lungime a cuvântului de date.De asemenea trebuie totuşi să se stabilească dacă se vor
folosi unul sau doi biţi de stop.
Am înțeles că principala sursă de eroare poate apărea atunci când configurarea între
dispozitive nu este făcută corect, aceasta fiind o problemă de incompatibilitate în comunicare.
La transmiterea sau recepţia mai multor cuvinte consecutive trebuie verificat dacă
USART-ul a realizat operaţia completă de trimitere sau citire, altfel poate apărea o altă eroare
de transmisie generată de data asta de partea soft.
Am lucrat cu librăria pentru funcțiile de intrare/ieșire, putînd astfel să implimentez
această librărie pentru calculator, și anume, să transmit și să citesc datele la terminal cu
ajutorul funcțiilor oferite de această librărie: ”printf” și ”scanf”.

S-ar putea să vă placă și