Fork me on GitHub

07/12/12

Projeto 15: Relógio e Calendário Digital com RTC DS1307

Relógio e Calendário Digital com RTC DS1307






Esse projeto trata-se de um relógio e um calendário digital. A base de contagem do tempo é o RTC DS1307. O DS1307 na mais é do que um Relógio de Tempo Real que se comunica com o microcontrolador via I2C.


O DS1307 possui 7 registros internos destinados para a contagem dos segundos, minutos, horas, dia da semana, dia do mês, mês e ano. Esse RTC também "sabe" se é ano bissexto ou não e possui a opção de horário 24 horas ou 12 Horas (AM - PM).

Uma coisa ruim que eu acho desse DS1307 é que ele trabalha com número BCD ao invés de trabalhar com binários (que é bem mais fácil).

Ao pressionar a chave S1, altera a seleção de ajuste (segundos, minutos, ... ). A chave S2 e S3, altera o valor, incrementando-o ou decrementando-o respectivamente.



No projeto foi utilizado um Clock de 4MHz para o PIC e para o RTC foi de 32,768KHz.

DOWNLOAD:
Firmware: Clock.hex;
Arquivo de simulação do Proteus: Clock.DSN;

CÓDIGO-FONTE:
MikroC PRO PIC
sbit LCD_RS at RB4_bit;
sbit LCD_EN at RB5_bit;
sbit LCD_D4 at RB6_bit;
sbit LCD_D5 at RB1_bit;
sbit LCD_D6 at RB2_bit;
sbit LCD_D7 at RB3_bit;
sbit LCD_RS_Direction at TRISB4_bit;
sbit LCD_EN_Direction at TRISB5_bit;
sbit LCD_D4_Direction at TRISB6_bit;
sbit LCD_D5_Direction at TRISB1_bit;
sbit LCD_D6_Direction at TRISB2_bit;
sbit LCD_D7_Direction at TRISB3_bit;

unsigned short segundos, minutos, horas, semana, dia, mes, ano;
unsigned short sgs, mins, hrs, ss, dd, mm, yy;
unsigned short cnt=7;

//Função para converter BCD para string e escrever no LCD
void BcdToStr(unsigned short x, unsigned short y, unsigned short var)
{
unsigned short var1, var2;
         //var1 = (var << 4) + 0x30; //Tá errado!!!!
         var1 = (var >> 4) + 0x30; //Erro corrigido...
         Lcd_Chr(x,y,var1);
         var2 = (var & 0x0F) + 0x30;
         Lcd_Chr_CP(var2);
}

//função para ajustar o valor
void escrita_i2c(unsigned short registro, unsigned short valor)
{
     i2c1_stop(); //caso o barramento estiver ocupado envia um sinal de STOP
     i2c1_start(); // envia um sinal de START
     i2c1_wr(0xD0);  //endereço do RTC no barramento e fazer a escrita
     i2c1_wr(registro); //endereço do registro(segundos=0x00, ...)
     i2c1_wr(valor); // valor que você quer escrever
     i2c1_stop(); //envia um sinal de STOP
}

//função que daz a leitura dos dados
void leitura_i2c()
{
     i2c1_start(); // Envia um sinal de START
     i2c1_wr(0xD0); //endereço no barramento e indicação de escrita
     i2c1_wr(0x00); //endereço inicial
     i2c1_Repeated_Start(); //Restart no barramento
     i2c1_wr(0xD1); // endereço no barramento e indicação de leitura
     segundos = i2c1_rd(1); //lê o 1º endereço e informa que ira continuar a leitura
     minutos = i2c1_rd(1); //lê o 2º endereço e informa que ira continuar a leitura
     horas  = i2c1_rd(1); //lê o 3º endereço e informa que ira continuar a leitura
     semana = i2c1_rd(1); //lê o 4º endereço e informa que ira continuar a leitura
     dia = i2c1_rd(1); //lê o 5º endereço e informa que ira continuar a leitura
     mes = i2c1_rd(1); //lê o 6º endereço e informa que ira continuar a leitura
     ano = i2c1_rd(0); //lê o 7º endereço e informa que não ira mais ler
     i2c1_stop(); // envia um sinal de STOP
}

