Hola a todos.
Estoy haciendo un proyecto en el que entre otras cosas tengo que comunicar un pic16f877 con una memoria 24lc256. El tema es que después de configurar el MSSP y enviar la condición de START el pic se queda colgado, es decir, la memoria no contesta. En un principio puse dos resistencia de pull-up de 10k y medía directamente con el osciloscopio en la pata SCL y la señal se parece a cualquier cosa menos a una señal de reloj. Después cambié las resistencia de pull-up por dos de 100k y la memoria contesta, escribe lo que quiero pero no lee lo que he escrito (esto lo sé porque después la leí con el icprog y en la posición 0 aparecía el valor que yo quería que escribiese). Con estas resistencias tampoco aparece la señal de reloj en el osciloscopio.
Os pongo el trozo de código que tiene que ver con el I2C:
bsf STATUS,RP0 ;Cambio a banco 1
bcf STATUS,RP1
bsf TRISC,3 ;SCL y SDA como entradas
bsf TRISC,4
movlw b'10000000' ;Velocidad estándard con
movwf SSPSTAT ;niveles I2C
movlw b'00001001' ;Velocidad del bus I2C
movwf SSPADD ;100KHz
bcf STATUS,RP0 ;Banco 0
movlw b'00101000' ;Módulo MSSP en On
movwf SSPCON
call S_START ;Envio condicion inicio
movlw b'10100000' ;Envio identificador esclavo
call SEND_B ;y modo escritura
movlw b'00000000' ;Parte alta direccion que
call SEND_B ;queremos escribir
movlw b'00000000' ;Parte baja
call SEND_B
movlw '000000001'
call SEND_B ;Lo enviamos a la direción de memoria adecuada
call S_STOP
call S_START ;Envio condicion inicio
movlw b'10100000' ;Envio identificador esclavo
call SEND_B ;y modo escritura
movlw b'00000000' ;Parte alta direccion que
call SEND_B ;queremos leer
movlw b'00000000' ;Parte baja
call SEND_B
call S_START
movlw b'10100001' ;Envio identificador esclavo
call SEND_B
call READ_B ;Esperamos dato
movwf VAL_MU ;lo movemos a una variable
call S_STOP ;Paramos
call VIS_RE_MU
;Rutinas para MSSP
S_START bcf PIR1,SSPIF ;Restaura el flag de MSSP
bsf STATUS,RP0 ;Seleccion de banco 1
bcf STATUS,RP1
bsf SSPCON2,SEN ;Activa secuencia de inicio
bcf STATUS,RP0 ;Banco 0
START_W btfss PIR1,SSPIF ;¿Ha terminado?
goto START_W ;No. Esperar
return
S_STOP bcf PIR1,SSPIF ;Restaura el flag de MSSP
bsf STATUS,RP0 ;Seleccion de banco 1
bcf STATUS,RP1
bsf SSPCON2,PEN ;Activa secuencia de inicio
bcf STATUS,RP0 ;Banco 0
STOP_W btfss PIR1,SSPIF ;¿Ha terminado?
goto STOP_W ;No. Esperar
return
SEND_B bcf PIR1,SSPIF ;Restaura flag MSSP
movwf SSPBUF ;Llevar byte a buffer salida
SEND_B_W btfss PIR1,SSPIF ;¿Recibido ACK#?
goto SEND_B_W ;No. Esperar.
return
READ_B bcf PIR1,SSPIF ;Restaura flag de MSSP
bsf STATUS,RP0 ;Seleccion de banco 1
bcf STATUS,RP1
bsf SSPCON2,RCEN ;Activa secuencia de inicio
bcf STATUS,RP0 ;Banco 0
READ_W btfss PIR1,SSPIF ;¿Byte recibido?
goto READ_W ;No. Esperar
bcf PIR1,SSPIF ;Restaura flag de MSSP
bsf STATUS,RP0 ;Seleccion de banco 1
bcf STATUS,RP1
bcf SSPCON2,ACKDT ;Pone bit ACK a 0
bsf SSPCON2,ACKEN ;Activa generacion de ACK
bcf STATUS,RP0 ;Banco 0
ACK_W btfss PIR1,SSPIF ;¿Secuencia ACK finalizada?
goto ACK_W ;No esperar
movf SSPBUF,W ;Sí. Lee el byte recibido
return
Gracias de antemano