Hi again,
did somebody test Al's code with a 18F14K22?
Regards,
Ralf
Hi again,
did somebody test Al's code with a 18F14K22?
Regards,
Ralf
There is an other problem with the i2cslave:
1. When the i2caddress is specifiead as constant (i2caddress CON $0F) it works perfect.
2. When bulding the address via a variable, it doesnt work:
...
i2caddress VAR byte
...
i2caddress = $0F
I need this because i build it from the status of four bits of Port A
Any idea?
Regards,
Ralf
I need this because i build it from the status of four bits of Port A
Any idea?
Ralf, you can try this:
It should work.Code:Select Case PortA Case 1 i2caddress CON $01 Case 2 i2caddress CON $02 case 3 i2caddress CON $03 . . . . Case x i2caddress CON $x End Select
Edited:
No! it doesn't work sorry.
Al.
Last edited by aratti; - 25th March 2010 at 14:19.
All progress began with an idea
ralfmayr, Here is what I have been using for years. It uses the base address for the first of 3 PCF8574's. I then calculate the address depending on the one I need to gather or send data to.
UNIT0 CON %01000000 'U5's CONTROL BYTE (PCF8574) I/O EXPANDER
'**************** I2C I/O ROUTINE (PCF8574A) I/O EXPANDER ************
READ_WRITE VAR BIT 'READ DATA or WRITE DATA FLAG
EXPAND_UNIT VAR BYTE 'CONTROL BYTE FOR I2C
DEVICE VAR BYTE 'SELECTED I/O EXPANDER DEVICE
OUTPUTS VAR BYTE[3] 'RELAY OUTPUT BYTES
SWITCHES VAR BYTE[3] 'SWITCH INPUTS BYTES
'************************************************* *******************
R_WI2CS:'READ DIGITAL INPUTS FROM or WRITE DIGITAL OUTPUTS TO PCF8574'S
'************************************************* *******************
EXPAND_UNIT = UNIT0 'COPY BASE ADDRESS OF PCF8574'S
EXPAND_UNIT = (EXPAND_UNIT | (DEVICE << 1)) 'SELECT WHICH DEVICE
IF READ_WRITE = 0 THEN 'READ INPUT STATUS FROM PCF8574'S
I2CREAD SDA,SCL,EXPAND_UNIT,[SWITCHES(DEVICE)]
ELSE 'SET OUTPUT STATES TO PCF8574'S
I2CWRITE SDA,SCL,EXPAND_UNIT,[OUTPUTS(DEVICE)]
ENDIF
RETURN
Then to use it first set the device index.
Next set the read_write flag.
Then finally call the routine.....
Dave Purola,
N8NTA
Ralf, you can try the case select using the proper addresses (not my example). You must correct your code as per the line in black bold and comment out the line in red bold. The code compile so it should work. Longing to hear from you on the final test.
Al.
Code:' Initialize I2C slave mode Select case PortA Case 1 SSPADD = 2 case 2 SSPADD = 3 case 3 SSPADD = 4 end select SCLDIR = 1 ' SCL must be made an input before enabling interrupts SDADIR = 1 'SSPADD = I2Caddress ' Set our address SSPCON2.7 = 0 ' General call address disabled SSPCON = $36 ' Set to I2C slave with 7-bit address SSPSTAT = 0 SSPIE = 1 SSPIF = 0 RxBufferIndex = 0 TxBufferIndex = 0 'Initialization Done! GoTo main i2cslave: ' I2C slave subroutine SSPIF = 0 ' Clear interrupt flag IF R_W = 1 Then i2crd ' Read data from us IF BF = 0 Then i2cexit ' Nothing in buffer so exit IF D_A = 1 Then i2cwr ' Data for us (not address) IF SSPBUF != SSPADD Then i2cexit ' Clear the address from the buffer readcnt = 0 ' Mark as first read GoTo i2cexit
All progress began with an idea
Hi Al,
my mistake, it works now.
I made a mistake in calculating the address from four bits of a port :-(
This works:
main_loop:
...
i2caddress = (addr0 * 16) + (addr1 * 8) + (addr2 * 4) + (addr3 * 2)
SSP1ADD = I2Caddress
...
goto main_loop
...in the moment i try to implement the slave routine into a 18LF14K22...
It does not work in the moment, it is the same like on a18F6722, there it
works great.
Regards,
Ralf
Very good Ralf !Code:i2caddress = (addr0 * 16) + (addr1 * 8) + (addr2 * 4) + (addr3 * 2) SSP1ADD = I2Caddress
Al.
All progress began with an idea
Bookmarks