Autor Tema: RTC DS1307 en XC8 no lee el tiempo  (Leído 3127 veces)

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

Desconectado micro_pepe

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3216
RTC DS1307 en XC8 no lee el tiempo
« en: 04 de Octubre de 2017, 19:15:38 »
Me estoy pegando con un RTC DC1307, y no consigo leer la hora, da siempre 0. El código lo usé tal cual hace tiempo con CCS y funcionaba, ahora lo estoy traduciendo a XC8, pero no consigo hacerlo andar.

Como librería i2c uso una que saqué del foro, por software.

Dejo el código del RTC:

Código: C
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include "sw_i2c.h"
  4. #include "rtc.h"
  5.  
  6. #ifndef COMUN_H
  7. #include "comun.h"
  8. #endif
  9.  
  10. /*
  11.  *
  12.  */
  13. void ds1307_init(void) {
  14.     BYTE seconds = 0;
  15.  
  16.     i2cs_start();
  17.     i2cs_write(0xD0); // SELECCIONA RTC CON  ORDEN WR
  18.     i2cs_write(0x00); // REG 0
  19.     i2cs_start();
  20.     i2cs_write(0xD1); // RD from RTC
  21.     seconds = bcd2bin(i2cs_read()); // Read current "seconds" in DS1307
  22.     i2cs_stop();
  23.     seconds = bin2bcd(seconds & 0x7F);
  24.  
  25.     __delay_us(3);
  26.  
  27.     i2cs_start();
  28.     i2cs_write(0xD0); // WR to RTC
  29.     i2cs_write(0x00); // REG 0
  30.     i2cs_write(seconds); // Start oscillator with current "seconds value
  31.     i2cs_start();
  32.     i2cs_write(0xD0); // WR to RTC
  33.     i2cs_write(0x07); // Control Register
  34.     //   i2c_write(0x80);     // Disable squarewave output pin
  35.     i2cs_write(0x10); // Disable squarewave output pin
  36.     i2cs_stop();
  37.  
  38. }
  39.  
  40. void ds1307_OUT(void) {
  41.     i2cs_start();
  42.     i2cs_write(0xD0); // WR to RTC
  43.     i2cs_write(0x07); // WR to RTC
  44.     i2cs_write(0x10); // Enable squarewave output pin
  45.     i2cs_stop();
  46. }
  47.  
  48. void ds1307_set_date_time(BYTE day, BYTE mth, BYTE year, BYTE dow, BYTE hr, BYTE min, BYTE sec) {
  49.     sec &= 0x7F;
  50.     hr &= 0x3F;
  51.  
  52.        
  53.     i2cs_start();
  54.     i2cs_write(0xD0); // I2C write address
  55.     i2cs_write(0x00); // Start at REG 0 - Seconds
  56.     i2cs_write(bin2bcd(sec)); // REG 0
  57.     i2cs_write(bin2bcd(min)); // REG 1
  58.     i2cs_write(bin2bcd(hr)); // REG 2
  59.     i2cs_write(bin2bcd(dow)); // REG 3
  60.     i2cs_write(bin2bcd(day)); // REG 4
  61.     i2cs_write(bin2bcd(mth)); // REG 5
  62.     i2cs_write(bin2bcd(year)); // REG 6
  63.     //i2c_write(0x80);            // REG 7 - Disable squarewave output pin
  64.     i2cs_write(0x10); // Enable squarewave output pin
  65.     i2cs_stop();
  66. }
  67.  
  68. void ds1307_get_date(BYTE * day, BYTE * mth, BYTE * year, BYTE * dow) {
  69.     i2cs_start();
  70.     i2cs_write(0xD0);
  71.     i2cs_write(0x03); // Start at REG 3 - Day of week
  72.     i2cs_start();
  73.     i2cs_write(0xD1);
  74.     *(dow) = bcd2bin(i2cs_read() & 0x7f); // REG 3
  75.     *(day) = bcd2bin(i2cs_read() & 0x3f); // REG 4
  76.     *(mth) = bcd2bin(i2cs_read() & 0x1f); // REG 5
  77.     *(year) = bcd2bin(i2cs_read()); // REG 6
  78.     i2cs_stop();
  79. }
  80.  
  81. void ds1307_get_time(BYTE * hr, BYTE * min, BYTE * sec) {
  82.     i2cs_start();
  83.     i2cs_write(0xD0);
  84.     i2cs_write(0x00); // Start at REG 0 - Seconds
  85.     i2cs_start();
  86.     i2cs_write(0xD1);
  87.     *(sec) = bcd2bin(i2cs_read() & 0x7f);
  88.     *(min) = bcd2bin(i2cs_read() & 0x7f);
  89.     *(hr) = bcd2bin(i2cs_read() & 0x3f);
  90.     i2cs_stop();
  91.  
  92. }
  93.  
  94. BYTE bin2bcd(BYTE binary_value) {
  95.     BYTE temp;
  96.     BYTE retval;
  97.  
  98.     temp = binary_value;
  99.     retval = 0;
  100.  
  101.     while (TRUE) {
  102.         // Get the tens digit by doing multiple subtraction
  103.         // of 10 from the binary value.
  104.         if (temp >= 10) {
  105.             temp -= 10;
  106.             retval += 0x10;
  107.         } else // Get the ones digit by adding the remainder.
  108.         {
  109.             retval += temp;
  110.             break;
  111.         }
  112.     }
  113.  
  114.     return (retval);
  115. }
  116.  
  117.  
  118. // Input range - 00 to 99.
  119.  
  120. BYTE bcd2bin(BYTE bcd_value) {
  121.     BYTE temp;
  122.  
  123.     temp = bcd_value;
  124.     // Shifting upper digit right by 1 is same as multiplying by 8.
  125.     temp >>= 1;
  126.     // Isolate the bits for the upper digit.
  127.     temp &= 0x78;
  128.  
  129.     // Now return: (Tens * 8) + (Tens * 2) + Ones
  130.  
  131.     return (temp + (temp >> 2) + (bcd_value & 0x0f));
  132. }