void encontrar_semana()
{
     switch(semana)
     {
         case 1: Lcd_Out(2,13,"DOMINGO");break;
         case 2: Lcd_Out(2,13,"SEGUNDA");break;
         case 3: Lcd_Out(2,13," TERCA ");break;
         case 4: Lcd_Out(2,13,"QUARTA ");break;
         case 5: Lcd_Out(2,13,"QUINTA ");break;
         case 6: Lcd_Out(2,13," SEXTA ");break;
         case 7: Lcd_Out(2,13,"SABADO ");break;
     }
}

//função que escreve no LCD qual ajuste você está fazendo
void funcao(unsigned short num)
{
      lcd_Out(1,13,"ADJ");
      switch(num)
      {
          case 0: Lcd_Out(1,17,"SGS");break;
          case 1: Lcd_Out(1,17,"MIN");break;
          case 2: Lcd_Out(1,17,"HRS");break;
          case 3: Lcd_Out(1,17,"DIA");break;
          case 4: Lcd_Out(1,17,"DATE");break;
          case 5: Lcd_Out(1,17,"MES ");break;
          case 6: Lcd_Out(1,17,"ANO");break;
          case 7: Lcd_Out(1,17,"OFF");break;
      }
}

void main()
{
bit oldstate;
    TRISD = 255;
    
    I2C1_Init( 100000 );
    
    Lcd_Init(); //inicia LCD
    Lcd_Cmd(_LCD_CLEAR); //Limpa LCD
    Lcd_cmd(_LCD_CURSOR_OFF); //desliga cursor do LCD

    funcao(7);
    while(1)
    {
       BcdToStr(1,1,horas);
       Lcd_Out_CP(":");
       BcdToStr(1,4,minutos);
       Lcd_Out_CP(":");
       BcdToStr(1,7,segundos);
       BCdToStr(2,1,dia);
       Lcd_Out_CP("/");
       BCdToStr(2,4,mes);
       Lcd_Out_CP("/");
       BCdToStr(2,7,ano);
       leitura_i2c();
       if(!PORTD.F0) oldstate=1;

       //para cada vez que pressionar o botao, altera a função de ajuste
       if(PORTD.F0 && oldstate)
       {
          cnt++;
          if(cnt==8) cnt=0;
          funcao(cnt);
          oldstate=0;
       }

       if(cnt==0)
       {
           if(PORTD.F1 && !PORTD.F2)
           {
                       sgs = Bcd2Dec(segundos); //recebe o valor, converte-o
                       sgs++; // incrementa-o
                       if(sgs==60) sgs=0;
                       escrita_i2c(0x00,Dec2Bcd(sgs)); //converte-o e escreve no RTC
           }else if(!PORTD.F1 && PORTD.F2)
           {
                      sgs = Bcd2Dec(segundos);
                      sgs--;
                      if(sgs > 0 || sgs < 59) sgs=59;
                      escrita_i2c(0x00,Dec2Bcd(sgs));
           }
      }
      else if(cnt==1)
      {
           if(PORTD.F1 && !PORTD.F2)
           {
                       mins = Bcd2Dec(minutos);
                       mins++;
                       if(mins==60) mins=0;
                       escrita_i2c(0x01,Dec2Bcd(mins));
           }else if(!PORTD.F1 && PORTD.F2)
           {
                      mins = Bcd2Dec(minutos);
                      mins--;
                      if(mins > 0 || mins < 59) mins=59;
                      escrita_i2c(0x01,Dec2Bcd(mins));
           }
      }
      else if(cnt==2)
      {
           if(PORTD.F1 && !PORTD.F2)
           {
                       hrs = Bcd2Dec(horas);
                       hrs++;
                       if(hrs==24) hrs=0;
                       escrita_i2c(0x02,Dec2Bcd(hrs));
           }else if(!PORTD.F1 && PORTD.F2)
           {
                      hrs = Bcd2Dec(horas);
                      hrs--;
                      if(hrs > 0 || hrs < 23) hrs=23;
                      escrita_i2c(0x02,Dec2Bcd(hrs));
           }
      }
      else if(cnt==3)
      {
           if(PORTD.F1 && !PORTD.F2)
           {
                       ss = Bcd2Dec(semana);
                       ss++;
                       if(ss==8) ss=1;
                       escrita_i2c(0x03,Dec2Bcd(ss));
           }
           else if(!PORTD.F1 && PORTD.F2)
           {
                      ss = Bcd2Dec(semana);
                      ss--;
                      if(ss==0) ss=7;
                      escrita_i2c(0x03,Dec2Bcd(ss));
           }
       }
       else if(cnt==4)
       {
           if(PORTD.F1 && !PORTD.F2)
           {
                       dd = Bcd2Dec(dia);
                       dd++;
                       if(dd==32) dd=1;
                       escrita_i2c(0x04,Dec2Bcd(dd));
           }
           else if(!PORTD.F1 && PORTD.F2)
           {
                      dd = Bcd2Dec(dia);
                      dd--;
                      if(dd > 1 || dd < 31) dd=31;
                      escrita_i2c(0x04,Dec2Bcd(dd));
           }
       }
       else if(cnt==5)
       {
           if(PORTD.F1 && !PORTD.F2)
           {
                       mm = Bcd2Dec(mes);
                       mm++;
                       if(mm==13) mm=1;
                       escrita_i2c(0x05,Dec2Bcd(mm));
           }
           else if(!PORTD.F1 && PORTD.F2)
           {
                      mm = Bcd2Dec(mes);
                      mm--;
                      if(mm==0) mm=12;
                      escrita_i2c(0x05,Dec2Bcd(mm));
           }
       }
       else if(cnt==6)
       {
           if(PORTD.F1 && !PORTD.F2)
           {
                       yy = Bcd2Dec(ano);
                       yy++;
                       if(yy==100) yy=0;
                       escrita_i2c(0x06,Dec2Bcd(yy));
           }
           else if(!PORTD.F1 && PORTD.F2)
           {
                      yy = Bcd2Dec(ano);
                      yy--;
                      if(yy > 0 || yy < 99) yy=99;
                      escrita_i2c(0x06,Dec2Bcd(yy));
           }
      }
      encontrar_semana();
      Delay_ms(200);
  }
}

