desktop

Reloj con DS1307 no arranca en la práctica

Como hacer para que cuando enciendan el pic saber si el reloj ya esta trabajando(ya configurado) por que si hay un apagon el pic configurara una hora que no es y cuando regresen de vacaciones. ?
Alimenta al DS1307 con una pila de botón.

una pregunta tonta.. cuando configuro el rtc, para escribir los segundos, minutos, etc, es decir sus registros, tengo que enviar los datos en binario y cuando los leo están en bcd???... o yo le envio datos en bcd(al reloj) y el me envia datos en bcd. ???????
Todo debe estar en BCD. Consulta la página 8 de la hoja de datos.

como hago para comparar 2 números en bcd ?. O sera que tengo que llevar ese bcd a binario para comparar después??
Exactamente igual que si fuera en binario, pero es más claro si en tu programa escribes los números constantes en hexadecimal. Por ejemplo, para escribir 12 en BCD sería H'12'.
 
Última edición por un moderador:
Gracias a todos por su ayuda me ayudo a comprender un poco mas la cosa.. ya pude lograr hacer funcionar perfectamente mi codigo.. ahora no lo veo como cosa de otro mundo jajjaj..

Gracias
 
¿Qué tal compañeros? Necesito de su ayuda.

Les explico:
Estoy haciendo un reloj digital con un DS1307, y pues todo va bien hasta este código:

Código:
#include <16F887.h>
#fuses NOWDT,NOBROWNOUT,INTRC,NOPUT,NOWRT,NOPROTECT,NOLVP
#use delay(clock=4000000)
//#use rs232(baud=1200,xmit=pin_c6, rcv=pin_c7, bits=8)
#include <LCD.c>
#BYTE TRISA=0X85
#BYTE PORTA=0X05
#use fast_io(A)
#use fast_io(B)
#use fast_io(C)                     ///   con esta instruccion evitamos que
//#use fast_io(D)                     ///   se este configurando cada vez que usamos
//#use fast_io(E)                     ///   alguna instruccion de entrada o salida
#byte portc = 0x07                     /// se definen direcciones de memoria
#byte portd = 8
#include "ds1307.c"     // Funciones usadas para acceder a los registros del DS1307

// Variables usadas:
//float valor_=80,valor2_=80,dat_in;
//float valor1f_,valor2f_;
int sec, min, hrs;
char nombre[10];

      void main() {
         ds1307_init (DS1307_OUT_32_KHZ);//ds1307_init (DS1307_OUT_ENABLED |  DS1307_OUT_32_KHZ);      ///se inicializa el ds1307
         bit_clear(TRISA,0);
//         port_b_pullups (true) ;
         enable_interrupts(INT_RDA);
         set_tris_B(0x00);
         set_tris_A(0x00);
         portA=0x00;
         set_tris_c (0x18) ;    // PIN_C4 Como entrada
//         set_tris_d (0x00) ;
         enable_interrupts(GLOBAL);
         lcd_init();
         ds1307_set_date_time (16, 01, 15, 4, 17, 19, 00); /// se escribe en el dispositivo
         /// la hora deseada
         WHILE(1) {
                  if((hrs==00)&&(min==00)&&(sec==00)){
                     lcd_init();
                     }
                  delay_ms (150) ;
                  ds1307_get_time (hrs, min, sec);   /// se obtiene la hora
                  ds1307_get_day_of_week(nombre);
                  lcd_gotoxy (1,1) ;
                  lcd_putc("Time:");
                  lcd_gotoxy (7,1);
                  printf(lcd_putc,"%02u:%02u:%02u",hrs,min,sec);
                  lcd_gotoxy (2,2);
                  printf(lcd_putc,"%s",nombre);
                  delay_ms(100);
                
                }               
          }
Se supone que de esa forma ya configuras el DS1307
Ya tiene el cristal y ya tiene la batería de 3.3V.
Y pues para que no se reconfigure el reloj con los valores que tiene el PIC cada vez que lo conecto de nuevo, pues apago el PIC y lo reprogramo.
Es el mismo código, solo que le quito la siguiente linea:

ds1307_set_date_time (16, 01, 15, 4, 17, 19, 00); /// se escribe en el dispositivo
/// la hora deseada


Y cuando lo vuelvo a conectar, pues el reloj no sigue funcionando, aparece otra fecha y hora, es como si se hubiera reseteado.

¿Qué puedo hacer para no tener ese problema?
 
Última edición por un moderador:
si se te resetea cuando le sacas la alimentacion del micro es porque no se esta alimentando de la pila externa, o capaz la pila externa no tiene carga, medila y fijate si tiene el minimo voltaje que necesita el reloj
 
pues no se a ciencia cierta si se resetea, o al menos no lo creo porque la bateria es nueva de 3.1v, pero bueno te diré que es lo que pasa, yo primero cargo un programa con la hora y fecha por decir la hora actual, ya que veo que lo despliega en pantalla, apago el pic, quito la linea que en mensajes anteriores describí, vuelvo a programar el pic, y pues ya aparece 00:00 martes, no logro entender porque pasa esto, voy a checar lo de la bateria, o alguna otra cosa que este pasando por alto, o si quitando esa linea se supone deberia estar funcionando el reloj perfectamente??
 
