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.