Autor Tema: Ejemplo de utilizacion del Modulo I2C del 16F877a  (Leído 42727 veces)

0 Usuarios y 4 Visitantes están viendo este tema.

Desconectado pibe

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 635
Re: Ejemplo de utilizacion del Modulo I2C del 16F877a
« Respuesta #45 en: 22 de Diciembre de 2008, 19:07:30 »
goto $-1 es volver a la instruccion anterior. Tambien puedes hacer -2 , -3, -4 etc
Mi jefe mirando el prototipo que estoy creando: "Y eso va a funcionar?"

Desconectado antimason

  • PIC12
  • **
  • Mensajes: 81
Re: Ejemplo de utilizacion del Modulo I2C del 16F877a
« Respuesta #46 en: 22 de Diciembre de 2008, 21:02:58 »
goto $-1 es volver a la instruccion anterior. Tambien puedes hacer -2 , -3, -4 etc


Gracias.

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: Ejemplo de utilizacion del Modulo I2C del 16F877a
« Respuesta #47 en: 22 de Diciembre de 2008, 22:38:29 »
Gracias Bruno por la aclaración.
Una pregunta: En el secuencial byte read, puedo leer toda la memoria con una sola instrucción mientras le sigo mandando reloj y CS? O sólo los primeros 64 bytes de la página?

Hola! No. Podés leer toda la memoria entera. Eso si, tene en cuenta que empezarás a leer desde la posición siguiente a la última que has leído. Es decir que primero deberías hacer un random access read a la posicion 0 por ejemplo, y dsps ya usar el secuential read y leer desde la 1 en adelante para asegurarte donde "estas parado".

antimason:

Tu programa escribe y lee siempre la posición 0. Si querés grabar la segunda vez en la posicion 1(que creo que esa era la idea), tenés que indicarlo en DIRH/DIRL antes de leer y grabar por segunda vez.

Saludos.
"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado antimason

  • PIC12
  • **
  • Mensajes: 81
Re: Ejemplo de utilizacion del Modulo I2C del 16F877a
« Respuesta #48 en: 25 de Diciembre de 2008, 21:59:37 »
¿Como se podría implementar el protocolo i2c por software para comunicar un pic16f84a con una memoria externa?.
« Última modificación: 27 de Diciembre de 2008, 08:48:35 por antimason »

Desconectado antimason

  • PIC12
  • **
  • Mensajes: 81
Re: Ejemplo de utilizacion del Modulo I2C del 16F877a
« Respuesta #49 en: 27 de Diciembre de 2008, 11:37:46 »
Estoy intentando escribir en dos posiciones consecutivas de memoria de la misma pagina el 1 y el 2 en binario y lo saco por leds, pues bien en la simulación sale el 1 se borra y acontinuación en vez del 2 se encienden todos los leds = 255 ¿que estoy haciendo mal?. Este es el código:



dato_1      call    i2c_init                 ;configurar y encender I2C
            clrf    DIRH                     ;cargar paginas de 24LC08B en las cuales escribir
            clrf    DIRL                     ;cargar direccion de 24LC08B en las cuales escribir     
            movlw   b'00000001'              ;1 en código binario
            movwf   DATASSP                  ;cargar dato a escribir en la 24LC08B
            call    WriteI2CByte

            call    DEMORA                   ;dar 10ms a que termine la escritura

            clrf    DIRH                     ;cargar paginas de 24LC08B de las cuales leer
            clrf    DIRL                     ;cargar direccion de 24LC08B de las cuales leer
            call    ReadI2CByte

            movf    DATO,w
            movwf   PORTB
            incf    DIRL,F

            call    Retardo_5s
            clrf    PORTB


           
