Autor Tema: 16F877A, I2C y DS1307 [SOLUCIONADO]  (Leído 3016 veces)

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

Desconectado LucasBols

  • PIC16
  • ***
  • Mensajes: 129
    • Desarrollos y Servicios Digitales
16F877A, I2C y DS1307 [SOLUCIONADO]
« en: 03 de Junio de 2014, 17:41:25 »
hola, buenas tardes,

estoy aprendiendo a usar el módulo i2c del 877 y a comunicar el pic con el rt ds1307,

después de muchas horas de lectura, encontré esta página http://.../pic-i2c-code-example.php, copié el código, le agregué una especie de mini debug por un lcd y resulta que el código se clava en el envío de los datos por i2c,


el proteus me dice que el clock i2c queda flotante, ese es el warning que se ve,

el código es este:

main.c
Código: C#
  1. #include "main.h"
  2.  
  3. //------------------------------------------------------------------------------
  4.  
  5. int main(void)
  6. {
  7.     /* Buffer where we will read/write our data */
  8.     unsigned char I2CData[] = {0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x09, 0x00};
  9.     t_byte caracter;
  10.  
  11.     /**** PORTD I/O ****/
  12.     TRISEbits.PSPMODE = 0; // PORTD functions in general purpose I/O mode
  13.  
  14.     TRISEbits.TRISE2  = 0; // Output
  15.     TRISEbits.TRISE1  = 0; // Output
  16.     TRISEbits.TRISE0  = 0; // Output
  17.  
  18.     /**** PORTA / PORTE I/O ****/
  19.     ADCON1 = 0b00000111; // RA5:RA0 y RE2:RE0 Digital
  20.  
  21.     TRISA = 0b00000000; // lcd
  22.     TRISE = 0b00000000; // lcd
  23.    
  24.     inicializaLCD();
  25.  
  26.     caracter.byte = _LCD_L1_C_01_;
  27.     enviaComandoLCD( caracter );
  28.  
  29.     /* Initialize I2C Port */
  30.     I2CInit();
  31.     escribeLineaLCD( "1", 0 );
  32.  
  33.     /* Send Start condition */
  34.     I2CStart();
  35.     escribeLineaLCD( "2", 0 );
  36.  
  37.     /* Send DS1307 slave address with write operation */
  38.     I2CSend(0xD0); //#### ACA SE CLAVA ####
  39.     escribeLineaLCD( "3", 0 );
  40.  
  41.     /* Send subaddress 0x00, we are writing to this location */
  42.     I2CSend(0x00);
  43.     escribeLineaLCD( "4", 0 );
  44.  
  45.     /* Loop to write 8 bytes */
  46.     for (unsigned char i = 0; i < 8; i++)
  47.     {
  48.         /* send I2C data one by one */
  49.         I2CSend(I2CData[i]);
  50.     }
  51.     escribeLineaLCD( "5", 0 );
  52.  
  53.     /* Send a stop condition - as transfer finishes */
  54.     I2CStop();
  55.     escribeLineaLCD( "6", 0 );
  56.  
  57.     /* We will now read data from DS1307 */
  58.     /* Reading for a memory based device always starts with a dummy write */
  59.     /* Send a start condition */
  60.     I2CStart();
  61.     escribeLineaLCD( "7", 0 );
  62.  
  63.     /* Send slave address with write */
  64.     I2CSend(0xD0);
  65.     escribeLineaLCD( "8", 0 );
  66.  
  67.     /* Send address for dummy write operation */
  68.     /* this address is actually where we are going to read from */
  69.     I2CSend(0x00);
  70.     escribeLineaLCD( "9", 0 );
  71.  
  72.  
  73.     /* Send a repeated start, after a dummy write to start reading */
  74.     I2CRestart();
  75.     escribeLineaLCD( "0", 0 );
  76.  
  77.     /* send slave address with read bit set */
  78.     I2CSend(0xD1);
  79.     escribeLineaLCD( "1", 0 );
  80.  
  81.  
  82.     caracter.byte = _LCD_L2_C_01_;
  83.     enviaComandoLCD( caracter );
  84.    
  85.     /* Loop to read 8 bytes from I2C slave */
  86.     for (unsigned char i = 8; i > 0; i--) {
  87.         /* read a byte */
  88.         I2CData[i] = I2CRead();
  89.  
  90.         caracter.byte = I2CData[i];
  91.         enviaDatoLCD( caracter );
  92.  
  93.         /* ACK if its not the last byte to read */
  94.         /* if its the last byte then send a NAK */
  95.         if (i - 1)
  96.             I2CAck();
  97.         else
  98.             I2CNak();
  99.     }
  100.     /* Send stop */
  101.     I2CStop();
  102.     /* end of program */
  103.     while (1);
  104. }
  105.  
  106. //------------------------------------------------------------------------------

