Numele UART vine de la Universal Asynchronous Receiver-Transmitter și reprezintă un protocol de comunicare ce suportă o gamă largă de configurații, dar și de platforme hardware.
Există mai multe tipuri de protocoale UART. Dintre acestea, cele mai importante sunt:
/*Fisiere Header Necessare*/
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
/*vom folosi UART abstractizat ca fisier ... si prin urmare are un "File Descriptor"*/
int uart0_filestream = -1;
/*Din Manualul de Linux:
Moduri de acces:
- O_RDONLY - Deschidere doar pentru citire.
- O_RDWR - Deschidere pentru citire si scriere.
- O_WRONLY - Deschidere doar pentru scriere.
Biti Suplimentari:
- O_NDELAY / O_NONBLOCK - în general ... la apeluri de sistem se introduce conceptul de Blocking/Non-Blocking ceea ce ne lasă să specificăm dacă operațiile dorite să se încerce a fi executate imediat sau dacă permitem sistemului de operare să ne blocheze procesul până când operația dorită poate fi executată conform apelului de funție (de obicei operații de scriere și de citire)
- O_NOCTTY - impune ca în momentul în care calea spre "Fișier" este un dispozitiv de tip terminal (în cazul Linux UART joacă rol de consolă terminal - poți să iți imaginezi un fel de SSH prin cablu direct) .. să nu preia controlul terminalului din care lansezi programul
*/
/*Deschiderea "Fisierului" de UART*/
uart0_filestream = open("/dev/ttyAMA0", O_RDWR | O_NOCTTY | O_NDELAY); //Open in non blocking read/write mode
if (uart0_filestream == -1)
{
printf("Error - Unable to open UART. Ensure it is not in use by another application\n");
}
/* Comfigurare mai avansată de UART se poate face mai avansată conform cu http://pubs.opengroup.org/onlinepubs/007908799/xsh/termios.h.html
- Baud rate:- B1200, B2400, B4800, B9600, B19200, B38400, B57600, B115200, B230400, B460800, B500000, B576000, B921600, B1000000, B1152000, B1500000, B2000000, B2500000, B3000000, B3500000, B4000000
- CSIZE:- CS5, CS6, CS7, CS8
- CLOCAL - In trecut UART se folosea la modemuri .. si avea nevoie de fire de status (clear to send, data ready. etc) .. acest flag configureaza perifericul de urat să folosească sau nu acele fire
- CREAD - Activează receptorul
- IGNPAR - Specifică dacă se ignoră caracterele cu erori de paritate.
- ICRNL - Configurează daca \r să fie sau nu înlocuit cu \n.
- PARENB - Activează bitul de paritate
- PARODD - Specifică dacă bitul de paritate e 1 în caz par sau inpar.
*/
struct termios options;
tcgetattr(uart0_filestream, &options);
options.c_cflag = B9600 | CS8 | CLOCAL | CREAD; //<Set baud rate
options.c_iflag = IGNPAR;
options.c_oflag = 0;
options.c_lflag = 0;
tcflush(uart0_filestream, TCIFLUSH);
tcsetattr(uart0_filestream, TCSANOW, &options);
/*Transmitere de bytes*/
unsigned char tx_buffer[20];
unsigned char *p_tx_buffer;
p_tx_buffer = &tx_buffer[0];
*p_tx_buffer++ = 'H';
*p_tx_buffer++ = 'e';
*p_tx_buffer++ = 'l';
*p_tx_buffer++ = 'l';
*p_tx_buffer++ = 'o';
if (uart0_filestream != -1)
{
int count = write(uart0_filestream, &tx_buffer[0], (p_tx_buffer - &tx_buffer[0]));
if (count < 0)
{
printf("UART TX error\n");
}
}
/*Receptie de bytes*/
if (uart0_filestream != -1)
{
/*încercarea de a citi 255 de bytes*/
unsigned char rx_buffer[256];
int rx_length = read(uart0_filestream, (void*)rx_buffer, 255);
if (rx_length < 0)
{
/*eroare*/
}
else if (rx_length == 0)
{
/*nu există dată*/
}
else
{
rx_buffer[rx_length] = '\0';
printf("%i bytes read : %s\n", rx_length, rx_buffer);
}
}
/*La fel ca și în cazul fișierelor .. ar fi de bun simț să închizi conexiunea*/-
close(uart0_filestream);