USART

USART est une interface en série de synchronisation universelle, et UART sa version simplifiée - est une interface en série asynchrone. La différence est, USART utilise la ligne du signal de l'horloge pour synchroniser les données alors que UART utilise les lignes de données. L'USART de l'AVR permet d'utiliser l'ensemble de la communication en duplex, des mots de 5- à 9-bits (un mot de 8-bits = byte), 1 ou 2 bits de stop, trois modes paritaires et une grande variété de baud rates. Les micro-contrôleurs AVR typiques ont 2 interfaces USART, bien que certain n'ait pas d'USART. La transmission de données est réalisée un mot par cycle - le AVR convertit le mot qu'il reçoit de l'utilisateur en bits et le transmet indépendamment et vice et versa. L'utilisateur contrôle l'USART en lisant et en écrivant une configuration, le statut et les données registres.

Chaque option de configuration a des registres correspondants, qui sont relativement faciles à configurer en utilisant la fiche technique. La vitesse de transmission, cependant est un peu plus difficile à configurer. Le signal d'horloge pour la transmission de données est généré à partir de la propre horloge du contrôleur et l'utilisateur peut spécifier un nombre de 1 à 4096, par lequel le cycle d'horloge du contrôleur est divisé. Le résultat est de plus divisé par 2, 8 ou 16, selon le mode. Le problème est que les fréquences d'horloge ne peuvent pas toutes être divisées pour que le résultat soit une vitesse de transmission standard. Avec quelques fréquences, la vitesse de transmission peut différer de du standard avec une hausse de 10 %. Les fiches techniques de l'AVR contiennent des tables avec des fréquences d'horloge typiques, des vitesses de transmission, le multiplicateur nécessaire pour atteindre cette vitesse de transmission et l'erreur de calcul possible.

Puisque la transmission de données a lieu indépendamment du processeur et beaucoup plus lentement, il est nécessaire de confirmer que l'interface est prête pour le mot suivant avant la transmission. Cela peut être fait en surveillant le bit prêt transmit par le buffer, qui a de l'importance si le buffer est prêt à accepter un nouveau mot ou non. Le contrôleur commence par le bit prêt valable. Aussitôt qu'un mot est transmis et que le buffer est vide, le bit prêt est modifié.

L'arrivée d'un mot est signifiée aussi par un bit de statut spécial. En plus de cela, il y a des bits de statut pour signifier des erreurs de cadrage, des erreurs paritaires et des dépassements de capacité du buffer. Il arrive que le buffer soit en dépassement de capacité, quand le dernier mot doit encore être lu à partir du buffer alors qu'un nouveau arrive - c'est pourquoi il est toujours important de lire les mots entrants dans le programme dès que possible, par exemple en utilisant un interruption. Il y a trois raisons d'interruptions possibles: transmettre que le buffer est prêt, transmission réussie et réception réussie.

Les buffers de transmission et de réception sont des registres séparés, mais ils transmettent les mêmes adresses de mémoires et les mêmes noms. En écrivant dans un registre de partage, la donnée est stockée dans un buffer de transmission pour la lire ensuite à partir du buffer de réception. En utilisant un mot de 9-bits, le neuvième bit est transmit et lu en utilisant l'un des registres de configuration.

 

Exemple

Tâche: Configurer l'interface de l'USART0 de l'ATmega128 de 8 bits pour transmettre un mot de 8-bits asynchrone à une vitesse de transmission de 9600 bps, 1 bit d'arrêt et pas de bit de parité. Envoi le symbole “X”.

#include <avr/io.h>
 
int main()
{
	// Set baud rate to 9600 bps. Formula:
	//   multiplier = clock frequency / 16 / baud rate - 1
	//   UBRR = 8000000 / 16 / 9600 - 1 = ~51
	UBRR0H = 0;
	UBRR0L = 51;
 
	// Allow transmitting
	UCSR0B = (1 << TXEN0);
 
	// Configure asynchronous mode, set the word size to 8 bits
	// 1 stop bit, no parity bits.
	UCSR0C = (1 << UCSZ01) | (1 << UCSZ00);
 
	// Wait for the data buffer to empty (previous word to transmit)
	// In this example there is no need to wait, as the first symbol is yet
        // to be sent, but it should be done when transmitting more symbols.
	while (!(UCSR0A & (1 << UDRE))) continue;
 
	// Write the symbol to the buffer for transmitting
	UDR0 = 'X';
 
	// Endless loop
	while (1) continue;
}