main.h
Código: C#
  1. //------------------------------------------------------------------------------
  2.  
  3. #ifndef MAIN_H
  4. #define MAIN_H
  5.  
  6. #include <xc.h>
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9.  
  10. #include "i2c_lib.h"
  11. #include "lcd16x2.h"
  12.  
  13. //******************************************************************************
  14. //******** configuracion del pic ***********************************************
  15. //******************************************************************************
  16.  
  17. #define _XTAL_FREQ 4000000 // Velocidad clock en Hz
  18.  
  19. #pragma config FOSC  = XT       // Oscillator Selection bits
  20.                                 // (XT oscillator)
  21.  
  22. #pragma config WDTE  = OFF      // Watchdog Timer Enable bit
  23.                                 // (WDT disabled)
  24.  
  25. #pragma config PWRTE = OFF      // Power-up Timer Enable bit
  26.                                 // (PWRT disabled)
  27.  
  28. #pragma config BOREN = ON       // Brown-out Reset Enable bit
  29.                                 // (BOR enabled)
  30.  
  31. #pragma config LVP   = OFF      // Low-Voltage (Single-Supply)
  32.                                 // In-Circuit Serial Programming
  33.                                 // Enable bit
  34.                                 // (RB3 is digital I/O, HV on MCLR
  35.                                 // must be usedfor programming)
  36.  
  37. #pragma config CPD   = OFF      // Data EEPROM Memory Code
  38.                                 // Protection bit
  39.                                 // (Data EEPROM code protection off)
  40.  
  41. #pragma config WRT   = OFF      // Flash Program Memory Write
  42.                                 // Enable bits
  43.                                 // (Write protection off;
  44.                                 // all program memory may be written
  45.                                 // to by EECON control)
  46.  
  47. #pragma config CP    = OFF      // Flash Program Memory
  48.                                 // Code Protection bit
  49.                                 // (Code protection off)
  50.  
  51. //******************************************************************************
  52. //******** retardos ************************************************************
  53. //******************************************************************************
  54.  
  55. #ifndef __DELAYS__
  56. #define __DELAYS__
  57.     #define __delay_us(x) _delay((unsigned long)((x)*(_XTAL_FREQ/4000000.0)))
  58.     #define __delay_ms(x) _delay((unsigned long)((x)*(_XTAL_FREQ/4000.0)))
  59. #endif
  60.  
  61. //******************************************************************************
  62. //********
  63. //******************************************************************************
  64.  
  65. //------------------------------------------------------------------------------
  66.  
  67. #endif  /* MAIN_H */

