;******************************************************************************
; RUTINAS DE COMUNICACION SERIE (MODULO I2C)
;******************************************************************************
;
; GENERA START BIT
;
START_I2C
BSF SDA ; dejo linea de datos en 1
BSF RP0 ; banco 1
MOVLW _TRISC ; configuro SDA y SCL como salidas
ANDLW b'11100111';
MOVWF TRISC ;
BCF RP0 ; banco 0
BCF SCL ; bajo clock
NOP ;
BSF SCL ; subo clock
GOTO $+1 ;
GOTO $+1 ;
GOTO $+1 ;
NOP ;
BCF SDA ; bajo datos
GOTO $+1 ;
GOTO $+1 ;
GOTO $+1 ;
NOP ;
BCF SCL ; y bajo clock para generar start bit
GOTO $+1 ;
GOTO $+1 ;
RETURN ;
;
; GENERA STOP BIT
;
STOP_I2C
BCF SDA ; dejo linea de datos en 0
BSF RP0 ; banco 1
MOVLW _TRISC ; configuro SDA y SCL como salidas
ANDLW b'11100111';
MOVWF TRISC ;
BCF RP0 ; banco 0
BCF SDA ; bajo datos
GOTO $+1 ;
GOTO $+1 ;
BSF SCL ; subo clock
GOTO $+1 ;
GOTO $+1 ;
BSF SDA ; subo datos
GOTO $+1 ;
GOTO $+1 ;
BCF SCL ; bajo clock
GOTO $+1 ;
GOTO $+1 ;
RETURN ; y retorno
;
; ENVIA UN BIT POR SDA
;
BITOUT_I2C
BSF RP0 ; banco 1
MOVLW _TRISC ; configuro SDA y SCL como salidas
ANDLW b'11100111';
MOVWF TRISC ;
BCF RP0 ; banco 0
BTFSS I2CDO ; enviar un 1 ?
GOTO I2CBLO ; no, envio un 0...
BSF SDA ; pongo SDA en 1
GOTO CLKOUT ;
I2CBLO
BCF SDA ; pongo SDA en 0
CLKOUT
BSF SCL ; y clockeo
GOTO $+1 ;
GOTO $+1 ;
GOTO $+1 ;
BCF SCL ;
RETURN ; y salgo
;
; RECIBE UN BIT POR SDA
;
BITIN_I2C
BSF I2CDI ; asumo que llega un 1
BSF RP0 ; banco 1
MOVLW _TRISC ; configuro SDA como entrada y SCL como salida
ANDLW b'11100111';
IORLW b'00010000';
MOVWF TRISC ;
BCF RP0 ; banco 0
BSF SCL ; subo clock
GOTO $+1 ;
GOTO $+1 ;
GOTO $+1 ;
BTFSS SDA ; recibio un 1 ?
BCF I2CDI ; no, es 0
BCF SCL ; bajo clock
RETURN ; y salgo
;
; RUTINA DE TRANSMISION POR I2C
;
I2C_TX
MOVLW .8 ; son 8 bits a contar
MOVWF CNT ;
I2C_TXLP
BCF I2CDO ; asumo que sale un 0
BTFSC I2CBUF,7; sacar un 0 ?
BSF I2CDO ; no, sale un 1...
CALL BITOUT_I2C; envio bit
RLF I2CBUF,F; acomodo para sacar proximo bit
DECFSZ CNT,F ; salieron los 8 ?
GOTO I2C_TXLP; no, continuo sacando...
CALL BITIN_I2C; leo bit de acknowledge
BCF I2CACKF ; asumo que es 0
BTFSC I2CDI ; es 0 ?
BSF I2CACKF ; no, envio un 1
RETURN ; y salgo
;
; RUTINA DE RECEPCION POR I2C
;
I2C_RX
CLRF I2CBUF ; borro buffer
MOVLW .8 ; son 8 bits a leer
MOVWF CNT ;
BCF C ; borro flag de carry
I2C_RXLP
RLF I2CBUF,F; roto un bit a la izquierda
CALL BITIN_I2C; y leo bit enviado
BTFSC I2CDI ; llego un 0 ?
BSF I2CBUF,0; no, escribo un 1 en el buffer
DECFSZ CNT,F ; llegaron los 8 bits ?
GOTO I2C_RXLP; no, sigo reciviendo...
BCF I2CDO ;
BTFSC I2CACKF ;
BSF I2CDO ;
CALL BITOUT_I2C; envio bit de acknowledge
RETURN ; y salgo
;
; LECTURA DE LA MEMORIA 24Cxx
;
RD24CXX
CALL START_I2C; envio condicion de start
MOVLW _24CADD ; traigo direccion de esclavo
MOVWF I2CBUF ; y cargo en buffer
CALL I2C_TX ; direcciono memoria
MOVFW ADD24C ; traigo direccion a leer
MOVWF I2CBUF ;
CALL I2C_TX ; y envio a memoria
CALL START_I2C; envio condicion de start
MOVLW _24CADD ;
IORLW 0x01 ; direcciono memoria para lectura
MOVWF I2CBUF ;
CALL I2C_TX ; y envio
BCF I2CACKF ; preparo para acknowledge en 0
CALL I2C_RX ; y leo byte direccionado
CALL STOP_I2C; genero condicion de stop
MOVFW I2CBUF ; cargo dato leido en
MOVWF DAT24C ; registro de datos de memoria
RETURN ; y salgo
;
; ESCRITURA DE LA MEMORIA 24Cxx
;
WR24CXX
CALL START_I2C; genero bit de start
MOVLW _24CADD ; cargo direccion del esclavo
MOVWF I2CBUF ; en buffer
CALL I2C_TX ; envio...
MOVFW ADD24C ; cargo direccion a escribir
MOVWF I2CBUF ; en buffer
CALL I2C_TX ; envio...
MOVFW DAT24C ; cargo dato a escribir
MOVWF I2CBUF ; en buffer
CALL I2C_TX ; envio...
CALL STOP_I2C; genero bit de stop
MOVLW .60 ;
MOVWF CNT1 ;
WR24POLL
CALL START_I2C;
MOVLW _24CADD ;
MOVWF I2CBUF ;
CALL I2C_TX ;
BTFSS SDA ;
GOTO WR24P_EXIT;
DECFSZ CNT1,F ;
GOTO WR24POLL;
RETLW 0xFF ;
WR24P_EXIT
; MOVLW .20 ;
; MOVWF DEL_TIME; espero 10 mseg para dar tiempo a memoria
; CALL DELAY ;
RETLW 0x00 ; y salgo
;
;*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*;