La librería del i2c:

Código: C
  1. void i2cs_start(void) {
  2.     SDADIR = 1;
  3.     SCLDIR = 1;
  4.     __delay_us(5);
  5.     SDAPIN_W = 0;
  6.     SDADIR = 0;
  7.     __delay_us(4);
  8.     SCLPIN_W = 0;
  9.     SCLDIR = 0;
  10. }
  11.  
  12. void i2cs_stop(void) {
  13.     SDAPIN_W = 0;
  14.     SDADIR = 0;
  15.     SCLPIN_W = 0;
  16.     SCLDIR = 0;
  17.     __delay_us(1);
  18.     SCLDIR = 1;
  19.     __delay_us(5);
  20.     SDADIR = 1;
  21. }
  22.  
  23. void i2cs_write(unsigned char _data) {
  24.     unsigned char _bits;
  25.  
  26.     __delay_us(5);
  27.     for (_bits = 8; _bits > 0; _bits--) {
  28.         if ((_data & 0x80) == 0) {
  29.             SDAPIN_W = 0;
  30.             SDADIR = 0;
  31.         } else
  32.             SDADIR = 1;
  33.         _data = _data << 1;
  34.         __delay_us(1);
  35.         SCLDIR = 1;
  36.         __delay_us(4);
  37.         SCLPIN_W = 0;
  38.         SCLDIR = 0;
  39.         __delay_us(5);
  40.     }
  41.     SDADIR = 1;
  42.     __delay_us(1);
  43.     SCLDIR = 1;
  44.     __delay_us(4);
  45.     SCLPIN_W = 0;
  46.     SCLDIR = 0;
  47. }
  48.  
  49. unsigned char i2cs_read(void) {
  50.     unsigned char _data;
  51.     unsigned char _bits;
  52.  
  53.     for (_bits = 8; _bits > 0; _bits--) {
  54.         __delay_us(5);
  55.         _data = _data << 1;
  56.         SCLDIR = 1;
  57.         __delay_us(2);
  58.         SDADIR = 1;
  59.         if (SDAPIN_R == 1)
  60.             _data |= 1;
  61.         __delay_us(2);
  62.         SCLDIR = 0;
  63.         SCLPIN_W = 0;
  64.     }
  65.     return _data;
  66. }
  67.  
  68. void i2cs_nack(void) {
  69.     __delay_us(5);
  70.     SDADIR = 1;
  71.     __delay_us(1);
  72.     SCLDIR = 1;
  73.     __delay_us(4);
  74.     SCLPIN_W = 0;
  75.     SCLDIR = 0;
  76.     __delay_us(5);
  77.     SDAPIN_W = 0;
  78.     SDADIR = 0;
  79. }
  80.  
  81. void i2cs_ack(void) {
  82.     __delay_us(5);
  83.     SDAPIN_W = 0;
  84.     SDADIR = 0;
  85.     __delay_us(1);
  86.     SCLDIR = 1;
  87.     __delay_us(4);
  88.     SCLPIN_W = 0;
  89.     SCLDIR = 0;
  90.     __delay_us(5);
  91.     SDAPIN_W = 0;
  92.     SDADIR = 0;
  93. }