dato_2      clrf    DIRH                     ;cargar paginas de 24LC08B en las cuales escribir
            movlw   b'00000001'              ;Dirección 1 de página 0x00
            movwf   DIRL                     ;cargar direccion de 24LC08B en las cuales escribir     
            movlw   b'00000010'              ;2 en código binario
            movwf   DATASSP                  ;cargar dato a escribir en la 24LC08B
            call    WriteI2CByte

            call    DEMORA                   ;dar 10ms a que termine la escritura

            clrf    DIRH                     ;cargar paginas de 24LC08B de las cuales leer
            movlw   b'00000001'
            movwf   DIRL                     ;cargar direccion de 24LC08B de las cuales leer
            call    ReadI2CByte

            movf    DATO,w
            movwf   PORTB

           
            call    Retardo_5s
            clrf    PORTB

            nop
            goto    $-1

Desconectado pibe

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 635
Re: Ejemplo de utilizacion del Modulo I2C del 16F877a
« Respuesta #50 en: 27 de Diciembre de 2008, 22:35:50 »
Si no me equivoco, una vez has leido el puntero se incrementa automaticamente. Por eso , al hacer incf DIRL le estás diciendo que se salte una direccion de memoria , por lo tanto te lee FF que es el default que llevan grabadas las memorias.
Entonces, deberias leer el dato en 00h, no incrementes, vuelves a leer dato.
A ver si te sale.
Mi jefe mirando el prototipo que estoy creando: "Y eso va a funcionar?"

Desconectado antimason

  • PIC12
  • **
  • Mensajes: 81
Re: Ejemplo de utilizacion del Modulo I2C del 16F877a
« Respuesta #51 en: 28 de Diciembre de 2008, 08:28:48 »
Si no me equivoco, una vez has leido el puntero se incrementa automaticamente. Por eso , al hacer incf DIRL le estás diciendo que se salte una direccion de memoria , por lo tanto te lee FF que es el default que llevan grabadas las memorias.
Entonces, deberias leer el dato en 00h, no incrementes, vuelves a leer dato.
A ver si te sale.


Gracias majo, lo haré.

Desconectado antimason

  • PIC12
  • **
  • Mensajes: 81
Re: Ejemplo de utilizacion del Modulo I2C del 16F877a
« Respuesta #52 en: 28 de Diciembre de 2008, 08:46:48 »
  Aquí está el código en el que le digo que el segundo dato lo lea en la dirección 0x00 (se supone que mas el puntero será 1), pues bien, al simularlo en el proteus presenta el 1 en binario y se apaga esta vez sin que se enciendan todos otra vez como antes ¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿??????????????????????¡QUIERO QUE SALGA EL 2!.....................DESESPERACIÓN, ¿SERÁ EL PROTEUS?.         




            call    i2c_init                ;configurar y encender I2C
            clrf    DIRH                  ;Pagina 0x00
            clrf    DIRL                   ;Dirección 0x00
            movlw   0x01               ;00000001
            movwf   DATASSP        ;cargar dato a escribir en la 24LC256
            call    WriteI2CByte
            call    DEMORA             ;dar 10ms a que termine la escritura
           
            clrf    DIRH                  ;Pagina 0x00 a leer
            clrf    DIRL                   ;Dirección 0x00 a leer
            call    ReadI2CByte

            movf    DATO,w
            movwf   PORTB            ;Lo saca por puerta B

            call    Retardo_5s
            clrf    PORTB


            movlw   0x00
            movwf   DIRH              ;Pagina 0x00
            movlw   0x00
            movwf   DIRL              ;Dirección 0x00
            movlw   0x02              ;00000010
            movwf   DATASSP       ;cargar dato a escribir en la 24LC256
            call    WriteI2CByte
            call    DEMORA            ;dar 10ms a que termine la escritura
           
            clrf    DIRH                 ;Pagina 0x00 a leer
            clrf    DIRL                  ;Dirección 0x00 a leer
            call    ReadI2CByte

            movf    DATO,w
            movwf   PORTB           ;Lo saca por puerta B

            call    Retardo_5s
            clrf    PORTB

            nop
            goto    $-1                 ;vuelve a línea anterior (nop)