i2c_lib.c
Código: C#
  1. #include "i2c_lib.h"
  2.  
  3. //------------------------------------------------------------------------------
  4. /*
  5.  * Function: I2CInit
  6.  * Return:
  7.  * Arguments:
  8.  * Description: Initialize I2C in master mode, Sets the required baudrate
  9.  */
  10. void I2CInit(void)
  11. {
  12.     TRISC3 = 1; /* SDA and SCL as input pin */
  13.     TRISC4 = 1; /* these pins can be configured either i/p or o/p */
  14.     SSPSTAT |= 0x80; /* Slew rate disabled */
  15.     SSPCON = 0x28; /* SSPEN = 1, I2C Master mode, clock = FOSC/(4 * (SSPADD + 1)) */
  16.     SSPADD = 0x28; /* 100Khz @ 4Mhz Fosc */
  17. }
  18.  
  19. //------------------------------------------------------------------------------
  20. /*
  21.  * Function: I2CStart
  22.  * Return:
  23.  * Arguments:
  24.  * Description: Send a start condition on I2C Bus
  25.  */
  26. void I2CStart()
  27. {
  28.     SEN = 1; /* Start condition enabled */
  29.     while (SEN); /* automatically cleared by hardware */
  30.     /* wait for start condition to finish */
  31. }
  32.  
  33. //------------------------------------------------------------------------------
  34. /*
  35.  * Function: I2CStop
  36.  * Return:
  37.  * Arguments:
  38.  * Description: Send a stop condition on I2C Bus
  39.  */
  40. void I2CStop()
  41. {
  42.     PEN = 1; /* Stop condition enabled */
  43.     while (PEN); /* Wait for stop condition to finish */
  44.     /* PEN automatically cleared by hardware */
  45. }
  46.  
  47. //------------------------------------------------------------------------------
  48. /*
  49.  * Function: I2CRestart
  50.  * Return:
  51.  * Arguments:
  52.  * Description: Sends a repeated start condition on I2C Bus
  53.  */
  54. void I2CRestart()
  55. {
  56.     RSEN = 1; /* Repeated start enabled */
  57.     while (RSEN); /* wait for condition to finish */
  58. }
  59.  
  60. //------------------------------------------------------------------------------
  61. /*
  62.  * Function: I2CAck
  63.  * Return:
  64.  * Arguments:
  65.  * Description: Generates acknowledge for a transfer
  66.  */
  67. void I2CAck()
  68. {
  69.     ACKDT = 0; /* Acknowledge data bit, 0 = ACK */
  70.     ACKEN = 1; /* Ack data enabled */
  71.     while (ACKEN); /* wait for ack data to send on bus */
  72. }
  73.  
  74. //------------------------------------------------------------------------------
  75. /*
  76.  * Function: I2CNck
  77.  * Return:
  78.  * Arguments:
  79.  * Description: Generates Not-acknowledge for a transfer
  80.  */
  81. void I2CNak()
  82. {
  83.     ACKDT = 1; /* Acknowledge data bit, 1 = NAK */
  84.     ACKEN = 1; /* Ack data enabled */
  85.     while (ACKEN); /* wait for ack data to send on bus */
  86. }
  87.  
  88. //------------------------------------------------------------------------------
  89. /*
  90.  * Function: I2CWait
  91.  * Return:
  92.  * Arguments:
  93.  * Description: wait for transfer to finish
  94.  */
  95. void I2CWait()
  96. {
  97.     while ((SSPCON2 & 0x1F) || (SSPSTAT & 0x04));
  98.     /* wait for any pending transfer */
  99. }
  100.  
  101. //------------------------------------------------------------------------------
  102. /*
  103.  * Function: I2CSend
  104.  * Return:
  105.  * Arguments: dat - 8-bit data to be sent on bus
  106.  * data can be either address/data byte
  107.  * Description: Send 8-bit data on I2C bus
  108.  */
  109. void I2CSend(unsigned char dat)
  110. {
  111.     SSPBUF = dat; /* Move data to SSPBUF */
  112.      //#### ACA SE CLAVA ####
  113.     while (BF); /* wait till complete data is sent from buffer */
  114.     I2CWait(); /* wait for any pending transfer */
  115. }
  116.  
  117. //------------------------------------------------------------------------------
  118. /*
  119.  * Function: I2CRead
  120.  * Return: 8-bit data read from I2C bus
  121.  * Arguments:
  122.  * Description: read 8-bit data from I2C bus
  123.  */
  124. unsigned char I2CRead(void)
  125. {
  126.     unsigned char temp;
  127.  
  128.     /* Reception works if transfer is initiated in read mode */
  129.     RCEN = 1; /* Enable data reception */
  130.     while (!BF); /* wait for buffer full */
  131.     temp = SSPBUF; /* Read serial buffer and store in temp register */
  132.     I2CWait(); /* wait to check any pending transfer */
  133.     return temp; /* Return the read data from bus */
  134. }
  135.  
  136. //------------------------------------------------------------------------------

