Configuración I2C para el PIC16F88 como maestro.

Buenos días a todos!

Estoy tratando de realizar la comunicación con el protocolo I2C.
Maestro: PIC16F88.
Esclavo: Memoria externa EEPROM 24C256.

Como el 16F88 tiene incorporado en su hardware el módulo I2C el caso sólo es configurarlo para que trabaje con este protocolo. Pero es aquí donde tropecé, ya que por mas que leo el datasheet del 16F88 y he buscado información en el foro, no he podido hacerle trabajar al micro en este modo.

Configuré los siguientes registros de la siguiente manera:

SSPCON = 0011 1011
(los 4 bits menos significativos indican al micro que trabaje como maestro según su datasheet).

SSPSTAT = 0000 0000
(los 6 bits menos significativos son banderas y por lo tanto son sólo de lectura).

SSPADD (no configuro, mantiene la dirección a la cual queremos acceder en el esclavo; pero en su modo de 10 bits ya no sé como trabajar con él ).

SSPBUF (no configuro, registro donde se almacena un dato que se va a transmitir)

La EEPROM externa ya la tengo grabada, ya que el grabador que tengo tiene este hardware y sólo tuve que escribir el byte que quiero comunicar. Estoy programando en ensamblador.

Me podría alguien decir cuál es la manera correcta de configurar este PIC para este protocolo?? Tal vez algún pequeño ejemplo?

Adjunto el esquema para explicarme mejor en mi problema.

Gracias y muchos saludos!

Para explicarme mejor he hecho un programa como ejemplo.

En este ejemplo no utilizo la memoria externa (ya que no pude hacerla trabajar), pero sí envío datos serialmente desde una TABLA que tengo en el código.
Es lo mismo que quiero hacer, sólo que con la memoria externa.
En el archivo adjunto está el circuito en PROTEUS y el archivo.HEX
Alguna sugerencia? Estaré atento a cualquier comentario al respecto.
Chau.
 

Adjuntos

  • Memoria externa con I2C.pdf
    16.2 KB · Visitas: 82
  • Ejemplo.zip
    16.9 KB · Visitas: 74
Última edición:
Hola, ese pic en particular tiene una pequeña nota en el manual que dice asi:

"I2C Firmware Controlled Master mode operation
with Start and Stop bit interrupts enabled; slave is
Idle"

En pocas palabras, si puede funcionar en modo maestro, pero lo tienes que hacer por medio de tu codigo porque no lo hace por hardware.

Yo he usado el modulo MSSP del pic16f877 con la nota de aplicación AN976 de microchip y me ha funcionado perfectamente. Ahí mismo viene el funcionamiento y uso del protocolo y usan una memoria EEPROM como la que ocupas.

Saludos!
 
Hola mcpiebot!

En ese punto es exáctamente donde no lo tenía del todo claro:

SSPCON = 0011 1011 (yo lo configuré así)

bit 7....... "0" significa que no hay colisión en la transmisión.
bit 6....... "0" significa que no hay desbordamiento en la transmisión.
bit 5....... "1" así habilito el puerto serial.
bit 4....... "1" significa que el clock está habilitado.

bits 3,2,1,0 sirven para seleccionar el modo de operación del SSP (synchronous serial port).
con "1011" dice la hoja de datos "I2C Firmware Controlled Master mode (Slave Idle)" .

Es eso lo que no entendía bien, pero entonces según tu explicación:

Tengo que hacer funcionar a mi maestro por software!

Bueno, entonces me pondré a trasbajar en eso. No quiero utilizar el 16F877 porque cuesta muchísimo mas del doble, y para lo que quiero hacer no necesito tantos pines.

Muchas gracias por tu ayuda... seguiré comentando. chau.
 
Hola mcpiebot...

Estoy esudiando el protocolo, mas o menos ya lo tengo entendido, pero tengo una duda:

Supongamos configuro los pines del 16F84A (maestro) asi:
RA2 = SDA (serial data)
RA3 = SCL (serial clock)

Cómo configuro el RA2??? como salida o como entrada?? puesto que en un momento enviará datos al esclavo con la dirección que quiere leer de él (actua como salida); en otro momento tiene que reconocer el bit ACKNOWLEDGE que reciba del esclavo (actua como entrada); luego también tiene que recibir el dato que lee del esclavo (actua como entrada).

RA3 lo configuro como salida, puesto que es el que da la señal de clock para sincronizar la transmisión, eso lo tengo claro.

Tienes alguna sugerencia? bueno, gracias y hasta pronto.

Ah!

Se me ocurre que podría ser asi:

1. cambio de banco y configuro RA2 = salida, entonces envío la dirección del esclavo a la que quiero acceder.

2. cambio de banco y configuro RA2 = entrada, entonces leo el bit ACKNOWLEDGE que me envía el esclavo.

3. mantengo RA2 como salida, ya que debo leer un byte que me envía la memoria externa.