Desconectado pibe

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 635
Re: Ejemplo de utilizacion del Modulo I2C del 16F877a
« Respuesta #53 en: 28 de Diciembre de 2008, 16:51:01 »
 
Aqui grabas el primer byte (1) en la posicion 00 00 h

            call    i2c_init                ;configurar y encender I2C
            clrf    DIRH                  ;Pagina 0x00
            clrf    DIRL                   ;Dirección 0x00
            movlw   0x01               ;00000001
            movwf   DATASSP        ;cargar dato a escribir en la 24LC256
            call    WriteI2CByte
            call    DEMORA             ;dar 10ms a que termine la escritura
   
Y aquí lo lees
        
            clrf    DIRH                  ;Pagina 0x00 a leer
            clrf    DIRL                   ;Dirección 0x00 a leer
            call    ReadI2CByte
            movf    DATO,w
            movwf   PORTB            ;Lo saca por puerta B
            call    Retardo_5s
            clrf    PORTB

AQUI SOBREESCRIBES en la misma dirección 00 00h pero con dato (2)

            movlw   0x00
            movwf   DIRH              ;Pagina 0x00
            movlw   0x00
            movwf   DIRL              ;Dirección 0x00
            movlw   0x02              ;00000010
            movwf   DATASSP       ;cargar dato a escribir en la 24LC256
            call    WriteI2CByte
            call    DEMORA            ;dar 10ms a que termine la escritura
   
Y aqui lo lees
        
            clrf    DIRH                 ;Pagina 0x00 a leer
            clrf    DIRL                  ;Dirección 0x00 a leer
            call    ReadI2CByte

            movf    DATO,w
            movwf   PORTB           ;Lo saca por puerta B

            call    Retardo_5s
            clrf    PORTB

            nop
            goto    $-1                 ;vuelve a línea anterior (nop)

Yo es que si lees un post anterior mío, he desistido con el I2c porque no hubo manera que me funcionara. Me he volcado por la SPI que no tuve problemas.
Supongo que las maneras de manejar los datos y direcciones serán los mismos.
Ahora, lo que tendrías que hacer es :
GRABAR un dato en dirección 00 00
GRABAR un dato en dirección 00 01

Luego lees el dato en dirección 00 00 y lo muestras, luego lees el dato en dirección 00 01 y lo muestras.
Creo que incluso puedes leer ambos datos consecutivos sin dejar de enviarle reloj : Lees el dato en dirección 00 00 y la dirección se incrementa automáticamente y lees el dato 2 sin cortar el reloj, inmediatamente después de leer el dato 1.

O sea:
Grabas ambos datos en distintas direcciones.
Envias comando lectura
dirección 00 00
Lees byte 1
guardar en variable 1
Lees byte 2
guardar en variable 2

Mostrar variable 1
pausa
Mostrar variable 2


El truco aqui es que guardes en una variable cada byte leído, porque no puedes cortar el reloj para mostrar los datos.

Prueba y me cuentas


« Última modificación: 28 de Diciembre de 2008, 16:54:35 por pibe »
Mi jefe mirando el prototipo que estoy creando: "Y eso va a funcionar?"

Desconectado antimason

  • PIC12
  • **
  • Mensajes: 81
Re: Ejemplo de utilizacion del Modulo I2C del 16F877a
« Respuesta #54 en: 28 de Diciembre de 2008, 21:37:38 »



Pibe te he hecho caso en lo de escribir los dos datos consecutivamente en memoria, pero no en lo de usar variables pues debo declararlas y ocupar memoria de programa, imagínate miles de datos en memoria con miles de variables declaradas (a lo mejor he dicho una burrada pero creo que es así), posteriormente he sacado los datos uno tras otro, pero al sacar el segundo dato se me ha ocurrido poner otra vez el "call    i2c_init", y mira por donde ahora si me funciona, (¿que opinará Brunof?). De momento esto ya funciona, pero seguiré buscando otra estructura de programa que funcione, aquí el código pibe:                 


                 






