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
A rotina de interrupção utiliza uma pequena máquina de estados para conferir o formato da mensagem e armazenar o id do tag. Ao converter o id para binário eu considerei a possibilidade de vir um número hexadecimal (apesar dos meus testes terem sempre apresentado um número decimal). Recebida uma mensagem correta, o id do tag é colocado em uma variável global, desde que ela esteja livre (com zero).// Ú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;
}
O programa principal fica monitorando a variável global que indica a detecção de um tag. Quando esta variável deixa de ser zero, indica que um tag foi detectado. O tag é então procurado na tabela, se achado o LED correspondente é aceso. Se o tag não estiver na tabela, e ela não estiver cheia, ele é acrescentado ao final. Em seguida a variável é retornada a zero, para indicar que está pronto para tratar uma nova leitura.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;
//}
}
}
TesteO 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