44 comentários:

  1. Boa tarde ,montei este circuito mas não esta funcionando, gostaria que me ajudasse,coloquei um cristal externo de 4mhz mas mas se eu medir em cima dos pinos de osc ele não tem nada, e é no programa o problemas, pois gravei outro programa no pic e coloquei no mesmo circuito montado e teve oscilação do cristal ....fico no aguardo por uma ajuda...Desde já agradeço

    ResponderExcluir
    Respostas
    1. Boa tarde!! O código não interfere no funcionamento do cristal. A causas pode ser algum mau contato nos pinos ou o tipo de cristal selecionado. Na hora de gravar o pic, configure os fusiveis e selecione o cristal do tipo XT.

      Excluir
  2. Obrigado Tiago Henrique,montei funcionou certinho,era somente as configurações na hora de gravar mesmo...
    Agora estou com outro problema eu preciso colocar um PCF8563 no lugar deste DS1307 alguém saberia me ajudar no que preciso alterar no programa para que funcione com esse PCF8563?

    ResponderExcluir
    Respostas
    1. Quando li seu comentário anterior, ja comecei a fazer o programa kkkkk!!!
      Fiz ele um pouco diferente, optando por utilizar struct.



      #define PCF8563_I2C_ADDR 0xA2
      #define PCF8563_CONTROL1 0x00 //control/status 1
      #define PCF8563_CONTROL2 0x01 //control/status 2
      #define PCF8563_CLKOUT 0x0D //CLKOUT control
      #define PCF8563_TCONTROL 0x0E //timer control
      #define PCF8563_TIMER 0x0F //timer countdown value
      #define PCF8563_SECONDS 0x02 //0..59 BCD
      #define PCF8563_MINUTES 0x03 //0..59 BCD
      #define PCF8563_HOURS 0x04 //0..23 BCD
      #define PCF8563_DAYS 0x05 //1..31 BCD
      #define PCF8563_WEEKDAY 0x06 //0..6
      #define PCF8563_MONTHS 0x07 //0..12
      #define PCF8563_YEARS 0x08 //0..99 BCD
      #define PCF8563_MINUTE_ALARM 0x09 //0..59 BCD
      #define PCF8563_HOUR_ALARM 0x0A //0..23 BCD
      #define PCF8563_DAY_ALARM 0x0B //0..31 BCD
      #define PCF8563_WEEKDAY_ALARM 0x0C //0..6

      typedef struct
      {
      char year; //0..99
      char month; //1..12
      char week; //0..6
      char days; //1..31
      char hour; //0..23
      char min; //0..59
      char sec; //0..59
      }TIME_STRUCT;

      TIME_STRUCT ts = {13, 8, 1, 7, 13, 40, 0};


      void PCF8563_Init()
      {
      I2C1_Init(400000);
      I2C1_start();
      I2C1_Wr(PCF8563_I2C_ADDR);
      I2C1_Wr(PCF8563_CONTROL1);
      I2C1_Wr(0x00);
      I2C1_Wr(0x00);
      I2C1_Stop();
      }

      void PCF8563_setDate(TIME_STRUCT *Pts)
      {
      I2C1_start();
      I2C1_Wr(PCF8563_I2C_ADDR);
      I2C1_Wr(PCF8563_SECONDS);
      I2C1_Wr(Dec2Bcd(Pts->sec));
      I2C1_Wr(Dec2Bcd(Pts->min));
      I2C1_Wr(Dec2Bcd(Pts->hour));
      I2C1_Wr(Dec2Bcd(Pts->days));
      I2C1_Wr(Dec2Bcd(Pts->week));
      I2C1_Wr(Dec2Bcd(Pts->month));
      I2C1_Wr(Dec2Bcd(Pts->year));
      I2C1_Stop();
      }

      void PCF8563_getDate(TIME_STRUCT *Pts)
      {
      I2C1_start();
      I2C1_Wr(PCF8563_I2C_ADDR);
      I2C1_Wr(PCF8563_SECONDS);
      I2C1_Repeated_Start();
      I2C1_Wr(PCF8563_I2C_ADDR | 1);
      Pts->sec = Bcd2Dec(I2C1_Rd(1) & 0x7F);
      Pts->min = Bcd2Dec(I2C1_Rd(1) & 0x7F);
      Pts->hour = Bcd2Dec(I2C1_Rd(1) & 0x3F);
      Pts->days = Bcd2Dec(I2C1_Rd(1) & 0x3F);
      Pts->week = Bcd2Dec(I2C1_Rd(1) & 0x07);
      Pts->month = Bcd2Dec(I2C1_Rd(1) & 0x1F);
      Pts->year = Bcd2Dec(I2C1_Rd(0));
      I2C1_Stop();
      }

      void main()
      {
      uart1_init(9600);
      delay_ms(10);
      PCF8563_Init();
      PCF8563_setDate(&ts);

      while(1)
      {
      PCF8563_getDate(&ts);
      uart1_write((ts.hour/10) + '0');
      uart1_write((ts.hour%10) + '0');
      uart1_write(':');
      uart1_write((ts.min/10) + '0');
      uart1_write((ts.min%10) + '0');
      uart1_write(':');
      uart1_write((ts.sec/10) + '0');
      uart1_write((ts.sec%10) + '0');
      uart1_write(13);
      delay_ms(500);
      }
      }

      Excluir
    2. caso queira adicionar algum botao, ficaria assim
      if(Botao==1)//pino qualquer
      {
      PCF8563_getDate(&ts);
      ts.sec++;
      if(ts.sec>59) ts.sec = 0;
      PCF8563_setDate(&ts);
      }

      Excluir
  3. coloquei rodar esse seu programa ai e percebi que ele esta faltando a parte que faz aparecer no lcd né, e to apanhando até agora pra tentar fazer isso e não consigo kkkk, isso que da não intender praticamente nada de programação né hahaha

    ResponderExcluir
  4. Boa noite Tiago! Gostei desse relogio, estou trabalhando nele aqui, ja compilei e tudo.
    Agora quero colocar um lm 35 para ler temperatura junto com o relogio, depois vou alterar o lcd para um de 4 linhas, Não sei como colocar o codigo para o lm 35, sou novo em Mikroc, Poderia me dar uma mãozinha ai? Obrigado pelo post compartilhado com a gente.

    ResponderExcluir
    Respostas
    1. unsigned LM35_ReadTemp()
      {
      unsigned temp;
      temp = ADC_Read(0);
      temp = temp * 100 / 206;
      return temp;
      }

      Insira a função acima e habilita a biblioteca ADC.
      Use a função WordToStr para converter o valor para string, depois vc escreve no lcd.

      Excluir
  5. Boa noite.
    Estou acompanhando seu blog, e seu projeto 15 do relógio calendário,e ele é bem parecido com o projeto que eu preciso para um trabalho, só que eu precisaria acrescentar um lote e turno na programação e no display, sendo o lote com 6 dígitos e o turno alternando de 1 à 3 a cada 8hrs. LOTE:227021 OBS: 227 CORRESPONDE O DIA DO ANO , 02 NUMERO DA MAQUINA É FIXO, 1 TURNO OBS: 1 DAS 5:01 AS 13:20 , 2 DAS 13:21 AS 21:40 , 3 DAS 21:41 AS 5:00.
    Será que você poderia me ajudar?
    Desde já agradeço sua atenção, fico a disposição para qualquer esclarecimento.

    ResponderExcluir
    Respostas
    1. envie mais detalhes pro meu email: microcontrolandos2012@gmail.com

      Excluir
  6. Boa tarde,
    montei o circuito todo correto mais na hora de ligar aparece apenas ??:??: e ??/??/?? ,.... o que eu faço???

    ResponderExcluir
    Respostas
    1. O meu tb apareceu isso, eu tinha alimentado o 1307 apenas com 3v, ai coloquei 5 volts na outra entrada e funcionou

      Excluir
    2. No proteus ele só vai funcionar com 5 volts, mas no físico só suporta 3.3 volts.

      Excluir
    3. Não. De acordo com o datasheet o DS1307 suporta 5V. Veja se há mal contato, ou os resistores de pullup..

      Excluir
  7. Boa tarde!!!

    Parabéns pelo blog!!!

    Estou acompanhando seu blog, e seu projeto 15 do relógio calendário,e ele é bem igual com o projeto que eu preciso para um trabalho de facull, mas ele tem que funcionar com o nokia 6610, alguém pode me ajuda? Minha duvida esta nesta parte do BCD...


    //Função para converter BCD para string e escrever no LCD
    void BcdToStr(unsigned short x, unsigned short y, unsigned short var){
    unsigned short var1, var2;
    var1 = (var >> 4) + 0x30;
    Lcd_Chr(x,y,var1);
    var2 = (var & 0x0F) + 0x30;
    Lcd_Chr_CP(var2);
    }

    ResponderExcluir
  8. CARLOS
    Olá sou novo por aqui gostaria de saber se tem como fazer este relógio com o pic16f628?

    ResponderExcluir
    Respostas
    1. Tem sim. Voce terá que usar a biblioteca Soft_I2C para fazer a comunicacao com o DS1307.

      Excluir
  9. Gostei muito do post. O seu blog é um guia de referência quando o assunto é mikroc. Como faço pra ele armazenar a hora e data atual quando for desligado ou a energia elétrica faltar, pois mesmo com a bateria isto não está acontecendo, sempre que ele é reiniciado a hora que ele mostra é a hora acertada na programação, aí tem que acertar toda vez que religá-lo.

    Muito obrigado.

    ResponderExcluir
    Respostas
    1. O problema era no código...retirei a função "programa_i2c()". Esta funcao resetava os valores do RTC sempre que o pic era ligado.
      Abraços.

      Excluir
    2. Tiago, eu já havia comentado esta função pra ver se o programa continuava a atualizar a hora mesmo depois de desligado, porém, percebi que sem ela o programa não roda. Na simulação se percebe que o rtc atualiza, mas o display fica congelado, as teclas não funcionam, fica tudo travado, testei também na bancada e acontece o mesmo.

      Excluir
    3. alem de ter comentada a funcao, tinha que inicializar o modulo I2C: "I2C1_Init(100000)".

      Excluir
  10. Como eu acho o componente l2C no proteus? Como está o nome dele lá?

    ResponderExcluir
    Respostas
    1. Na barra lateral esquerda, localize o botao "Virtual Instruments Mode" e selecione "I2C Debugger"

      Excluir
  11. Meu mikroC Alega que o termo Bdc2Dec não foi declarado quando coloco esse programa. Te alguma idéia de qual seja o problema?

    ResponderExcluir
    Respostas
    1. Voce habilitou a biblioteca Conversions? Tente isso. Tome cuidado tbm na escrita, o certo é "Bcd2Dec"

      Excluir
    2. Sim, todas as bibliotecas estão ativadas, e no programa esta escrito correto!
      se eu busco no help "Bcd2Dec" não encontra, encontra apenas o "Dec2Bcd"

      Excluir
    3. li que pode ser algo do mikroc "pro", vou tentar arranjar outro. =/

      Excluir
  12. Boa noite Tiago sou Osmar e preciso de um programa usando ds1307 só que tem que ser feito com o Source Boost IDE criado na linguagem boost C onde mostra a data e as horas em um display lcd 16x2
    onde eu troco a hora e os dias com botões.
    Ti agradeço desde agora.

    ResponderExcluir
  13. Bom Dia Thiago!

    Montei esse circuito no Proteus mas o LCD fica congelado, oque pode ser?

    ResponderExcluir
    Respostas
    1. Verifique se você colocou os resistores de pull-up nas linhas SCL e SDA.

      Excluir
    2. Ainda continua travado, poderia me passar o aquivo do MickroC do projeto e o compilado agradeco, bruno.ruinho@gmaill.com

      Excluir
  14. Olá Tiago, primeiramente parabéns pelo blog, e gostaria de saber se você tem algum projeto (ou mesmo o código fonte para este projeto) para acionamento semanal, pois preciso acionar um motor uma vez por semana e com controle do horário e do dia da semana, para um silo para secagem de milho. Você teria alguma coisa que me atenda?

    OBS: Não entendo muito de programação.

    Desde já muito obrigado

    ResponderExcluir
  15. Tentei simular no Proteus 8.1 e está ficando com display parado, não faz ajuste em nenhum botão. Usei o clock.hex. Alguém sabe o que está acontecendo?

    ResponderExcluir
    Respostas
    1. Compila o fonte na sua maquina que funciona, não esqueça de corrigir a função para converter o bcd, o correto é deslocar os bits para a direita e não para a esquerda como está.

      Excluir

  16. bom dia Tiago,
    Eu consegui compilar seu projeto do relógio calendário com ds1307 para PIC16f877a modifiquei os comandos I2c1 para I2C porque o compilador não aceitou I2C1....acho que é porque o pic16f877a só tem um HD I2c não é isso ?
    e alterei o config do LCD
    Compílou mas acredito que o barramento I2C não funciona porque mostra no lcd ? : ? : ? ?/ ?/ ? pode me ajudar ?
    Eu vi os pulsos no barramento I2C aparente mente esta ok , alimentei o vbat com 3,0 vdc , resitor de pull up de 2K2 no barramento I2C , xt no pic 4 MHZ e 32768 no rtc

    ResponderExcluir
  17. Na função de conversão de BCD possui um erro no deslocamento dos bits.

    void BcdToStr(unsigned short x, unsigned short y, unsigned short var)
    {
    unsigned short var1, var2;
    var1 = (var << 4) + 0x30; Linha com erro, o correto seria deslocar para direita.
    Lcd_Chr(x,y,var1);
    var2 = (var & 0x0F) + 0x30;
    Lcd_Chr_CP(var2);
    }

    Função corrigida:

    void BcdToStr(unsigned short x, unsigned short y, unsigned short var)
    {
    unsigned short var1, var2;
    var1 = (var >> 4) + 0x30; Linha Corrigida, deslocando para direita
    Lcd_Chr(x,y,var1);
    var2 = (var & 0x0F) + 0x30;
    Lcd_Chr_CP(var2);
    }

    ResponderExcluir
  18. Boa noite Tiago, em primeiro lugar, deixo os parabéns pelas matérias, muito boas, sempre busco informações em seu blog, estou utilizando um 18F4520 e quando compilo o código fonte na versão 6.6.1 ele me da o seguinte erro "15 393 'ss' Identifier redefined" da linha "unsigned short sgs, mins, hrs,ss, dd, mm, yy;" referenciando para SS, será que tenho que mudar alguma linha de código para este micro, na simulação o display fica stop e não aceita configuração, obrigado.

    ResponderExcluir
  19. Tiago, você poderia me ajudar a fazer um software para gerenciar um equpamento? Você é de qual estado? Se tiver, eu pago pela ajuda. Um abraço.

    ResponderExcluir
  20. precisava do mesmo código e do programa para fazer um relogio digital, porém utilizando matriz de led. alguem poderia ajudar??

    ResponderExcluir
  21. Como eu uso esse código com o arduino?
    Estou fazendo esse relogio RTC para um projeto da faculdade porém o professor exige que seja com o microcontrolador atmega328p(arduino) essa programão é para pic e não consegui arruma-la para arduino, tem como ajudar?

    ResponderExcluir

Postagens Relacionadas!!