escribo_dato1               call    i2c_init                  ;configurar y encender I2C
                                   clrf    DIRH                     ;Pagina 0x00
                                   clrf    DIRL                      ;Dirección 0x00
                                   movlw   0x01                  ;00000001
                                   movwf   DATASSP           ;cargar dato a escribir en la 24LC256
                                   call    WriteI2CByte
                                   call    DEMORA                ;dar 10ms a que termine la escritura
   
         


escribo_dato2                movlw   0x00
                                    movwf   DIRH                 ;Pagina 0x00
                                    movlw   0x01
                                    movwf   DIRL                  ;Dirección 0x01
                                    movlw   0x02                  ;00000010
                                    movwf   DATASSP           ;cargar dato a escribir en la 24LC256
                                    call    WriteI2CByte
                                    call    DEMORA                ;dar 10ms a que termine la escritura
   
         
leo_primer_dato            clrf    DIRH                      ;Pagina 0x00 a leer
                                   clrf    DIRL                       ;Dirección 0x00 a leer
                                   call    ReadI2CByte
             
                                   movf    DATO,w
                                   movwf   PORTB                 ;Lo saca por puerta B

                                   call    Retardo_5s
                                   clrf    PORTB
                                   call    Retardo_5s
         

leo_segundo_dato         call    i2c_init                     ;configurar y encender I2C
                                   clrf    DIRH                        ;Pagina 0X00 a leer
                                   movlw   0x01
                                   movwf   DIRL                    ;Direccion 0X01 a leer
                                   clrw
                                   call    ReadI2CByte
             
                                   movf    DATO,w
                                   movwf   PORTB                 ;Lo saca por puerta B

                                   call    Retardo_5s
                                   clrf    PORTB

                                   nop
                                   goto    $-1                        ;vuelve a línea anterior (nop)


Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: Ejemplo de utilizacion del Modulo I2C del 16F877a
« Respuesta #55 en: 30 de Diciembre de 2008, 03:03:02 »
Hola. Mira, yo creo que debe ser un error del Proteus. Al menos esa es mi opinión porque estás haciendo los pasos correctamente. Tal vez sea hora de probarlo en la realidad si tienes la posibilidad.

Saludos.
"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado antimason

  • PIC12
  • **
  • Mensajes: 81
Re: Ejemplo de utilizacion del Modulo I2C del 16F877a
« Respuesta #56 en: 30 de Diciembre de 2008, 10:33:55 »
Hola. Mira, yo creo que debe ser un error del Proteus. Al menos esa es mi opinión porque estás haciendo los pasos correctamente. Tal vez sea hora de probarlo en la realidad si tienes la posibilidad.

Saludos.

Gracias, ¿pero te refieres al último código que he puesto o al anterior?.

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: Ejemplo de utilizacion del Modulo I2C del 16F877a
« Respuesta #57 en: 30 de Diciembre de 2008, 14:47:05 »
Sin el segundo i2c_init debería funcionar también asi que creo que me podría referir a cualquiera de ambos.

Saludos
"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado antimason

  • PIC12
  • **
  • Mensajes: 81
Re: Ejemplo de utilizacion del Modulo I2C del 16F877a
« Respuesta #58 en: 31 de Diciembre de 2008, 09:54:42 »
He creado un archivo .bin para simularlo en el proteus. El siguiente código solo pretende leer lo que hay en memoria en las páginas y direcciones asignadas,
supongo que funcionaria en la realidad (grabando previamente en la eeprom externa claro), pero con el proteus que tengo no hay manera.






eo_primer_dato          call    i2c_init                   ;configurar y encender I2C
                                 clrf    DIRH                      ;Pagina 0x00 a leer
                                 clrf    DIRL                       ;Dirección 0x00 a leer
                                 call    ReadI2CByte
             
                                 movf    DATO,w
                                 movwf   PORTB                 ;Lo saca por puerta B

                                 call    Retardo_5s
                                 clrf    PORTB
                                 call    Retardo_5s
         

