I2CDEL EQU 12 ; Was 30 _I2CPORT EQU Port_A _SCL EQU 0 _SDA EQU 1 _SCLMASK EQU 1 << _SCL _SDAMASK EQU 1 << _SDA _I2CCOUNT EQU BASE _I2CVALUE EQU BASE+1 _I2CDUMMY EQU BASE+2 _I2CADRES EQU BASE+3 BASE SET BASE+4 I2C_SET_TX MACRO MOVLW 255 - (_SCLMASK + _SDAMASK) TRIS _I2CPORT ENDM I2C_SET_RX MACRO MOVLW 255 - _SCLMASK TRIS _I2CPORT ENDM DJNZ MACRO var, address DECFSZ var ; 1 uS GOTO address ; 2 uS ENDM DELAY MACRO var ; 2 + var * 3 uS cycles... LOCAL loopx MOVLW var ; 1 uS MOVWF _I2CDUMMY ; 1 uS loopx DJNZ _I2CDUMMY, loopx ; 3 uS ENDM I2C_Init CALL I2C_Stop CALL I2C_Start CALL I2C_Stop RETURN I2C_Start I2C_SET_RX I2C_Start2 BTFSS _I2CPORT,_SDA GOTO I2C_Start2 I2C_SET_TX DELAY I2CDEL BCF _I2CPORT,_SDA DELAY I2CDEL BCF _I2CPORT,_SCL DELAY I2CDEL RETURN I2C_Stop I2C_SET_TX DELAY I2CDEL BCF _I2CPORT,_SDA DELAY I2CDEL BSF _I2CPORT,_SCL DELAY I2CDEL BSF _I2CPORT,_SDA DELAY I2CDEL RETURN I2C_Adres MOVWF _I2CDUMMY ; On Entry, W : 0=Write 1=Read RRF _I2CDUMMY ; R/W bit in Carry MOVF _I2CADRES,W MOVWF _I2CVALUE ; Copy it to value RLF _I2CVALUE ; Rotate it into LSB (R/W bit) CALL I2C_Start MOVLW 8 MOVWF _I2CCOUNT I2C_Adres1 RLF _I2CVALUE BCF _I2CPORT,_SDA BTFSC STATUS,CARRY BSF _I2CPORT,_SDA CALL I2C_Clock DJNZ _I2CCOUNT,I2C_Adres1 ; Now, get the ACK... I2C_SET_RX DELAY I2CDEL BTFSS _I2CPORT,_SDA GOTO I2C_ACK ; No ACK CALL I2C_Clock I2C_SET_TX RETLW 1 I2C_ACK CALL I2C_Clock I2C_SET_TX RETLW 0 I2C_Send MOVWF _I2CVALUE MOVLW 8 MOVWF _I2CCOUNT I2C_Send1 RLF _I2CVALUE BCF _I2CPORT,_SDA BTFSC STATUS,CARRY BSF _I2CPORT,_SDA CALL I2C_Clock DJNZ _I2CCOUNT,I2C_Send1 ; Now, get the ACK... I2C_SET_RX DELAY I2CDEL BTFSS _I2CPORT,_SDA GOTO I2C_SACK ; No ACK CALL I2C_Clock I2C_SET_TX RETLW 1 I2C_SACK CALL I2C_Clock I2C_SET_TX RETLW 0 I2C_Clock DELAY I2CDEL BSF _I2CPORT, _SCL DELAY I2CDEL BCF _I2CPORT, _SCL DELAY I2CDEL RETURN ; Single byte only (No ACK send) I2C_Read CLRF _I2CVALUE I2C_SET_RX MOVLW 8 MOVWF _I2CCOUNT I2C_Recv1 RLF _I2CVALUE BCF _I2CVALUE, 0 ; Default 0 DELAY I2CDEL BSF _I2CPORT,_SCL DELAY I2CDEL BTFSC _I2CPORT,_SDA BSF _I2CVALUE, 0 ; Als SDA=1 dan 1 BCF _I2CPORT,_SCL DELAY I2CDEL DJNZ _I2CCOUNT,I2C_Recv1 I2C_SET_TX BSF _I2CPORT,_SDA CALL I2C_Clock I2C_SET_RX MOVF _I2CVALUE, W RETURN