//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Relógio digital com display 7 segmentos multiplexados. // // O relógio em seu estado normal mostra as horas. // // Para ajustar as horas: Simplesmente pressionar as teclas Hr e Min // // Para ajustar e ativar despertador: Pressionando as teclas Hr e Min simultaneamente com a tecla ALARME. // // Estará ativo se o alarme não estiver setado para 00h00min. Mostra que está ativo pelo ponto do 7seg (RB5) // // Quando o alarme está disparando, tem que ficar pressionando o alarme por x segundos até que ele pare. // // Ajuste do x pode ser feito na linha 357 // // Autor: Rafael Oliveira Del Pino - Tecnólogo em Automação Industrial // // //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #include <16F677.h> //PIC on use: 16F677 #FUSES NOWDT //No Watch Dog Timer #FUSES INTRC_IO //Internal RC Osc, no CLKOUT #FUSES PROTECT //Code protected from reads #FUSES NOBROWNOUT //No brownout reset #FUSES NOMCLR //Master Clear pin disabled #FUSES CPD //Data EEPROM Code Protected #FUSES PUT //Power Up Timer #FUSES IESO //Internal External Switch Over mode enabled #FUSES FCMEN //Fail-safe clock monitor enabled #use delay(clock=8000000) //Oscilator Frequency = 8MHz #use fast_io (a) #use fast_io (b) #use fast_io (c) #define STATUSALM pin_B5 #define BUZZER pin_A3 #define BOTAOALARME pin_C7 #define BOTAOHORA pin_B6 #define BOTAOMINUTO pin_B7 #define ATIVAHORA1 pin_A1 #define ATIVAHORA2 pin_A0 #define ATIVAMIN1 pin_A4 #define ATIVAMIN2 pin_A2 #define ATIVASEG1 pin_B4 #define ATIVASEG2 pin_A5 #define CARACTERE_A 0b0001000 #define CARACTERE_L 0b1000111 int conversorbcd (int ientrada) { if (ientrada == 0) return (0b1000000); if (ientrada == 1) return (0b1111001); if (ientrada == 2) return (0b0100100); if (ientrada == 3) return (0b0110000); if (ientrada == 4) return (0b0011001); if (ientrada == 5) return (0b0010010); if (ientrada == 6) return (0b0000010); if (ientrada == 7) return (0b1111000); if (ientrada == 8) return (0b0000000); if (ientrada == 9) return (0b0010000); } int iestouro; int ihoras1, ihoras2; int iminutos1, iminutos2; int isegundos1, isegundos2; short habilitaloop2; #int_TIMER1 void TIMER1_isr(void) { set_timer1(15539); // Timer 1 contará de 200ms em 200ms (0,06214s até 0,26214s) = 15535 iestouro++; if (iestouro > 4) // A cada 5 estouros de 200ms (1 segundo), isegundo = + 1 { iestouro = 0; isegundos2++; habilitaloop2 = 1; ///////////////////////////////////////// ///// CONTADOR HR, MIN, SEG /////// ///// RELÓGIO /////// ///////////////////////////////////////// if(isegundos2 > 9) ///// { ///// isegundos1++; ///// isegundos2 = 0; ///// } ///// if(isegundos1 > 5) ///// { ///// isegundos1 = 0; ///// iminutos2++; ///// } ///// ///// ///// if(iminutos2 > 9) ///// { ///// iminutos1++; ///// iminutos2 = 0; ///// } ///// if(iminutos1 > 5) ///// { ///// iminutos1 = 0; ///// ihoras2++; ///// } ///// ///// ///// if(ihoras2 > 9) ///// { ///// ihoras1++; ///// ihoras2 = 0; ///// } ///// if((ihoras1 > 1) && ihoras2 > 3) ///// { ///// ihoras1 = 0; ///// ihoras2 = 0; ///// } ///// ///////////////////////////////////////// } } void main() { int iretorno, icontador; int ihorasalm1, ihorasalm2; int iminutosalm1, iminutosalm2; int imemoria; short almstatus, buzzstatus, habilitaloop1; ihoras1 = ihoras2 = iminutos1 = iminutos2 = isegundos1 = isegundos2 = iretorno = iestouro = imemoria = 0; ihorasalm1 = ihorasalm2 = iminutosalm1 = iminutosalm2 = 0; almstatus = buzzstatus = habilitaloop1 = habilitaloop2 = 1; set_tris_a(0b00000000); // RA0, RA1, RA2, RA3, RA4, RA5, RA6 e RA7 são saídas set_tris_b(0b11000000); // RB7 e RB6 são entradas e RB5, RB4, RB3, RB2, RB1 e RB0 são saídas set_tris_c(0b10000000); output_bit(STATUSALM, almstatus); // Alarme é ativado com nível lógico LOW, logo, inicia o programa desativado output_bit(BUZZER, almstatus); // Alarme é ativado com nível lógico LOW, logo, inicia o programa desativado //========================================================================================================================================== //// setup_adc_ports(NO_ANALOGS); //// setup_adc(ADC_OFF); //// setup_spi(SPI_SS_DISABLED); //// setup_timer_0(RTCC_INTERNAL); //// setup_timer_1(T1_INTERNAL|T1_DIV_BY_8); // Timer1 (PLL = 8 ; BITS = 16 ; Estouro = 0,26214s ; Resolução: 4us) //// set_timer1(15539); // Timer 1 contará de 200ms em 200ms (0,06214s até 0,26214s) //// setup_timer_2(T2_DISABLED,0,1); //// setup_comparator(NC_NC_NC_NC); // This device COMP currently not supported by the PICWizard //// enable_interrupts(INT_TIMER1); //// enable_interrupts(GLOBAL); //// //Setup_Oscillator parameter not selected from Intr Oscillator Config tab //// // TODO: USER CODE!! //// //// //========================================================================================================================================== while(TRUE) { iretorno = conversorbcd(isegundos2); // Chama função conversorbcd e valor de entrada = isegundo2, iretorno = isegundo2 convertido p BCD output_c(iretorno); // Coloca o valor que retorna da função conversorbcd na porta C output_c(iretorno); output_bit(ATIVASEG2,0); // Ativa o display 2 dos segundos delay_ms(10); // Tempo que fica acionado o display2 output_bit(ATIVASEG2,1); // Desativa o display 2 dos segundos iretorno = conversorbcd(isegundos1); // Chama função conversorbcd e valor de entrada = isegundo1, iretorno = isegundo1 convertido p BCD output_c(iretorno); // Coloca o valor que retorna da função conversorbcd na porta C output_c(iretorno); output_bit(ATIVASEG1,0); // Ativa o display 1 dos segundos delay_ms(10); // Tempo que fica acionado o display 1 dos segundos output_bit(ATIVASEG1,1); // Desativa o display 1 dos segundos iretorno = conversorbcd(iminutos2); // Chama função conversorbcd e valor de entrada = iminutos2, iretorno = iminutos2 convertido p BCD output_c(iretorno); // Coloca o valor que retorna da função conversorbcd na porta C output_c(iretorno); output_bit(ATIVAMIN2,0); // Ativa o display 2 dos minutos delay_ms(10); // Tempo que fica acionado o display2 output_bit(ATIVAMIN2,1); // Desativa o display 2 dos segundos iretorno = conversorbcd(iminutos1); // Chama função conversorbcd e valor de entrada = iminutos1, iretorno = iminutos1 convertido p BCD output_c(iretorno); // Coloca o valor que retorna da função conversorbcd na porta C output_c(iretorno); output_bit(ATIVAMIN1,0); // Ativa o display 1 dos minutos delay_ms(10); // Tempo que fica acionado o display1 output_bit(ATIVAMIN1,1); // Desativa o display 1 dos segundos iretorno = conversorbcd(ihoras2); // Chama função conversorbcd e valor de entrada = ihoras2, iretorno = ihoras2 convertido p BCD output_c(iretorno); // Coloca o valor que retorna da função conversorbcd na porta C output_c(iretorno); output_bit(ATIVAHORA2,0); // Ativa o display 1 das horas delay_ms(10); // Tempo que fica acionado o display1 output_bit(ATIVAHORA2,1); // Desativa o display 1 das horas iretorno = conversorbcd(ihoras1); // Chama função conversorbcd e valor de entrada = ihoras1, iretorno = ihoras1 convertido p BCD output_c(iretorno); // Coloca o valor que retorna da função conversorbcd na porta C output_c(iretorno); output_bit(ATIVAHORA1,0); // Ativa o display 1 das horas delay_ms(10); // Tempo que fica acionado o display1 output_bit(ATIVAHORA1,1); // Desativa o display 1 das horas if(!input(BOTAOHORA)) // Entra no loop do IF se tiver nível low no pino { ihoras2++; if(ihoras2 > 9) { ihoras2 = 0; ihoras1++; } if((ihoras1 == 2) && (ihoras2 > 3)) ihoras1 = ihoras2 = 0; while (!input(BOTAOHORA)); // Só sai do loop quando o botão for solto } if(!input(BOTAOMINUTO)) { iminutos2++; //Ao entrar no loop, iminutos2 fica com +1 if((iminutos1 > 4) && (iminutos2 > 9) && (ihoras1 == 0) && (ihoras2 == 0)) // Quando o valor da hora for 00h ihoras1 = ihoras2 = iminutos2 = iminutos1 = 0; if((iminutos1 > 4) && (iminutos2 > 9) && (ihoras1 == 0) && (ihoras2 > 0)) // Quando o valor da hora for entre 01h até 09h ihoras2--; if((iminutos1 > 4) && (iminutos2 > 9) && (ihoras1 > 0) && (ihoras2 >= 0)) // Quando o valor da hora for entre 10h até 24h { if((ihoras1 < 2) && (ihoras2 <= 9)) // Parte 1: Valor entre 10 e 19h ihoras2--; if((ihoras1 >= 2) && (ihoras2 < 4 )) // Parte 2: Valor entre 20 e 24h ihoras2--; } } while (!input(BOTAOMINUTO)); // Só sai do loop quando o botão for solto //=================================================================================================================================================// while ((!input(BOTAOALARME)) && (buzzstatus == 1)) // Quando o botão do alarme for pressionado, entra no loop { if(!input(BOTAOHORA)) // Quando botão hora for pressionado irá incrementar as horas do alarme { ihorasalm2++; if(ihorasalm2 > 9) { ihorasalm2 = 0; ihorasalm1++; } if((ihorasalm1 == 2) && (ihorasalm2 > 3)) ihorasalm1 = ihorasalm2 = 0; while (!input(BOTAOHORA)); // Só sai do loop quando o botão for solto } if(!input(BOTAOMINUTO)) // Quando botão minuto for pressionado irá incrementar os minutos do alarme { iminutosalm2++; if(iminutosalm2 > 9) { iminutosalm2 = 0; iminutosalm1++; } if(iminutosalm1 > 5) iminutosalm1 = 0; while (!input(BOTAOMINUTO)); // Só sai do loop quando o botão for solto } output_c(CARACTERE_L); // Coloca o caractere L no display 2 dos segundos output_c(CARACTERE_L); output_bit(ATIVASEG2,0); // Ativa o display 2 dos segundos delay_ms(10); // Tempo que fica acionado o display2 output_bit(ATIVASEG2,1); // Desativa o display 2 dos segundos output_c(CARACTERE_A); // Coloca o caractere A no display 1 dos segundos output_c(CARACTERE_A); output_bit(ATIVASEG1,0); // Ativa o display 1 dos segundos delay_ms(10); // Tempo que fica acionado o display 1 dos segundos output_bit(ATIVASEG1,1); // Desativa o display 1 dos segundos iretorno = conversorbcd(iminutosalm2); // Chama função conversorbcd e valor de entrada = iminutosalm2, iretorno = iminutosalm2 convertido p BCD output_c(iretorno); // Coloca o valor que retorna da função conversorbcd na porta C output_c(iretorno); output_bit(ATIVAMIN2,0); // Ativa o display 2 dos minutos delay_ms(10); // Tempo que fica acionado o display2 output_bit(ATIVAMIN2,1); // Desativa o display 2 dos segundos iretorno = conversorbcd(iminutosalm1); // Chama função conversorbcd e valor de entrada = iminutosalm1, iretorno = iminutosalm1 convertido p BCD output_c(iretorno); // Coloca o valor que retorna da função conversorbcd na porta C output_c(iretorno); output_bit(ATIVAMIN1,0); // Ativa o display 1 dos minutos delay_ms(10); // Tempo que fica acionado o display1 output_bit(ATIVAMIN1,1); // Desativa o display 1 dos segundos iretorno = conversorbcd(ihorasalm2); // Chama função conversorbcd e valor de entrada = ihorasalm2, iretorno = ihorasalm2 convertido p BCD output_c(iretorno); // Coloca o valor que retorna da função conversorbcd na porta C output_c(iretorno); output_bit(ATIVAHORA2,0); // Ativa o display 1 das horas delay_ms(10); // Tempo que fica acionado o display1 output_bit(ATIVAHORA2,1); // Desativa o display 1 das horas iretorno = conversorbcd(ihorasalm1); // Chama função conversorbcd e valor de entrada = ihorasalm1, iretorno = ihorasalm1 convertido p BCD output_c(iretorno); // Coloca o valor que retorna da função conversorbcd na porta C output_c(iretorno); output_bit(ATIVAHORA1,0); // Ativa o display 1 das horas delay_ms(10); // Tempo que fica acionado o display1 output_bit(ATIVAHORA1,1); // Desativa o display 1 das horas } if((ihorasalm1 == 0) && (ihorasalm2 ==0) && (iminutosalm1 == 0) && (iminutosalm2 == 0)) // Se alarme = 00h00min, entra no loop { almstatus = 1; // Status do alarme e sua saída = 1, ALARME DESATIVADO output_bit(STATUSALM, almstatus); } else // Se alarme != 00h00min, entra NESTE LOOP { almstatus = 0; // Status do alarme e sua saída = 0, ALARME ATIVADO! output_bit(STATUSALM, almstatus); } if ((almstatus == 0) && (buzzstatus == 1) && (habilitaloop1 == 1) && (ihorasalm1 == ihoras1) && (ihorasalm2 == ihoras2) && (iminutosalm1 == iminutos1) && (iminutosalm2 == iminutos2)) { buzzstatus = 0; // Quando horário alarme = horário do relógio, BUZZER e sua saída = 0: BUZZER ATIVADO output_bit(BUZZER, buzzstatus); } if ((!input(BOTAOALARME)) && (buzzstatus == 0)) // Rotina para desligar o buzzzer { habilitaloop1 = 0; // Desabilita a entrada no loop da linha 332 if(habilitaloop2 != 0) { icontador++; // contador é o timer para a tecla pressionada habilitaloop2 = 0; // Desabilita a entrada nesse loop até o próximo segundo (interrupção) } if(icontador == 6) // Tempo necessário pressionando a tecla p/ desativar o buzzer { buzzstatus = 1; // Buzzer = DESATIVADO output_bit(BUZZER, buzzstatus); } } else icontador = 0; if (iminutos2 != iminutosalm2) // Habilita a entrada do loop 332 só depois que iminalm != imin relógio habilitaloop1 = 1; } }