CONFIGURANDO CORRETAMENTE OS REGISTRADORES DOS
MICROCONTROLADORES AVR - parte 5 USO DOS REGISTROS UCSRA, UCSRB, UCSRC, UDR, UBRRL E UBRRH NA COMUNICAÇÃO ASSÍNCRONA COMUNICAÇÃO RS-232 O padrão RS-232 foi e ainda é um dos mais difundidos no mundo da automação e controle. Hoje em dia muitos equipamentos fazem uso do mesmo. O tipo de transmissão é serial, ou seja, transmitimos os bytes através de uma única via bit a bit e não byte a byte como em uma porta paralela, por exemplo. Este método permite que seja utilizado um único fio para a transmissão/recepão ou dois fios, uma para transmissão e outro para recepção, dependendo do caso. E devido aos níveis de tensão estabelecidos na norma a distância de transmissão (tamanho do cabo) pode chegar a 45 metros. Existem notícias de técnicos que conseguiram comunicação com cabos com 80 metros de comprimento, porém cada caso é um caso e não posso afirmar que isso poderia funcionar em qualquer situação e ambiente, sem um estudo prévio. Aconselho sempre usar a distância segura de no máqimo 25 metros. Para trabalhar com a comunicação RS-232, é preciso conhecer um pouco sobre o que a norma determina com relação as características “mecânicas” (formato dos conectores e distribuição dos pinos), “elétricas” (níveis de tensão presentes) e lógicas (como os dados são transmitidos e recebidos) da mesma.
Na figura abaixo você pode ver como são os conectores para a RS-232 na maioria dos PC’s e na tabela a seguir a distribuição dos pinos e suas funções. Tabela – Distribuição dos pinos nos conectores
Obs.: Existem muitas formas de conexão entre equipamentos DTE e DCE, e a norma EIA RS-232C determina como as mesmas devem ser feitas. Não abordarei este tema neste artigo, restringindo-me a comunicação RS-232 entre um PC (DTE) e um microcontrolador (DCE) sem qualquer controle de fluxo (hardware ou software).
Os sinais elétricos na porta serial (RS-232) possuem níveis de tensão entre +15VDC e -15VDC. Na figura abaixo, temos a representação de um sinal RS-232 na transmissão de um byte. Na RS-232 o “1” lógico tem nível de tensão entre -15VDC à -3VDC e o “0” lógico tem nível entre +3VDC à +15VDC.
Toda comunicação assíncrona depende de alguns fatores, tais como: velocidade, número de bits, paridade e stop bits. A velocidade de comunicação é medida em bps (bits por segundo). Ela também é fundamental para o sucesso na comunicação entre equipamentos. Ambos os equipamentos (transmissor e receptor) devem ser configurados para operar na mesma velocidade, sempre. Esta velocidade pode ser configurada de 300 bps a 115000 bps nos dias atuais, dependendo exclusivamente do equipamento. O número de bits define quantos bits compõe o byte a ser enviado. Nos dias de hoje, para a maioria dos equipamentos ele tem oito bits. Porém é possível a comunicação de 5 à 8 bits. A paridade é o modo mais antigo e simples de se verificar um erro durante a transmissão. Ela considera o número de bits em estado lógico igual a “1”. Assim a unidade transmissora “conta” o número de bits do byte transmitido em estado lógico “1” e envia um bit informando isso. Se o número de bits for par, o bit de paridade assume o estado lógico “1”. Se ele for impar seu estado lógico será “0”. Existem três formas de controle de paridade: par, impar e nenhuma. A diferença está em indicar se o número de bits no estado lógico “1” é sempre par, impar ou nenhum. Nesse caso o bit de paridade assume estado lógico “1” de acordo com a opção selecionada. Se a escolha for nenhum, o bit de paridade é ignorado pelo equipamento receptor. Obs.: Apesar do bit de paridade poder informar um erro, não existe fator de correção. Neste caso seria necessário via software verificar a paridade e se detectado um erro, promover um novo envio do byte danificado. O Stop bit é uma forma de informar o agente receptor sobre o final do byte. Ele pode assumir “1” ou “2” bits de parada. O Start bit serve para informar sobre o inicio de uma transmissão. Sendo
assim a configuração de uma porta RS-232 exige as
seguintes informações: -
velocidade;
- número de bits; - paridade; - número de stop bits. A configuração para velocidade de comunicação, número de bits, paridade e número de stop bits deve ser a mesma nos equipamentos transmissor e receptor, caso contrário a comunicação não será estabelecida corretamente. A
USART DOS MICROCONTROLADORES AVR MEGA A USART ou Universal Synchronous Assynchronous Receiver Transmitter (Receptor Transmissor Universal Síncrono e Assíncrono) dos microcontroladores AVR ATMEGA, permite que estes se comuniquem com outros dispositivos através do padrão RS-232. Os níveis de tensão na USART estão dentro do padrão TTL (0 - 5VDC) e devem, portanto, ser convertidos para os níveis de tensão do padrão RS-232 (+/- 15 VDC). A USART presente no microcontrolador tem as seguintes características:
-
Operação Full
Duplex;
- Modo de operação Síncrono ou assíncrono; - Operação no modo síncrono como mestre ou escravo; - Gerador de Baud Rate de alta resolução; - Suporte a frame de dados com: 5, 6, 7, 8 ou 9 bits; - Suporte a uso de 1 ou 2 stop bits; - Gerador de paridade par ou impar; - Recurso para checar a paridade via hardware na recepção; - Detector para estouro da pilha de dados; - Detector de erro no frame; - Filtros para detecção de falsos start bits; - Filtro passa-baixa digital; - Três interrupções para controle: -
Transmissão completa;
-
Comunicação multi-processador;
- Registro de transmissão vazio; - Recepção completa. - Modo double speed para modo assíncrono.
REGISTRO UCSRA A seguir é dada a descrição do registro UCSRA – USART Control and Status Register A, a posição de cada um dos bits de controle, o valor inicial dos mesmos durante o RESET do microcontrolador e a descrição de suas funções. Tabela – Registro UCSRA
RXC – USART Receive Complete: Bit
de leitura que indica de acordo com seu valor lógico (0 ou 1):
0
– registro de recepção vazio;
1 – byte recebido e não lido, gera INT para avisar. TXC – USART Transmit Complete: Bit
de leitura e escrita que indica de acordo com seu valor lógico (0 ou
1):
0
– registro de transmissão com um byte a transmitir;
1 – byte transmitido – gera INT para avisar. UDRE – USART Data Register Empty: Bit
de leitura que indica de acordo com seu valor lógico (0 ou 1):
0
– registro de transmissão cheio;
1 – registro de transmissão vazio e pronto para receber novo byte. FE – Frame Error: Bit
de leitura que indica de acordo com seu valor lógico (0 ou 1):
0
– caracter recebido sem erro de frame;
1 – caracter recebido com erro no frame. DOR – Data Over Run: Bit
de leitura que indica de acordo com seu valor lógico (0 ou 1):
0
– Over
Run
não detectado no caracter recebido;
1 – Over Run detectada no caracter recebido. PE – Parity Error: Bit
de leitura que indica de acordo com seu valor lógico (0 ou 1):
0
– erro de paridade não detectado no caracter recebido;
1 – erro de paridade detectado no caracter recebido. U2X – Double the USART Transmission Speed: Bit
de leitura e escrita que permite configurar de acordo com seu valor
lógico (0 ou 1):
0
– velocidade normal no modo assíncrono;
1 – velocidade dobrada no modo assíncrono. Obs.: No modo síncrono, este bit não tem efeito e deve ser configurado como “0”. MPCM – Multi Processor Comunication Mode: Bit
de leitura e escrita que permite configurar de acordo com seu valor
lógico (0 ou 1):
0
– desabilita modo multi-processador;
1 – habilita o modo multi-processador (todos os bytes recebidos que não contiverem o endereço do processador serão ignorados). REGISTRO UCSRB A seguir é dada a descrição do registro UCSRB – USART Control and Status Register B, a posição de cada um dos bits de controle, o valor inicial dos mesmos durante o RESET do microcontrolador e a descrição de suas funções. Tabela - Registro UCSRB
RXCIE – RX Complete Interrupt Enable: Bit
de leitura e escrita que permite configurar de acordo com seu valor
lógico (0 ou 1):
0
– desabilita interrupção para byte recebido;
1 – habilita interrupção para byte recebido – aviso através do bit RXC em UCSRA. TXCIE – TX Complete Interrupt Enable: Bit
de leitura e escrita que permite configurar de acordo com seu valor
lógico (0 ou 1):
0
– desabilita interrupção para byte transmitido;
1 – habilita interrupção para byte transmitido – aviso através do bit TXC em UCSRA. UDRIE – USART Data Register Empty Interrupt Enable: Bit
de leitura e escrita que permite configurar de acordo com seu valor
lógico (0 ou 1):
0
– desabilita interrupção para registro de transmissão vazio;
1 – habilita interrupção para registro de transmissão vazio – aviso através do bit UDRE em UCSRA. RXEN – RX Enable: Bit
de leitura e escrita que permite configurar de acordo com seu valor
lógico (0 ou 1):
0
– desabilita o elemento receptor da USART;
1 – habilita o elemento receptor da USART. TXEN – TX Enable: Bit
de leitura e escrita que permite configurar de acordo com seu valor
lógico (0 ou 1):
0
– desabilita o elemento transmissor da USART;
1 – habilita o elemento transmissor da USART. UCSZ2– Caracter Size 2: Bit
de leitura e escrita que permite configurar junto com UCSZ1 e UCSZ0
em UCSRC o tamanho do caracter a ser trabalhado pela USART.
Na descrição das funções dos bits UCSZ1 e UCSZ0
este bit terá sua
configuração detalhada.
RXB8 – Receive Data Bit 8: Este
é o nono bit recebido quando o tamanho do frame (caracter)
selecionado for nove.
TXB8 – Transmit Data Bit 8: Este
é o nono bit a ser transmitido quando o tamanho do frame (caracter)
selecionado for nove e deve ser alterado, antes de ser solicitada a
transmissão do caracter.
REGISTRO UCSRC A seguir é dada a descrição do registro UCSRC – USART Control and Status Register C, a posição de cada um dos bits de controle, o valor inicial dos mesmos durante o RESET do microcontrolador e a descrição de suas funções. Tabela – Registro UCSRC
URSEL – Register Select Bit
de leitura e escrita que permite configurar de acordo com seu valor
lógico (0 ou 1):
0
– qualquer escrita ou leitura é desviada para o registro UBRRH;
Obs.:
Os registros UCSRC e UBRRH possuem o mesmo endereço. Por isso a
necessidade da seleção deste bit para qualquer atividade de leitura
ou escrita nos registradores descritos.1 – qualquer escrita ou leitura é desviada para o registro UCSRC. UMSEL – USART Mode Select Bit
de leitura e escrita que permite configurar de acordo com seu valor
lógico (0 ou 1):
0
– seleciona modo assíncrono;
1 – seleciona modo síncrono. UPM1:0 – Parity Mode – Bit 1 e Bit 0 Estes
bits, juntos, permitem configurar a paridade conforme tabela abaixo.
Tabela – Seleção da
Paridade através de
UPM1
e UPM0
USBS – USART Stop Bit Select Bit
de leitura e escrita que permite configurar de acordo com seu valor
lógico (0 ou 1):
0
– seleciona um stop
bit;
1 – seleciona dois stop bit. UCSZ1:0 – Caracter Size - Bit 1 e Bit 0 Estes
bits, juntos com UCSZ2 em UCSRB, permitem configurar o tamanho do
caracter desejado conforme tabela abaixo.
Tabela – Seleção do
tamanho do caracter através de UICSZ2,
UCSZ1
e UCSZ0
UCPOL – USART Clock Polarity Bit
de leitura e escrita que permite configurar de acordo com seu valor
lógico (0 ou 1):
0
– borda de subida na transmissão, borda de descida na recepção;
Obs.:
Este bit só tem atuação quando a USART estiver operando no modo
síncrono, pois o mesmo permite selecionar a relação entre os dados
de entrada e saída com o clock. 1 – borda de descida na transmissão, borda de subida na recepção. A seguir, na tabela, é dada a descrição dos registros UBRRL e UBRRH - USART Baud Rate Register Low and High, a posição de cada um dos bits de controle, o valor inicial dos mesmos durante o RESET do microcontrolador e a descrição de suas funções. Tabela – Registros UBRRL e UBRRH
URSEL – Register Select Bit
de leitura e escrita que permite configurar de acordo com seu valor
lógico (0 ou 1):
0
– qualquer escrita ou leitura é desviada para o registro UBRRH;
Obs.:
Os registros UCSRC e UBRRH possuem o mesmo endereço. Por isso a
necessidade da seleção deste bit para qualquer atividade de leitura
ou escrita nos registradores descritos.1 – qualquer escrita ou leitura é desviada para o registro UCSRC. UBRR11:0 – Register Select Estes
doze bits permitem, juntos, selecionar a taxa de baud
rate
desejada. O valor a ser inserido no registro pode ser calculado de
acordo com as fórmulas:
Modo
Assíncrono: UBRR = (FOSC / 16 x BAUD) - 1 , quando U2X = 0; UBRR = (FOSC / 8 x BAUD) - 1, quando U2X = 1; Modo
síncrono: UBRR = (FOSC / 2 x BAUD) - 1;
A
margem de erro é dada pela fórmula: ERRO[%] = [(BAUDRATECLOSEST_MATCH / BAUDRATE) - 1] x 100%
O usuário pode ainda, contar com tabelas fornecidas no datasheet do microcontrolador. O datasheet pode ser encontrado no site do fabricante ATMEL.
A seguir é dada a descrição do registro UDR - USART Data Register. Este registro não é utilizado para o controle da USART. Sua função principal é conter o byte a ser transmitido ou o byte recebido. Tabela – Registro UDR (escrita e leitura)
EXEMPLOS - ROTINAS DE CONFIGURAÇÃO E USO Agora que já foram descritos os registros, vou passar alguns exemplos para a configuração e uso da USART dos microcontroladores AVR. A
primeira coisa a fazer é determinar qual será o formato desejado para a
sua comunicação RS-232. Estou falando da velocidade (quantos bps?),
quantidade de bits, paridade e número de stop bits. Feito isso, você
ainda precisa determinar quantas e quais interrupções você gostaria de
usar. Minha dica é usar apenas uma na USART que considero a mais
importante, a interrupção de recepção de caracter RXCIE. Assim seu
programa não precisa ficar "lendo" a USART constantemente atrás de um
caracter recebido. Quando e se o mesmo chegar, a interrupção desviará o
programa para a rotina que fará o "atendimento" desta e depois
retornará para o ponto de onde partiu.
A
configuração da USART dos microcontroladores AVR é bem simples.
Basicamente usamos os registros UCSRA, UCSRB, UCSRC, UBRRH e UBRRL.
Veja o exemplo dado abaixo. Código fonte - Configuração da USART // Inicializa a USART - 9600,n,8,1 a 7.3728MHz // // Entradas : nenhuma // Saídas : nenhuma //******************************************************************************** void init_UART(void){ UCSRB = 0x00; //desabilita TX, RX para setar baud rate UCSRA = 0x00; //limpa flag TXC, seleciona veloc. normal e desab. Multi-Proc. Com. UCSRC = ((1<<URSEL0) | (1<<UCSZ2) | (1<<USCZ1)); //modo assincrono, 8 bits, sem paridade e 1 stop bit UBRRH = 0x00; //seta baud rate a 9600 bps (7.3728MHz) e U2X=0 (veloc. normal) UBRRL = 0x2F; //valor 47 decimal, conforme tabela no datasheet UCSRB = ((1<<RXCIE) | (1<<RXEN) | (1<<TXEN)); //transmissão e recepção habilitados, int de recepção habilitada }
RECEBENDO UM BYTE ATRAVÉS DA USART DOS MICROCONTROLADORES AVR A
recepção de um byte através da USART dos microcontroladores AVR é
também algo simples. Considerando que você habilitou a interrupção para
recepção, conforme dica passada mais atrás, você só precisa inserir uma
função que usará o endereço do vetor da interrupção que você
selecionou. Abaixo você pode ver o código fonteque exemplifica isso. Código Fonte - Recepção de um byte através da USART // Interrupção UART - RX // // Entradas - nenhuma // Saídas - chama função para realizar tratamento //******************************************************************************** ISR(USART_RXC_vect){ UART_rec(); //recebe dado da UART do microcontrolador }
Para
usar uma interrupção do AVR, usando a Linguagem C, basta preparar uma
função identificada com a macro ISR() passando para esta o vetor da
interrupção que se deseja tratar. Note que o tratamento não está sendo
feito dentro da função que atende a interrupção. Isso é feito por uma
segunda função no meu exemplo, mas nada impediria que fosse feito
diretamente dentro desta função. Cada um tem seu jeito de programar,
certo? Abaixo, a minha função UART_rec(). A única coisa que a mesma faz
é receber o caracter, guardá-lo em uma variável tipo GLOBAL (pode
ajudar em um posterior processamento) e em seguida enviar o "eco" do
caracter recebido (também ajuda, dependendo do protocolo usado ou ainda
se você estiver usando o módulo com um programa terminal como o
HyperTerminal.
Código Fonte - Função UART_rec() //******************************************************************************** // Recebe um dado quando vector de interrupção UART_RX_vect é disparado // // Entradas : nenhuma // Saidas : nenhuma //******************************************************************************** void UART_rec(void){ byte c; c = UDR; //le byte if (bit_is_clear(UCSRA, RXC)){ //finalizou recepção rec_u = c; //guarda na variável global, declarada anteriormente mputch(c); //envia eco do caracter recebido } } TRANSMITINDO UM BYTE ATRAVÉS DA USART DOS MICROCONTROLADORES AVR A transmissão de um byte através da USART dos microcontroladores AVR também pode ser considerado algo bem simples de ser feito. Basicamente o que se tem a fazer é inserir o byte que se deseja enviar no registro UDR, desde que o bit UDRE no registrador UCSRA esteja com valor lógico "1". Se valor for igual a "0", isso indica que o registro UDR está "cheio" e é necessário aguardar que o mesmo seja "esvasiado". Veja um exemplo abaixo de como fazer uma transmissão. Trata-se do código fonte da função mputch(char). Código fonte - Transmitindo um byte através da USART //******************************************************************************** // Envia um byte através da USART // // Entradas : byte a enviar // Saídas : nenhuma //******************************************************************************** void mputch(unsigned char caracter){ while (! (UCSRA & (1<<UDRE))); //verifica se está desocupado, senão espera UDR = caracter; //transmite caracter } MAIS ALGUMAS DICAS A partir da função mputch você poderá construir sua própria função printf(). Claro que você também poderá buscar na INTERNET funções prontas para uso da USART dos microcontroladores AVR. Algumas bastante poderosas. Eu particularmente, prefiro construir minhas próprias soluções. Uma outra dica é que dependendo do número de caracteres que você tem a receber, você deve sempre usar um buffer de dados para este e somente após recebê-los em sua totalidade realizar o tratamento. Isso porque, o compilador do AVR desabilita automaticamente o tratamento de uma interrupção quando está tratando a mesma. Sendo assim, se o seu tratamento consumir muito tempo (tempo maior que o de um byte na velocidade selecionada) você poderá perder caracteres por estar realizando o tratamento de um anterior.
Nesta
parte de minha pequena série tentei passar o máximo de informação
possível a respeito do uso da USART dos microcontroladores AVR, mais
especificamente na comunicação assíncrona. Como eu disse antetiormente,
há muita coisa "pronta" na INTERNET e sei que muitos se sentem tentados
a usá-las sem se preocupar com o "depois". Porém,
se você apenas "copiar" sem se preocupar em "como" as mesmas
funcionam, seus conhecimentos sobre o microcontrolador AVR não poderão
ser considerados bons. Você estará mostrando que é bom apenas no "Control Chupe" (CTRL+C, CTRL+V). Tudo passa, mas conceito fica! Bons estudos e até a próxima!
Datasheets recomendados:
ATtiny11/12
-
http://www.atmel.com/dyn/resources/prod_documents/doc1006.pdf |
Copyright deste conteúdo reservado para Márcio José Soares e protegido pela Lei de Direitos Autorais LEI N° 9.610, de 19 de Fevereiro de 1998. É estritamente proibida a reprodução total ou parcial do conteúdo desta página em outros pontos da internet, livros ou outros tipos de publicações comerciais ou não, sem a prévia autorização por escrito do autor. |