Autor Tema: Ayuda con reloj ds1307, LCD y pulsadores para cambiar hora y fecha con CCS en C  (Leído 7824 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado Arkaedus

  • PIC10
  • *
  • Mensajes: 25
Hola me gustaria saber como hacer un reloj con un ds1307 ya que el compilador PIC CCS Compiler no viene con driver ds1307. Así que necesitaré el codigo del driver DS1307

Y me gustaría que se programar la fecha y la hora con unos pulsadores que aumenten o disminuyan la hora, minutos, .... etc


Es decir deberia guardar los datos en la eeprom, no?

Alguien podria echarme una mano porque en esto que estoy perdido y para un proyecto que quiero hacer necesito poder introducir esto.
« Última modificación: 19 de Junio de 2015, 07:01:05 por Arkaedus »

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Primero que estas pidiendo todo, cosa que aqui en el foro creo que el ds1307 es uno de los RTC mas tratados y que si buscas vas a encontrar una libreria ( driver)
O de ultima portar alguna que encontres por internet.
Obviamente podes incrementar/decrementar horas,minutos,segundos para setear la hora.

El datasheet del DS1307 explica cuales son los comandos que deben enviarse para:
escribir 1 solo byte
escribir multiples bytes
leer 1 solo byte
leer multiples bytes

Y tambien te indica todos los registros que posee el DS1307
A partir de ahi es facil crear una libreria, por ejemplo para leer creo que era:

i2c_start();
i2c_write(direccion_ds1307 + write); //Esto contiene bit de R/W si no mal recuerdo , aca escritura
i2c_write(direccion_registro);
i2c_start();
i2c_write(direccion_ds1307 +read); //Esto contiene bit de R/W si no mal recuerdo, aca lectura
dato = i2c_read();                       // dato es lo que contiene la direccion de memoria (direccion_registro) del DS1307
i2c_stop();

Si lees el datasheet vas a ver que esta igual que la operacion de lectura

Con respecto a tu duda
Citar
Es decir deberia guardar los datos en la eeprom, no?

No, no hace falta, el DS1307 tiene unos registros que contienen la hora, al momento de querer saber que hora es, directamente lo lees del DS1307.
Si queres guardar/cambiar la hora, entonces escribis el registro del DS1307 con la nueva hora asi el RTc sigue contando desde ese punto.

Si quisieras cambiar la hora lo que harias es:

Leer la hora del DS1307
Que el usuario mediante botones la cambie ( me refiero tener guardado localmente en la RAM los valores mientras se cambian)
Finalizado todos cambios ( hora,minuto,segundos ) por mas que alguno se deje igual. Actualizas los datos en el DS1307
Fin

Desconectado Arkaedus

  • PIC10
  • *
  • Mensajes: 25
A ver es que yo he hehco un proyecto y el problema que tengo es que me salen simbolos raros al cabo de un tiempo encendido con el codigo que he puesto para el ds_1307 y no encuentro el problema, la pantalla LCD pro la que se "imprime" los datos es un 4 lineas 20 caracteres LM044L simulada en proteus. Uso el compilador CCS en C llamado PCW. Y como simulador Proteus 7.7 SP2

Alguien podria ayudarme, seria muy amable por su parte

Este es el driver del LCD:

Código: [Seleccionar]

// Flex_LCD420.c

#use delay(clock=4000000)

// These pins are for my Microchip PicDem2-Plus board,
// which I used to test this driver.
// An external 20x4 LCD is connected to these pins.
// Change these pins to match your own board's connections.

#define LCD_DB4   PIN_B0
#define LCD_DB5   PIN_B1
#define LCD_DB6   PIN_B2
#define LCD_DB7   PIN_B3

#define LCD_RS    PIN_D6
//#define LCD_RW    PIN_E1
#define LCD_E     PIN_D7

/*
// To prove that the driver can be used with random
// pins, I also tested it with these pins:
#define LCD_DB4   PIN_D4
#define LCD_DB5   PIN_B1
#define LCD_DB6   PIN_C5
#define LCD_DB7   PIN_B5

#define LCD_RS    PIN_E2
#define LCD_RW    PIN_B2
#define LCD_E     PIN_D6
*/

// If you want only a 6-pin interface to your LCD, then
// connect the R/W pin on the LCD to ground, and comment
// out the following line.  Doing so will save one PIC
// pin, but at the cost of losing the ability to read from
// the LCD.  It also makes the write time a little longer
// because a static delay must be used, instead of polling
// the LCD's busy bit.  Normally a 6-pin interface is only
// used if you are running out of PIC pins, and you need
// to use as few as possible for the LCD.
//#define USE_RW_PIN   1    


// These are the line addresses for most 4x20 LCDs.
#define LCD_LINE_1_ADDRESS 0x00
#define LCD_LINE_2_ADDRESS 0x40
#define LCD_LINE_3_ADDRESS 0x14
#define LCD_LINE_4_ADDRESS 0x54

// These are the line addresses for LCD's which use
// the Hitachi HD66712U controller chip.
/*
#define LCD_LINE_1_ADDRESS 0x00
#define LCD_LINE_2_ADDRESS 0x20
#define LCD_LINE_3_ADDRESS 0x40
#define LCD_LINE_4_ADDRESS 0x60
*/


//========================================

#define lcd_type 2   // 0=5x7, 1=5x10, 2=2 lines(or more)

int8 lcd_line;

int8 const LCD_INIT_STRING[4] =
{
 0x20 | (lcd_type << 2),  // Set mode: 4-bit, 2+ lines, 5x8 dots
 0xc,                     // Display on
 1,                       // Clear display
 6                        // Increment cursor
 };
                            

//-------------------------------------
void lcd_send_nibble(int8 nibble)
{
// Note:  !! converts an integer expression
// to a boolean (1 or 0).
 output_bit(LCD_DB4, !!(nibble & 1));
 output_bit(LCD_DB5, !!(nibble & 2));
 output_bit(LCD_DB6, !!(nibble & 4));  
 output_bit(LCD_DB7, !!(nibble & 8));  

 delay_cycles(1);
 output_high(LCD_E);
 delay_us(2);
 output_low(LCD_E);
}

//-----------------------------------
// This sub-routine is only called by lcd_read_byte().
// It's not a stand-alone routine.  For example, the
// R/W signal is set high by lcd_read_byte() before
// this routine is called.    

#ifdef USE_RW_PIN
int8 lcd_read_nibble(void)
{
int8 retval;
// Create bit variables so that we can easily set
// individual bits in the retval variable.
#bit retval_0 = retval.0
#bit retval_1 = retval.1
#bit retval_2 = retval.2
#bit retval_3 = retval.3

retval = 0;
  
output_high(LCD_E);
delay_us(1);

retval_0 = input(LCD_DB4);
retval_1 = input(LCD_DB5);
retval_2 = input(LCD_DB6);
retval_3 = input(LCD_DB7);
 
output_low(LCD_E);
delay_us(1);
  
return(retval);  
}  
#endif

//---------------------------------------
// Read a byte from the LCD and return it.

#ifdef USE_RW_PIN
int8 lcd_read_byte(void)
{
int8 low;
int8 high;

output_high(LCD_RW);
delay_cycles(1);

high = lcd_read_nibble();

low = lcd_read_nibble();

return( (high<<4) | low);
}
#endif

//----------------------------------------
// Send a byte to the LCD.
void lcd_send_byte(int8 address, int8 n)
{
output_low(LCD_RS);

#ifdef USE_RW_PIN
while(bit_test(lcd_read_byte(),7)) ;
#else
delay_us(60);
#endif

if(address)
   output_high(LCD_RS);
else
   output_low(LCD_RS);
    
 delay_cycles(1);

#ifdef USE_RW_PIN
output_low(LCD_RW);
delay_cycles(1);
#endif

output_low(LCD_E);

lcd_send_nibble(n >> 4);
lcd_send_nibble(n & 0xf);
}
//----------------------------

void lcd_init(void)
{
int8 i;

lcd_line = 1;

output_low(LCD_RS);

#ifdef USE_RW_PIN
output_low(LCD_RW);
#endif

output_low(LCD_E);

// Some LCDs require 15 ms minimum delay after
// power-up.  Others require 30 ms.  I'm going
// to set it to 35 ms, so it should work with
// all of them.
delay_ms(35);        

for(i=0 ;i < 3; i++)
   {
    lcd_send_nibble(0x03);
    delay_ms(5);
   }

lcd_send_nibble(0x02);

for(i=0; i < sizeof(LCD_INIT_STRING); i++)
   {
    lcd_send_byte(0, LCD_INIT_STRING[i]);
  
    // If the R/W signal is not used, then
    // the busy bit can't be polled.  One of
    // the init commands takes longer than
    // the hard-coded delay of 50 us, so in
    // that case, lets just do a 5 ms delay
    // after all four of them.
    #ifndef USE_RW_PIN
    delay_ms(5);
    #endif
   }

}

//----------------------------

void lcd_gotoxy(int8 x, int8 y)
{
int8 address;


switch(y)
  {
   case 1:
     address = LCD_LINE_1_ADDRESS;
     break;

   case 2:
     address = LCD_LINE_2_ADDRESS;
     break;

   case 3:
     address = LCD_LINE_3_ADDRESS;
     break;

   case 4:
     address = LCD_LINE_4_ADDRESS;
     break;

   default:
     address = LCD_LINE_1_ADDRESS;
     break;
    
  }

address += x-1;
lcd_send_byte(0, 0x80 | address);
}

//-----------------------------
void lcd_putc(char c)
{
 switch(c)
   {
    case '\f':
      lcd_send_byte(0,1);
      lcd_line = 1;
      delay_ms(2);
      break;
  
    case '\n':
       lcd_gotoxy(1, ++lcd_line);
       break;
  
    case '\b':
       lcd_send_byte(0,0x10);
       break;
  
    default:
       lcd_send_byte(1,c);
       break;
   }
}

//------------------------------
#ifdef USE_RW_PIN
char lcd_getc(int8 x, int8 y)
{
char value;

lcd_gotoxy(x,y);

// Wait until busy flag is low.
while(bit_test(lcd_read_byte(),7));

output_high(LCD_RS);
value = lcd_read_byte();
output_low(LCD_RS);

return(value);
}
#endif



Este es el codigo que uso para el ds_1307 (hay que decir que este codigo esta dentro del programa principal)

Código: [Seleccionar]

#use i2c(Master,Slow,sda=PIN_C4,scl=PIN_C3)

//PROTOTIPOS///////////////////////////////////////////////////////////////////
void leer_reloj();

void pulse_out(int);

short test_reloj();
void inicializa_reloj();
void ajusta_reloj();



//VALORES LEIDOS DEL RELOJ
int dia_sem = 1;           //0 = DOM, 1 = LUN, ... , 6 = SAB
int dia     = 1;           //numero de dia del mes en BCD
int mes     = 1;           //numero del mes en BCD
int anyo    = 0x09;        //numero del año en BCD
int hora    = 0;           //numero de la hora del dia (formato 24h) en BCD
int min     = 0;           //numero del minuto en BCD        

//-----------------------------------------------------------------------------
short test_reloj() //devuelve 1 si recibe ACK, 0 error de algun tipo
{
   i2c_start();
   temp = i2c_write(0b11010000);      //ID del reloj, Escribir  
   i2c_stop();
  
   if (temp == 0){
      return 1;
   }else{
      return 0;
   }
}
//-----------------------------------------------------------------------------
void inicializa_reloj()
{
   //Set Address 00H
   i2c_start();
   i2c_write(0b11010000);      //ID del reloj, Escribir
   i2c_write(0x00);            //Direccion 00H
   i2c_stop();

   //Read Address 00H
   i2c_start();
   i2c_write(0b11010001);      //ID del reloj, Leer
   temp = i2c_read(0);         //00H - Clock Halt, segundos, NOT ACK
   i2c_stop();

   if (temp & 0b10000000)      //Si Clock Halt == 1
   {
      //Clear Clock Halt
      i2c_start();
      i2c_write(0b11010000);      //ID del reloj, Escribir
      i2c_write(0x00);            //Adress 00H
      i2c_write(temp & 0b01111111); //Clear CH  
      i2c_stop();
   }
}
//-----------------------------------------------------------------------------
void leer_reloj()
{
   //Set Address 01H
   i2c_start();
   i2c_write(0b11010000);      //ID del reloj, Escribir
   i2c_write(0x01);            //Direccion 01H
   i2c_stop();

   //Read Address 01H
   i2c_start();
   i2c_write(0b11010001);      //ID del reloj, Leer
   min     = i2c_read();       //01H - minutos
   hora    = i2c_read();       //02H - horas
   dia_sem = i2c_read() - 1;   //03H - dia de la semana
   dia     = i2c_read();       //04H - dia del mes
   mes     = i2c_read();       //05H - mes
   anyo    = i2c_read(0);      //06H - año, NOT ACK para terminar lectura
   i2c_stop();
}
//-----------------------------------------------------------------------------
void ajusta_reloj()
{
   //Set Address 00H
   i2c_start();
   i2c_write(0b11010000);      //ID del reloj, Escribir
   i2c_write(0x00);            //Direccion 00H
   i2c_write(0x00);            //seg = 0
   i2c_write(min);             //minutos
   i2c_write(hora);            //horas
   i2c_write(dia_sem + 1);     //dia de la semana
   i2c_write(dia);             //dia del mes
   i2c_write(mes);             //mes
   i2c_write(anyo);            //anyo
//   i2c_write(0x10);            //OUT = 0, SQWE = 1, RS1 = 0, RS0 = 0 (1Hz)  
//   i2c_write(0x80);            //OUT = 1, SQWE = 0, RS1 = 0, RS0 = 0 (1Hz)  
   i2c_stop();
}  




Si no es problema de esto sera problema de escritura, o no sé ya. Estoy muy apurado proque no veo el error y me gustaría sacarlo adelante este proyecto.

Adjunto el proyecto por si alguien me peude ayudar o echar una mano con la solución al problema de que con el tiempo encendido salen interrogantes momentaneamente en la pantalla de info y luego vuelve a la normalidad ( como si el Ds_1307 se volviese loco, solo ocurre en la primera linea del LCD que es donde aparecen lso datos del DS_1307 y claro la segunda linea cambia dependiendo de la primera linea pues se basa elñ programa en encender unasa salidas segun la hora)
« Última modificación: 20 de Junio de 2015, 14:19:00 por Arkaedus »

Desconectado Miquel_S

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1251
Hola Arkaedus te paso mi proyecto entero que hice con el DS1307 con lo que tuve mas problemas fue con guardar en la eprom y luego leerla pero en el proyecto que te paso quedo resuelto.
http://www.ucontrol.com.ar/forosmf/proyectos-con-pic/reloj-alarmas-para-escuelas/

Saludos!

Nota: Con respuesta a este otro tema: http://www.todopic.com.ar/foros/index.php?topic=39889.0;topicseen
Todos somos muy ignorantes. Lo que ocurre es que no todos ignoramos las mismas cosas.

Desconectado anthony123

  • PIC10
  • *
  • Mensajes: 18
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 (estoy usando la de acá del foro) pero todas dan el mismo problema. ¿Alguien lo ha tenido?

Adjunto código y librería:
CÓDIGO
Código: [Seleccionar]
#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: [Seleccionar]
///////////////////////////////////////////////////////////////////////////////////////
///                               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!

Desconectado allennet

  • PIC16
  • ***
  • Mensajes: 112
la baterria de 3v normalmente la cr2032 o otra sirve se usa para no perder la hora
"La curiosidad mato al gato, pero murio sabiendo"

Desconectado anthony123

  • PIC10
  • *
  • Mensajes: 18
Pues tiene conectada su batería de 3V... Aun sigo sin poder resolver. Me he fijado que lo mismo pasa con la variable dia de la semana.  :?

Desconectado Isabel Espejel

  • PIC10
  • *
  • Mensajes: 8
Re:Ayuda con reloj ds1307, LCD y pulsadores para cambiar hora y fecha con CCS en C
« Respuesta #7 en: 21 de Junio de 2017, 01:33:43 »
Holaq que tal, tengo un dilema cuando modulo el programa en proteus la fecha no cambia solo se queda en lunes y no se como arreglarlo, ya lo intente de diferentes maneras


 

anything