Protocolo I2C «maestro-esclavo», PIC C Compiler

En esta sección aprenderás a conectar dos microcontroladores PIC mediante el protocolo I2C censando un potenciómetro conectado a una entrada analógica en un PIC maestro y mostrando su valor en una pantalla LCD conectada a un PIC esclavo.

Circuito de conexión

Programación PIC Maestro

Inicialmente se establecen los parámetros de comunicación I2C del PIC Maestro.

Se establecen los pines de comunicación del PIC18F4550 donde sda=PIN_B0 y scl=PIN_B1 de acuerdo con la hoja de datos del PIC.

FORCE_SW: Utiliza las funciones I2C del Software.

#use i2c(Master,Fast, sda=PIN_B0, scl=PIN_B1,force_sw)//parametros I2C

Se habilita la conversión analógico digital (ADC) para la lectura del potenciómetro.

setup_adc(ADC_CLOCK_INTERNAL);

Se habilita la lectura del pin analógico AN0 conectado al potenciómetro.


set_adc_channel(0);//lectura Vout del potenciometro en pin AN0

Se asigna una variable de 8 bits necesarios para poder transmitir la información.

int8 dato;
Se realiza la lectura del valor en el potenciómetro y se guarda en la variable asignada.

dato=read_adc();//lectura del valor

Se inicializa la comunicación mediante el protocolo i2c.

i2c_start();//inicializar la comunicacion i2c

Se envía la dirección del esclavo que recibirá la información.

i2c_write(0xa0);//direccion del esclavo

Se envía la información que se guardo en la variable.

i2c_write(dato);//envia la informacion del dato

Termina la comunicación cuando se envía la información.

i2c_stop();//termina la comunicación

Código PIC Maestro

#FUSES NOMCLR 

#use i2c(Master,Fast, sda=PIN_B0, scl=PIN_B1,force_sw)//parametros I2C

void main()
{
   setup_adc(ADC_CLOCK_INTERNAL);
   set_adc_channel(0);//lectura Vout del potenciometro en pin AN0
   
   int8 dato;

   while(TRUE)
   {

      dato=read_adc();//lectura del valor

      i2c_start();//inicializar la comunicacion i2c
      i2c_write(0xa0);//direccion del esclavo
      i2c_write(dato);//envia la informacion del dato
      i2c_stop();//termina la comunicación
      delay_ms(100);
     
   }
}

Programación PIC Esclavo

Se establecen los parámetro de comunicación del PIC Esclavo.

Se establecen los pines de comunicación del PIC18F4550 donde sda=PIN_B0 y scl=PIN_B1 de acuerdo con la hoja de datos del PIC.

Se establece la dirección del esclavo address=0xa0, este permite al PIC Maestro identificar a que PIC Esclavo se le enviaran los datos.

#use I2C(slave, SDA=PIN_B0, SCL=PIN_B1, address=0xa0)//Parametros I2C 

Se asignan los pines para la conexión del display LCD y se coloca la librería del LCD.

#define LCD_RS_PIN PIN_D6
#define LCD_RW_PIN PIN_D5
#define LCD_ENABLE_PIN PIN_D4
#define LCD_DATA4 PIN_D3
#define LCD_DATA5 PIN_D2
#define LCD_DATA6 PIN_D1
#define LCD_DATA7 PIN_D0

#include <lcd.c>

Dado que la comunicación i2c reciben datos de 8 Bits se asigna una variable que recibirá los datos que envié el PIC maestro.

int8 dato;

La siguiente instrucción espera la recepción de datos, si detecta la recepción de los datos la instrucción retorna 1 o TRUE.

i2c_poll()

Una vez que se detecta la recepción de los datos se procede a la lectura.

dato=i2c_read(); //lectura de datos

La información que se recibe del PIC maestro es la dirección del esclavo más el valor del potenciómetro por lo que despreciamos la dirección para obtener solo el valor del potenciómetro.

if (dato!=0xa0) //desprecimos el dato de direccion
{}

Finalmente se colocan las instrucciones para mostrar el valor del potenciómetro en la pantalla LCD.

lcd_gotoxy(1,1); printf(LCD_PUTC, "\fSENSOR PIN_AN0");
lcd_gotoxy(1,2); printf(LCD_PUTC,"VALOR=%u",dato); 

Código PIC Esclavo

#FUSES NOMCLR 

#use I2C(slave, SDA=PIN_B0, SCL=PIN_B1, address=0xa0)//Parametros I2C 

#define LCD_RS_PIN PIN_D6
#define LCD_RW_PIN PIN_D5
#define LCD_ENABLE_PIN PIN_D4
#define LCD_DATA4 PIN_D3
#define LCD_DATA5 PIN_D2
#define LCD_DATA6 PIN_D1
#define LCD_DATA7 PIN_D0
#include <lcd.c>

void main()
{
   lcd_init();
   int8 dato;
   while(TRUE)
   {
      if (i2c_poll()) //si se reciben datos en el buffer?
      {
         dato=i2c_read(); //lectura de datos
         
         if (dato!=0xa0) //desprecimos el dato de direccion
         {
            lcd_gotoxy(1,1); printf(LCD_PUTC,"\fSENSOR PIN_AN0");
            lcd_gotoxy(1,2); printf(LCD_PUTC,"VALOR=%u",dato);
         }
      }
   }

}
Scroll al inicio