yo te pasaria un codigo pero esta en c18, y uso visual studio para configurar la hora y mostrarla, trata de hacer un programa en el que cuando inicies te muestre la hora y fecha y que tenga una opcion para configurar la hora. es decir cuando inices que te muestre la hora y tener la opcion de que si queres cambiarle la hora. yo los problemas que tenia era que si o si necesitas modificarle un dato al reloj para que ande y luego mantiene esa hora o fecha si tiene la pila puesta. proba si la polaridad de la pila corresponde a la del ds, por ahi tenes la pila al reves. otra no se me ocurre.

if((hrs==00)&&(min==00)&&(sec==00)){
lcd_init();
}
esta linea que tenes dice que si la hora es 00:00:00 ahi inicia el lcd? si tiene otra hora no la inicia??
 
esa linea la puse por el hecho de que cuando cambia de dia puede que el dia siguiente sea nombre mas corto y al cambiar de dia pasaría esto,

son las :
11:59
Miercoles

cambia a las:
00:00
juevesles

por eso inicio la pantalla a las 00:00 de todos los dias para que no haya problemas con la impresión
 
ok. otra se me ocurre que hagas un paso a paso en el proteus, armas el circuito y en vez de cargar el archivo .hex carga el archivo .cof inicia la simulacion en pausa y vas paso a paso viendo que hace tu codigo, en la barra de menu esta debug ahi tenes varias opciones, ver paso a paso el codigo tambien como se van modificando los registros. y si no bueno suerte jaja
 
despues de varios pruebas descubrí que es la bateria, aunque la bateria es de 3.2 v, tiene una caida de voltaje algo notable cuando se apaga el circuito, pero al conectarla con una fuente de 3.3v el reloj funcionó correctamente sin problemas
 
Buenos días compañeros:

Mi problema con el DS1307 no es para que arranque sino para que guarde el día del mes, los demás datos como hora, mes, año permanecen intactos al retirar la alimentación de 5V.

He intentado de todo: revisé las resistencias pull-up, medir el voltaje de la batería, cambiar el integrado y cambiar la librería pero todas dan el mismo problema. ¿Alguien lo ha tenido?

Adjunto código y librería:

CÓDIGO DEL PIC
Código:
#include <16F873.h>
#fuses XT,NOWDT,NOPROTECT
#use delay(clock=4000000)
#BYTE TRISD=0x88
#BYTE PORTD=0x08
#include <math.h> 
#include <ds1307todopic.c>
#use i2c(Master,slow,sda=PIN_C4,scl=PIN_C3)
byte day=31;
byte dow=7;
byte year=15;
byte mth=12;
byte hr=23;
byte prehr=0,min=59,copia=0, TIMESET=0;
byte contaseg=0, estado=1,mipre=0,uni=0,dec=0,buni=0,bdec=0,grup1=0,grup2=0,lectoconta=0, daycarrier=0;
byte sec=0;
int1 turnseg=0,setling=0,leeds=0;
byte const num[10]={238,6,220,158,54,186,250,14,254,62};
#define DATA      PIN_A1    
#define CLOCK     PIN_A0
#define RAYA      PIN_C1
#define SEGUNDERO PIN_C0
#define HAB1      PIN_C2
#define HAB2      PIN_C5
#define HAB3      PIN_C6
#define HAB4      PIN_C7
#define TS        PIN_B0
#define MINSET    PIN_B2
#define HORASET   PIN_B1
#define DIASET    PIN_B3
#define SETMES    PIN_B4
#define ANOSET    PIN_B5
#define AM        PIN_B6
#define PM        PIN_B7
//#define DEBUG3    PIN_C3
//#define DEBUG4    PIN_C4

void escribir(int8 aux){ ////////FUNCION ESCRIBIR PARA LOS REGISTROS DE DESPLAZAMIENTO
   int i;
   for(i=0;i<8;i++)
    {
      if(bit_test(aux, i)==0)
      {
         output_low (DATA);
         output_low (CLOCK);
         output_high(CLOCK);
      }
      if(bit_test(aux,i)==1)
      {
         output_high(DATA);
         output_low (CLOCK);
         output_high(CLOCK);
      }
   }
} ///////////////////////////////FIN DE FUNCION ESCRIBIR

