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////////////////////////////////////////////////////////////////////////////////
// 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////////////////////////////////////////////////////////////////////////////////
// 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#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#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 171 veces)