Asi sucesivamente... claro, estoy tomando en cuenta las condiciones "START" y "STOP"; también que hay que enviarle al esclavo el byte alto y luego el bayte bajo de la dirección a la que quiero acceder.

Está correcto este algoritmo? asi podría funcionar? en seguida lo pruebo... pero si alguien por ahí tiene un ejemplo de la rutina en assembler me serviría de mucho... gracias y seguire informando del avance..chau.
 
Última edición:
Efectivamente, el PIC16F84A no tiene controlador serial, asi que cuando quieras enviar datos necesitas configurar el pin como salida y cuando los quieras recibir necesitas configurarlo como entrada.... peeeero...

El protocolo I2C establece que en cierto momento los niveles se dejan "flotando" para detectar si hay colisiones en la transmision, y eso no lo vas a poder implementar con pines estandar, te recomiendo mejor que cambies a un PIC que tenga modulo I2C integrado

http://es.wikipedia.org/wiki/I²C
 
Hola mcpiebot...

Estoy esudiando el protocolo, mas o menos ya lo tengo entendido, pero tengo una duda:

Supongamos configuro los pines del 16F84A (maestro) asi:
RA2 = SDA (serial data)
RA3 = SCL (serial clock)

Cómo configuro el RA2??? como salida o como entrada?? puesto que en un momento enviará datos al esclavo con la dirección que quiere leer de él (actua como salida); en otro momento tiene que reconocer el bit ACKNOWLEDGE que reciba del esclavo (actua como entrada); luego también tiene que recibir el dato que lee del esclavo (actua como entrada).

RA3 lo configuro como salida, puesto que es el que da la señal de clock para sincronizar la transmisión, eso lo tengo claro.

Tienes alguna sugerencia? bueno, gracias y hasta pronto.

Ah!

Se me ocurre que podría ser asi:

1. cambio de banco y configuro RA2 = salida, entonces envío la dirección del esclavo a la que quiero acceder.

2. cambio de banco y configuro RA2 = entrada, entonces leo el bit ACKNOWLEDGE que me envía el esclavo.

3. mantengo RA2 como salida, ya que debo leer un byte que me envía la memoria externa.

Asi sucesivamente... claro, estoy tomando en cuenta las condiciones "START" y "STOP"; también que hay que enviarle al esclavo el byte alto y luego el bayte bajo de la dirección a la que quiero acceder.

Está correcto este algoritmo? asi podría funcionar? en seguida lo pruebo... pero si alguien por ahí tiene un ejemplo de la rutina en assembler me serviría de mucho... gracias y seguire informando del avance..chau.

Si, si se puede así, lo que mencionan acerca de lo detectar colisiones es opcional ya que si usas solo un dispositivo pues no habrá colisiones.

Es verdad que tienes que estar cambiando el direccionamiento de los pines pero puedes tomar en cuenta que el pin RA4 de muchos pics de 18 pines es de colector abierto, así te salvarías de los cortocircuitos en los pines.

Tal como mencionas el algoritmo me parece viable, ojala te puedas conseguir un osciloscopio para que puedas ver las señales y avances mas rápido en tu proyecto. Saludos!
 
Hola Chico3001,
gracias por hacer notar el detalle de que se me pueden presentar colisiones durante la transmisión; pero como dice Mcpiebot, como por ahora sólo necesito trabajar con un esclavo, entonces creo que no tendré ese problema.

Mcpiebot, estoy entonces programando ya en base al algoritmo antes mencionado... pero veo en la teoria que hay tres formas de lectura:

Lectura de dirección actual.
Lectura aleatoria.
Lectura secuencial.

Estoy probando la lectura secuencial ya que es la que más se presta a lo que estoy haciendo.
Espero acabar pronto y doy aviso... Hasta pronto.
 
Hola Chico3001,
gracias por hacer notar el detalle de que se me pueden presentar colisiones durante la transmisión; pero como dice Mcpiebot, como por ahora sólo necesito trabajar con un esclavo, entonces creo que no tendré ese problema.

Mcpiebot, estoy entonces programando ya en base al algoritmo antes mencionado... pero veo en la teoria que hay tres formas de lectura:

Lectura de dirección actual.
Lectura aleatoria.
Lectura secuencial.

Estoy probando la lectura secuencial ya que es la que más se presta a lo que estoy haciendo.
Espero acabar pronto y doy aviso... Hasta pronto.

La forma mas sencilla es la de dirección actual pero si ya estas encaminado pues ojala que termines pronto. :)

saludos!
 
Hola amigo ya han pasado 3 años desde que pusiste tu pregunta y ahora soy yo el que tiene el mismo problema, no se si ya habrás solucionado tu problema porque yo tambien estoy tratando de hacer funcionar este pic con el I2C, si ya lo solucionaste por favor dame una mano para yo también poder hacerlo, muchas gracias.
 
Atrás
Arriba