Autor Tema: Conflicto con RTC en PIC 18F46K22  (Leído 2867 veces)

0 Usuarios y 2 Visitantes están viendo este tema.

Desconectado BINARIO

  • PIC16
  • ***
  • Mensajes: 156
Conflicto con RTC en PIC 18F46K22
« en: 30 de Septiembre de 2014, 18:44:17 »
 :-/ :-/ :-/ :-/ :-/ :-/ :-/ :-/

Colegas!

He incursionado en el manejo de RTC particularmente el de dallas, el DS1307. De la mano del post invaluable del amigo RedPic, un gran docente en esto de los uControladores.
Actualmente estoy queriendo mostrar un reloj en un menu de opciones de un equipito que estoy armando, mi idea es que cuando pase una hora, un minuto o un segundo, poder hacer un evento como prender un ledo o activar alguna alarma o rutina.
Hasta aca todo bien, pude hacer por separado que el pic me muestre la hora, claro que aun no se como inicializar el reloj, he logrado cargar la hora cero y que corra a partir de ese horario mostrando un tiempo continuo.

Pero! porque siempre en electronica habra un pero, cuando coloque mi trozo de codigo en mi programa tuve el problema de que toda la ejecucion se cuelga y solo responde si reseteo el micro, no me hace caso a los botones para pasar de menu, ni tampoco me muestra hora o fecha coherente. Aca coloco una parte del codigo que implemente

Código: [Seleccionar]
#include <18f46k22.h>                                                           //Incluimos el archivo cabezera del micro
#fuses XT,NOWDT                                                                 //Cristal de >4Mhz, sin Watch Dog Timer


//1----------- MODULO AD DE 10 BITS.--------------------------------------------

#device adc=10                                                                                          //AD de 10 bits = 1024 muestras


//----------- CLOCK DE 4 MHz -------------------------------------------------
#use delay( clock = 4000000 )                                                               

#include <lcd4x20PORTD.c>                                                                         //Libreria que fue editada para usar un
                                                                                                                  //LCD de 4x20 lineas en puerto D.

#include <math.h>                                                                                      //Libreria matematica para calcular logaritmos

//Definiciones para el RTC ---------------------------------------------------------
#define RTC_SDA  PIN_C4
#define RTC_SCL  PIN_C3
#define USE_INTERRUPTS 1
#include "ds1307.c"                                                                                    // Libreria del RTC



//----------- DIRECCIONAMIENTO DE PUERTOS -------------------------------------
#BYTE TRISA = 0xF92                                                            // TRISA
#BYTE PORTA = 0xF80                                                            // PORTA
#BYTE TRISB = 0xF93                                                            // TRISB
#BYTE PORTB = 0xF81                                                            // PORTB
#BYTE TRISC = 0xF94                                                            // TRISC
#BYTE PORTC = 0xF82                                                            // PORTC
#BYTE TRISD = 0xF95                                                            // TRISD
#BYTE PORTD = 0xF83                                                            // PORTD
#BYTE TRISE = 0xF96                                                            // TRISE
#BYTE PORTE = 0xF84                                                            // PORTE
//------------------------------------------------------------------------------

//----------------------VARIABLES GLOBALES--------------------------------------

//PLUVIOMETRO
int16 lluvia=0;                                                                        //Variable que se emplea para el contador
                                                                                            //del pluviometro

//ANEMOMETRO
int16 c=0; 
int conT2=0;
int16 pulsos=0;
int16 pulsos_kmh=0;   

//RTC
byte seg;
byte min;
byte hor;
byte dia;
byte mes;
byte year;
byte dow;
char sdow[11];
//------------------------------------------------------------------------------

#int_EXT                                                                        //Directiva de pre-procesador de la interrupcion
                                                                                    //externa.
                                                                               
#int_ccp1                                                                       //Directiva de preprocesador del modulo de
                                                                                    //captura y comparacion CCP1.
                                                                               
