Comunicacion I2C

hola necesito saber en donde puedo encontrar como se configuran todos lo registros de funcion especifica que van asociados con la comunicacion I2C del pic 16f8xx en donde puedo encontrar información para realizar un proyecto y que ojala sea en español gracias de antemano
 
bueno no especificas que lenguajes utilizas para la programación... tampoco qué pretendes conectar mediante i2c si una memoria si otro pic etc.

primero si no va a ser una memoria mira en el datasheet si tiene modulo spi, que es la interrupción de llegada de algun byte por el i2c.

En ccs (compilador c) es facil

defines dirección i2c, y patillas, luego si es master, usamos read y write y a correr


Código:
//VITAL '06
//Ejemplo que demuestra como conectar
//un pic a una memoria i2c y muestra resultados por lcd


#INCLUDE <16F628.H>
#fuses INTrc_io,NOWDT,NOBROWNOUT,NOPROTECT,NOPUT,NOLVP,NOMCLR //ordenes para el programador
#use delay (clock=4000000) //Fosc=4Mhz

#define EEPROM_SDA PIN_A0
#define EEPROM_SCL PIN_A1
//#define EEPROM_SIZE 1024
#define use_portb_lcd

#INCLUDE <2408.C>
#INCLUDE <lcd.c>

void main() {

char caracter[16];
char i,j=0;

   //iniciamos lcd
   lcd_init();
   lcd_putc("\fIniciando...");
   delay_ms(2000);
   lcd_putc("\fIniciando...\n EEPROM");
   init_ext_eeprom();

   while(ext_eeprom_ready())
   {
      for (i=0;i<EEPROM_SIZE;i++)
      {
            if (i>15){
               //desplazamos los caracteres a la izquierda
               for (j=0;j<15;j++)
               {
                  caracter[j]=caracter[j+1];
               }
               caracter[15]= read_ext_eeprom(i);
               printf(lcd_putc, "\fLeido \n%s", caracter);
               delay_ms(500);
            }
            else
               caracter[i]= read_ext_eeprom(i);
      }
   }

}
 
elmasvital dijo:
bueno no especificas que lenguajes utilizas para la programación... tampoco qué pretendes conectar mediante i2c si una memoria si otro pic etc.

gracias pelao lo que necesito conectar es un micro (16fxx) con una memoria y el programa lo hago en ensamblador (mplap) gracias de antemano por la ayuda
 
DARFER dijo:
elmasvital dijo:
bueno no especificas que lenguajes utilizas para la programación... tampoco qué pretendes conectar mediante i2c si una memoria si otro pic etc.

gracias pelao lo que necesito conectar es un micro (16fxx) con una memoria y el programa lo hago en ensamblador (mplap) gracias de antemano por la ayuda

Te has dignado a leer un poco de los application notes de microchip? Yo tuve que hacer algo asi hace un tiempo y estaba todo en las application notes.
 
utilizen un lenguaje como el PICBASIC o el PICC compiler es mas facil hacer una comunicacion I2C, yo tengo uno hecho entre el PIC16F628A y una memoria 24C256 funciona bien solo que el simulador (Proteus) es muy lento y aveces ocurre una falla, talvez alguien me ayude con eso, ha! y variando las resistencias de Pull Up mejora un poco.
 
Bueno, estoy probando las comunicación entre dos PIC's, ya me funciono la comunicación SPI.

En un PIC (el maestro) tengo conectado un teclado Hexagesimal, en el otro PIC (esclavo) tengo conectado un LCD 16x2, la idea es que al oprimir una tecla del teclado se vea en el LCD.

Primero el código del Maestro

Código:
#include<16F877A.h>
#use delay(clock=4000000)


#Byte PORTB = 0x006

#fuses XT,NOWDT,NOPROTECT,NOPUT,NOBROWNOUT,NOLVP


//******Declaración de Funciones****************
char Teclado();



void main()
{
   char Tecla;

   setup_spi(spi_master |spi_h_to_l |spi_clk_div_16 );
   set_tris_a(0x17);
   set_tris_b(0x0F);
   set_tris_c(0b11010111);

   do
   {
      output_low(PIN_A4);
      Tecla = 'F';
      while(Tecla == 'F')
      {
         Tecla = Teclado();
      }
      while('F' != Teclado())
      {  
           output_high(PIN_A4);
      }
      spi_write(Tecla);      
   }while(true);

}


char Teclado()//Función para leer el Teclado Hexa
{
   PORTB = 0xFF;
   delay_ms(10);
   if((PORTB & 0xF0) > 0)
   {
      PORTB = 0x8F;
      delay_ms(10);
      switch(PORTB & 0x0F)
      {
         case 1:{return('*');}break;
         case 2:{return('7');}break;
         case 4:{return('4');}break;
         case 8:{return('1');}break;
         default:{}
      }
      PORTB = 0x4F;
      delay_ms(10);
      switch(PORTB & 0x0F)
      {
         case 1:{return('0');}break;
         case 2:{return('8');}break;
         case 4:{return('5');}break;
         case 8:{return('2');}break;
         default:{}
      }
      PORTB = 0x2F;
      delay_ms(10);
      switch(PORTB & 0x0F)
      {
         case 1:{return('#');}break;
         case 2:{return('9');}break;
         case 4:{return('6');}break;
         case 8:{return('3');}break;
         default:{}
      }
      PORTB = 0x1F;
      delay_ms(10);
      switch(PORTB & 0x0F)
      {
         case 1:{return('D');}break;
         case 2:{return('C');}break;
         case 4:{return('B');}break;
         case 8:{return('A');}break;
         default:{}
      }
   }
   return('F');
}

