Programación Específica > Microcontroladores

 Programar Un Ds1307 Con El Pic16f877 Con I2c

<< < (4/5) > >>

damico:
Hola compañeros, con respecto al pic no me importa cual utilizar lo que me gustaria saber es como mantener una "relacion" PIC y ds1307 ya que soy un poco negado para esto, si me podeis decir por ejemplo y para empezar como mostrar la hora en LCD con la comunicacion i2C y DS1307. gracias y un saludo

© Jonathan ©:
Bueno, te adjunto un archivo de un proyecto que descargue una vez de ucontrol.com.ar, tiene la simulacion para proteus, esta escrito en C y corre en un 16F877. Espero te sea de ayuda. Saludos

damico:
Hola, Jonathan Y compania, gracias por el codigo para hacer el reloj, queria preguntarte como podemos añadir seis alarmas es decir alas 4:00  , 9:00 , 14:30  ,  18:10  ,  21:20 ,  23:25.

el codigo es el que me diste tan solo lo he modificado para mostrar tambien dia mes y año, ¿SABRIAS DECIRME COMO AÑADIR DICHAS ALARMAS?

////////////////////////////////////////////////////////////////////////////////////////////////////
////////////ESTE PROGRAMA UTILZA EL CIRCUITO DS1307 PARA MOSTRAR LA //////////////
//////////HORA EN TIEMPO REAL A TRAVEZ DE UN UNA LCD DE 2 POR 16 CARACTERES/////
///////////////////////////////////////////////////////////////////////////////////////////////////
#include <16F877A.h>                ///   libreria para el manejo del pic16f877a
#use delay(clock=8000000)          ///   declara  la frecuencia del cristal
#fuses HS,NOWDT,NOPUT,NOLVP,NOBROWNOUT,NOWRT,NOPROTECT
#include <lcd.c>

#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 = 7                     /// se definen direcciones de memoria
#byte portd = 8
#define RTC_SDA  PIN_C4
#define RTC_SCL  PIN_C3

#use i2c(master, sda=RTC_SDA, scl=RTC_SCL, SLOW)
int sec;
int min;
int hrs;
int  day;
int  month;
int  yr;
int  dow;

///////////////////////////////////////////////////////////////////////////////////
//////////////////////Comienzo de la funcion principal//////////////////////////
///////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
///                               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, SLOW)

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

void ds1307_init(void)
{
   BYTE seconds = 0;

   i2c_start();
   i2c_write(0xD0);      // SELECCIONA RTC CON  ORDEN WR
   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 = bin2bcd(seconds & 0x7F);

   delay_us(3);

   i2c_start();
   i2c_write(0xD0);      // WR to RTC
   i2c_write(0x00);      // REG 0
   i2c_write(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_write(0x10);     // Disable squarewave output pin
   i2c_stop();

}

void ds1307_OUT(void){
   i2c_start();
   i2c_write(0xD0);      // WR to RTC
   i2c_write(0x07);      // WR to RTC
   i2c_write(0x10);     // Enable 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_write(0x10);     // Enable 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));
}

void main(){
   ds1307_init ();      ///se inicializa el ds1307
   
   set_tris_a (0xff) ;
   set_tris_d (0x00) ;
   set_tris_b (0x00) ;
   set_tris_c (0x04) ;
   set_tris_e (0x01) ;
   port_b_pullups (true) ;
   lcd_init ();        /// inicializamos lcd
   // Set date FOR - > 15 June 2005 Tuesday
   // Set time FOR - > 15:20:55 (9:49:00 am)
   ds1307_set_date_time (8, 11, 7, 2, 19, 05, 00); /// se escribe en el displositivo
   /// el tiempo deseado
   WHILE (1){
      delay_ms (100) ;
      ds1307_get_date (day, month, yr, dow);  /// se obtiene la fecha
      ds1307_get_time (hrs, min, sec);   /// se obtiene la hora
      lcd_gotoxy (1, 2) ;
      printf (lcd_putc, " %02d: %02d: %02d  ", hrs,min,sec);///se despliegan los datos
      lcd_gotoxy (1, 1) ;
      printf (lcd_putc, " %02d: %02d: %02d  ", day,month,yr);
   }
}

© Jonathan ©:
Bueno una manera sencilla seria comparar la hora y los minutos actuales con los almacenados en las variables de alarma, mas o menos asi:

if((horas==Hsalarma1)&&(minutos==Minalarma1)).
{}
if((horas==Hsalarma2)&&(minutos==Minalarma2)).
{}
if((horas==Hsalarma3)&&(minutos==Minalarma3)).
{}
if((horas==Hsalarma4)&&(minutos==Minalarma4)).
{}
if((horas==Hsalarma5)&&(minutos==Minalarma5)).
{}
if((horas==Hsalarma6)&&(minutos==Minalarma6)).
{}

No se si me hago entender, tambien hay funciones para comparar dos cadenas, por ejemplo podrias meter la hora y el minuto actual en un string y compararlo con el de las alarmas, osea, guardas los datos de hora y minutos en un string y lo comparas con el de las alarmas usando la funcion strcmp(string1,string2).

Capaz con esta informacion te des alguna idea de como hacer las alarmas, Saludos.

damico:
Hola Jonathan, intentare hacer las alarmas tal y como me dijiste, por cierto nose si has simulado este reloj pero yo al simularlo con PROTEUS he visto que no va muy sincronizado es decir 1minutos en la simulacion equivale a 1 minuto y 15 segundo en un reloj real, ¿sabrias decirme como sulucionarlo?

Un saludo

Navegación

[0] Índice de Mensajes

[#] Página Siguiente

[*] Página Anterior

Ir a la versión completa