void ccp1_int()                                                                 //Funcion del modulo de captura y comparacion
{                                                                                   //CCP1, aqui se atiende al pluviometro.
  lluvia++;                                                                     //si hubo pulso, se incrementa el contador.
}



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



#INT_TIMER2
void TIMER2_isr(void)
{
   conT2++;
   //set_timer2(0);
   if(conT2==100)
   {
      pulsos=c;
      conT2=0;
      c=0;
      pulsos_kmh=1.244070691*pulsos;
   }
   set_timer2(0);
}




void main()
{
 
 int SELECCION=0;                                                        //variable empleado en el switch.
 
 float q, p, t, hum, presion, pres_atm, pres_psi, alt,PR, PRt, PRhum;
 float tST, tFST, tv, tr, temp, y, tf, muestras, precipitaciones;
 float QT, WC, humST, HI, viento=14.5;

 float pol_01, pol_10, pol_11, pol_20, pol_02, pol_21, pol_12, pol_22;          //Estas variables son los polinomios
                                                                                                             //que conforman la ecuacion de Heat Index,
                                                                                                             //dado que es sumamente compleja debio ser
                                                                                                             //segmentada en muchos polinomios para que
                                                                                                             //el micro pudiera realizar el calculo.
 setup_timer_2(T2_DIV_BY_16, 194, 16);
 
 enable_interrupts (int_ccp1);                                                                  //habilitamos interrupcion por CCP1
 enable_interrupts(INT_TIMER2);                                                             //Interrupcion de timer 2 para el anemometro
 enable_interrupts (GLOBAL);                                                                  //habilitacion de interrupciones globales
 
 setup_timer_1 (T1_INTERNAL);                                                              //configuramos el timer1 con reloj interno
 setup_ccp1 (CCP_CAPTURE_RE);                                                           //configuramos el ccp1 como captura
 
 
 lcd_init();                                                                                            //funcion de inicializacion del LCD
 
 setup_adc_ports(sAN0|sAN1|sAN2|sAN3|sAN4);                                 //entradas analogicas puertos RA0, RA1, RA2, RA3 y RA5
 setup_adc( ADC_CLOCK_INTERNAL );   
 
ds1307_set_date_time(1,1,14,1,18,0,00);

SWITCH (SELECCION)

{
  ....

  CASE 9:
         
          lcd_putc("\f");           
          lcd_gotoxy (1,1);
          Lcd_putc ("  RELOJ CALENDARIO  ");
          lcd_gotoxy (1,2);
          printf(lcd_putc, "   Fecha: \%02d/\%02d/\%02d ",dia,mes,year);
          lcd_gotoxy (1,3);
          printf(lcd_putc, "   Hora:  \%02d:\%02d:\%02d ",hor,min,seg);
          lcd_gotoxy (1,4);
          lcd_putc("<<                >>");
         
 
          ds1307_get_date(dia,mes,year,dow);                                   // obtengo fecha
          ds1307_get_time(hor,min,seg);                                        // obtengo hora

             
   
             if (bit_test (PORTE, 0) )
          {
            delay_ms(500);
            if (bit_test (PORTE, 0) )
               SELECCION = 8;
          }
           
           
          if (bit_test (PORTE, 1) )
          {
            delay_ms(500);
            if (bit_test (PORTE, 1) )
               SELECCION = 0;
          }
          delay_ms(100);
   BREAK;
}


000101111 101110000011110 00010 11101 110 1 000111 00010010011010111100 101101001 11110000 001 00 10110 111 00001 01110 0010101 01011110 00 00011111111 0011111 011110001111111111 1011111111101100000000

Desconectado BINARIO

  • PIC16
  • ***
  • Mensajes: 156
Re: Conflicto con RTC en PIC 18F46K22
« Respuesta #1 en: 30 de Septiembre de 2014, 18:50:40 »
lo unico que no tiene puesto es la bateria de 3V, no se que tanto puede esto afectar al funcionamiento del RTC
000101111 101110000011110 00010 11101 110 1 000111 00010010011010111100 101101001 11110000 001 00 10110 111 00001 01110 0010101 01011110 00 00011111111 0011111 011110001111111111 1011111111101100000000

Desconectado AKENAFAB

  • Colaborador
  • DsPIC30
  • *****
  • Mensajes: 3227
Re: Conflicto con RTC en PIC 18F46K22
« Respuesta #2 en: 30 de Septiembre de 2014, 19:44:20 »
lo unico que no tiene puesto es la bateria de 3V, no se que tanto puede esto afectar al funcionamiento del RTC

No creo que resuelva tu problema actual pero si uno futuro.

Pon el pin a GND sino conectas la batería , a veces se comportaba de manera extraña cuando no hacia esto.

Saludos!

Desconectado RedPic

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 5544
    • Picmania by Redraven
Re: Conflicto con RTC en PIC 18F46K22
« Respuesta #3 en: 01 de Octubre de 2014, 07:43:05 »
Mi experiencia me dice que el DS1307 sin batería no va fino. No se si la solución de AKENAFAB es correcta porque no lo he probado pero seguro que si él tiene la experiencia es algo a tener en cuenta. En cuanto a lo que comenta BINARIO a ver si cuando vuelva por casa puedo darle un vistazo con más detenimiento.  :mrgreen:
Contra la estupidez los propios dioses luchan en vano. Schiller
Mi Güeb : Picmania

Desconectado AKENAFAB

  • Colaborador
  • DsPIC30
  • *****
  • Mensajes: 3227
Re: Conflicto con RTC en PIC 18F46K22
« Respuesta #4 en: 01 de Octubre de 2014, 13:29:47 »
No leí tu código ,te comento mi experiencia ,
Se llego a bloquear por no colocar el pin a GND o la batería , probé ambas conexiones.
En el prototipo lo deje sin la batería ya que no requería respaldo.

No trabaje tanto con este rtc como otros compañeros , así que me iría por lo que comenta RedPic.

Saludos!


Desconectado donvalles

  • PIC10
  • *
  • Mensajes: 35
Re: Conflicto con RTC en PIC 18F46K22
« Respuesta #5 en: 01 de Octubre de 2014, 23:38:07 »
yo estoy usando el ds1307, me parece pero no veo en tu código la inicialización del RTC."ds1307_init()"  y despúes setear la hora y fecha. y luego podes hacer una lectura a cada 1 seg. , tenes que pasar la hora en segundos, luego pasar los min en seg y luego los segundos en segundos, los sumas a los tres y obtenes los segundos totales, asi es más facil para calcular la hora exata y no generas códigos o lineas solo para ver si es la hora. ojo está es mi opinón. :)

