Operação
O tempo no display esta no formato MM:SS (minutos : segundos). A operação é bastante simples e utiliza os três botões do display:
- O primeiro botão é usado para parar e inciar a contagem. Se o valor no display for zero, será ativada a função de cronômetro, com o valor sendo incrementado a cada segundo (ao atingir 99:59 voltará a zero e continuará contando). Se o valor for diferente de zero ele será decrementado a cada segundo, parando quando atingir zero (modo timer).
- O segundo botão incrementa os segundos, quando o timer estiver parado. A contagem vai de 0 a 59.
- O terceiro botão incrementaros minutos, quando o timer estiver parado. A contragem vai de 0 a 99.
Código
O código aproveita o gerador de caracteres e a rotina de escrita anteriores, acrescentando o caracter "dois pontos":
- // Matriz de Caracteres 5x7
- // Contem os dígitos de 0 a 9 e dois pontos
- uint8_t digitos [11][7] PROGMEM =
- {
- { 0x0E, 0x11, 0x15, 0x15, 0x15, 0x11, 0x0E },
- { 0x04, 0x0C, 0x04, 0x04, 0x04, 0x04, 0x1F },
- { 0x0E, 0x11, 0x02, 0x04, 0x08, 0x10, 0x1F },
- { 0x0E, 0x11, 0x01, 0x06, 0x01, 0x11, 0x0E },
- { 0x11, 0x11, 0x11, 0x1F, 0x01, 0x01, 0x01 },
- { 0x1F, 0x10, 0x10, 0x1E, 0x01, 0x11, 0x0E },
- { 0x06, 0x08, 0x10, 0x1E, 0x11, 0x11, 0x0E },
- { 0x1F, 0x11, 0x01, 0x02, 0x04, 0x04, 0x04 },
- { 0x0E, 0x11, 0x11, 0x0E, 0x11, 0x11, 0x0E },
- { 0x0E, 0x11, 0x11, 0x0F, 0x01, 0x02, 0x0C },
- { 0x00, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00 }
- };
- // Mostra o digito d a partir da posição x
- static void display (uint8_t x, uint8_t d)
- {
- uint8_t i, y, mask, gc;
- for (y = 0; y < 7; y++)
- {
- gc = pgm_read_byte(&(digitos[d][y]));
- mask = 0x10;
- for (i = 0; i < 5; i++)
- {
- ht1632c_setLED (x+i, y, gc & mask);
- mask = mask >> 1;
- }
- }
- }
- // Variaveis
- static volatile uint8_t tempo[5];
- static volatile enum { PARADO, SUBINDO, DESCENDO } modo;
- // Programa principal
- int main(void)
- {
- uint8_t i;
- // Zera o relogio
- tempo[0] = 0;
- tempo[1] = 0;
- tempo[2] = 10;
- tempo[3] = 0;
- tempo[4] = 0;
- modo = PARADO;
- for (i = 0; i < 5; i++)
- display (6*i, tempo[i]);
- // Liga pullup das teclas
- TEC_DDR &= ~(TEC_KEY1|TEC_KEY2|TEC_KEY3);
- TEC_PORT |= TEC_KEY1|TEC_KEY2|TEC_KEY3;
- ht1632c_init(); // inicia o controlador do display
- ht1632c_send_screen (); // limpa o display
- tempo_init(); // inicia a contagem de tempo
- // Loop perpétuo - somente tratando a interrupção de timer
- for (;;)
- {
- }
- }
- // Inicia a contagem de tempo
- static void tempo_init (void)
- {
- ASSR |= (1<<AS2); // timer2 async from external quartz
- TCCR2 = 0b00000010; // normal,off,/8; 32768Hz/256/8 = 16 Hz
- TIMSK |= (1<<TOIE2); // enable timer2 overflow int
- sei(); // enable interrupts
- }
- // Interrupção do Timer2
- ISR(TIMER2_OVF_vect)
- {
- static uint8_t cnt_seg = 16;
- static uint8_t teclas = TEC_KEY1|TEC_KEY2|TEC_KEY3;
- uint8_t mudou = FALSE;
- uint8_t i;
- if (--cnt_seg == 0)
- {
- cnt_seg = 16;
- // Atualiza a contagem
- if (modo == SUBINDO)
- {
- mudou = TRUE;
- if (++tempo[4] == 10)
- {
- tempo[4] = 0;
- if (++tempo[3] == 6)
- {
- tempo[3] = 0;
- if (++tempo[1] == 10)
- {
- tempo[1] = 0;
- if (++tempo[0] == 10)
- tempo[0] = 0;
- }
- }
- }
- }
- else if (modo == DESCENDO)
- {
- mudou = TRUE;
- if (tempo[4] == 0)
- {
- tempo[4] = 9;
- if (tempo[3] == 0)
- {
- tempo[3] = 5;
- if (tempo[1] == 0)
- {
- tempo[1] = 9;
- tempo[0]--;
- }
- else
- tempo[1]--;
- }
- else
- tempo[3]--;
- }
- else
- tempo[4]--;
- if ((tempo[0] + tempo[1] + tempo[3] + tempo[4]) == 0)
- modo = PARADO;
- }
- }
- // Trata as teclas
- if (((teclas & TEC_KEY1) == 0) && ((TEC_PIN & TEC_KEY1) != 0))
- {
- // soltou tecla de modo
- if (modo == PARADO)
- {
- if ((tempo[0] + tempo[1] + tempo[3] + tempo[4]) == 0)
- modo = SUBINDO;
- else
- modo = DESCENDO;
- }
- else
- modo = PARADO;
- }
- if (modo == PARADO)
- {
- if (((teclas & TEC_KEY2) == 0) && ((TEC_PIN & TEC_KEY2) != 0))
- {
- mudou = TRUE;
- if (++tempo[4] == 10)
- {
- tempo[4] = 0;
- if (++tempo[3] == 6)
- tempo[3] = 0;
- }
- }
- if (((teclas & TEC_KEY3) == 0) && ((TEC_PIN & TEC_KEY3) != 0))
- {
- mudou = TRUE;
- if (++tempo[1] == 10)
- {
- tempo[1] = 0;
- if (++tempo[0] == 10)
- tempo[0] = 0;
- }
- }
- }
- teclas = TEC_PIN;
- if (mudou)
- {
- // Atualiza o display
- for (i = 0; i < 5; i++)
- display (6*i, tempo[i]);
- }
- }
Outra melhoria possível é fazer o display piscar quando estiver no modo timer e a contagem chegar a zero. Pode-se também conectar um alto-falante ou buzzer para gerar um alarme sonoro.
O Timer em Funcionamento
O vídeo abaixo mostra o resultado obtido.
Nenhum comentário:
Postar um comentário