Haz una pregunta
  Foros de Electrónica » Diseño digital » Microcontroladores y sistemas embebidos
Foros Registrarse ¿Olvidaste tu contraseña?

Temas similares

15/01/2016 #1

Avatar de superdog13

Problema I2C - PIC16F1827 [X2]
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:
////////////////////////////////////////////////////////////////////////////////
//                    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:
////////////////////////////////////////////////////////////////////////////////
//                    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:
#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:
#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&quot ni en la comunicación serial. Aunque no es indispensable para el proyecto, también tengo esta duda. ...
15/01/2016 #2

Avatar de J2C

.


No olvides que ambas líneas de I2C deben llevar las resistencias Pull-Up !!!!!

En la primer imagen son las R2 y R3 que no figuran en tu ejemplo del 16F1827. Tengo entendido que no sirve colocar las Pull-Up internas de cada µControlador.




Saludos, JuanKa.-
16/01/2016 #3
Moderador

Avatar de D@rkbytes

superdog13 dijo: Ver Mensaje
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.
La función I2C_POLL(Stream) se usa cuando la transmisión es por hardware.
La ayuda de PIC C dijo:
The I2C_POLL() function should only be used when the built-in SSP is used.
This function returns TRUE if the hardware has a received byte in the buffer.
When a TRUE is returned, a call to I2C_READ() will immediately return the byte that was received.
Entonces la configuración del esclavo debe ser esta:
Código:
#include <16F1827.h>
#fuses   NOMCLR
#use     delay(internal = 32MHz)
#use     I2C(I2C1, SLAVE, SLOW, ADDRESS = 0xA0)
superdog13 dijo: Ver Mensaje
¿Dónde podría estar el error?
He comparado con el código del ejemplo y no veo alguna diferencia con la comunicación.
Se usaron otros PIC y he ahí la gran diferencia.
Siempre se debe tener consideración sobre los puertos involucrados para poder adaptar un programa.
superdog13 dijo: Ver Mensaje
Pd: el Display 7 Segmentos, por alguna razón, no enciende el segmento del medio (ni en la comunicación serial.
Aunque no es indispensable para el proyecto, también tengo esta duda.
El PIC Esclavo está configurado para usar oscilador a cristal, y estás usando los pines del oscilador para controlar el display.
Cuando se usa el oscilador a cristal, esos pines ya no están disponibles como I/O
Aparte, el pin RA5 (MCLR) es únicamente entrada y también lo tienes conectado al display.

Otro detalle a tener en cuenta cuando se simula I2C en proteus, es que se deben configurar las resistencias Pull-Up como digitales, y en tu esquema las dejaste como análogas. (R2, R3 del archivo RAR adjunto.)
Respuesta
¿Tienes una mejor respuesta a este tema? ¿Quieres hacerle una pregunta a nuestra comunidad y sus expertos? Registrate

Foros de Electrónica » Diseño digital » Microcontroladores y sistemas embebidos

Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO ©2011, Crawlability, Inc.