Desconectado BINARIO

  • PIC16
  • ***
  • Mensajes: 156
Re: Conflicto con RTC en PIC 18F46K22
« Respuesta #6 en: 02 de Octubre de 2014, 13:44:20 »
Colegas, acabo de colocar la bateria y no funciono, tambien puse a masa el pin de bateria y no funciono, voy a ver de hacer lo que dice don valles, no sabia que habia una funcion de incializacion del RTC, pero ahora que lo pienso es logico, donvalles yo uso la libreria ds1307.c que viene con CCS version 5.25
000101111 101110000011110 00010 11101 110 1 000111 00010010011010111100 101101001 11110000 001 00 10110 111 00001 01110 0010101 01011110 00 00011111111 0011111 011110001111111111 1011111111101100000000

Desconectado BINARIO

  • PIC16
  • ***
  • Mensajes: 156
Re: Conflicto con RTC en PIC 18F46K22
« Respuesta #7 en: 02 de Octubre de 2014, 14:07:17 »
donvalles!!!

Creo que la solucion pasa por lo que vos dijiste, tengo este metodo de funcion dentro de la libreria de CCS ds1307.c

Código: [Seleccionar]
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

}

Alcanzo a entender la funcion, pero no entiendo bien que variable debo pasarle, por lo visto es un int, pero no se que valor tiene que tener ni de donde la leo, seguire investigando de esta inicializacion creo que la solucion viene por aqui.