Y luego en el main, inicializo con esto:

Código: C
  1. ds1307_init();
  2.  
  3.     ds1307_get_time(& hrs, & min, & sec);
  4.     ds1307_get_date(& day, & month, & yr, & dow);
  5.     ds1307_set_date_time(day, month, yr, dow, hrs, min, (sec & 0b01111111));

y lo pruebo con esto:

Código: C
  1. ds1307_get_time(& hrs, & min, & sec);
  2.  
  3. separa_digitos((unsigned char) sec, S, 3);//Convierte un entero a cadena de caracteres
  4. lcd_gotoxy(5, 2);
  5. LCDprint(S);//imprime cadena de caracteres

Estas ultimas funciones funcionan bien, si dentro de "ds1307_get_time" le doy un valor fijo a sec, lo visualiza bien en el LCD.

Gracias!!! Un saludo.
« Última modificación: 04 de Octubre de 2017, 19:19:25 por micro_pepe »
Se obtiene más en dos meses interesandose por los demás, que en dos años tratando de que los demás se interesen por ti.

新年快乐     的好奇心的猫死亡

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:RTC DS1307 en XC8 no lee el tiempo
« Respuesta #1 en: 04 de Octubre de 2017, 20:57:51 »
¿ I2C por software ... no podes realizarlo por hardware ? Como para eliminar posibles problemas de tiempos que tenes sea por instrucciones extras que pone el compilador.


Citar
Estas ultimas funciones funcionan bien, si dentro de "ds1307_get_time" le doy un valor fijo a sec, lo visualiza bien en el LCD.

No entiendo, decis que si haces :

Código: C
  1. void ds1307_get_time(BYTE * hr, BYTE * min, BYTE * sec) {
  2.     i2cs_start();
  3.     i2cs_write(0xD0);
  4.     i2cs_write(0x00); // Start at REG 0 - Seconds
  5.     i2cs_start();
  6.     i2cs_write(0xD1);
  7.     *(sec) = 30;
  8.     *(min) = bcd2bin(i2cs_read() & 0x7f);
  9.     *(hr) = bcd2bin(i2cs_read() & 0x3f);
  10.     i2cs_stop();
  11.  
  12. }

¿funciona correctamente todo ?

Desconectado micro_pepe

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3216
Re:RTC DS1307 en XC8 no lee el tiempo
« Respuesta #2 en: 04 de Octubre de 2017, 21:04:15 »

Citar
Estas ultimas funciones funcionan bien, si dentro de "ds1307_get_time" le doy un valor fijo a sec, lo visualiza bien en el LCD.

No entiendo, decis que si haces :

Código: C
  1. void ds1307_get_time(BYTE * hr, BYTE * min, BYTE * sec) {
  2.     i2cs_start();
  3.     i2cs_write(0xD0);
  4.     i2cs_write(0x00); // Start at REG 0 - Seconds
  5.     i2cs_start();
  6.     i2cs_write(0xD1);
  7.     *(sec) = 30;
  8.     *(min) = bcd2bin(i2cs_read() & 0x7f);
  9.     *(hr) = bcd2bin(i2cs_read() & 0x3f);
  10.     i2cs_stop();
  11.  
  12. }

¿funciona correctamente todo ?

Con eso solo compruebo que la parte de visualización y paso de parámetros a las funciones está bien.

La idea de hacerlo por software es que la misma librería debería funcionar en cualquier micro, por hardware, cada micro tiene sus registros.

Saludos!!!
Se obtiene más en dos meses interesandose por los demás, que en dos años tratando de que los demás se interesen por ti.

