Did you pullup SCL and SDA with a 3.3K resistor?
Cheers
Al.
Did you pullup SCL and SDA with a 3.3K resistor?
Cheers
Al.
All progress began with an idea
Hi aratti,
Thanks for replying, I added the resistors but I have the same output("Time out" on the lcd). Any idea what causing the issue?
Thanks in advance,
tacbanon
Attachment 6422
Last edited by tacbanon; - 25th April 2012 at 08:13.
You should post the schematic of your setup along with the code you are using. Without more info it is difficult to give you proper answers.
Al.
All progress began with an idea
Hi again,
Here is the code I'm using..
Master pic using Pic16F877A
Here is the code for the Slave Pic16F88Code:'------------------------------------------------------------------------------- ' Master '------------------------------------------------------------------------------- '------------------------------------------------------------------------------- DEFINE OSC 4 'OPTION_REG.7 = 0 ADCON1 = 7 '------------------------------------------------------------------------------ DEFINE I2C_SLOW 1 TRISB.5 = 1 TRISB.7 = 1 '------------------------------------------------------------------------------ scl VAR PORTB.5 ' i2c clock input sda VAR PORTB.7 ' i2c data input '------------------------------------------------------------------------------ I2Caddress VAR BYTE valor VAR BYTE '------------------------------------------------------------------------------ ' Set LCD Data port DEFINE LCD_DREG PORTD ' Set starting Data BIT (0 OR 4) IF 4-BIT bus DEFINE LCD_DBIT 4 ' Set LCD Register Select port DEFINE LCD_RSREG PORTC ' Set LCD Register Select BIT DEFINE LCD_RSBIT 6 ' Set LCD Enable port DEFINE LCD_EREG PORTC ' Set LCD Enable BIT DEFINE LCD_EBIT 7 ' Set LCD bus size (4 OR 8 bits) DEFINE LCD_BITS 4 ' Set number of lines ON LCD DEFINE LCD_LINES 2 ' Set command delay time in us DEFINE LCD_COMMANDUS 2000 ' Set Data delay time in us DEFINE LCD_DATAUS 50 '------------------------------------------------------------------------------ Pause 500 ' Wait for LCD to startup LCDOut $fe, 1 LCDOut $fe, "Daniel" Pause 500 ' Wait for LCD to startup valor = 0 '------------------------------------------------------------------------------ main: I2Caddress = $3 LCDOut $fe, 1 LCDOut "Write 1 - LED ON" Pause 500 I2CWrite SDA, SCL, I2Caddress, [6], bogus ' Write offset to slave Pause 500 LCDOut $fe, 1 LCDOut "Write 1 - LED OFF" Pause 500 I2CWrite SDA, SCL, I2Caddress, [8], bogus ' Write to slave Pause 500 LCDOut $fe, 1 LCDOut "Reading 1..." Pause 500 I2CRead SDA, SCL, I2Caddress, [valor], bogus ' Read from slave LCDOut $fe, 1 LCDOut "Value1: ", DEC valor Pause 500 '-------- I2Caddress = $5 LCDOut $fe, 1 LCDOut "Write 2 - LED ON" Pause 500 I2CWrite SDA, SCL, I2Caddress, [4], bogus ' Write to slave Pause 500 LCDOut $fe, 1 LCDOut "Write 2 - LED OFF" Pause 500 I2CWrite SDA, SCL, I2Caddress, [10], bogus ' Write to slave Pause 500 LCDOut $fe, 1 LCDOut "Reading 2..." Pause 500 I2CRead SDA, SCL, I2Caddress, [valor], bogus ' Read from slave LCDOut $fe, 1 LCDOut "Value2: ", DEC valor Pause 500 '-------- GoTo main ' Do it forever '------------------------------------------------------------------------------- bogus: LCDOut $fe,1, "Time out" ' I2C command timed out Pause 500 GoTo main '------------------------------------------------------------------------------- End
The codes I'm using is from Daniel(copy and paste).Code:DEFINE OSC 8 OSCCON = 110001 '8mhz '------------------------------------------------------------------------------ CMCON = 7 ADCON1 = 0 ' Disable A/D converter ADCON0 = 0 ANSEL = 0 ' all analog pins to digital '--- tris port config here (don't use SCL & SDA pins other than I2C) ---------- DEFINE I2C_HOLD 1 TRISB.1 = 1 TRISB.4 = 1 '--- Alias pins --------------------------------------------------------------- SDADIR VAR TRISB.1 SCLDIR VAR TRISB.4 '--- Define here your variables and alias ------------------------------------- LEDT VAR PORTA.2 LEDL VAR PORTB.7 LEDM VAR PORTB.6 LEDR VAR PORTB.5 readcnt VAR BYTE datain VAR BYTE WrData VAR BYTE '--- Define used register flags ------------------------------------------------ SSPIF VAR PIR1.3 ' SSP (I2C) interrupt flag SSPIE VAR PIE1.3 BF VAR SSPSTAT.0 ' SSP (I2C) Buffer Full R_W VAR SSPSTAT.2 ' SSP (I2C) Read/Write D_A VAR SSPSTAT.5 ' SSP (I2C) Data/Address CKP VAR SSPCON.4 ' SSP (I2C) SCK Release Control SSPEN VAR SSPCON.5 ' SSP (I2C) Enable SSPOV VAR SSPCON.6 ' SSP (I2C) Receive Overflow Indicator WCOL VAR SSPCON.7 ' SSP (I2C) Write Collision Detect STAT_BF VAR SSPSTAT.0 ' SSP (I2C) Buffer Full STAT_RW VAR SSPSTAT.2 ' SSP (I2C) Read/Write STAT_DA VAR SSPSTAT.5 ' SSP (I2C) Data/Address CKE VAR SSPSTAT.6 ' SSP (I2C) Data/Address '--- Rx Buffer defintion ------------------------------------------------------ RxBufferLEN CON 1 RxBuffer VAR BYTE[Rxbufferlen] RxBufferIndex VAR BYTE '--- Tx Buffer defintion ------------------------------------------------------ TxBufferLEN CON 1 TxBuffer VAR BYTE[txbufferlen] TxBufferIndex VAR BYTE '--- Define constants --------------------------------------------------------- I2Caddress CON $3 ' Make address = 3 '--- Initialize I2C slave mode ------------------------------------------------ SCLDIR = 1 ' SCL must be an input before enabling interrupts SDADIR = 1 SSPADD = I2Caddress ' Set our address SSPCON = $36 ' Set to I2C slave with 7-bit address SSPSTAT = 0 SSPIE = 1 SSPIF = 0 RxBufferIndex = 0 TxBufferIndex = 0 '--- Initialization Done! ----------------------------------------------------- GoTo main '--- I2C subroutine ---------------------------------------------------------- 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 != I2Caddress Then i2cexit ' Clear the address from the buffer readcnt = 0 ' Mark as first read GoTo i2cexit i2cwr: ' I2C write data to us datain = SSPBUF ' Put buffer data into array Rxbuffer[Rxbufferindex]=datain Rxbufferindex=rxbufferindex+1 IF rxbufferindex=RxBufferLEN Then ' end of buffer transfer WrData=1 rxbufferindex=0 EndIF GoTo i2cexit i2crd: ' I2C read data from us IF D_A = 0 Then TxBufferIndex = 0 EndIF While STAT_BF : Wend ' loop while buffer is full wcol = 0 ' clear collision flag SSPBUF = TxBuffer[TxBufferIndex] While wcol wcol = 0 SSPBUF = TxBuffer[TxBufferIndex] Wend CKP = 1 ' release clock, allowing read by master TxBufferIndex = TxBufferIndex + 1 ' increment index IF TxBufferIndex = TxBufferlen Then ' all bytes have been tx TxBufferIndex = 0 ' reset index EndIF i2cexit: Return '--- End I2C subroutine ------------------------------------------------------ Main: pause 100 txbuffer = 12 IF SSPIF = 1 Then GoSub i2cslave EndIF SSPOV = 0 WCOL = 0 Select Case RxBuffer[0] Case 6 High LEDT Case 8 Low LEDT End Select WrData=0 GoTo Main '------------------------------------------------------------------------------ End
BTW I'm using a simulator...
regards,
tacbanon
Last edited by tacbanon; - 25th April 2012 at 11:07.
Very likely is a simulator problem!
Al.
All progress began with an idea
Okay, I will try it in the real hardware(need first to buy Pic16F88), and post here the result. Can anybody in the forum who has Proteus to try to test if similar output I'm having?
Thanks,
tacbanon
Last edited by tacbanon; - 25th April 2012 at 17:27.
Hello,
While waiting for my Pic16F88(probable by next week) I tried to play with this code below with success in the simulation...
master(Pic18F2620)
Slave(Pic18F2620)Code:DEFINE OSC 40 DEFINE I2C_HOLD 1 DEFINE LCD_DREG PORTB DEFINE LCD_DBIT 0 DEFINE LCD_RSREG PORTB DEFINE LCD_RSBIT 4 DEFINE LCD_EREG PORTB DEFINE LCD_EBIT 5 DEFINE LCD_BITS 4 DEFINE LCD_LINES 2 DEFINE LCD_COMMANDUS 2000 DEFINE LCD_DATAUS 50 PAUSE 100 LCDOUT $FE,1,$FE,2 ADCON1=001111 CMCON=000111 scl VAR PORTC.3 sda VAR PORTC.4 i2c_address VAR BYTE i2c_data VAR BYTE[6] main: i2c_address=$02 I2CREAD sda,scl,i2c_address,[STR i2c_data\6] LCDOUT $FE,$80,DEC i2c_data[0] LCDOUT " ", DEC i2c_data[1] LCDOUT " ", DEC i2c_data[2] LCDOUT " ", DEC i2c_data[3] LCDOUT " ", DEC i2c_data[4] LCDOUT " ", DEC i2c_data[5] GOTO main
As I understood, in the master pic the code below tries to communicate to the Slave having the address $02Code:DEFINE OSC 40 INCLUDE "DT_INTS-18.bas" INCLUDE "ReEnterPBP-18.bas" ADCON1=001111 CMCON=000111 i2c_buffer_full VAR SSPSTAT.0 i2c_read VAR SSPSTAT.2 i2c_release_scl VAR SSPCON1.4 i2c_data VAR BYTE[6] i2c_data_index VAR BYTE dummy VAR BYTE ;---------------------------------- i var byte i=1 SSPADD=$02 ' I2C Address: $0A SSPCON1=$36 SSPCON2.0=1 i2c_data[0]=6 i2c_data[1]=5 i2c_data[2]=4 i2c_data[3]=3 i2c_data[4]=2 i2c_data[5]=1 i2c_data_index=0 ASM INT_LIST macro INT_Handler SSP_INT, _i2c_int_handler, PBP, yes endm INT_CREATE INT_ENABLE SSP_INT endasm main: goto main i2c_int_handler: IF i2c_read then dummy=SSPBUF IF i2c_buffer_full=0 THEN SSPBUF=i2c_data[i2c_data_index] i2c_data_index=i2c_data_index+1 IF i2c_data_index=6 THEN i2c_data_index=0 ENDIF ENDIF i2c_release_scl=1 @ INT_RETURN
and display data from Slave to the Master pic LCD. Then I tried to modify the setup and add another Slave#2 with address $0B like the this code below..Code:i2c_address=$02 I2CREAD sda,scl,i2c_address,[STR i2c_data\6] LCDOUT $FE,$80,DEC i2c_data[0] LCDOUT " ", DEC i2c_data[1] LCDOUT " ", DEC i2c_data[2] LCDOUT " ", DEC i2c_data[3] LCDOUT " ", DEC i2c_data[4] LCDOUT " ", DEC i2c_data[5]
What I get is "6 5 4 3 2 1" and "0 0 0 0 0 0 " should be "1 2 3 4 5 6" for Slave#2Code:main: i2c_address=$02 I2CREAD sda,scl,i2c_address,[STR i2c_data\6] LCDOUT $FE,$80,DEC i2c_data[0] LCDOUT " ", DEC i2c_data[1] LCDOUT " ", DEC i2c_data[2] LCDOUT " ", DEC i2c_data[3] LCDOUT " ", DEC i2c_data[4] LCDOUT " ", DEC i2c_data[5] PAUSE 1000 LCDOUT 254,1 pause 500 i2c_address=$0B I2CREAD sda,scl,i2c_address,[STR i2c_data\6] LCDOUT $FE,$80,DEC i2c_data[0] LCDOUT " ", DEC i2c_data[1] LCDOUT " ", DEC i2c_data[2] LCDOUT " ", DEC i2c_data[3] LCDOUT " ", DEC i2c_data[4] LCDOUT " ", DEC i2c_data[5] PAUSE 1000 GOTO main
Slave#2
I was only hoping that it would work that way(I guess notCode:DEFINE OSC 40 INCLUDE "DT_INTS-18.bas" INCLUDE "ReEnterPBP-18.bas" ADCON1=001111 CMCON=000111 i2c_buffer_full VAR SSPSTAT.0 i2c_read VAR SSPSTAT.2 i2c_release_scl VAR SSPCON1.4 i2c_data VAR BYTE[6] i2c_data_index VAR BYTE dummy VAR BYTE ;---------------------------------- i var byte i=1 SSPADD=$0B ' I2C Address: $0B SSPCON1=$36 SSPCON2.0=1 i2c_data[0]=1 i2c_data[1]=2 i2c_data[2]=3 i2c_data[3]=4 i2c_data[4]=5 i2c_data[5]=6 i2c_data_index=0 ASM INT_LIST macro INT_Handler SSP_INT, _i2c_int_handler, PBP, yes endm INT_CREATE INT_ENABLE SSP_INT endasm main: goto main i2c_int_handler: IF i2c_read then dummy=SSPBUF IF i2c_buffer_full=0 THEN SSPBUF=i2c_data[i2c_data_index] i2c_data_index=i2c_data_index+1 IF i2c_data_index=6 THEN i2c_data_index=0 ENDIF ENDIF i2c_release_scl=1 @ INT_RETURN), how can I add another Slave and get data from it? I appreciate any help and the time for sharing.
Thanks in advance,
tacbanon
![]()
Last edited by tacbanon; - 26th April 2012 at 13:56.
I need Working I2C Slave code for PIC16LF1513 in C program with some instructions.
Bookmarks