Hardware
Como vimos anteriormente, o leitor requer somente três conexões, nos pinos +5, GND e D0. Estas conexões serão feitas na barra de pinos da placa JY-MEGA32. As duas primeiras são óbvias (Vcc e GND), a terceira requer uma olhada no datasheet do ATmega32, para descobrir que o sinal Rx da USART é compartilhado com PD0.
Um outro detalhe não óbvio é que o sinal PD0 está ligado na placa ao conector USB (isto pode ser verificado no esquema da placa, que está nos arquivos do blog). Se o leitor e o cabo USB estiverem conectados simultaneamente, a comunicação com o leitor não será confiável. Após a carga do firmware é recomendável alimentar a placa ligando a alimentação por um dos outros conectores. No meu caso, usei o conector de programação SPI.
Software
Para este teste vamos acender os LEDs com os tags. O objetivo é associar cada tag a um LED. Incialmente não temos nenhuma associação; quando um novo tag é detectado, o próximo LED é associado a ele (desde que ainda tenhamos LEDs não associados). Quando um tag conhecido é detectado, o LED correspondente é aceso.
Para facilitar as coisas, os ids dos tags são convertidos em valores binários de 32 bits. Uma tabela de 8 posições guarda os ids dos tags conhecidos, o valor zero indica que a posição da tabela esta livre. Cada posição da tabela corresponde a um LED.
O ponto principal neste teste é a comunicação entre o leitor e o ATmega. O ATmega32 possui uma USART, que é programada com os parâmetros adequados (comunicação assíncrona no formato 8N1, a 9600bps). É também habilitada a interrupção de recepção:
- // Programa a USART para 9600 8N1
- UCSRA = _BV(U2X); // para maior resolução do baud rate
- UCSRB = _BV(RXEN)|_BV(RXCIE); // liga recepção, com interrupção
- UCSRC = _BV(URSEL)|_BV(UCSZ1)|_BV(UCSZ0) ; // 8bit, 1 stop, sem paridade
- UBRRL = (CLK_CPU / (8 * 9600UL)) - 1; // 9600 bps
- // Último tag detectado
- volatile uint32_t tagLido;
- // Lista de tags conhecidos
- volatile uint32_t tags[8];
- // Interrupção de recepção da USART
- ISR(USART_RXC_vect)
- {
- static uint8_t estado = 0;
- static uint32_t idTag;
- uint8_t c;
- c = UDR;
- if (bit_is_clear(UCSRA, FE))
- {
- // recebeu caracter sem erro
- if (estado == 0)
- {
- // Aguardando o STX
- if (c == 0x02)
- {
- estado = 1;
- idTag = 0;
- }
- }
- else if (estado == 9)
- {
- // Aguardando o ETX
- if (c == 0x03)
- {
- // Recebeu ID com sucesso
- tagLido = idTag;
- }
- estado = 0;
- }
- else
- {
- // recebeu um dígito, vamos tratar como hexadecimal
- if ((c >= '0') && (c <= '9'))
- idTag = (idTag << 4) | (c & 0xF);
- else if ((c >= 'A') && (c <= 'F'))
- idTag = (idTag << 4) | (c - 'A' + 10);
- else if ((c >= 'a') && (c <= 'f'))
- idTag = (idTag << 4) | (c - 'a' + 10);
- else
- estado = 0xFF;
- estado++;
- }
- }
- else
- estado = 0;
- }
- for (;;)
- {
- if (tagLido != 0)
- {
- int i;
- // Procura nos conhecidos
- for (i = 0; (i < 8) && (tags[i] != 0); i++)
- {
- if (tags[i] == tagLido)
- {
- // achou, acende o LED correspondente
- LED_PORT = 1 << i;
- break;
- }
- }
- if ((i < 8) && (tags[i] == 0))
- {
- // Não encontrou e tem espaço, coloca na lista
- tags[i] = tagLido;
- LED_PORT = 1 << i;
- }
- tagLido = 0;
- }
- //if (TIFR & _BV(OCF1A ))
- //{
- // TIFR = _BV(OCF1A ); // Limpa indicação do timer
- // LED_PORT ^= 0x80;
- //}
- }
- }
O vídeo abaixo mostra o sistema em funcionamento. Cinco tags (três cartões e dois chaveiros) são apresentados primeiro em ordem e depois aleatoriamente. Para facilitar, os tag estão identificados com o número do LED correspondente.
Nenhum comentário:
Postar um comentário