Saludos y gracias por leer y responder.
000101111 101110000011110 00010 11101 110 1 000111 00010010011010111100 101101001 11110000 001 00 10110 111 00001 01110 0010101 01011110 00 00011111111 0011111 011110001111111111 1011111111101100000000

Desconectado donvalles

  • PIC10
  • *
  • Mensajes: 35
Re: Conflicto con RTC en PIC 18F46K22
« Respuesta #8 en: 02 de Octubre de 2014, 14:28:42 »
Código: [Seleccionar]
fijate que es void la función init y ese dato es para desabilitar la onda cuadrada del ds1307
[code=cpp]
////////////////////////////////////////////////////////////////////////////////
///                               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;

#ifndef USE_INTERRUPTS
 disable_interrupts(global);
#endif
   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();
#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 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();
#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);            // 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();
#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);            // 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();
#ifndef USE_INTERRUPTS
  enable_interrupts(global);
#endif
}

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));
}


[/code]
« Última modificación: 02 de Octubre de 2014, 14:47:53 por donvalles »

Desconectado BINARIO

  • PIC16
  • ***
  • Mensajes: 156
Re: Conflicto con RTC en PIC 18F46K22
« Respuesta #9 en: 02 de Octubre de 2014, 14:49:42 »
no me responde che!!!!

vos sabes que cargo todo como esta en la mayoria de los codigos y se me tilda!

rarisimo! me cago en microchip! //perdon!

te muestro lo que implemente:

Código: [Seleccionar]

#include <18f46k22.h>                                                         
#fuses XT,NOWDT

#define RTC_SDA  PIN_C4
#define RTC_SCL  PIN_C3
#define USE_INTERRUPTS 1
#include "ds1307_2.c"

//RTC
byte seg;
byte min;
byte hor;
byte dia;
byte mes;
byte year;
byte dow;
char sdow[11];


while ( !bit_test(PORTA,4) )                                                   //el programa queda a la espera de que el
  {                                                                             //operador presione la tecla ENTER en RD0     
 
  delay_ms(500);                                                                 //Retardo
  lcd_gotoxy (1,1);                                                             //posiciona al cursor en el comienzo del LCD
  Lcd_putc ("PRESIONE ENTER");
  lcd_gotoxy (1,2);                                                             //posiciona al LCD en la segunda linea
  Lcd_putc ("Para comenzar...");
  }
 
  lcd_putc("\f");                                                               //Comando para borrar el LCD
  ds1307_init();
  delay_ms(1200);
  ds1307_set_date_time(02,10,14,2,14,21,00);
 
 
  for(;;)                                                                       //Este for lo que nos da es un bucle infinito
 {
   .... //etc


despues del for(;;) deberia mostrar otros menus en el lcd, pero el programa se cuelga totalmente y no responde a nada, porsupuesto en la simulacion anda bien porque el desgraciado de proteus toma el reloj del metodo de horario del sistema, asi cualquiera...

ds1307_2 es la libreria que vos me mostraste consegui la misma en hilos viejos del foro, pero basicamente es similar a la ds1307.c que viene con CCS, solo que cuando vos inicializas pones ds1307_init(); y en la de CCS pones ds1307_init(DS1307_ALL_DISABLED); por ejemplo. Son muy similares, pero con ninguna de las dos librerias me anduvo, creo estar seguro de estar usando el puerto I2C(MSSP) del pic, que segun hoja de datos es

SCL1 -------> PIN18 ----> RC3
SDA1 -------> PIN23 ----> RC4

Asi que estoy en ascuas con esto sigo investigando...


 :5] :5] :5] :5] :5]
000101111 101110000011110 00010 11101 110 1 000111 00010010011010111100 101101001 11110000 001 00 10110 111 00001 01110 0010101 01011110 00 00011111111 0011111 011110001111111111 1011111111101100000000