新年快乐     的好奇心的猫死亡

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:RTC DS1307 en XC8 no lee el tiempo
« Respuesta #3 en: 04 de Octubre de 2017, 21:29:13 »
Citar
La idea de hacerlo por software es que la misma librería debería funcionar en cualquier micro

No cuando los compiladores pueden generan distintos tiempos, a no ser que tengas una buena frecuencia y no se note. Segurametne sean problemas de tiempos, si es que todo lo demas funciona correcto ( el DS1307, el PIC, etc)
Por hardware, editas un archivo y listo :P.

Desconectado micro_pepe

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3216
Re:RTC DS1307 en XC8 no lee el tiempo
« Respuesta #4 en: 05 de Octubre de 2017, 08:14:22 »

Por hardware, editas un archivo y listo :P.

A que te refieres, a usar MCC para configurarlo y usar las librerías que genera? Esas librerías son complicadas de usar.
Se obtiene más en dos meses interesandose por los demás, que en dos años tratando de que los demás se interesen por ti.

新年快乐     的好奇心的猫死亡

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:RTC DS1307 en XC8 no lee el tiempo
« Respuesta #5 en: 05 de Octubre de 2017, 08:26:23 »
No, me refiero a independizar la libreria del DS1307 respecto al hardware, asi lo unico que hace es llamar a funciones a otro archivo. Ese otro archivo es el que vas atener que cambiar. o usar #define que detecte el compilador que estes usando.

Desconectado micro_pepe

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3216
Re:RTC DS1307 en XC8 no lee el tiempo
« Respuesta #6 en: 06 de Octubre de 2017, 13:29:07 »
Bueno, lo solucioné con una librería de funciones para el i2c por hardware, y otra a parte para el rtc.

Gracias, un saludo!!!
Se obtiene más en dos meses interesandose por los demás, que en dos años tratando de que los demás se interesen por ti.

新年快乐     的好奇心的猫死亡

Desconectado JulioJMH

  • PIC10
  • *
  • Mensajes: 2
Re:RTC DS1307 en XC8 no lee el tiempo
« Respuesta #7 en: 21 de Noviembre de 2017, 18:36:32 »
Hola señores del foro, me gustaría saber como solucionaron el problema de no poder leer, ya que tengo el mismo problema con un DS1307 y un PIC16F877A. La cosa es que estoy conectando normalmente el PIC con el RTC por SDA y SCL y hago que el RTC se escriba bien (fija la los datos bien, incluso oscila a un segundo de frecuencia) pero cuando voy a a leer de él pareciera que no responde y solo logro leer el buffer la dirección 0xD1 que es lo último que se grabó cuando envío este comando para leer alguna posición en el RTC. La verdad ando un poco agotado, ya que he buscado mucho pero hay poca información sobre PIC y DS1307 con XC8, no entiendo por qué!. Por favor necesito ayuda urgente! alguien que me pueda dar luces?

Desconectado JulioJMH

  • PIC10
  • *
  • Mensajes: 2
Re:RTC DS1307 en XC8 no lee el tiempo
« Respuesta #8 en: 21 de Noviembre de 2017, 18:40:32 »
Hola señores del foro, me gustaría saber como solucionaron el problema de no poder leer, ya que tengo el mismo problema con un DS1307 y un PIC16F877A. La cosa es que estoy conectando normalmente el PIC con el RTC por SDA y SCL y hago que el RTC se escriba bien (fija la los datos bien, incluso oscila a un segundo de frecuencia) pero cuando voy a a leer de él pareciera que no responde y solo logro leer el buffer la dirección 0xD1 que es lo último que se grabó cuando envío este comando para leer alguna posición en el RTC. La verdad ando un poco agotado, ya que he buscado mucho pero hay poca información sobre PIC y DS1307 con XC8, no entiendo por qué!. Por favor necesito ayuda urgente! alguien que me pueda dar luces?

Desconectado antayhua

  • PIC10
  • *
  • Mensajes: 32
Re:RTC DS1307 en XC8 no lee el tiempo
« Respuesta #9 en: 22 de Noviembre de 2017, 22:42:04 »
Ahora la mayoría de los micros incluyen I2C , hace años me complique la vida con una librería I2C usando el pic16f84a, me demore una semana en hacerlo andar, eso era cuando me iniciaba en el mundo de los pic, luego descubri que muchos pic venían con I2C, ahora no me complico la vida.


 

anything