Vamos começar pela iniciação do hardware: entradas e saídas digitais, USART (para receber os dados do leitor de RFID) e o timer:
- // LEDs
- #define LED_TOVIVO LED8
- #define LED_LEU LED7
- #define LED_TRANCA LED6
- #define LED_CADASTRA LED2
- #define LED_APAGA LED3
- // Servo
- #define SERVO_PORT PORTB
- #define SERVO_DDR DDRB
- #define SERVO _BV(PB7)
- // Teclas
- #define TEC_CADASTRA TEC1
- #define TEC_APAGA TEC4
- // Inicia as direçoes dos pinos de conexão dos LEDs
- LED_DDR |= 0xFF;
- // LEDs Apagados
- LED_PORT = 0x00;
- // Inicia conexão ao servo
- SERVO_DDR |= SERVO;
- SERVO_PORT &= ~SERVO;
- // Liga pullup das teclas
- TEC_DDR &= ~(TEC1|TEC2|TEC3|TEC4);
- TEC_PORT |= TEC1|TEC2|TEC3|TEC4;
- // 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
- // Preparar o timer 1 operar no modo CTC com 16MHz / 8
- // gerando interrupcao contando até 100 (0,05 ms)
- OCR1A = 100;
- TCCR1B = _BV(WGM12) | _BV(CS11);
- TIMSK |= (1<<OCIE1A);
- // Lista de tags conhecidos
- #define NMAX_TAGS 8
- static uint32_t tags[NMAX_TAGS];
- // Tags salvos na EEPROM
- uint32_t eepTags[NMAX_TAGS] EEMEM;
- int i;
- // Carrega os tags conhecidos da EEPROM
- for (i = 0; i < NMAX_TAGS; i++)
- tags[i] = eeprom_read_dword (&eepTags[i]);
- // Último tag detectado
- volatile uint32_t tagLido;
- // Controle do LED de leitura
- volatile uint8_t cntLedLeu = 0;
- // 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;
- cntLedLeu = 100;
- LED_PORT |= LED_LEU;
- }
- 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;
- }
- // Modo de Operação
- typedef enum { MODO_NORMAL, MODO_CADASTRA, MODO_APAGA1, MODO_APAGA2 } MODOOPER;
- static MODOOPER modo = MODO_NORMAL;
- for (;;)
- {
- if (modo == MODO_NORMAL)
- {
- if (tagLido != 0)
- {
- // Procura nos conhecidos
- for (i = 0; (i < NMAX_TAGS) && (tags[i] != 0xFFFFFFFF); i++)
- {
- if (tags[i] == tagLido)
- {
- // achou, move a tranca
- if (tranca == ABERTA)
- {
- Fecha();
- tranca = FECHADA;
- }
- else
- {
- Abre();
- tranca = ABERTA;
- }
- tagLido = 0;
- break;
- }
- }
- }
- }
- else if (modo == MODO_CADASTRA)
- {
- if (tagLido != 0)
- {
- // Procura nos conhecidos
- for (i = 0; (i < NMAX_TAGS) && (tags[i] != 0xFFFFFFFF); i++)
- {
- if (tags[i] == tagLido)
- {
- // achou, ignora
- break;
- }
- }
- if ((i < NMAX_TAGS) && (tags[i] == 0xFFFFFFFF))
- {
- // Não encontrou e tem espaço, coloca na lista
- tags[i] = tagLido;
- eeprom_update_dword (&eepTags[i], tagLido);
- }
- tagLido = 0;
- }
- }
- else if (modo == MODO_APAGA2)
- {
- // Apaga a lista de Tags
- for (i = 0; i < NMAX_TAGS; i++)
- {
- tags[i] = 0xFFFFFFFF;
- eeprom_update_dword (&eepTags[i], 0xFFFFFFFF);
- }
- modo = MODO_NORMAL;
- }
- }
- // Estado da Fechadura
- typedef enum { ABERTA, FECHADA } FECHADURA;
- static FECHADURA tranca = FECHADA;
- // Controle do servo
- volatile uint8_t nCiclos = 0;
- volatile uint16_t posServo = 0;
- // Abre a fechadura
- static void Abre(void)
- {
- posServo = 10; // 0,5 ms
- nCiclos = 50;
- LED_PORT &= ~LED_TRANCA;
- }
- // Fecha a fechadura
- static void Fecha(void)
- {
- posServo = 30; // 1,5 ms
- nCiclos = 50;
- LED_PORT |= LED_TRANCA;
- }
- // Interrupção do Timer1
- // Ocorre a cada 0,05 ms
- ISR(TIMER1_COMPA_vect)
- {
- static uint16_t cntCiclo = 0; // número de pulsos para o servo
- static uint8_t cntServo = 0; // largura do pulso
- static uint8_t cnt10ms = 200; // 200*0,05ms = 10ms
- // Tempos a seguir usam a base de 10ms
- static uint16_t cntCadastra = 500; // 5 seg
- static uint16_t cntApaga = 1000; // 10 seg
- static uint8_t cntLed = 20; // 0,2 seg
- static uint8_t cntToVivo = 50; // 0,5 seg
- if (nCiclos != 0)
- {
- if (cntCiclo == 0)
- {
- // Fim do ciclo
- if (--nCiclos != 0)
- {
- // Novo ciclo
- SERVO_PORT |= SERVO;
- cntServo = posServo;
- cntCiclo = 400; // 20 ms
- }
- }
- if (nCiclos != 0)
- {
- if ((cntServo != 0) && (--cntServo == 0))
- SERVO_PORT &= ~SERVO;
- cntCiclo--;
- }
- }
- if (--cnt10ms == 0)
- {
- cnt10ms = 200;
- if (cntLedLeu != 0)
- {
- if (--cntLedLeu == 0)
- LED_PORT &= ~LED_LEU;
- }
- if (--cntToVivo == 0)
- {
- LED_PORT ^= LED_TOVIVO;
- cntToVivo = 50;
- }
- if (modo == MODO_NORMAL)
- {
- if ((TEC_PIN & TEC_CADASTRA) == 0)
- {
- if (--cntCadastra == 0)
- {
- LED_PORT |= LED_CADASTRA;
- modo = MODO_CADASTRA;
- }
- }
- else
- cntCadastra = 500;
- if ((TEC_PIN & TEC_APAGA) == 0)
- {
- if (--cntApaga == 0)
- {
- modo = MODO_APAGA1;
- cntApaga = 1000;
- cntLed = 20;
- }
- }
- else
- cntApaga = 1000;
- }
- else if (modo == MODO_CADASTRA)
- {
- if ((TEC_PIN & TEC_CADASTRA) == 0)
- {
- if (--cntCadastra == 0)
- {
- LED_PORT &= ~LED_CADASTRA;
- modo = MODO_NORMAL;
- }
- }
- else
- cntCadastra = 500;
- }
- else if (modo == MODO_APAGA1)
- {
- if (--cntLed == 0)
- {
- LED_PORT ^= LED_APAGA;
- cntLed = 20;
- }
- if ((TEC_PIN & TEC_APAGA) == 0)
- {
- if (--cntApaga == 0)
- {
- modo = MODO_APAGA2;
- cntApaga = 1000;
- LED_PORT &= ~LED_APAGA;
- }
- }
- else
- {
- modo = MODO_NORMAL;
- cntApaga = 1000;
- LED_PORT &= ~LED_APAGA;
- }
- }
- }
- }
Nenhum comentário:
Postar um comentário