Autor Tema: Problema para escribir memoria 24lc512 con pic 16f876  (Leído 3806 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado Loren_Son

  • PIC10
  • *
  • Mensajes: 12
Problema para escribir memoria 24lc512 con pic 16f876
« en: 16 de Mayo de 2005, 17:36:00 »
Estoy intentando hacer una prueba, con memoria 24lc512 y pic 16f876. La prueba consiste en que se llene la memoria entera, con el dato 0xBB, creo recordar. El caso es que no consigo escribir ningun bit en dicha memoria, y es algo crucial para mi ya que necesito esto, para mi proyecto de fin de ciclo. El objetivo de esta prueba es conseguir las funciones que luego he de usar en mi proyecto. A continuacion, expongo mi codigo:

;PROGRAMA PARA PROBAR LA GRABACION EN MEMORIAS I2C



      LIST p=PIC16F876
      #include "P16f876.inc"

DIR_ALT      equ   20H      
DIR_ALT_AUX   equ   21H

DIR_BAJ      equ   22H
DIR_BAJ_AUX   equ   23H

SCLAVO      equ   24H
SCLAVO1      equ   25H

DATO      equ   26H
DATO_L      equ   27H

TXBUF      equ   28H

CONT20      equ   29H
CONT100      equ   2AH

; Esto es exclusivo para la prueba

C_MEM_1      equ   2BH
C_MEM_2      equ   2CH


      ORG   0000H
      goto   PROGRAMA

      ORG   0005H
      
;////////////////////////////////////////////////////////////////
;///// FUNCIONES NECESARIAS                               ///////
;////////////////////////////////////////////////////////////////

; FUNCION QUE GENERA EL BIT DE: START

B_START      bcf   STATUS, RP1
      bsf   STATUS, RP0      ; Banco 1

      bsf   SSPCON2, SEN      ; Genera el bit START
      nop

S_START      btfsc   SSPCON2, SEN      
      goto   S_START         ; Espero a que finalice la señal de START

      bcf   STATUS, RP1
      bcf   STATUS, RP0      ; Banco 0

      return

; FUNCION QUE GENERA EL BIT DE: RESTART

B_RESTART   bcf   STATUS, RP1
      bsf   STATUS, RP0      ; Banco 1

      bsf   SSPCON2, RSEN      ; Genera el bit RESTART
      nop

S_RESTART      btfsc   SSPCON2, RSEN      
      goto   S_RESTART         ; Espero a que finalice la señal de START

      bcf   STATUS, RP1
      bcf   STATUS, RP0      ; Banco 0

      return


; FUNCION QUE GENERA EL BIT DE: ACK

B_ACK      bcf   STATUS, RP1
      bsf   STATUS, RP0      ; Banco 1

      bcf   SSPCON2, ACKDT      ; Cargo un cero, para sacarlo luego

      bsf   SSPCON2, ACKEN      ; Genera el bit ACK
      
S_ACK      btfsc   SSPCON2, ACKEN      
      goto   S_ACK         ; Espero a que finalice la señal de ACK

      bcf   STATUS, RP1
      bcf   STATUS, RP0      ; Banco 0

      return

; FUNCION QUE GENERA EL BIT DE: NOACK

B_NOACK      bcf   STATUS, RP1
      bsf   STATUS, RP0      ; Banco 1

      bsf   SSPCON2, ACKDT      ; Cargo un uno, para sacarlo luego

      bsf   SSPCON2, ACKEN      ; Genera el bit NOACK
      
S_NOACK      btfsc   SSPCON2, ACKEN      
      goto   S_NOACK         ; Espero a que finalice la señal de NOACK

      bcf   STATUS, RP1
      bcf   STATUS, RP0      ; Banco 0

      return

; FUNCION QUE GENERA EL BIT DE: STOP

B_STOP      bcf   STATUS, RP1
      bsf   STATUS, RP0      ; Banco 1

      bsf   SSPCON2, PEN      ; Genera el bit STOP
      nop

S_STOP      btfsc   SSPCON2, PEN      
      goto   S_STOP         ; Espero a que finalice la señal de STOP

      bcf   STATUS, RP1
      bcf   STATUS, RP0      ; Banco 0

      return

; FUNCION PARA TRANSMITIR A LAS MEMORIAS I2C

TX      bcf   STATUS, RP1
      bcf   STATUS, RP0      ; Banco 0

      
      movf   TXBUF, W
      movwf   SSPBUF         ; Coloco el dato a transmitir en el buffer de salida del
                  ; bus I2C

      bcf   STATUS, RP1
      bsf   STATUS, RP0      ; Banco 1

ENVIANDO   btfsc   SSPSTAT, R_W      
      goto   ENVIANDO      ; Espero a que se haya transmitido todo el dato

REC_ACK      btfsc   SSPCON2, ACKDT      
      goto   REC_ACK         ; Compruebo que se haya recibido ACK

      bcf   STATUS, RP1
      bcf   STATUS, RP0      ; Banco 0

      return



; FUNCION QUE REALMENTE SE ENCARGA DE LA ESCRITURA EN LAS MEMORIAS I2C

ESC_MEMO   movf   DIR_ALT_AUX, W
      movwf   DIR_ALT         ; Paso la parte alta de la direccion, en la funcion

      movf   DIR_BAJ_AUX, W
      movwf   DIR_BAJ         ; Paso la parte baja de la direccion, en la funcion

      call   B_START         ; Genero el bit de START

      movf   SCLAVO, W
      movwf   TXBUF         ; Coloco el dato, para poder pasarlo a la funcion TRANSMITIR

      call   TX         ; Transmito el dato

      movf   DIR_ALT, W
      movwf   TXBUF         ; Coloco la parte alta de la direccion,
                  ; para poder pasarlo a la funcion TRANSMITIR

      call   TX         ; Transmito el dato

      movf   DIR_BAJ, W
      movwf   TXBUF         ; Coloco la parte baja de la direccion,
                  ; para poder pasarlo a la funcion TRANSMITIR

      call   TX         ; Transmito el dato

      movf   DATO, W
      movwf   TXBUF         ; Coloco el dato a escribir,
                  ; para poder pasarlo a la funcion TRANSMITIR

      call   TX         ; Transmito el dato

      call   B_STOP         ; Genero el bit de STOP

ESCRITO      call   B_START         ; Genero el bit de START

      movf   SCLAVO, W
      movwf   TXBUF

      movf   TXBUF, W
      movwf   SSPBUF         ; Coloco el dato a transmitir en el buffer de salida del
                  ; bus I2C
      bcf   STATUS, RP1
      bsf   STATUS, RP0      ; Banco 1

ENVIANDO2   btfsc   SSPSTAT, R_W      
      goto   ENVIANDO2      ; Espero a que se haya escrito todo el dato

      btfsc   SSPCON2, ACKDT      
      goto   ESCRITO         ; Compruebo que se haya recibido ACK

      bcf   STATUS, RP1
      bcf   STATUS, RP0      ; Banco 0


      

      return

; FUNCION QUE REALMENTE SE ENCARGA DE LA LECTURA DE LAS MEMORIAS I2C

LEC_MEMO   movf   DIR_ALT_AUX, W
      movwf   DIR_ALT         ; Paso la parte alta de la direccion, en la funcion

      movf   DIR_BAJ_AUX, W
      movwf   DIR_BAJ         ; Paso la parte baja de la direccion, en la funcion

      call   B_START         ; Genero el bit de START

      movf   SCLAVO, W
      movwf   TXBUF         ; Coloco el dato, para poder pasarlo a la funcion TRANSMITIR

      call   TX         ; Transmito el dato

      movf   DIR_ALT, W
      movwf   TXBUF         ; Coloco la parte alta de la direccion,
                  ; para poder pasarlo a la funcion TRANSMITIR

      call   TX         ; Transmito el dato

      movf   DIR_BAJ, W
      movwf   TXBUF         ; Coloco la parte baja de la direccion,
                  ; para poder pasarlo a la funcion TRANSMITIR

      call   TX         ; Transmito el dato


      call   B_RESTART      ; Genero el bit RESTART

      movf   SCLAVO, W
      movwf   TXBUF         ; Coloco el dato, para poder pasarlo a la funcion TRANSMITIR

      bsf   TXBUF, 0      ; Preparo la cabecera para indicar lectura

      call   TX         ; Transmito el dato

; FUNCION PARA RECIBIR DE LAS MEMORIAS I2C

      bcf   STATUS, RP1
      bsf   STATUS, RP0      ; Banco 1

      bsf   SSPCON2, RCEN      ; Genera el comienzo de la LECTURA
      nop

LLEGANDO   btfsc   SSPCON2, RCEN      
      goto   LLEGANDO      ; Espero a que finalice la recepcion del DATO

      bcf   STATUS, RP1
      bcf   STATUS, RP0      ; Banco 0

      movf   SSPBUF, W      ; Cargo el dato LLEGADO en W

      movwf   DATO_L         ; Guardo el dato leido

      call   B_NOACK         ; Genero el bit NOACK
      
      call   B_STOP         ; Genero el bit de STOP

;************************************************************
;****** PROGRAMA                                       ******
;************************************************************


PROGRAMA   bcf   STATUS, RP1
      bcf   STATUS, RP0      ; Banco 0

      movlw   b"00101000"
      movwf   SSPCON         ; Habilitado:
                  ; Modo Maestro. Reloj = Fosc / ( 4*(SSPADD + 1))

      bcf   STATUS, RP1
      bsf   STATUS, RP0      ; Banco 1

      movlw   0x02
      movwf   SSPADD         ; A 400 KHz, con un cristal de 4 MHz

      movlw   b"00000000"      
      movwf   SSPSTAT         ; Habilito "Slew-Rate", para 400 KHz

      movlw   b"00011000"
      movwf   TRISC         ; Configuro SCL y SDA, como entradas

      bcf   STATUS, RP1
      bcf   STATUS, RP0      ; Banco 0


      movlw   0x00
      movwf   C_MEM_1
      movwf   C_MEM_2         ; Inicializo ambos contadores a 0

      movwf   DIR_ALT_AUX
      movwf   DIR_BAJ_AUX      ; Inicializo a 0, los punteros de direccion

      movlw   b"10100000"
      movwf   SCLAVO1         ; Cabecera para direccionar la memoria 1

      movlw   0xBB
      movwf   DATO


BUCLE      movlw   0x00
      movwf   C_MEM_2

      call   ESC_MEMO

      incfsz   DIR_BAJ_AUX, 1
      goto   BUCLE

      incfsz   DIR_ALT_AUX, 1
      goto   BUCLE

; ESTO ES SOLO PARA LA PRUEBA

      bsf   PORTC, 0

; HASTA AQUI, INDICA EL FIN

BUCLE2      goto   BUCLE2

      end


Espero que se lea bien el codigo. Sino diganme como adjuntarlo.

Un saludo. Gracias a tod@s.

Desconectado antoniof

  • Moderadores
  • PIC24F
  • *****
  • Mensajes: 729
RE: Problema para escribir memoria 24lc512 con pic 16f876
« Respuesta #1 en: 16 de Mayo de 2005, 17:48:00 »
Prueba a poner el SCL y SDA como salidas.

Desconectado Loren_Son

  • PIC10
  • *
  • Mensajes: 12
RE: Problema para escribir memoria 24lc512 con pic 16f876
« Respuesta #2 en: 16 de Mayo de 2005, 18:05:00 »
En el datasheet de microchip, pone que hay que configurarlo como entradas. En cualquier caso, lo probare, y comentare aqui.

Pero yo pienso que el fallo debe andar por otro sitio.

Gracias

Desconectado antoniof

  • Moderadores
  • PIC24F
  • *****
  • Mensajes: 729
RE: Problema para escribir memoria 24lc512 con pic 16f876
« Respuesta #3 en: 17 de Mayo de 2005, 04:31:00 »
Supongo que habras puesto las resistencias de 4K7 de pull-up. Prueba a colocar una resistencia de 100 ohmios entre el SDA del PIC y el SDA de la memoria. Aunque parezca tonto esto me solucionó un problema con un rejol/calendario por I2C. De todas formas, lo mejor es ir comprobando con un osciloscopio, si es digital mucho mejor, que las señales son correctas. El fallo puede estar en la dirección del esclavo, no esperar el tiempo suficiente por el ACK, etc... Ya nos contarás.

Desconectado Loren_Son

  • PIC10
  • *
  • Mensajes: 12
RE: Problema para escribir memoria 24lc512 con pic 16f876
« Respuesta #4 en: 17 de Mayo de 2005, 16:29:00 »
Al mirar con el osciloscopio digital, la trama que salia no tenia nada que ver con lo que yo pretendia. Revisando codigo he visto que a la hora de escribir olvidaba un paso, cargar el contenido de sclavo1, en la variable sclavo, que era la que enviaba en la funcion escritura.

Despues de esto, analizando la secuencia ya si era parecida a la esperada, excepto porque el nivel "0" de ack, no es recibida cuando el noveno bit del reloj es uno.

Al finalizar el octavo pulso de reloj, sda se pone a "1", y no se hace cero hasta que no transcurre el noveno bit, e incluso aguanta un poco a "1".

Otra cosa que he observado es que despues de enviar el bit de STOP, ambas lineas se mantienen a "1", y esto digamos que es infinito.

El resultado final, al leer la memoria con el ic-prog, es todo como 00FF, o lo que es lo mismo, que no escribo nada.

Probare lo de las resistencias de 100 Ohmios.

Desearia que revisasen mi rutina de obtencion de ACK, y de espera de fin de escritura. Y si encuentran el fallo, que seguro que los hay, me lo notificasen.

Las Pull-UP que habia puesto eran 10 Kohmios, que son las que recomendaban en el datasheet que lei. Pero hoy en uno de los anexos, de la pagina de Microchip, he leido que para trabajar a 400 KHz, que es lo que intento, han de ser de 2Kohmios.

Desconectado antoniof

  • Moderadores
  • PIC24F
  • *****
  • Mensajes: 729
RE: Problema para escribir memoria 24lc512 con pic 16f876
« Respuesta #5 en: 17 de Mayo de 2005, 16:54:00 »
Si el esclavo no responde al primer byte con el ACK es que no reconoce su dirección. Comprueba con un polímetro, que las entradas A0 A1 A2 y WP están a masa.

Codigo:
Otra cosa que he observado es que despues de enviar el bit de STOP, ambas lineas se mantienen a "1", y esto digamos que es infinito.


Este es el estado por defecto en el bus I2c, es decir, las dos líneas a 1 lógico. Comprueba con el osciloscopio que antes de comenzar la comunicación ambas líneas estén a 1.

El primer paso entonces es comprobar que ambas líneas están a 1, después se envía un START, seguidamente la dirección "10100000" y después se recibe un ACK.

Desconectado Loren_Son

  • PIC10
  • *
  • Mensajes: 12
RE: Problema para escribir memoria 24lc512 con pic 16f876
« Respuesta #6 en: 17 de Mayo de 2005, 18:36:00 »
Si con el osciloscopio, al principio estan las 2 lineas a 1. Baja una y luego la otra (START), y se ve que segun van transcurriendo los pulsos de reloj va mandando la direccion de la memoria 10100000 (estados comprobados con el polimetro y estan ok).

Lo que no veo es que en el estado "1" del noveno pulso de reloj, sda sea "0". Digamos que con mi codigo es "1" hasta aproximadamente 9 y 1/2 ciclos de reloj.

Esta es la funcion que he implementado para detectar ACK. Pienso que lo que detecta realmente no sirbe para nada, y lo que estoy haciendo es mandarle byte control - los dos punteros, el dato, ... sin detectar la respuesta y estoy volviendo loca a la memoria.

Podrias mirar la funcion, y corregir lo que sea oportuno. O indicarme si se puede comprobar el estado de otros bit´s para detectar el ACK.

B_ACK bcf STATUS, RP1
bsf STATUS, RP0 ; Banco 1

bcf SSPCON2, ACKDT ; Cargo un cero, para sacarlo luego

bsf SSPCON2, ACKEN ; Genera el bit ACK

S_ACK btfsc SSPCON2, ACKEN
goto S_ACK ; Espero a que finalice la señal de ACK

bcf STATUS, RP1
bcf STATUS, RP0 ; Banco 0

return

Tambien me gustaria que me indicaras alguna forma de comprobar que el dato realmente esta escrito.

GRACIAS DE NUEVO

Desconectado antoniof

  • Moderadores
  • PIC24F
  • *****
  • Mensajes: 729
RE: Problema para escribir memoria 24lc512 con pic 16f876
« Respuesta #7 en: 18 de Mayo de 2005, 04:25:00 »
Después de revisar detalladamente tus subrrutinas y de mirarme bien el datasheet del PIC, he detectado varios errores:

El primero en la función TX:

Codigo:
; FUNCION PARA TRANSMITIR A LAS MEMORIAS I2C

TX bcf STATUS, RP1
bcf STATUS, RP0 ; Banco 0


movf TXBUF, W
movwf SSPBUF ; Coloco el dato a transmitir en el buffer de salida del
; bus I2C

bcf STATUS, RP1
bsf STATUS, RP0 ; Banco 1

ENVIANDO btfsc SSPSTAT, R_W
goto ENVIANDO ; Espero a que se haya transmitido todo el dato

REC_ACK btfsc SSPCON2, ACKDT
REC_ACK btfsc SSPCON2, ACKSTAT
goto REC_ACK ; Compruebo que se haya recibido ACK

bcf STATUS, RP1
bcf STATUS, RP0 ; Banco 0

return


Debes comprobar el bit ACKSTAT para comprobar que efectivamente el ACK se ha recibido. El ACKDT es cuando, en una operación de lectura, el PIC debe mandar un ACK a la memoria.

Si con el osciloscopio te sale que en el noveno pulso de reloj el SDA está a 1, el bit ACKSTAT que compruebes estará a 1 también por lo que el PIC se te quedará colgado. El problema está entonces en que la memoria no reconoce su dirección (el dato que cargas en SCLAVO). Para ver que todo anda bien, debes comprobar con un polímetro que los pines de la memoria A0, A1, A2, WP esten a masa. Si estos pines están a masa y en el noveno pulso sigues teniendo un 1 es que la memoria no es la que dices, o bien la memoria no soporta los 400KHz prueba a hacerlo más lento con 100KHz por ejemplo, o bien está quemada, prueba con otra.

De que soluciones ese problema, y no antesSonrisa Gigante, podrías excplicarme para que haces lo siguiente que te señalo en rojo:

Codigo:
; FUNCION QUE REALMENTE SE ENCARGA DE LA ESCRITURA EN LAS MEMORIAS I2C

ESC_MEMO movf DIR_ALT_AUX, W
movwf DIR_ALT ; Paso la parte alta de la direccion, en la funcion

movf DIR_BAJ_AUX, W
movwf DIR_BAJ ; Paso la parte baja de la direccion, en la funcion

call B_START ; Genero el bit de START

movf SCLAVO, W
movwf TXBUF ; Coloco el dato, para poder pasarlo a la funcion TRANSMITIR

call TX ; Transmito el dato

movf DIR_ALT, W
movwf TXBUF ; Coloco la parte alta de la direccion,
; para poder pasarlo a la funcion TRANSMITIR

call TX ; Transmito el dato

movf DIR_BAJ, W
movwf TXBUF ; Coloco la parte baja de la direccion,
; para poder pasarlo a la funcion TRANSMITIR

call TX ; Transmito el dato

movf DATO, W
movwf TXBUF ; Coloco el dato a escribir,
; para poder pasarlo a la funcion TRANSMITIR

call TX ; Transmito el dato

call B_STOP ; Genero el bit de STOP

ESCRITO call B_START ; Genero el bit de START

movf SCLAVO, W
movwf TXBUF

movf TXBUF, W
movwf SSPBUF ; Coloco el dato a transmitir en el buffer de salida del
; bus I2C
bcf STATUS, RP1
bsf STATUS, RP0 ; Banco 1

ENVIANDO2 btfsc SSPSTAT, R_W
goto ENVIANDO2 ; Espero a que se haya escrito todo el dato

btfsc SSPCON2, ACKDT
goto ESCRITO ; Compruebo que se haya recibido ACK

bcf STATUS, RP1
bcf STATUS, RP0 ; Banco 0




return


porque realmente no hace nada.

La única forma de comprobar que se ha escrito algo en la memoria es leyendola, por lo que debes realizar otro bucle con las lecturas en el programa principal. Primero escribes y luego lees.

No te he revisado antes las subrrtinas por falta de tiempo y porque yo siempre utilizo el bus I2C por software. Si lo quieres, te paso un archivo con mis rutinas por soft que te aseguro que funcionan y compruebas si la memoria anda bien o no.


Desconectado Loren_Son

  • PIC10
  • *
  • Mensajes: 12
RE: Problema para escribir memoria 24lc512 con pic 16f876
« Respuesta #8 en: 18 de Mayo de 2005, 08:28:00 »
Respecto a lo que me dices del ackstat, ya estube estudiando ayer esa posibilidad. Hoy le he estado dando vueltas, y he implementado otro metodo de deteccion, con el PIR1, SSPADD a ver si funciona.


Y lo que me comentas de la funcion ESCRITO, lei en un anexo (o crei entender eso), que con este proceso se puede detectar, cuando a finalizado la escritura.

Te agradeceria tambien que me mandases tus funciones, para revisar las mias y complementarlas. Puedes hacerlo a:

Loren_Son@hotmail.com

Gracias

Desconectado antoniof

  • Moderadores
  • PIC24F
  • *****
  • Mensajes: 729
RE: Problema para escribir memoria 24lc512 con pic 16f876
« Respuesta #9 en: 18 de Mayo de 2005, 09:18:00 »
Ya te he enviado el archivo i2c.asm.

Desconectado Loren_Son

  • PIC10
  • *
  • Mensajes: 12
RE: Problema para escribir memoria 24lc512 con pic 16f876
« Respuesta #10 en: 19 de Mayo de 2005, 16:16:00 »
la desesperacion se apodera de mi. He unido la memoria con cables con: A0, A1 y A2 a gnd. W/r a 0, para escribir. Sda y Scl pon pull-up de 10k. una R de 200 ohm en el hilo Sda. Directamente a los pines del pic.

He hecho este programa con tus funciones y no consigo nada.

      LIST p=PIC16F876
      #include "P16f876.inc"

sda       equ 0x00   ;(Bit 0 del puerto c como datos)
scl       equ 0x01   ;(Bit 1 del puerto c para el reloj)
p_i2c       equ 0x07   ;(para el puerto c)

temp1      equ   20H
temp2      equ   21H
temp3      equ   22H


      ORG   0000H
      goto   PROGRA
;SUBRRUTINA "START":
;Realiza la condición de inicio de transmisión del protocolo I2C.      ********* COMPROBADA ********

start   bsf   p_i2c,sda
   bsf   p_i2c,scl
   nop         ;Comprueba que SDA y SCL estén en alto
   bcf   p_i2c,sda
   nop         ;Baja SDA
   bcf   p_i2c,scl
   nop         ;BAJA SCL
   return

;SUBRRUTINA "STOP":
;Realiza la condición de fin de transmisión del protocolo I2C.         ********* COMPROBADA ********

stop   bcf   p_i2c,sda
   bcf   p_i2c,scl
   nop         ;Comprueba que SCL y SDA estén en bajo
   bsf   p_i2c,scl
   nop         ;Sube SCL
   bsf   p_i2c,sda
   nop         ;Sube SDA
   return

;SUBRRUTINA "TX_BYTE": Transmite un byte.
;El byte a transmitir viene en el registro "w".               ********* COMPROBADA ********

tx_byte   movwf   temp1      ;Salva el byte a transmitir en el registro temporal "temp1"
   movlw   0x08
   movwf   temp2      ;Inicializa el contador
bck_txb   bsf   p_i2c,sda   ;Sube sda
   btfss   temp1,7      ;Comprueba el bit y lo baja si es cero
   bcf   p_i2c,sda
   nop         ;Envia el SDA
   bsf   p_i2c,scl
   nop         ;Da un pulso de reloj
   bcf   p_i2c,scl
   nop
   rlf   temp1,f      ;Rotamos a la izquierda "temp1"
   decfsz   temp2,f      ;Comprobamos el contador, para ver si hemos enviado los 8 bits
   goto   bck_txb      ;Si no, repetimos el bucle
   call   rx_ack      ;Espera el envio del ACK
   return         ;Terminamos

;SUBRRUTINA "RX_BYTE": Recibe un byte.
;El byte que es recibido se devuelve en el registro "w".         ********* COMPROBADA ********

rx_byte   movlw   0x08      ;Inicializamos el contador
   movwf   temp2
   bsf   STATUS,5   ;SDA como entrada
   bsf   p_i2c,sda
   bcf   STATUS,5
bck_rxb   bsf   p_i2c,scl
   nop         ;Subimos SCL
   rlf   temp1,f      ;Rota el registro "temp1", donde vamos a guardar el byte recibido
   bsf   temp1,0      ;Subimos el bit
   btfss   p_i2c,sda   ;Comprobamos que no es cero
   bcf   temp1,0
   bcf   p_i2c,scl
   nop         ;Bajamos SCL
   decfsz   temp2,f      ;Vemos si hemos recivido ya los 8 bits
   goto   bck_rxb
   bsf   STATUS,5   ;SDA como salida
   bcf   p_i2c,sda
   bcf   STATUS,5
   movf   temp1,w      ;Devolvemos el byte en el registro "w"
   return         ;Fin

;SUBRRUTINA "TX_ACK": Trasmite el bit de reconocimiento "ack".         ********* COMPROBADA ********

tx_ack   bcf   p_i2c,sda
   nop         ;Baja SDA
   bsf   p_i2c,scl
   nop         ;Sube SCL
   bcf   p_i2c,scl
   nop         ;Baja SCL
   bsf   p_i2c,sda
   nop         ;Sube SDA
   return         ;Fin

;SUBRRUTINA "NO_ACK": Envía un "1" como bit de "ack".            ********* COMPROBADA ********

no_ack   bsf   p_i2c,sda
   nop         ;Sube SDA
   bsf   p_i2c,scl
   nop         ;Sube SCL
   bcf   p_i2c,scl
   nop         ;Baja SCL
   bsf   p_i2c,sda
   nop         ;Sube SDA
   return         ;Fin

;SUBRRUTINA "RX_ACK": Espera el bit de agradecimiento "ack".         ********* COMPROBADA ********

rx_ack   bsf   STATUS,5   ;SDA como entrada
   bsf   p_i2c,sda
   bcf   STATUS,5
   movlw    d"50"      ;Inicializa el "temp2" que nos sirve de temporizador para no
   movwf   temp2      ;esperar el ACK indefinidamente
   bcf   temp3,7      ;Borra el bit de error
bck_rxa   btfss   p_i2c,sda   ;Espera el ACK
   goto   no_err
   decfsz   temp2,f      ;Decrementa el "temp2"
   goto   bck_rxa
   bsf   temp3,7      ;Si pasa mucho tiempo pone a uno el bit error y sale de la rutina
   bsf   STATUS,5
   bcf   p_i2c,sda   ;SDA como salida
   bcf   STATUS,5
   return         ;Fin
no_err   bsf   p_i2c,scl   ;Si no hay error
   nop         ;Manda un pulso de reloj
   bcf   p_i2c,scl
   nop
   bsf   STATUS,5
   bcf   p_i2c,sda   ;SDA como salida
   bcf   STATUS,5
   return         ;Fin


PROGRA      clrf   PORTA
      clrf   PORTB
      clrf   PORTC

      call   start

      call   rx_ack

      movlw   0x00

      call   tx_byte      
      
      call   rx_ack      ; Puntero ALTO

      movlw   0x00

      call   tx_byte
      
      call   rx_ack      ; Puntero BAJO

      movlw   0xAA

      call   tx_byte
      
      call   rx_ack      ; Dato

      call   stop


BUCLE      bsf   PORTC, 0   ; Enciendo el LED
      goto   BUCLE

      end










Desconectado Loren_Son

  • PIC10
  • *
  • Mensajes: 12
RE: Problema para escribir memoria 24lc512 con pic 16f876
« Respuesta #11 en: 19 de Mayo de 2005, 16:25:00 »
tengo 4 memorias y no graba en ninguna de las 4, que a su vez estan bien, porque el ic-prog garaba y escribe en todas ellas.

¿patillas del pic, jodidas? ¿puede ser posible? En el osciloscopio veo grafica

Desconectado antoniof

  • Moderadores
  • PIC24F
  • *****
  • Mensajes: 729
RE: Problema para escribir memoria 24lc512 con pic 16f876
« Respuesta #12 en: 19 de Mayo de 2005, 17:14:00 »
Bueno no te desesperes. Te comento lo que tienes mal:

Codigo:
PROGRA clrf PORTA
clrf PORTB
clrf PORTC

Esto esta muy bien pero mejor configuras el puerto C como salida y debes desactivar el conversor analógico-digital del puerto A asi:

;Inicio de los puertos/registros del PIC

inicio   bsf   status,5   ;Banco 1
   clrf   PORTA       ;PA como salida
   clrf           PORTB      ;PB como salida
   clrf   PORTC      ;PC como salida
   movlw   b"00000111"
   movwf   ADCON      ;CAD desactivado   
   bcf   status,5                    ;Banco 0
   movlw      0x03
                movwf      PORTC                     ;SDA y SCL a 1 que es como tienen que estar por defecto

call start

call rx_ack ;No hace falta esperar por el ACK después de un START

movlw 0x00 ;La dirección de memoria es la 10100000

movlw 0xA0

call tx_byte ; Dirección del esclavo

call rx_ack ; Puntero ALTO ; Si te fijas en mi rutina, se espera por el ACK siempre después de enviar un byte

movlw 0x00 ; Dirección alta

call tx_byte

movlw 0x00 ; Dirección baja

call tx_byte

movlw 0xAA ; Dato a escribir

call tx_byte

call stop


BUCLE bsf PORTC, 0 ; Enciendo el LED

No puedes poner un led en el bit SDA, altamente desaconsejado. Mejor en el bit 2 que está libre.

BUCLE bsf PORTC,2 ;Enciendo el LED
goto BUCLE

end


Si con este programa no te funciona, me compro una memoria igual y hago el código aqui en casa y lo pruebo yo mismoSonrisa Gigante

Desconectado Loren_Son

  • PIC10
  • *
  • Mensajes: 12
RE: Problema para escribir memoria 24lc512 con pic 16f876
« Respuesta #13 en: 19 de Mayo de 2005, 18:21:00 »
La verdad es que he cometido algunos fallos en el programa, algunos mas de los que tu me has indicado, es culpa de la desesperacion, se acaba el plazo.

 Como SDA, utilizo el PORTC4, y como SCL PORTC3 (asi esta hecha ya la placa). Y lo del led es porque con PORTC.0 activo un rele que abre una cerradura, y tiene un led como testigo.

Acontinuacion, veras el ultimo codigo que he cargado (espero que ya si este bien). Pero creo que vas a tener que ir comprandote la memoria, porque sigue sin grabar.

Juro, que segun estaba escribiendo esto, cuando iba a hacer el copy-paste, me he dado cuenta de que las definiciones de SDA y SCL no estaban guardadas, las he cambiado y... PREMIO.


MUCHISIMAS GRACIAS, ERES UN JEFE!!

Si consigo acabarlo con tiempo, si kieres te mando unas fotos del bicho, por correo, o si sabes de algun sitio donde se pueda colgar para que lo baje la gente, pues te paso todo. MUCHAS GRACIAS DE NUEVO.

Espero ser yo solo capaz de hacer las lecturas, jajajaja

Desconectado antoniof

  • Moderadores
  • PIC24F
  • *****
  • Mensajes: 729
RE: Problema para escribir memoria 24lc512 con pic 16f876
« Respuesta #14 en: 20 de Mayo de 2005, 09:46:00 »
Porfin hemos conseguido algo. Menos mal que no me tengo que comprar la memoria jajajaja.

RebotadoRebotadoRebotadoRebotadoRebotadoRebotadoRebotadoRebotadoRebotadoRebotadoRebotadoRebotado

Suerte con las lecturas.