leo_segundo_dato       clrf     DIRH                  ;Pagina 0X00 a leer
                                 movlw   0x01
                                 movwf   DIRL                  ;Direccion 0X01 a leer
                                 clrw
                                 call    ReadI2CByte
             
                                 movf    DATO,w
                                 movwf   PORTB                 ;Lo saca por puerta B

                                 call    Retardo_5s
                                 clrf    PORTB

                                nop
                                goto    $-1                   ;vuelve a línea anterior (nop)

Desconectado alogic.on

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 772
Re: Ejemplo de utilizacion del Modulo I2C del 16F877a
« Respuesta #59 en: 17 de Enero de 2009, 19:45:27 »
hola, me he tomado la lbertad de intentar usar el ejemplo de Bruno para utilizar el bus i2c con una memoria 24lc256 que son las que tengo a mano. La intencion es copiar 256bytes de esta, guardarlos en la eeprom y viceversa, para ello estoy preparando esta macro de momento la de lectura

Código: ASM
  1. CONFIG_I2C              MACRO
  2. ;RC4=SDA
  3. ;RC3=SCL                Y LOS DOS COMO ENTRADA??
  4.                 movlw   B'00011000'
  5.                 banksel TRISC         ;banco 1
  6.                 iorwf   TRISC,F
  7.                 BANKSEL SSPSTAT                        
  8.                 MOVLW   B'00000000'                     ;7----> SMP     0=VELOCIDAD 400KHZ
  9.                                                                         ;6----> CKE     0=EL DATO SE TRANSMITE EN FLANCO DE SUBIDA
  10.                                                                         ;5----> D/A     1=INDICA QUE EL ULTIMO DATO REC/TRANSMITIDO ERA UN DATO
  11.                                                                         ;                               0=INDICA QUE ERA UNA DIRECCION
  12.                                                                         ;4----> P       1=INDICA QUE HA SIDO DETECTADA UNA CONDICION DE STOP
  13.                                                                         ;                               0=NO SE HA DETECTADO STOP
  14.                                                                         ;3----> S       1=SE HA DETECTADO UNA CONDICION DE START
  15.                                                                         ;                               0=NO SE HA DETECTADO UNA CONDICION DE START
  16.                                                                         ;2----> R_W     1=TRANSMISION EN PROGRESO
  17.                                                                         ;                               0=TRANSMISION FINALIZADA
  18.                                                                         ;1----> UA      SOLO EN I2C DIRECCION 10BITS
  19.                                                                         ;0----> BF              1=LA TRANSMISION ESTA EN PROGRESO SSPBUF LLENO
  20.                                                                         ;                               0=LA TRANSMISION HA FINALIZADO SSPBUF VACIO
  21.                 MOVWF   SSPSTAT
  22.         ;-------------------------------
  23.                 BANKSEL SSPCON
  24.                 MOVLW   B'00101000'                     ;7----> WCOL    0=NO HAY COLISION
  25.                                                                         ;                               1=SE HA ESCRITO SSPBUF MIENTRAS SE HACIA UNA TRANSMISION       
  26.                                                                         ;6----> SSPOV   0=NO HAY OVERFLOW
  27.                                                                         ;                               1=UN BYTE SE HA RECIBIDO SIN LEER EL ANTERIOR   dEBE SER BORRADO POR SOFT                      
  28.                                                                         ;5----> SSPEN   1=HABILITA EL I2C Y LOS PINES SDA SCL
  29.                                                                         ;4----> CKP     0=MANTIENE EL RELOJ EN ESTADO BAJO
  30.                                                                         ;                               1=HABILITA EL RELOJ
  31.                                                                         ;3-0--> SSPM3-0 1000=MAESTRO reloj=f_osc/4*(sspadd+1)
  32.                 MOVWF   SSPCON
  33.         ;-------------------------------
  34.                 BANKSEL SSPCON2
  35.                 MOVLW   B'00010000'
  36.                                                                         ;7----> GCEN    SOLO EN ESCLAVO
  37.                                                                         ;6----> ACKSTAT EN MODO MASTER TRANSMISION, EL ESCLAVO ENVIA EL ACK CUANDO HA RECIBIDO EL DATO
  38.                                                                         ;                               1=NO RECIBIDO ACK DEL ESCLAVO
  39.                                                                         ;                               0=ACK RECIBIDO DEL ESCLAVO
  40.                                                                         ;5----> ACKDT   EN MODO MASTER RECEPCION, EL MASTER ENVIA UN ACK CUANDO HA TERMINADO DE RECIBIR
  41.                                                                         ;                               1=NO ACK
  42.                                                                         ;                               0=SI ACK
  43.                                                                         ;4----> ACKEN   EN MODO MASTER RECEPCION
  44.                                                                         ;                               1= INICIA LA SECUENCIADE SDA SCL, Y TRANMITE EL ACKDT BORRADO POR HARDWARE
  45.                                                                         ;                               0=DESHABILITADO
  46.                                                                         ;3----> RCEN    EN MASTER I2C
  47.                                                                         ;                               1= RECEPCION HABILITADA
  48.                                                                         ;                               0= RECEPCION DESHABILITADA
  49.                                                                         ;2----> PEN             SOLO EN I2C MASTER
  50.                                                                         ;                               1=INICIA UNA SECUENCIA DE STOP BORRADO POR HARD
  51.                                                                         ;                               0=DESHABILITADA
  52.                                                                         ;1----> RSEN    SOLO EN I2C MASTER START REPETIDO
  53.                                                                         ;                               1=INICIA CONDICION DE SR BORRADO POR HARD
  54.                                                                         ;                               0=DESHABILITADO
  55.                                                                         ;0----> SEN             SOLO EN I2C MASTER
  56.                                                                         ;                               1=INICIA LA CONDICION START EN SCL SDA BORRADO POR HARD
  57.                                                                         ;                               0=DESHABILITADO
  58.  
  59.                 MOVWF   SSPCON2
  60.                 banksel SSPADD
  61.                 movlw   b'00001011'             ;.11 para 400khz @ 20 mhz
  62.                 movwf   SSPADD                  ;400 khz @ 20 mhz
  63.                 ENDM
  64. I2C_BUS                 MACRO
  65.  
  66.                 CALL    RESET_DIRECCION ;APUNTA AL PAD 00, HABRA QUE BUSCAR LA FORMA DE SELECIONAR ENTRE VARIOS CADA 255 BYTES
  67. I2C_MEMO_READ
  68.                 BANKSEL SSPCON
  69.                 BSF             SSPCON, CKP     ;PRIMERO INICIA EL RELOJ
  70.                 CALL    IIC_START               ;ENVIA LA CONDICION DE START
  71.                 MOVLW   B'10100001'             ;CONTROL BYTE--> |STARTBIT|1|0|1|0|A2|A1|A0|RW|ACK
  72.                 CALL    IIC_ENVIA               ;Y SE LO ENVIA A LA EEPROM
  73.                 CALL    IIC_ADRESS              ;MANDA DIRH,ESPERA ACK,MANDA DIRL, ESPERA ACK, RETURN
  74. SIGUE_READ
  75.                 BANKSEL SSPCON2
  76.                 BSF     SSPCON2,RCEN    ;activar modo lectura
  77.                 BTFSC   SSPCON2,RCEN    ;termino la recepcion? 
  78.                 GOTO    $-1
  79.                 BTFSS   SSPSTAT,BF      ;dato disponible en SSPBUF para ser leido?
  80.             GOTO    $-1                 ;no, esperar
  81.                 BANKSEL DIRL
  82.                 INCFSZ  DIRL,F                  ;UNA VEZ LLEGA A 255 SALE DE LA RUTINA
  83.                 GOTO    GUARDA_PADS
  84. IIC_STOP       
  85.                 BANKSEL SSPCON2
  86.                 BSF             SSPCON2,PEN
  87.                 BTFSC   SSPCON2,PEN
  88.                 GOTO    $-1
  89.                 BANKSEL SSPCON
  90.                 BCF             SSPCON, CKP     ;APAGA EL RELOJ
  91.                 RETURN                                 
  92.  
  93. GUARDA_PADS
  94.                 BANKSEL SSPBUF
  95.                 MOVF    SSPBUF,W
  96.                 BANKSEL REG_MUESTRA
  97.                 MOVWF   REG_MUESTRA
  98.                 CALL    ESCRITURA_EEPROM_IIC    ;Y GUARDA EL DATO EN LA EEPROM
  99.                 GOTO    SIGUE_READ
  100.  
  101. IIC_IDLE
  102.                 BANKSEL SSPSTAT
  103.                 BTFSC   SSPSTAT,R_W
  104.                 GOTO    $-1
  105.  ;  movf       SSPCON2,w ; POR QUE SE HACE ESTO
  106.  ;  andlw       0x1F
  107.  ;  btfss       STATUS,Z
  108.  ;  goto       $-3
  109.  
  110.                 RETURN
  111.  
  112. ESCRITURA_EEPROM_IIC
  113.                 BANKSEL DIRL
  114.                 MOVF    DIRL,W                  ;Data Memory
  115.                 BANKSEL EEADR
  116.                 MOVWF   EEADR                   ;Address to write
  117.                 CLRW
  118.                 ADDWF   EEADR,F                 ;DE ESTA FORMA SE COMIENZA A CONTAR DESDE EL REGISTRO DE POTES
  119.                 GOTO    CONTINUA_ESCRITURA     
  120.                
  121. IIC_ADRESS
  122.                 BANKSEL DIRH
  123.                 MOVF    DIRH,W
  124.                 CALL    IIC_ENVIA
  125.                 BANKSEL DIRL
  126.                 MOVF    DIRL,W
  127.                 CALL    IIC_ENVIA
  128.                 RETURN
  129. IIC_ENVIA
  130.                 CALL    IIC_IDLE                ;ESERA A QUE TERMINE LA ULTIMA TRANSMISION
  131.                 BANKSEL SSPBUF                 
  132.                 MOVWF   SSPBUF
  133.                 BANKSEL SSPCON2
  134.                 RETURN
  135.  
  136. RESET_DIRECCION
  137.                 BANKSEL DIRH                    ;CARGAMOS EN LOS REGISTROS DE DIRECCION A LA QUE QUEREMOS ACCEDER
  138.                 CLRF    DIRH                    ;DE MOMENTO DIRECCION 00
  139.                 CLRF    DIRL
  140.                 RETURN         
  141.  
  142. IIC_START
  143.                 CALL    IIC_IDLE
  144.                 BANKSEL SSPCON2
  145.                 BSF             SSPCON2, SEN    ;INICIA START
  146.                 BTFSC   SSPCON2,SEN
  147.                 GOTO    $-1
  148.                 BANKSEL PIR1
  149.                 BTFSS   PIR1,SSPIF
  150.                 GOTO    $-1
  151.                 BCF             PIR1,SSPIF
  152.                 RETURN
  153.                 ENDM
  154.         ;------------------------------------------

pero hay una cosa que no entiendo de la rutina i2c_idle
Código: ASM
  1. i2c_idle
  2.  
  3.    bsf      STATUS,RP0      ;banco 1
  4.    btfsc       SSPSTAT,R_W
  5.    goto       $-1
  6.  
  7.    movf       SSPCON2,w
  8.    andlw       0x1F
  9.    btfss       STATUS,Z
  10.    goto       $-3
  11.  
  12.    bcf      STATUS,RP0      ;banco 0
  13.    return
para que se suma SSPCON2+0x1F en W y testeas Z ?? perdona pero no me entero de esto. para conocer si el bufer esta lleno, no basta testear el bit R_W

y otra dudilla, he visto en el ejemplo que poneis SDA y SCL como entradas, es así?, los configura el modulo segun se este recibiendo o enviando??

un saludo y gracias