Nuevamente Gracias Suki por probar el Slave (ahora que me fijo no te mandé el IC2_Master.INC que va con el assembler del Master), ahi va:
(Si me contestas , por favor dime como poner el código en ese recuadro gris que no ocupa tanto lugar)
; ////////////////////// I2C_MASTER.INC ////////////////////////////////////////////////
; VARIABLES LOCALES ******************************************************************
CBLOCK 0xA0 ; TODAS LAS VARIABLES DEL I2C ESTAN EN EL BANK 1 !!!!!
Bus_Status ; Status Reg of I2C Bus for both TXMT & RCVE
Bus_Control ; control Register of I2C Bus
DataByte ; load this reg with the data to be transmitted
BitCount ; The bit number (0:7) transmitted or received
DelayCount
SlaveAddr
ENDC
; ******************** DEFINICIONES **************************************************
#DEFINE I2C_SCL TRISA,3 ; I2C Clock
#DEFINE I2C_SDA TRISA,4 ; I2C Data
#DEFINE _SCL PORTA,3 ; I2C Clock Estado del Bus
#DEFINE _SDA PORTA,4 ; I2C Data Estado del Bus
; NO SE TRABAJA CON BSF NI BCF SOBRE EL PORT !!!!!
; SE PONEN AMBOS PORT LATCHS EN CERO, PULLUPS EXTERNOS DE 4K7 Y SE TRABAJA CON TRIS
; Si TRIS es 0 (output) entonces pone cero (lo que tenía en el latch).
; Si TRIS es 1 (input) entonces deja que el pullup levante a 1 (el port que High Z).
;*************************************************************************************
; I2C Bus Status Reg Bit Definitions
;*************************************************************************************
#define _Bus_Busy Bus_Status,0
#define _Abort Bus_Status,1
#define _Txmt_Progress Bus_Status,2
#define _Rcv_Progress Bus_Status,3
#define _Txmt_Success Bus_Status,4
#define _Rcv_Success Bus_Status,5
#define _Fatal_Error Bus_Status,6
#define _ACK_Error Bus_Status,7
;*************************************************************************************
; I2C Bus Control Register
;*************************************************************************************
#define _10BitAddr Bus_Control,0
#define _Slave_RW Bus_Control,1
#define _Last_Byte_Rcv Bus_Control,2
#define _SlaveActive Bus_Control,6
#define _TIME_OUT_ Bus_Control,7
;*************************************************************************************
;*************************************************************************************
RELEASE_BUS MACRO ; pone el port en Input y deja que actue el pullup externo de 4k7
bsf STATUS,RP0 ; select page 1
bsf I2C_SDA ; tristate SDA
bsf I2C_SCL ; tristate SCL
ENDM ; fin de la Macro. OJO queda en Bank 1 !!
;**************************************************************************************
; EQUIVALENCIAS ***********************************************************************
TRUE equ 1
FALSE equ 0
;*************************************************************************************
; SINGLE MASTER, MULTIPLE SLAVES
;*************************************************************************************
; I2C Bus Initialization
;*************************************************************************************
InitI2CBus_Master
bcf STATUS,RP0 ; bank 0
movf PORTA,W
andlw 0xE7 ; do not use BSF & BCF on Port Pins
movwf PORTA ; set SDA & SCL to zero. From Now on, simply play with TRIS
RELEASE_BUS ; MACRO
clrf Bus_Status ; reset status reg
clrf Bus_Control ; clear the Bus_Control Reg, reset to 8 bit addressing
return
;***************************************************************************************
; Send Start Bit
;***************************************************************************************
SendStartBit
bsf I2C_SDA ; set SDA high
bsf I2C_SCL ; set SCL high
call Delay10uS ; only necessary for setup time
bcf I2C_SDA ; give a falling edge on SDA while clock is high
call Delay10uS ; only necessary for START HOLD time
bsf _Bus_Busy ; on a start condition bus is busy
return
;****************************************************************************************
; Send Stop Bit
;****************************************************************************************
SendStopBit
bsf STATUS,RP0 ; select page 1
bcf I2C_SCL
bcf I2C_SDA ; set SDA low
bsf I2C_SCL ; Clock is pulled up
call Delay10uS
bsf I2C_SDA ; give a rising edge on SDA while CLOCK is high
bcf _Bus_Busy ; on a stop condition bus is considered Free
return
;*****************************************************************************************
; Abort Transmission / Send STOP Bit & set Abort Flag
;*****************************************************************************************
AbortTransmission
call SendStopBit
bsf _Abort
return
;*****************************************************************************************
; Transmit Address (1st Byte)& Put in Read/Write Operation
; Transmits Slave Addr On the 1st byte and set LSB to R/W operation
; Slave Address must be loaded into SlaveAddr reg
; On Success, return TRUE in WREG, else FALSE in WREG
; If desired, the failure may tested by the bits in Bus Status Reg
;*******************************************************************************************
SendSlaveAddr
bcf _ACK_Error ; reset Acknowledge error bit
movf SlaveAddr,W
movwf DataByte ; load addr to Data Byte for transmission
call SendData ; send 8 bits of address
; if successfully transmitted, expect an ACK bit
_AddrSendTest
btfss _Txmt_Success ; skip if successful
goto _AddrSendFail
retlw TRUE
_AddrSendFail
btfss _ACK_Error
retlw FALSE ; Addr Txmt Unsuccessful, so return 0
; Address Not Acknowledged, so send STOP bit
call SendStopBit
retlw FALSE ; Addr Txmt Unsuccessful, so return 0
;*******************************************************************************************
; TRANSMIT A BYTE OF DATA
; The data to be transmitted must be loaded into DataByte Reg
;*******************************************************************************************
SendData ; send 8 bits & wait for ACK
bsf _Txmt_Progress ; set Bus status for txmt progress
bcf _Txmt_Success ; reset status bit
movlw 0x08
movwf BitCount
TxmtNextBit
bcf I2C_SCL ; set clock low
rlf DataByte, F ; MSB first, Note DataByte Is Lost
bcf I2C_SDA
btfsc STATUS,C
bsf I2C_SDA
call Delay10uS
bsf I2C_SCL ; set clock high
; check if clock is high, else clock is being stretched
call Delay10uS
decfsz BitCount, F
goto TxmtNextBit
; Check For Acknowledge
bcf I2C_SCL ; set clock low
bsf I2C_SDA ; Release SDA line for Slave to pull down
call Delay10uS
bsf I2C_SCL ; clock for slave to ACK
call Delay10uS
bcf STATUS,RP0 ; select PAGE 0 to test PortA pin SDA
btfsc _SDA ; SDA should be pulled low by slave if OK
goto _TxmtErrorAck
bsf STATUS,RP0 ; select page 1
bcf _Txmt_Progress ; reset TXMT bit in Bus Status
bsf _Txmt_Success ; transmission successful
bcf _ACK_Error ; ACK OK
return
_TxmtErrorAck
RELEASE_BUS
bcf _Txmt_Progress ; reset TXMT bit in Bus Status
bcf _Txmt_Success ; transmission NOT successful
bsf _ACK_Error ; No ACK From Slave
return
;********************************************************************************************
; General Purpose Delay Routine
;********************************************************************************************
Delay10uS ; 2us for the Call + 8 nops + 2us for return = 10us
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
return
;********************************************************************************************
Por otra parte, no entendí bien el tema del address. Si la dirección del Slave es 0x22 , cómo es que hay que poner 0x44 para escribir un byte en él?
Saludos y
gracias