Desconectado BINARIO

  • PIC16
  • ***
  • Mensajes: 156
Re: Conflicto con RTC en PIC 18F46K22
« Respuesta #10 en: 03 de Octubre de 2014, 10:46:22 »
sigue sin andar...  :z) :z) :z)
000101111 101110000011110 00010 11101 110 1 000111 00010010011010111100 101101001 11110000 001 00 10110 111 00001 01110 0010101 01011110 00 00011111111 0011111 011110001111111111 1011111111101100000000

Desconectado allennet

  • PIC16
  • ***
  • Mensajes: 108
Re: Conflicto con RTC en PIC 18F46K22
« Respuesta #11 en: 05 de Octubre de 2014, 15:21:13 »
ese es el codigo completo para revisarle le falta el clock de frecuencia
"La curiosidad mato al gato, pero murio sabiendo"

Desconectado BINARIO

  • PIC16
  • ***
  • Mensajes: 156
Re: Conflicto con RTC en PIC 18F46K22
« Respuesta #12 en: 06 de Octubre de 2014, 10:41:49 »
ese es el codigo completo para revisarle le falta el clock de frecuencia

A que te referis con el clock de frecuencia? estimo que no hablas del clock del micro.
000101111 101110000011110 00010 11101 110 1 000111 00010010011010111100 101101001 11110000 001 00 10110 111 00001 01110 0010101 01011110 00 00011111111 0011111 011110001111111111 1011111111101100000000

Desconectado BINARIO

  • PIC16
  • ***
  • Mensajes: 156
Re: Conflicto con RTC en PIC 18F46K22
« Respuesta #13 en: 21 de Octubre de 2014, 13:54:55 »
Retomando esto no me funciona, aca el siguiente codigo

Código: [Seleccionar]
while ( !bit_test(PORTE,1) )                                                   //el programa queda a la espera de que el
  {                                                                             //operador presione la tecla ENTER en RD0     
 
  delay_ms(500);                                                                 //Retardo
  lcd_gotoxy (1,1);                                                             //posiciona al cursor en el comienzo del LCD
  Lcd_putc ("PRESIONE ENTER");
  lcd_gotoxy (1,2);                                                             //posiciona al LCD en la segunda linea
  Lcd_putc ("Para comenzar...");
  }
 
  lcd_putc("\f");                                                               //Comando para borrar el LCD
  ds1307_init();
  ds1307_set_date_time(02,10,14,2,12,30,30);
 
 
  for(;;)                                                                       //Este for lo que nos da es un bucle infinito
 {

ETC...

El programa funciona correctamente hasta que llamo a cualquier funcion de la libreria ds1307.c, alli es donde el flujo de programa se cuelga, les comento que cada linea tiene R de pull up de 10K, ademas ya cambie la pila, y probe con dos RTCs mas y sigue fallando, deduzco que el problema esta en el codigo o en la funcion o hay algo que estoy olvidando, pero aun no puedo resolverlo.

Saludos!
000101111 101110000011110 00010 11101 110 1 000111 00010010011010111100 101101001 11110000 001 00 10110 111 00001 01110 0010101 01011110 00 00011111111 0011111 011110001111111111 1011111111101100000000

Desconectado BINARIO

  • PIC16
  • ***
  • Mensajes: 156
Re: Conflicto con RTC en PIC 18F46K22
« Respuesta #14 en: 21 de Octubre de 2014, 14:19:02 »
Un detalle de mi PCB que no se que tan importante sea, no tiene el anillo de guardia conectado a masa que sugiere la hoja de datos del DS1307 lo muestro en la siguiente foto

000101111 101110000011110 00010 11101 110 1 000111 00010010011010111100 101101001 11110000 001 00 10110 111 00001 01110 0010101 01011110 00 00011111111 0011111 011110001111111111 1011111111101100000000


 

anything