void bin_bcd(){ /////////////////SEPARA LOS DATOS PARA IMPRIMIR
  if (hr==0){
  prehr=12;
  output_low (PM); //PM OFF
  output_high (AM);   //AM ON
  }
  else if (hr==12){
  prehr=hr;
  output_low (AM); // AM OFF
  output_high (PM);   //PM ON
  }
  else if (hr>12){
  prehr=hr-12;
  output_low (AM); // AM OFF
  output_high (PM);   //PM ON
  }
  else{
  prehr=hr;
  output_low (PM); //PM OFF
  output_high (AM);   //AM ON
  }
if (TIMESET==1){
grup2=20;
grup1=year;
}
if ((TIMESET==2)||(estado==2)){
grup2=day;
grup1=mth;
//grup1=daycarrier;
}
if ((TIMESET==3)||(estado==1)){
grup2=prehr;
grup1=min;
}
      copia=grup1;
      dec= copia/10;
      copia= copia%10;
      uni=copia;
      copia=grup2;
      bdec= copia/10;
      copia= copia%10;
      buni=copia;  
}   

void mostrar(){
   bin_bcd();
   output_low(HAB4);
   escribir(num[uni]);
   output_high(HAB1);
   if (leeds==0){
   delay_ms(2);
   }
   if (leeds==1){
   ds1307_get_date(day,mth,year,dow);
   }
   output_low(HAB1);
   output_low(HAB2);
   output_low(HAB3);
   output_low(HAB4);
   escribir(num[dec]);
   delay_us(10);
   output_high(HAB2);
   if (leeds==1){
   ds1307_get_time(hr,min,sec);
   leeds=0;
   }
   if (leeds==0){
   delay_ms(2);
   }
    output_low(HAB1);
   output_low(HAB2);
   output_low(HAB3);
   output_low(HAB4);
   escribir(num[buni]);
   delay_us(10);
   output_high(HAB3);
   delay_ms(2);
   if((bdec>0))
   {
      output_low(HAB1);
      output_low(HAB2);
      output_low(HAB3);
      output_low(HAB4);
      escribir(num[bdec]);
      delay_us(10);
      output_high(HAB4);
      delay_ms(2);
   }
   else
   {
      output_low(HAB1);
      output_low(HAB2);
      output_low(HAB3);
      output_low(HAB4);
      delay_ms(2); 
   }
 
}
#INT_TIMER1
void temp1_isr() {
      disable_interrupts(INT_TIMER1);
      if (mipre==2){
      turnseg=!turnseg;
      mipre=0;

      }
      if (contaseg==20){
      contaseg=0;
      estado++;
      }
      if (estado>2){
      estado=1;
      }
      if (lectoconta==0){
      lectoconta=20;
      leeds=1;
      }
      contaseg++;
      mipre++;
      lectoconta--;
      set_timer1(3036);
      enable_interrupts(INT_TIMER1);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
void main(){ //INICIO DEL PROGRAMA
      set_tris_C(0b00000000);
      PORTD=0b00000000;
      delay_ms(1000);
      disable_interrupts(global);
      output_low (SEGUNDERO);
      output_low (RAYA);
      ds1307_init(DS1307_ALL_DISABLED); //INICIALIZACIÓN DEL DS1307
      setup_timer_1(T1_INTERNAL|T1_DIV_BY_4);
      set_timer1(3036);
      disable_interrupts(INT_TIMER1);
      ds1307_get_date(day,mth,year,dow);//LECTURA INICIAL
      ds1307_get_time(hr,min,sec);      //LECTURA INICIAL
      enable_interrupts(GLOBAL);
      enable_interrupts(INT_TIMER1);

while (1){
mostrar();
if (input(TS)==0){
 while (input(TS)==0){
 mostrar();
 }
 TIMESET++;
 if (TIMESET>3){
 TIMESET=0;
 }
 }

if (TIMESET>0){ ///INICIO DEL DE LA CONFIGURACIÓN DEL TIEMPO
       disable_interrupts(INT_TIMER1);
       setling=1;
       estado=0;
       leeds=0;
       if (TIMESET==1){
       output_low(SEGUNDERO);
       output_low(RAYA);
       }
       if (TIMESET==2){
       output_high (RAYA);
       output_low  (SEGUNDERO);
       }
       if (TIMESET==3){
       output_high (SEGUNDERO);
       output_low  (RAYA);
       }
       if ((input(HORASET)==0)&&(TIMESET==3)){//INICIO CONFIGURACION DE LA HORA
           while(input(HORASET)==0){
           mostrar();}
            if (hr>=23){
               hr=0;
            }
            else{
               hr++;
            }   
       }//////////////////FINAL CONFIGURACIÓN DE LA HORA   
       if((input(MINSET)==0)&&(TIMESET==3)){ //INICIO CONFIGURACIÓN DE LOS MINUTOS
         while(input(MINSET)==0){
         mostrar();}
            if (min>=59){
               min=0;
            }
            else{
               min++;
            }
         } //////////////////FINAL CONFIGURACIÓN DE LOS MINUTOS 
    if ((input(DIASET)==0)&&(TIMESET==2)){//////INICIO CONFIGURACION DEL DÍA
      while(input(DIASET)==0){
      mostrar();
      }
         if (mth==1||mth==3||mth==5||mth==7||mth==8||mth==10||mth==12){
            if(day>=31){
               day=1;
            }
            else{
               day++;
            }
         }
         else if (mth==4||mth==6||mth==9||mth==11){
            if(day>=30){
               day=1;
            }
            else{
               day++;
            }
         }
         else if (mth==2){
            if(year==16||year==20||year==24||year==28||year==32||year==36||year==40||year==44){
               if (day==29){
                  day=1;
               }
               else{
                  day++;
               }
            }
            else if (day==28){
                 day=1;
                
            }
            else{
                 day++;
            
            }
      }
  }//////////////////////////FINAL DE CONFIGURACIÓN DEL DÍA
   if ((input(SETMES)==0)&&(TIMESET==2)){////INICIO DE CONFIGURACIÓN DEL MES
         while(input(SETMES)==0){
         mostrar();
           }
         if (mth>=12){
               mth=1;
            }
            else{
               mth++;
            }
        } //////////////////FIN DE CONFIGURACIÓN DEL MES
  
  if ((input(ANOSET)==0)&&(TIMESET==1)){///INICIO CONFIGURACION DEL AÑO
         while(input(ANOSET)==0){
         mostrar();
         }
         if (year>=99){
            year=1;
           }
            else{
               year++;
               }
      }//////////////////////FINAL DE CONFUGURACIÓN DEL AÑO
         
}////////////////////////////FINAL DEL CICLO IF DE LA CONFIGURACIÓN DEL TIEMPO
if ((TIMESET==0)&&(setling==1)){
setling=0;
sec=0;
daycarrier=day;
delay_ms(200);
ds1307_set_date_time(day,mth,year,dow,hr,min,sec);
delay_ms(200);
estado=1;
set_timer1(3036);
enable_interrupts(INT_TIMER1);
}

  if (TIMESET==0){
  if ((estado==1)&&(turnseg==1)){
  output_high(SEGUNDERO);
  }
  else {
  output_low (SEGUNDERO);
  }
  if (estado==2){
  output_high (RAYA);
  }
  else{
  output_low (RAYA);
  }
  }
 }
}//FINAL DEL PROGRAMA

LIBRERÍA
Código:
///////////////////////////////////////////////////////////////////////////////////////
///                               DS1307.C                                           ///
///                     Driver for Real Time Clock                                   ///
///                     modified by Redpic 08/2006                                   ///
///                  http://picmania.garcia-cuervo.com                               ///
///                                                                                  ///
/// void ds1307_init(val)                                                            ///
///                  - Enable oscillator without clearing the seconds register       ///
///                    used when PIC loses power and DS1307 run from 3V BAT          ///
///                  - Config Control Register with next parameters:                 ///
///                     DS1307_ALL_DISABLED          All disabled                    ///
///                     DS1307_OUT_ON_DISABLED_HIHG  Out to Hight on Disable Out     ///
///                     DS1307_OUT_ENABLED           Out Enabled                     ///
///                     DS1307_OUT_1_HZ              Freq. Out to 1 Hz               ///
///                     DS1307_OUT_4_KHZ             Freq. Out to 4.096 Khz          ///
///                     DS1307_OUT_8_KHZ             Freq. Out to 8.192 Khz          ///
///                     DS1307_OUT_32_KHZ            Freq. Out to 32.768 Khz         ///
///                                                                                  ///
///                     Example init:                                                ///
///                     ds1307_init(DS1307_ALL_DISABLED);                            ///
///                     ds1307_init(DS1307_OUT_ENABLED | DS1307_OUT_1_HZ);           ///
///                                                                                  ///
/// void ds1307_set_date_time(day,mth,year,dow,hour,min,sec) - Set the date/time     ///
///                                                                                  ///
/// void ds1307_get_date(day,mth,year,dow)                   - Get the date          ///
///                                                                                  ///
/// void ds1307_get_time(hr,min,sec)                         - Get the time          ///
///                                                                                  ///
/// char ds1307_read_nvram_byte(char addr)                   - Read byte in address  ///
///                                                                                  ///
/// void ds1307_write_nvram_byte(char addr, char value)      - Write byte in address ///
///                                                                                  ///
/// void ds1307_get_day_of_week(char* ptr)                   - Get string Day Of Week///
///                                                                                  ///
/// If defined USE_INTERRUPTS all functions disable Global Interrupts on starts and  ///
///                           enable Global on ends else usar can do it hiself       ///
///                                                                                  ///
///////////////////////////////////////////////////////////////////////////////////////

#ifndef RTC_SDA
#define RTC_SDA  PIN_C4
#define RTC_SCL  PIN_C3
#endif

#use i2c(master, sda=RTC_SDA, scl=RTC_SCL)

#define DS1307_ALL_DISABLED         0b00000000 // All disabled
#define DS1307_OUT_ON_DISABLED_HIHG 0b10000000 // Out to Hight on Disable Out
#define DS1307_OUT_ENABLED          0b00010000 // Out Enabled
#define DS1307_OUT_1_HZ             0b00000000 // Freq. Out to 1 Hz
#define DS1307_OUT_4_KHZ            0b00000001 // Freq. Out to 4.096 Khz
#define DS1307_OUT_8_KHZ            0b00000010 // Freq. Out to 8.192 Khz
#define DS1307_OUT_32_KHZ           0b00000011 // Freq. Out to 32.768 Khz

#define Start_user_address_nvram    0x08
#define End_user_address_nvram      0x3f

char days_of_week[7][11]={"Lunes\0","Martes\0","Miércoles\0","Jueves\0","Viernes\0","Sábado\0","Domingo\0"};

byte ds1307_bin2bcd(byte binary_value);
byte ds1307_bcd2bin(byte bcd_value);

void ds1307_init(int val){

   byte seconds = 0;

#ifndef USE_INTERRUPTS
   disable_interrupts(global);
#endif

   i2c_start();
   i2c_write(0xD0);
   i2c_write(0x00);
   i2c_start();
   i2c_write(0xD1);
   seconds = ds1307_bcd2bin(i2c_read(0));
   i2c_stop();
   seconds &= 0x7F;

   delay_us(3);

   i2c_start();
   i2c_write(0xD0);
   i2c_write(0x00);
   i2c_write(ds1307_bin2bcd(seconds));
   i2c_start();
   i2c_write(0xD0);
   i2c_write(0x07);
   i2c_write(val);
   i2c_stop();

#ifndef USE_INTERRUPTS
   enable_interrupts(global);
#endif

}

void ds1307_set_date_time(byte day, byte mth, byte year, byte dow, byte hr, byte min, byte sec){

#ifndef USE_INTERRUPTS
   disable_interrupts(global);
#endif

  sec &= 0x7F;
  hr &= 0x3F;

  i2c_start();
  i2c_write(0xD0);
  i2c_write(0x00);
  i2c_write(ds1307_bin2bcd(sec));
  i2c_write(ds1307_bin2bcd(min));
  i2c_write(ds1307_bin2bcd(hr));
  i2c_write(ds1307_bin2bcd(dow));
  i2c_write(ds1307_bin2bcd(day));
  i2c_write(ds1307_bin2bcd(mth));
  i2c_write(ds1307_bin2bcd(year));
  i2c_stop();

#ifndef USE_INTERRUPTS
   enable_interrupts(global);
#endif

}

void ds1307_get_date(byte &day, byte &mth, byte &year, byte &dow){

#ifndef USE_INTERRUPTS
   disable_interrupts(global);
#endif

  i2c_start();
  i2c_write(0xD0);
  i2c_write(0x03);
  i2c_start();
  i2c_write(0xD1);
  dow  = ds1307_bcd2bin(i2c_read() & 0x7f);
  day  = ds1307_bcd2bin(i2c_read() & 0x3f);
  mth  = ds1307_bcd2bin(i2c_read() & 0x1f);
  year = ds1307_bcd2bin(i2c_read(0));
  i2c_stop();

#ifndef USE_INTERRUPTS
   enable_interrupts(global);
#endif

}

void ds1307_get_time(byte &hr, byte &min, byte &sec){

#ifndef USE_INTERRUPTS
   disable_interrupts(global);
#endif

  i2c_start();
  i2c_write(0xD0);
  i2c_write(0x00);
  i2c_start();
  i2c_write(0xD1);
  sec = ds1307_bcd2bin(i2c_read() & 0x7f);
  min = ds1307_bcd2bin(i2c_read() & 0x7f);
  hr  = ds1307_bcd2bin(i2c_read(0) & 0x3f);
  i2c_stop();

#ifndef USE_INTERRUPTS
   enable_interrupts(global);
#endif

}


char ds1307_read_nvram_byte(char addr){

   char retval;

#ifndef USE_INTERRUPTS
   disable_interrupts(global);
#endif

   i2c_start();
   i2c_write(0xD0);
   i2c_write(addr);

   i2c_start();
   i2c_write(0xD1);
   retval = i2c_read(0);
   i2c_stop();

   return(retval);

#ifndef USE_INTERRUPTS
   enable_interrupts(global);
#endif

}

void ds1307_write_nvram_byte(char addr, char value){

#ifndef USE_INTERRUPTS
   disable_interrupts(global);
#endif

   i2c_start();
   i2c_write(0xD0);
   i2c_write(addr);
   i2c_write(value);
   i2c_stop();

#ifndef USE_INTERRUPTS
   enable_interrupts(global);
#endif

}

void ds1307_get_day_of_week(char* ptr){

   byte lday;
   byte lmonth;
   byte lyr;
   byte ldow;
   ds1307_get_date(lday,lmonth,lyr,ldow);
   sprintf(ptr,"%s",days_of_week[ldow]);
}

///////////////////////////////////////////////////////////////////////////////

byte ds1307_bin2bcd(byte binary_value){

  byte temp;
  byte retval;

  temp = binary_value;
  retval = 0;
  while(1){
    if(temp >= 10){
      temp -= 10;
      retval += 0x10;
    }else{
      retval += temp;
      break;
    }
  }
  return(retval);
}

byte ds1307_bcd2bin(byte bcd_value){

  byte temp;

  temp = bcd_value;
  temp >>= 1;
  temp &= 0x78;
  return(temp + (temp >> 2) + (bcd_value & 0x0f));
}

Saludos y gracias.
 
Hola, no he revisado minuciosamente tu código pero lo que puede estar pasando es que estés confundiendo entre los dos registros de día que tiene el DS1307: uno para el día como tal 1:30-31 y otro para el día de la semana 1-7.

Código:
i2c_start();
  i2c_write(0xD0);
  i2c_write(0x00);
  i2c_write(ds1307_bin2bcd(sec));
  i2c_write(ds1307_bin2bcd(min));
  i2c_write(ds1307_bin2bcd(hr));
  i2c_write(ds1307_bin2bcd(dow));
  i2c_write(ds1307_bin2bcd(day));
  i2c_write(ds1307_bin2bcd(mth));
  i2c_write(ds1307_bin2bcd(year));
  i2c_stop();

El código pasado lo copié de la librería, allí está la variable "dow" (day of week) y la otra "day".

Por cierto, veo que usas muchas sentencias "if" para ajustar los datos del RTC, esto no es necesario pues la misma lógica del integrado corrige los contadores.

Saludos compañero.
 
Hola que tal? Primero que nada, gracias por tu respuesta.

Lo de la variable día de la semana (dow, en el driver) no creo que sea lo que suceda porque mando a imprimir es day, día del mes.

Estuve preguntando en otros foros y en el de CCS me comentaron que un problema puede ser que estoy usando las mismas variables locales del driver como globales.

Lo que me extraña es que en todos los códigos que he visto, lo realizan así.

Sigo buscando soluciones.

Saludos!
 
Hola! Antes que nada soy nuevo en este foro y me gustaría que supieran que es simplemente fenomenal tanto conocimiento colectivo, realmente me impresiona todo esto y ciertamente aquí se aprende con solo pasearse un momento.

Luego de lo anterior quisiera que me ayudasen con algo. Soy un estudiante y no domino del todo el lenguaje C así que pido paciencia.

Para obtener la nota de periodo en mi instituto debemos realizar un proyecto, he elegido un reloj calendario utilizando un DS1307 y un pic 16f876a así que me conseguí el proyecto en internet y decidí realizarlo. El problema está en que simulé todo en proteus y me salió, pero cuando lo armé en la protoboard no me apareció nada. No se si el problema está en el programa ya que he armado el circuito 3 veces ya y como aparece en el proteus y nada, solo aparecen dos lineas.

Les ruego encarecidamente que me ayuden. Adjunto los programas, librería el esquema y una foto para que vean lo que me aparece. Espero que puedan ayudar y de antemano se los agradezco.
 

Adjuntos

  • reloj.rar
    161.1 KB · Visitas: 34
Última edición:
El problema está en que simulé todo en proteus y me salió, pero cuando lo armé en la protoboard no me apareció nada.
No sé si el problema está en el programa ya que he armado el circuito 3 veces ya y como aparece en el proteus y nada, sólo aparecen dos líneas.
Si ya revisaste todo y mencionas que lo has armado 3 veces, seguramente el PIC o la pantalla están dañados, porque armé el circuito que subiste, y si funciona.
Aquí una foto del circuito "funcionando": DSC00114.JPG

Tiene problemas con el formato de las horas, pero al menos podrás ver que si se muestran datos.

Primero verifica que puede estar dañado o mal conectado y después corrige el problema del formato.

Algo por lo que puedes empezar a revisar, son las conexiones de la pantalla.

Suerte.
 
D@rkbyte, gracias por atenderme. Lo he vuelto a armar y nada. Revisé las conexiones y todas están como debería, lo revisé 3 veces con lentitud y calma.

He visto la imágen y puedo notar que utilizas un capacitor y dos resistencias en el pin 3 del ds1307, ademas de un cristal pequeño. Yo utilizo un cristal de 4MHz para el ds y no pongo el capacitor ni las resistencias. Además quisiera saber de cuanto son las resistencias que le pusiste al pin 5 y 6 del ds.

Como te dije lo estoy haciendo exactamente igual a la simulación y no se si los valores de los elementos que uso influyan grandemente en el funcionamiento del reloj. Lo unico que me falta por verificar es el pic y el LCD.

Gracias por tu ayuda.
 
Yo utilizo un cristal de 4MHz para el ds y no pongo el capacitor ni las resistencias.
El DS1307 usa un cristal de 32768 Hz. (32.768 KHz.) No uno de 4 MHz.

DS1307 Pin Assignment.jpg
Las resistencias pull-up son necesarias porque se usa comunicación I2C.
DS1307 Typical Operating Circuit.jpg
Además quisiera saber de cuanto son las resistencias que le pusiste al pin 5 y 6 del ds.
Son de 4.7 KΩ y son las que en el esquema se muestran como RPU (Resistencias Pull-Up)
El capacitor que usé es de 100 nF. (Opcional) Lo puse en el pin 3 (VBat) y también una batería de Li-Ion

Te recomiendo que siempre leas la hoja de datos de cada componente que llegues a usar.

DS1307 Datasheet

Suerte.
 
Necesito ayuda. Mi proyecto hace que al tener un 0 en el pin RB0, encienda un led y viceversa.
Por otro lado, incorpora un driver para el manejo I2C de un DS1307.
Resulta que detecta bien el pin RB0, si no pongo ninguna función del driver.
Si pongo la función ds1307_init() ya no atiende el pin RB0:confused: , si añado las demás funciones, trabaja bien el DS1307, pero me queda deshabilitada la detección input.

Adjunto el driver, programa y simulación en Proteus.
PHP:
/////////////////////////////////////////////////////////////////////////////// 
///                               DS1307.C                                   /// 
///                     Driver for Real Time Clock                           /// 
///                                                                          /// 
/// ds1307_init() - Enable oscillator without clearing the seconds register -/// 
///                 used when PIC loses power and DS1307 run from 3V BAT     /// 
///               - Disable squarewave output                                /// 
///                                                                          /// 
/// ds1307_set_date_time(day,mth,year,dow,hour,min,sec)  Set the date/time   /// 
///                                                                          /// 
/// ds1307_get_date(day,mth,year,dow)               Get the date             /// 
///                                                                          /// 
/// ds1307_get_time(hr,min,sec)                     Get the time             /// 
///                                                                          /// 
//////////////////////////////////////////////////////////////////////////////// 

#define RTC_SDA  PIN_C4 
#define RTC_SCL  PIN_C3 

#use i2c(master, sda=RTC_SDA, scl=RTC_SCL) 

BYTE bin2bcd(BYTE binary_value); 
BYTE bcd2bin(BYTE bcd_value); 

void ds1307_init(void) 
{ 
   BYTE seconds = 0; 

   i2c_start(); 
   i2c_write(0xD0);      // WR to RTC 
   i2c_write(0x00);      // REG 0 
   i2c_start(); 
   i2c_write(0xD1);      // RD from RTC 
   seconds = bcd2bin(i2c_read(0)); // Read current "seconds" in DS1307 
   i2c_stop(); 
   seconds &= 0x7F; 

   delay_us(3); 

   i2c_start(); 
   i2c_write(0xD0);      // WR to RTC 
   i2c_write(0x00);      // REG 0 
   i2c_write(bin2bcd(seconds));     // Start oscillator with current "seconds value 
   i2c_start(); 
   i2c_write(0xD0);      // WR to RTC 
   i2c_write(0x07);      // Control Register 
   i2c_write(0x80);     // Disable squarewave output pin 
   i2c_stop(); 

} 

void ds1307_set_date_time(BYTE day, BYTE mth, BYTE year, BYTE dow, BYTE hr, BYTE min, BYTE sec) 
{ 
  sec &= 0x7F; 
  hr &= 0x3F; 

  i2c_start(); 
  i2c_write(0xD0);            // I2C write address 
  i2c_write(0x00);            // Start at REG 0 - Seconds 
  i2c_write(bin2bcd(sec));      // REG 0 
  i2c_write(bin2bcd(min));      // REG 1 
  i2c_write(bin2bcd(hr));      // REG 2 
  i2c_write(bin2bcd(dow));      // REG 3 
  i2c_write(bin2bcd(day));      // REG 4 
  i2c_write(bin2bcd(mth));      // REG 5 
  i2c_write(bin2bcd(year));      // REG 6 
  i2c_write(0x80);            // REG 7 - Disable squarewave output pin 
  i2c_stop(); 
} 

void ds1307_get_date(BYTE &day, BYTE &mth, BYTE &year, BYTE &dow) 
{ 
  i2c_start(); 
  i2c_write(0xD0); 
  i2c_write(0x03);            // Start at REG 3 - Day of week 
  i2c_start(); 
  i2c_write(0xD1); 
  dow  = bcd2bin(i2c_read() & 0x7f);   // REG 3 
  day  = bcd2bin(i2c_read() & 0x3f);   // REG 4 
  mth  = bcd2bin(i2c_read() & 0x1f);   // REG 5 
  year = bcd2bin(i2c_read(0));            // REG 6 
  i2c_stop(); 
} 

void ds1307_get_time(BYTE &hr, BYTE &min, BYTE &sec) 
{ 
  i2c_start(); 
  i2c_write(0xD0); 
  i2c_write(0x00);            // Start at REG 0 - Seconds 
  i2c_start(); 
  i2c_write(0xD1); 
  sec = bcd2bin(i2c_read() & 0x7f); 
  min = bcd2bin(i2c_read() & 0x7f); 
  hr  = bcd2bin(i2c_read(0) & 0x3f); 
  i2c_stop(); 

} 

BYTE bin2bcd(BYTE binary_value) 
{ 
  BYTE temp; 
  BYTE retval; 

  temp = binary_value; 
  retval = 0; 

  while(1) 
  { 
    // Get the tens digit by doing multiple subtraction 
    // of 10 from the binary value. 
    if(temp >= 10) 
    { 
      temp -= 10; 
      retval += 0x10; 
    } 
    else // Get the ones digit by adding the remainder. 
    { 
      retval += temp; 
      break; 
    } 
  } 

  return(retval); 
} 


// Input range - 00 to 99. 
BYTE bcd2bin(BYTE bcd_value) 
{ 
  BYTE temp; 

  temp = bcd_value; 
  // Shifting upper digit right by 1 is same as multiplying by 8. 
  temp >>= 1; 
  // Isolate the bits for the upper digit. 
  temp &= 0x78; 

  // Now return: (Tens * 8) + (Tens * 2) + Ones 

  return(temp + (temp >> 2) + (bcd_value & 0x0f)); 
}

Ahora el programa, el cual al levantarle los " // " en FUNCION 1, FUNCION 2, " /**/ " en FUNCION DISPLAY, presenta la hora, y cada 30 segundos aproximadamente, la fecha.
PHP:
#include <16F886.h>
#include <string.h>
#include <stdlib.h>
#fuses INTRC_IO,NOWDT,MCLR,NOLVP,NOPROTECT //ordenes para el programado
#use delay(clock=4M)    //especifica los 4MHz CLK_INTERNO
#include <ds_1307V2.c>
#use RS232(BAUD=9600, BITS=8 ,PARITY=N, XMIT=PIN_C6, RCV=PIN_C7, STREAM=RED) //Configuracion de Rs232
#Use Fast_Io(A)   //Optimizamos E/S del PORTA
#Use Fast_Io(B)    //Optimizamos E/S del PORTB
#Use Fast_Io(C)    //Optimizamos E/S del PORTC 



#DEFINE LED_SENSOR PIN_C0       // LED DE SENSOR


#DEFINE SENSOR_IR1 PIN_B0    //DATO RECIBIDO IR1
#DEFINE SENSOR_IR2 PIN_B1    //DATO RECIBIDO IR2
#DEFINE SENSOR_IR3 PIN_B2    //DATO RECIBIDO IR3
#DEFINE SENSOR_IR4 PIN_B3    //DATO RECIBIDO IR4


int ir1_1=1,ir2_2=1,dia,hora,minuto,segundo,mes,anio,nomdia;

void main()
{  SET_TRIS_A (0XF0);    //(0XF0); //   1111 0000   4 altos ENTRADAS 4 bajos SALIDAS Y 
   SET_TRIS_B (0x1F) ;    //(0X0F); //   0001 1111   3 bajos SALIDAS 5 ALTOS ENTRADAS    
   PORT_B_PULLUPS(0x0F);// pullup a las entradas
   SET_TRIS_C (0x84);     // 1000 0100    

   // desactivo el comparador y el ADC
   setup_comparator(NC_NC_NC_NC);
   SETUP_ADC(ADC_OFF);
   // Desactivo el SPI
   SETUP_SPI( SPI_SS_DISABLED);

//______________________________________________________________

 //  ds1307_init();//se inicializa el ds1307           // FUNCION 1


//ds1307_set_date_time(21,4,16,4,10,46,30);     // FUNCION 2


while(TRUE)
{

if(input(SENSOR_IR1)==0)   // B0 SENSOR IR1
    {ir1_1=0;}
    else
    {ir1_1=1;} 


if(ir1_1==0)// ¿SIGUEN ACTIVO el SENSOR?
    output_high(LED_SENSOR);  // SENSOR ACTIVO   
   else 
     output_low(LED_SENSOR);  // SENSOR INACTIVO       


   delay_ms(1000);
   
/*   //FUNCION DISPLAY
   ds1307_get_time(hora,minuto,segundo);    //   Get the time 
 
   fprintf(RED,"{%02d:%02d:%02d}\r",hora,minuto,segundo); 
   
   if(segundo==30||segundo==59)
   {
 
      ds1307_get_date(dia,mes,anio,nomdia);
      fprintf(RED,"{fecha :%02d/%02d/%02d}\r",dia,mes,anio);
   }  
 */  
   fprintf(RED,"OK\r");  
}
}
 

Adjuntos

  • IsisDS1307.jpg
    IsisDS1307.jpg
    129.4 KB · Visitas: 14
Última edición por un moderador:
Si usas el pin RB0 es mejor que uses esa interrupción, pero debes activar la salida de señal de onda cuadrada del RTC DS1307 en la librería, que también debes configurar para generar 1 Hz.
Así, cada vez que ocurra la interrupción puedes tomar las lecturas y actuar sobre el LED.
Con eso liberas el bucle del programa que te servirá para realizar otras acciones.
 
Atrás
Arriba