Autor Tema: Problema I2C - PIC16F1827 [X2]  (Leído 2015 veces)

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

Desconectado joseluislo12

  • PIC10
  • *
  • Mensajes: 20
Problema I2C - PIC16F1827 [X2]
« en: 15 de Enero de 2016, 13:43:09 »
Buenos días

Actualmente estoy iniciando en el tema de la comunicación por I2C. Buscando en internet encontré un ejemplo muy básico de la comunicación entre 2 PIC: el maestro tiene un teclado matricial 4X4 y el esclavo tiene una LCD.

El ejemplo en cuestión es el siguiente:



Maestro
Código: [Seleccionar]
////////////////////////////////////////////////////////////////////////////////
//                    COMUNICACIÓN I2C EN TRE DOS PIC                         //
//                                                                            //
//                      Aplicación para PIC MAESTRO                           //
//                                                                            //
//       El PIC maestro lee teclado y envía el dato al PIC esclavo via I2C    //
//                      que lo mostrará en un lcd.                            //
//                                                                            //
//                            (c) RobotyPic                                   //
////////////////////////////////////////////////////////////////////////////////

#include <16F876a.h>

#fuses XT,PUT,NOPROTECT,BROWNOUT,NOLVP,NOWDT
#use delay (clock=4000000)                     

#use i2c(MASTER, SDA=PIN_C4, SLOW, SCL=PIN_C3, NOFORCE_SW)

#define use_portb_kbd TRUE       //Configuración puerto b para lectura teclado
#include <kbd.c>                 //Carga archivo para control de teclado

#use standard_io(b)
#use standard_io(c)

int tecla;                       //Dato a transmitir
   
/******************************************************************************/
/***************************** Envío I2C **************************************/
   
void envio_I2C (){
   
      i2c_start();         //Comienzo de la comunicación I2C ...
      i2c_write(0xa0);     //...con la dirección del PIC esclavo...
      i2c_write(tecla);    // Envia dato
      i2c_stop();          //Finalización de la transmisión
  }

/******************************************************************************/
/*************************** FUNCIÓN PRINCIPAL ********************************/

void main(){
   kbd_init();                   //Inicializa función de teclado
   port_b_pullups(TRUE);         
   
   while (true){
     
// Lectura del teclado     
      tecla=kbd_getc();       //En "tecla" valor de la tecla pulsada
      if(tecla!=0){           //Si se pulsa teclado...
            envio_I2C();      //...se envía el dato
            delay_ms(100);
      }
   }
}

Esclavo
Código: [Seleccionar]
////////////////////////////////////////////////////////////////////////////////
//                    COMUNICACIÓN I2C EN TRE DOS PIC                         //
//                                                                            //
//                      Aplicación para PIC ESCLAVO                           //
//                                                                            //
//       El PIC maestro lee teclado y envía el dato al PIC esclavo via I2C    //
//                      que lo mostrará en un lcd.                            //
//                                                                            //
//                            (c) RobotyPic                                   //
////////////////////////////////////////////////////////////////////////////////

#include <16F876a.h>
#fuses XT
#use delay (clock=4000000)

#use standard_io(b)
#use standard_io(c)
#use I2C(SLAVE, SDA=PIN_C4 ,SLOW, SCL=PIN_C3, ADDRESS=0xa0, NOFORCE_SW)

#define use_portb_lcd TRUE
#include <lcd.c>

void main() {
 
   int dato;
   lcd_init(); 
   
   while (1) {
   
      // Recepción por comunicación I2C     
      if(i2c_poll()) {
         dato=i2c_read();
         lcd_putc(dato);                  //Muestra dato recibido por pantalla
         if (dato=='*') lcd_putc("\f");   //Si es * borra la pantalla lcd
         }
   }
}

Este ejemplo funciona correctamente.

Ahora bien, el PIC que yo voy a utilizar es un PIC16F1827, por lo que realicé algunos cambios en el programa:



Maestro
Código: [Seleccionar]
#include <16F1827.h>
#fuses XT,PUT,NOPROTECT,BROWNOUT,NOLVP,NOWDT
#use delay(clock=32M)
#use RS232(BAUD=9600, XMIT=PIN_B2, RCV=PIN_B1, stream=com,errors)
//#use i2c(MASTER, SDA=PIN_B1, SLOW, SCL=PIN_B4, NOFORCE_SW)

char i = 0;

/*void envio_I2C (){
   i2c_start();
   i2c_write(0xA0);
   i2c_write(i);
   i2c_stop();
}*/

void main(){
   output_LOW(PIN_B6);
   while(true){
      if(input(PIN_A0)){
         //envio_I2C();
         putc(i);
         output_toggle(PIN_B6);
         i++;
         if(i>9){i=0;}
         while(input(PIN_A0)){;}
      }
   }
}

Esclavo
Código: [Seleccionar]
#include <16F1827.h>
#fuses XT
#use delay(clock=32M)
#use RS232(BAUD=9600, XMIT=PIN_B2, RCV=PIN_B1, stream=com,errors)
//#use I2C(SLAVE, SDA=PIN_B2 ,SLOW, SCL=PIN_B5, ADDRESS=0xA0, NOFORCE_SW)

void main(){
   int num[10] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x83,0xB8,0x80,0x98};
   
   //set_tris_a(0);
   
   output_LOW(PIN_B6);
   
   while(true){
       /*if(i2c_poll()){
         output_a(num[i2c_read()]);
         output_toggle(PIN_B6);
       }*/
       if(kbhit(com)){
         output_a(num[getc()]);
         output_toggle(PIN_B6);
       }
   }
}

Aún siendo un esquema tan sencillo, lo probé antes por comunicación serial (están las líneas de código tanto para comunicación serial como para I2C) y funcionó correctamente.
Luego de unas pruebas con el I2C, y ningún resultado exitoso, le puse un LED a cada PIC para saber cuándo envía un dato, en caso del maestro, y cuando recibe un dato, en caso del esclavo.
En la comunicación serial funcionan correctamente los dos LED.
En la comunicación por I2C, el LED del PIC maestro enciende y apaga correctamente, pero el del PIC esclavo no hace nada.

Dónde podría estar el error ??? He comparado con el código del ejemplo y no veo alguna diferencia con la comunicación.

Pd: el Display 7 Segmentos, por alguna razón, no enciende el segmento del medio ("g") ni en la comunicación serial. Aunque no es indispensable para el proyecto, también tengo esta duda.
* I2C.zip
(15.84 kB - descargado 170 veces)