====== USART ====== Um USART é uma interface serial síncrona universal; um UART, é uma versão simplificada - interface serial assíncrono universal. A diferença é que um USART usa também uma linha de sinal do relógio para sincronizar os dados, mas um UART só usa linhas de dados. O USART do AVR permite o uso de comunicação full duplex, com palavras de dados de 5 a 9 bits (8 bits de palavras = byte), 1 ou 2 bits de paragem, três modos de paridade e uma grande variedade de taxas de transmissão. Os microcontroladores AVR têm normalmente até 2 interfaces USART, embora alguns possam não tê-los. A transmissão de dados é realizada usando uma palavra de cada vez - o AVR converte a palavra que recebe do utilizador para bits ao nível de hardware e transmite-a de forma independente e vice-versa. O utilizador controla o USART lendo e escrevendo a configuração, o status e registos de dados. Cada opção de configuração tem registos correspondentes, que são muito fáceis de configurar usando a datasheet. A taxa de transmissão, porém, é um pouco mais difícil de definir. O sinal de relógio para transmissão de dados é gerada a partir próprio relógio do controlador, e o utilizador pode especificar um número de 1 a 4096, pelo qual ciclo de relógio do controlador é dividido. O resultado é adicionalmente dividido por 2, 8 ou 16, dependendo do modo. O problema é que nem todas as frequências de relógio podem ser divididas de modo que o resultado seja uma velocidade de transmissão padrão. Em algumas frequências, a taxa de transmissão pode ser diferente do padrão até 10%. A datasheet de um AVR contêm tabelas com freqüências de relógio típicas, taxas de transmissão, o multiplicador necessário para chegar a essa taxa de transmissão e o erro de cálculo possível. Uma vez que a transmissão de dados ocorre de forma independente do processador e de forma muito mais lenta, é necessário confirmar que a interface está pronta para a próxima palavra antes de a transmitir. Isso pode ser feito tendo em conta o ready bit do buffer de transmissão, que significa que o buffer está pronto para aceitar uma nova palavra ou não. O controlador começa com o ready bit habilitado. Logo que uma palavra é transmitida e o buffer está vazio, o ready bit é estabelecido. A chegada de uma palavra é sinalizada também por um bit de status especial. Além disso, há bits de status para sinalizar erros de enquadramento, erros de paridade e para receber overflows do buffer. O overflow do buffer pode ocorrer quando a última palavra ainda está para ser lida a partir do buffer, enquanto uma nova chega - é por isso que é sempre importante ler as palavras de entrada para o programa tão rapidamente quanto possível, por exemplo, utilizando uma interrupção. Há três razões possíveis de interrupção: buffer de transmissão pronto, transmissão bem sucedida e recepção bem sucedida. Os buffers de transmissão e recepção são registos fisicamente separados, mas partilham o mesmo endereço de memória e nome. Quando escrevemos para o registo comum, os dados são armazenados na memória intermédia de transmissão, e quando lemos a partir dele, os dados são lidos a partir da memória intermédia de recepção. Ao usar palavras 9 bits, o nono bit é transmitido e lido usando um dos registos de configuração. Task: Configure an 8 MHz ATmega128's USART0 interface to transmit 8-bit words asynchronously using 9600 bps baud rate, 1 stop bit and no parity bits. Send the symbol "X". #include 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; }