Codigo del Esclavo

Código:
#include<16F877A.h>
#use delay(clock=4000000)


#define use_portb_lcd = TRUE
#Byte PORTB = 0x006
#include<lcd.c>
#fuses XT,NOWDT,NOPROTECT,NOPUT,NOBROWNOUT,NOLVP




void main()
{
   int Tecla;

   setup_spi(spi_slave | spi_h_to_l | spi_clk_div_16 | spi_ss_disabled );
   set_tris_c(0b11011111);
   
   lcd_init();
   do
   {
      while(spi_data_is_in())
      Tecla = spi_read();
      lcd_gotoxy(1,1);
      printf(lcd_putc,"Recibe: %c",Tecla);
   }while(true);

}

Recuerden la conexión se los pines, C3<->C3 C4<->C5 C5<->C4


Luego les paso el protocolo I2C, cuando lo pruebe.
 
hey men bastante bueno eso que tienes, pero si el esclavo decidiera responder algo al maestro ¿como haces?...
que instrucion se utilizaria,..., otra cosa, serias tan amable de darme una breve explicacion de lo que hacen la instruccion case, switch, break...algo breve pero didactico te lo agradezco de antemano ..soy novato
 
Bueno, realmente no probe el caso en que el esclavo respondiera, pero para hacerlo se puede hacer lo siguiente:

en el maestro:

Código:
spi_write(dato);
dato_devuelto = spi_read();

y en el esclavo:

Código:
dato_recibido = spi_read(dato_a_mandar);


no estoy seguro, es cuestión de probar, de aca se destaca que el maestro es el que debe empezar la comunicación mandando algo, y el esclavo apenas reciba ese algo podrá responder por medio de la función read (a la vez recibe y envía).


Sobre el switch, hay ocasiones en que respecto a una variable se pueden hacer muchas preguntas como por ejemplo si es 1 ó si es 2 ó si es 3 etc... esto nos llenaría de if dentro de otro if y otro y otro, para este caso lo mejor es usar switch.

en el switch ponemos la variable a analizar, y dentro de este ponemos los diferentes casos

Código:
switch(variable_a_analizar)
{
       case 0:{//esto se hace si variable_a_analizar vale cero}break;//el break siempre debe ir al final de cada caso.
       case 2:{//esto se hace si variable_a_analizar vale uno}brak;
           .
           .
           .
       case n:{//n es el límite que Ud necesite}break;
       default:{//esto se hace si no se dió ningún caso}//aca no se pone break
}

variable_a_analizar puede ser tambien de tipo char y en los casos pregunar case 'A' por ejemplo.

En resumen el switch es la mejor opción para los casos donde a partir del valor de una variable se puedan tomar mas de dos caminos, si son solo dos caminos pues bastará un if.

Espero haber sido de ayuda.

Gracias
 
Tuve un pequeño error en lo que coloque anteriormente, puse case 2:{//si la variable_a_analizar vale uno}, corrijo
case 2:{//si la variable_a_analizar vale dos} ó case 1:{//si la variable_a_analizar vale uno}.


Gracias
 
que tal el chelo, oye ya probe enviar datos del esclavo al maestro como sugeristes pero nada de nada, el maestro envia pero el esclavo no quiere responder
 
Bueno, ya probe el envío esclavo maestro, no estaba tan lejos



En el Maestro debe poner

Valor_a_leer = spi_read(0); //Se espera el dato y a la vez se activa la señal de reloj (mandando 0)


En el esclavo

No_importa = spi_read(Dato_a_enviar); //En No_importa quedaría el 0, y a la vez envía el dato del esclavo hacia el maestro.


Espero que ahora si le funcione.
 
Con la comunicación SPI se pueden crear redes de un PIC maestro y varios PIC esclavos, solo será necesario que del maestro salga una linea de enable a cada esclavo, todos los pics comparten las lineas de clk RDO RDI, entonces cuando se necesite enviar un dato al PIC esclavo numero 1, abra que activar el enable de ese PIC, desactivar el enable de los otros y enviar el dato.


Otro tipo de comunicacion que funciona para hacer una red sería I2C que es muy similar a SPI, en esta se fija una direccion para cada PIC esclavo, asi antes de enviar un dato primero se envía la direccion al esclavo que se quiere comunicar y luego si envía los datos.

también esta la comunicación rs485, en la cual igualmente sirve para crear una red de PICs.


Creo que a eso se refería tu pregunta.
 
ok en lo que respecta a la teoria de estas comunicaciones estoy mas o menos claro he leido bastante el problema es a la hora de programarlas en ccs..las he programado en assembler pero en c me ha costado ..mi pregunta es si es posible el diseño de redes con el protocolo tcp/ip en los pic, que me dices de eso habras leido algo
 
Ya comprendo tu pregunta, si es posible, primero se podría desarrollar el protocolo tcp/ip en el PIC vía software, yo personalmente a nivel de voltajes y tiempos no conozco como funciona el tcp/ip, pero sea como sea creo que esto no sería nada fácil de desarrollar, segundo se podría emplear el siguiente integrado Enc28j60, este integrado se convertiría en el puerto ethernet del PIC, la comunicación entre el integrado y el PIC es vía SPI de está manera si se hace mucho mas posible crear la red tcp/ip que quieres.
 
Atrás
Arriba