i2c_lib.h
Código: C#
  1. #ifndef I2C_LIB_H
  2. #define I2C_LIB_H
  3.  
  4. #include <xc.h>
  5. #include <pic16f877a.h>
  6.  
  7. //------------------------------------------------------------------------------
  8.  
  9. void I2CInit(void);
  10. void I2CStart();
  11. void I2CStop();
  12. void I2CRestart();
  13. void I2CAck();
  14. void I2CNak();
  15. void I2CWait();
  16. void I2CSend(unsigned char dat);
  17. unsigned char I2CRead(void);
  18.  
  19.  
  20. //------------------------------------------------------------------------------
  21.  
  22. #endif  /* I2C_LIB_H */

adjunto el proyecto y el proteus,

muchas gracias,

saludos,
« Última modificación: 04 de Junio de 2014, 13:14:36 por LucasBols »
Un experto es alguien que te explica algo sencillo de forma confusa de tal manera que te hace pensar que la confusión sea culpa tuya.

DSD http://www.dysd.com.ar/

Desconectado LucasBols

  • PIC16
  • ***
  • Mensajes: 129
    • Desarrollos y Servicios Digitales
Re: 16F877A, I2C y DS1307
« Respuesta #1 en: 04 de Junio de 2014, 12:31:01 »
volviendo sobre el tema, noto que en el data del i2c del 877, para el bit BF de SSPSTAT dice esto:

BF: Buffer Full Status bit
    In Transmit mode:
        1 = Receive complete, SSPBUF is full
        0 = Receive not complete, SSPBUF is empty
    In Receive mode:
        1 = Data Transmit in progress (does not include the ACK and Stop bits), SSPBUF is full
        0 = Data Transmit complete (does not include the ACK and Stop bits), SSPBUF is empty

¿no debería decir esto?

BF: Buffer Full Status bit
    In Transmit mode:
        1 = Data Transmit in progress (does not include the ACK and Stop bits), SSPBUF is full
        0 = Data Transmit complete (does not include the ACK and Stop bits), SSPBUF is empty
    In Receive mode:
        1 = Receive complete, SSPBUF is full
        0 = Receive not complete, SSPBUF is empty

porque en el código de envío tengo esto:
Código: C#
  1. SSPBUF = dat;
  2.     while (BF); /* si el data esta bien, esto no deberia ser while ( !BF ) ; ? */
  3.     while ((SSPCON2 & 0x1F) || (SSPSTAT & 0x04));
Gracias,

saludos,
Un experto es alguien que te explica algo sencillo de forma confusa de tal manera que te hace pensar que la confusión sea culpa tuya.

DSD http://www.dysd.com.ar/

Desconectado LucasBols

  • PIC16
  • ***
  • Mensajes: 129
    • Desarrollos y Servicios Digitales
Re: 16F877A, I2C y DS1307
« Respuesta #2 en: 04 de Junio de 2014, 13:14:14 »
solucionado, el problema estaba en el proteus, reemplacé las dos pullup de SCL y SDA por dos de 10k y funcionó

saludos
Un experto es alguien que te explica algo sencillo de forma confusa de tal manera que te hace pensar que la confusión sea culpa tuya.

DSD http://www.dysd.com.ar/


 

anything