COMUNICAÇÃO SERIAL
Revisão: Prof. Dr. André Riyuiti Hirakawa e Prof. Dr. Jorge Kinoshita
1. OBJETIVO
Esta experiência visa a familiarização com o recurso de comunicação serial disponível no 80C51,
envolvendo as configurações permitidas e respectivas aplicações, bem como o fornecimento de uma taxa de
comunicação configurável.
2. SUBSÍDIOS
A interligação de dois sistemas digitais pode ser realizada basicamente de duas formas, paralela ou
serial. No caso da interligação paralela, como o próprio nome sugere, os dois sistemas são conectados
fisicamente através de fios conectados em paralelo, um para cada bit de dado. Como exemplos pode-se citar
a conexão de um computador com uma impressora, onde a proximidade física dos equipamentos e as
necessidades de velocidade alta face à quantidade de dados transferida justifica tal configuração.
Em casos de interligação de sistemas geograficamente distantes, a conexão por fios em paralelos
apresentaria custos proibitivos (tanto envolvendo os próprios cabos, como os circuitos requeridos para
viabilizar tecnicamente tal ligação face às distâncias envolvidas), tornando-a inviável. Nestas situações a
conexão serial é a recomendada. É o caso das conexões via modem, onde as informações são serialmente
enviadas ou recebidas (bit a bit), através de um mecanismo de comunicação adequado, envolvendo tanto
programas como circuitos e meios de comunicação (fios, rádio, etc).
1 2 3
Este agrupamento se repete para cada caracter a ser transmitido/recebido, ou seja, o estado de
espera (nível 1 – stop bit) é interrompido com o envio/chegada de um start bit que indica um novo caracter
será transmitido ou recebido. As taxas de comunicação devem ser previamente definidas entre os elementos
que se comunicam.
O 80C51 permite que equipamentos sejam interligados no modo full-duplex. Os dados recebidos
ou transmitidos utilizam-se de um registrador especial chamado de SBUF (serial buffer). Uma escrita no
SBUF implicará numa transmissão automática do dado. Um dado que chegue no pino de recepção implicará
na recepção automática, desde que o canal serial esteja habilitado. Internamente ele é implementado com
dois registradores em separado (um para transmissão e outro para recepção), permitindo a operação no
modo full-duplex.
A recepção inicia-se quando o bit REN do registro SCON estiver em 1, nos modos 1, 2 ou 3 de
comunicação serial, e o sistema detecte um start bit (nível 0).
O canal serial tem a sua configuração baseada no registrador de controle denominado SCON, que
apresenta a seguinte estrutura:
Bit 7 6 5 4 3 2 1 Bit 0
Onde a combinação de SM0 e SM1 estabelece o modo de comunicação serial, conforme a tabela a
seguir:
MODO 0: operação do canal serial em modo síncrono, onde o pino RXD é utilizado para a transmissão e
recepção de dados. O clock de sincronismo é gerado no pino no TXD;
MODO 1: operação do canal serial em modo assíncrono, onde o pino RXD é utilizado para a recepção de
dados, e o pino TXD para a transmissão. Cada caracter transmitido ou recebido envolve tipicamente 10 bits:
MODO 2: operação do canal serial assíncrono – RXD é o pino de recepção de dados e o TXD é o pino de
transmissão. Cada pacote de dados implica em 11 bits:
Bit 7 6 5 4 3 2 1 Bit 0
Este registrador não é endereçável em bits. O bit IDL ativa o Modo Idle, e o bit PD, o Modo Power
Down. Os bits GF1 e GF2 são flags de uso geral.
Na comunicação serial, o bit SMOD define as taxas de transmissão da seguinte maneira, de acordo
com o modo de operação escolhido:
• no Modo 0: a taxa é fixada em 1/12 da freqüência do clock do 80C51.
• no Modo 2:
• se SMOD = 0, a taxa de comunicação é 1/64 da freqüência do clock;
• se SMOD = 1, a taxa de comunicação é 1/32 da freqüência do clock.
Nos Modos 1 e 3, a taxa de comunicação pode ser fornecida pelo Timer/Counter 1, onde cada
ordem de transmissão é gerada pela ocorrência de overflow de contador. O mais comum é o uso do modo de
recarga automática para o timer configurado para de 8 bits.
SMOD
Taxa = ((2 )/32) * ( freq. clock) / (12*(256-TH1) )
Exemplo: para uma freqüência de operação do 80C51 igual a 11.0592 Mhz, e o valor de recarga do
contador TH1 igual a 0E8H. Caso:
O Anexo I apresenta os valores de TH1 para vários modos de operação e taxas de comunicação.
3. PARTE EXPERIMENTAL
Para diversos itens descritos a seguir será necessário o uso de um terminal de vídeo ou um programa
emulador de terminar em um microcomputador (por exemplo, o Hyperterminal do Windows). Haverá a
necessidade de reconfigurá-lo para a taxa e padrão de comunicação utilizado.
3.1 Pesquisa
Efetue uma pesquisa em livros, manuais e sites especializados, e acrescente um anexo no relatório
contendo:
• Um resumo de cada modo de operação do canal serial do 80C51.
• Uma explicação sobre como o modo 0 do canal serial poderia ser utilizado para expandir a
capacidade de linhas de saída do 80C51. Esboce um diagrama exemplificando.
• Calcular o erro para as taxas de comunicação apresentadas na Tabela 1 do Anexo 1, caso o clock do
80C51 fosse alterado para 12 MHz.
• Erros de comunicação, como frame e paridade no 80C51: eles são tratados automaticamente?
o Caso afirmativo, explique como isso é feito.
o Caso negativo, indique como a paridade ela poderia ser gerada na transmissão e tratada na
recepção. Esboce os programas necessários.
a) Testar o programa prog1.c apresentado no Anexo II, fazendo as alterações e complementações que
eventualmente sejam necessárias.
b) Dado o programa prog2.c do Anexo II, inclua uma rotina de tratamento de interrupção que, ao receber
um caractere pela porta serial, retorne o mesmo caractere para o Hyperterminal . Faça as alterações e
complementações que eventualmente sejam necessárias.
c) Adaptar o programa prog2.c para que possa receber um conjunto de caracteres até que um CR
(carriage return) seja encontrado. O usuário deve digitar cada um dos caracteres (no mínimo 16
caracteres) no terminal e finalizar com CR. Após isso, o conjunto de caracteres deve ser enviado da
Placa Experimental para o terminal.
a) Alternar o prog1.c para que a transmissão seja realizada em 4800 baud. Re-configurar o Hyperterminal
e verificar o resultado. Sugestão: colocar no início do programa um atraso de vários segundos, para
dar tempo de se reconfigurar o Hyperterminal para a nova taxa de comunicação (lembrar de
desconectá-lo, alterar a velocidade e reconectá-lo). No relatório, comente o seguinte caso:
“Um aluno realizou esse item, sem colocar o atraso sugerido. Após executar o programa, reconfigurou o
Hyperterminal e esperava visualizar na tela uma seqüência de letras “A” maiúsculas. Contudo
visualizou uma seqüência de letras “P” maiúsculas. Isso é possível? Explique.
b) Alternar o prog2.c para que a recepção e a transmissão sejam realizadas em 4800 baud. Reconfigurar o
Hyperterminal e verificar o resultado.
a) Projetar e codificar um programa que envia um bloco de caracteres (mínimo de 256 bytes) colocados em
posições de memória consecutivas da memória RAM externa da Placa Experimental. Os caracteres
recebidos no Hyperterminal devem ser salvos em um arquivo utilizando o recurso de recepção e
armazenamento de arquivo texto. Sugestão: colocar no início do programa um atraso de vários
segundos, para dar tempo de se ativar a captura de arquivo texto no Hyperterminal.
b) Projetar e codificar um programa que recebe um bloco de caracteres (os mesmos do item a)) enviados
pelo Hyperterminal (utilizando o recurso de envio de arquivo texto), e os coloca em posição distinta da
item a), de forma consecutiva da memória RAM externa da Placa Experimental. Após a recepção, deve
ser feita uma comparação dos blocos para verificar se algum erro foi introduzido na seqüência.
c) Quando acontece “overrun”, a Placa Experimental não consegue processar todos os caracteres enviados
pelo Hyperterminal , perdendo caracteres. Possíveis soluções para esse problema:
• uso de uma fila circular de dados;
• uso do protocolo XON/XOFF para a comunicação serial;
• uso de uma combinação das duas alternativas anteriores.
Detalhar essas alternativas no relatório e propor formas de provocar o “overrun” na experiência para
poder tratá-lo.
4. PLANEJAMENTO
a) Para a elaboração do planejamento deve-se, após a leitura desta apostila, efetuar o estudo dos itens da
literatura referenciados.
5. BIBLIOGRAFIA
[3] STEWART, J.W. The 8051 Microcontroller. Prentice Hall, 1993. ISBN: 0-13-584046-5.
[3] TOCCI, R.J. Digital Systems – Principles and Applications Prentice Hall, 7ª ed., 1998.
[4] HOROWITZ, P.; HILL, W. The art of Electronics. Cambridge University Press, 2ª ed., 1998.
[5] PHILIPS. 80C51-Based 8-bit Microcontrollers. Philips Semiconductors Data Handbook, 1995.
[6] PHILIPS. Application Notes and Development Tools for 80C51 – Data Handbook. Philips Electronics
North America Corporation, USA, 1997.
[8] Apostilas de PCS 305, Departamento PCS, 1999: Transmissão e comunicação serial.
[10] MATSUNAGA, A.M.; TSUGAWA, M.O. Sistema de Pesagem Dinâmica. Projeto de Formatura
(disciplina PCS-588). Escola Politécnica da USP, 1997.
As informações abaixo relacionadas auxiliam na programação dos timers e canal serial do 80C51. Maiores
detalhes podem ser obtidos em www.intel.com.
I - Tabela 1 – Valores de TH1 para algumas taxas de transmissão
Baud Rate Freq. (Mhz) SMOD TH1
56.800 11,0592 1 FF
19.200 11,0592 1 FD
9.600 11,0592 1 FA
4.800 11,0592 1 F4
2.400 11,0592 1 E8
1.200 11,0592 1 D0
600 11,0592 1 A0
300 11,0592 1 40
9.600 11,0592 0 FD
4.800 11,0592 0 FA
2.400 11,0592 0 F4
1.200 11,0592 0 E8
600 11,0592 0 D0
300 11,0592 0 A0
Observação: para que o compilador SDCC gere o código adequadamente, caso o modelo large seja
utilizado, deve-se definir inicialmente a área de xram e depois a de code: por exemplo, xram de 0x8000 a
0x9FFF e code de 0xA000 a 0xFFFF. O endereço inicial do programa estará em 0xA000 e o vetor de
interrupções deslocado de 0xA000. Isso deve ser feito para evitar a superposição da área da RAM externa
com a área de código associado ao vetor de interrupções (caso seja feita a colocação através de programa do
LJMP), que na placa experimental encontra-se em 0xFFFx.
ANEXO II
Programa Exemplo 1 – prog1.c - Comunicação serial no 8051 usando o modo 1, com timer 1, sem interrupção (*)
Este programa transmite o código ASCII da letra “A” repetidamente, a uma taxa de 9.600 baud:
/* Timer 1 é utilizado para gerar a taxa de comunicação, sem uso de interrupção */
/* Canal serial: mode = 1 (8-bit UART Serial Port) sem uso de interrupção */
void init_serial(void)
{
PCON = 0x00; /* SMOD = 0, no modo 1, divide clock por 32 */
SCON = 0x42; /* Seleciona modo 1: UART, 8 bits, clock do Timer 1 */
TMOD = 0X20 ; /* Configura timer 1: modo 2, 8 bits, auto reload */
TH1 = 0XFD ; /* divisão para 9.600 baud */
TR1 = 1; /* TCON.6 - dispara timer */
TI = 1; /* Inicia TI – transmissor pronto */
}
void main(void)
{
init_serial();
while(1)
{
while (!TI); /* Espera transmissor estar pronto para transmitir */
TI = 0; /* Bloqueia transmissor */
SBUF = 0x41; /* Envia caractere */
} /* Após a transmissão, o canal serial fará TI = 1 */
}
Programa Exemplo 2 – prog2.c - Comunicação serial no 8051 usando o modo 1, com timer 1 e recepção com interrupção
(*) Este programa recebe dados a 9600 bauds, usando interrupção.
/* Timer 1 é utilizado para gerar a taxa de comunicação, sem uso de interrupção */
/* Canal serial: mode = 1 (8-bit UART Serial Port) com uso de interrupção */
void init_serial(void)
{ /* Timer 1 é utilizado para gerar a taxa de comunicação */
PCON = 0x00; /* SMOD=0, no modo 1, divide o clock por 32 */
SCON = 0X52; /* Seleciona modo 1: UART, 8 bits, clock do Timer 1 */
/* SCON.4 - REN=1(habilita a recepção) */
/* SCON.1 - TI=1 (transmissor pronto) */
/* SCON.0 - RI=0 (receptor vazio)*/
TMOD = 0X20; /* Configura timer 1: modo 2, 8 bits, auto reload */
TH1 = 0XFD /* divisão para 9.600 baud */
TR1 = 1; /* TCON.6 - dispara timer 1 */
IE = 0x90; /* IE.4– habilita interrupção do canal serial e IE.7- global */
}
void int_serial (void) interrupt 4 using 1
{
if (RI ==1)
{ /* Se for interrupção de recepção: */
RI = 0; /* limpa pedido de interrupção de recepção */
AUX = SBUF; /* Retira caractere recebido do bufer */
while (!TI); /* Espera transmissor estar pronto para transmitir */
TI = 0; /* Bloqueia transmissor */
SBUF = AUX; /* Envia caractere recebido (eco) */
}
}
void main(void)
{
init_serial( );
while(1);
}
(*) Programas de referência. Não estão representados: includes, declarações de variáveis, etc.
Canal serial: interrupção 4, endereço 0x0023, desviado para 0xFFFC.