I2C Slave with a PIC - Page 3


Closed Thread
Page 3 of 4 FirstFirst 1234 LastLast
Results 81 to 120 of 130
  1. #81
    Join Date
    Nov 2005
    Location
    Perth, Australia
    Posts
    429


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by Darrel Taylor View Post
    It's Proteus VSM, and it's extremely handy.

    My breadboards are all covered in a layer of dust.
    They don't get used much anymore.
    Unfortunately, as I feared, the price is pretty steep.
    "I think fish is nice, but then I think that rain is wet, so who am I to judge?" - Douglas Adams

  2. #82
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    That was my initial reaction too.
    But I've since found that it is EXTREMELY inexpensive, if you consider the value vs. cost.

    You can't even buy a decent Digital O-Scope for that much.
    But Proteus gives you Multiple 4ch-DSO's, 32ch-logic analyzers, voltmeters, ammeters, virtual terminals, signal generators, pattern generators, power supplies, I2C debuggers, SPI debuggers, frequency counters ...

    There's a whole boat load of PIC's to choose from, plus all the other chips and discrete parts.
    You can simulate multiple PIC's in the same circuit simultaneously.

    And with PBP 2.60a, it integrates right into the MPLAB IDE for step by step debugging.

    $479 gives you all that and either the 16F's or 18F's.
    Can't get much cheaper than that.

    I should be getting a commission, I sound like a commercial.

    P.S. You can download the Demo Version and run your PBP programs on the sample circuits. You just can't modify the circuit.
        Take a test drive.
    <br>
    <br>
    Last edited by Darrel Taylor; - 17th August 2010 at 21:57. Reason: .
    DT

  3. #83
    Join Date
    Dec 2007
    Location
    Paris
    Posts
    101


    Did you find this post helpful? Yes | No

    Default

    Would it be possible to easily change one of these example routines to use the MSSP module for I2C Master?

    In my program I change the clock speed from 12MHz to 250kHz, and it takes about 50ms to execute an I2CWRITE command at the slower speed. I measured the I2C clock to be about 800µs which is 1,2kHz... that's not much. I'm guessing that the PBP command includes it's own set of hardcoded delay... I'd like to save power, and if running I2C at 100kHz, I could get the PIC back to sleep 100 time faster.

    I'm understanding quite well changes to make in registers to configure the hardware part, but I must say that when it get to assembler I don't understand too much of it right now...

  4. #84
    Join Date
    Jun 2011
    Location
    Philippines
    Posts
    223


    Did you find this post helpful? Yes | No

    Default Re: I2C Salve with a PIC

    Hi, I'm interested to try the master-slave(I2C) worked by Daniel and other members, sorry if it is not obvious for me in the code given, but can someone share the schematic used in the example?
    I'm using Pic16877(master) and Pic16F88(salve).
    Thanks,
    tacbanon
    Last edited by tacbanon; - 24th April 2012 at 10:37.

  5. #85
    Join Date
    Jun 2011
    Location
    Philippines
    Posts
    223


    Did you find this post helpful? Yes | No

    Default Re: I2C Salve with a PIC

    From the code provided, here is how I interpret the pin connection between pics.
    Master(Pic16F877A) Slave(Pic16F88)
    (SCL)RB5 <---> RB4
    (SDA)RB7 <---> RB1
    but with this connection, LCD displays "Time out", can anyone help me what I'm missing?

  6. #86
    Join Date
    May 2008
    Location
    Italy
    Posts
    825


    Did you find this post helpful? Yes | No

    Default Re: I2C Salve with a PIC

    Did you pullup SCL and SDA with a 3.3K resistor?

    Cheers

    Al.
    All progress began with an idea

  7. #87
    Join Date
    Jun 2011
    Location
    Philippines
    Posts
    223


    Did you find this post helpful? Yes | No

    Default Re: I2C Salve with a PIC

    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
    Attached Images Attached Images  
    Last edited by tacbanon; - 25th April 2012 at 08:13.

  8. #88
    Join Date
    May 2008
    Location
    Italy
    Posts
    825


    Did you find this post helpful? Yes | No

    Default Re: I2C Salve with a PIC

    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

  9. #89
    Join Date
    Jun 2011
    Location
    Philippines
    Posts
    223


    Did you find this post helpful? Yes | No

    Default Re: I2C Salve with a PIC

    Hi again,
    Here is the code I'm using..
    Master pic using Pic16F877A
    Code:
    '-------------------------------------------------------------------------------
    ' 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
    Here is the code for the Slave Pic16F88
    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
    The codes I'm using is from Daniel(copy and paste).
    BTW I'm using a simulator...

    regards,
    tacbanon
    Attached Images Attached Images  
    Last edited by tacbanon; - 25th April 2012 at 11:07.

  10. #90
    Join Date
    May 2008
    Location
    Italy
    Posts
    825


    Did you find this post helpful? Yes | No

    Default Re: I2C Salve with a PIC

    Very likely is a simulator problem!

    Al.
    All progress began with an idea

  11. #91
    Join Date
    Jun 2011
    Location
    Philippines
    Posts
    223


    Did you find this post helpful? Yes | No

    Default Re: I2C Salve with a PIC

    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.

  12. #92
    Join Date
    Jun 2011
    Location
    Philippines
    Posts
    223


    Did you find this post helpful? Yes | No

    Default Please help me understand how the application works

    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)
    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
    Slave(Pic18F2620)
    Code:
    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
    As I understood, in the master pic the code below tries to communicate to the Slave having the address $02
    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]
    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:
    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
    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#2
    Slave#2
    Code:
    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
    I was only hoping that it would work that way(I guess not ), how can I add another Slave and get data from it? I appreciate any help and the time for sharing.

    Thanks in advance,
    tacbanon
    Name:  I2cerr1234.gif
Views: 2541
Size:  120.2 KB
    Last edited by tacbanon; - 26th April 2012 at 13:56.

  13. #93
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default Re: Please help me understand how the application works

    In your previous code with the F88, 3 is not a valid I2C address.
    In the current code, $B is not a valid I2C address.

    They should be a multiple of 2.
    Bit 0 is reserved for the R/W bit.
    DT

  14. #94
    Join Date
    Jun 2011
    Location
    Philippines
    Posts
    223


    Did you find this post helpful? Yes | No

    Default Re: Please help me understand how the application works

    Quote Originally Posted by Darrel Taylor View Post
    In your previous code with the F88, 3 is not a valid I2C address.
    In the current code, $B is not a valid I2C address.

    They should be a multiple of 2.
    Bit 0 is reserved for the R/W bit.
    Hi Darrel,
    Thanks for replying, I did some testing on 1Master and 1Slave with these address($02,$04,$06,$08,$10,$12,$14) and works fine. But when I trying to add Slave #2 I get "0 0 0 0 0 0". It only reads on the Slave #1 correct (displays "1 2 3 4 5 6").
    This is how I code to read the 2nd Slave.
    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_address2     VAR BYTE
    
    
    i2c_data        VAR BYTE[6]
    i2c_data2       VAR BYTE[6] 
    
    
    
    
    main:
    
    
    i2c_address=$10
    pause 200
    I2CREAD sda,scl,i2c_address,[STR i2c_data\6]
    LCDOUT $FE,$80,"1> ",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 500
    LCDOUT $FE,1
    '*********************************************
    i2c_address2=$14
    pause 200
    I2CREAD sda,scl,i2c_address2,[STR i2c_data2\6]
    LCDOUT $FE,$80,"2> ",DEC i2c_data2[0]
    LCDOUT " ",    DEC i2c_data2[1]
    LCDOUT " ",    DEC i2c_data2[2]
    LCDOUT " ",    DEC i2c_data2[3]
    LCDOUT " ",    DEC i2c_data2[4]
    LCDOUT " ",    DEC i2c_data2[5]
    
    
    PAUSE 500
    LCDOUT $FE,1  
    GOTO main
    BTW the code for Slave1 and Slave2 are identical (Slave#1 is address $10 and Slave#2 is address $14)
    What I'm doing wrong in the code? I appreciate very much your help.

    Thanks,
    Tacbanon
    Last edited by tacbanon; - 27th April 2012 at 12:53.

  15. #95
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default Re: Please help me understand how the application works

    If you comment out the first I2CREAD, is it able to read from the second slave?

    If you change the order so that it reads the second slave first, is it then unable to read the first slave?
    DT

  16. #96
    Join Date
    Jun 2011
    Location
    Philippines
    Posts
    223


    Did you find this post helpful? Yes | No

    Default Re: Please help me understand how the application works

    If you comment out the first I2CREAD, is it able to read from the second slave?
    Yes it is able to read.
    If you change the order so that it reads the second slave first, is it then unable to read the first slave?
    Nope, displays "0 0 0 0 0 0" for first Slave, 2nd Slave shows "6 5 4 3 2 1"
    Last edited by tacbanon; - 27th April 2012 at 17:57.

  17. #97
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default Re: Please help me understand how the application works

    It sounds like a buffer overflow.

    ... bad comment deleted ... duh!!

    If you post or email your .DSN, I'll take a closer look.
    Last edited by Darrel Taylor; - 28th April 2012 at 03:20.
    DT

  18. #98
    Join Date
    Jun 2011
    Location
    Philippines
    Posts
    223


    Did you find this post helpful? Yes | No

    Default Re: Please help me understand how the application works

    Thanks Darrel, oh sorry to ask this, but how do I send a winrar file?

  19. #99
    Join Date
    Sep 2004
    Location
    montreal, canada
    Posts
    6,898


    Did you find this post helpful? Yes | No

    Default Re: Please help me understand how the application works

    Steve

    It's not a bug, it's a random feature.
    There's no problem, only learning opportunities.

  20. #100
    Join Date
    Jun 2011
    Location
    Philippines
    Posts
    223


    Did you find this post helpful? Yes | No

    Default Re: Please help me understand how the application works

    Thanks mister_e

  21. #101
    Join Date
    Jan 2005
    Location
    Montreal, Quebec, Canada
    Posts
    2,588


    Did you find this post helpful? Yes | No

    Default Re: Please help me understand how the application works

    Or you can stuff it in a ZIP file and post it here. The forum accepts ZIPs as attachments.

    Some RAR programs can also save as ZIP format.

    Robert

  22. #102
    Join Date
    Jun 2011
    Location
    Philippines
    Posts
    223


    Did you find this post helpful? Yes | No

    Default Re: Please help me understand how the application works

    Thanks for the info Robert...
    and here is the zip file.

    Regards,
    tacbanon
    Attached Files Attached Files
    Last edited by tacbanon; - 28th April 2012 at 06:03.

  23. #103
    Join Date
    Jun 2011
    Location
    Philippines
    Posts
    223


    Did you find this post helpful? Yes | No

    Default Re: Please help me understand how the application works

    Oops here are the codes I'm using for the master, Slave1 and Slave 2.
    Attached Files Attached Files

  24. #104
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default Re: Please help me understand how the application works

    Thanks for the files tacbanon.

    Well, this code for the slaves will allow it to read from both devices.
    Code:
    main:  
        IF SSPCON1.6 THEN SSPCON1.6 = 0
    goto main 
    
    i2c_int_handler:
        IF i2c_read then
            IF i2c_buffer_full=0 THEN
                SSPBUF=i2c_data[i2c_data_index]
                i2c_data_index=i2c_data_index+1
            ELSE
                dummy = SSPBUF
            ENDIF
        ELSE
            i2c_data_index=0
        ENDIF
        i2c_release_scl=1 
    @ INT_RETURN
    But it's still not right. And is not a complete slave.

    According to AN734 there are 5 states to maintain. 6 including the ERROR state.
    Your original code only handles 1 state, and this modification only does 2 states.

    I think by adding the other 4 states, it will get rid of the buffer overflows, but I'm not absolutely sure.
    I'm going to convert AN734 state machine to PBP and see what happens.
    May take me awhile.
    Last edited by Darrel Taylor; - 28th April 2012 at 18:17.
    DT

  25. #105
    Join Date
    Jun 2011
    Location
    Philippines
    Posts
    223


    Did you find this post helpful? Yes | No

    Default Re: Please help me understand how the application works

    Thank you for the code, and thanks in advance DT for your valuable time...looking forward for the end result(I wish and pray that things goes well). I've been reading about I2C on net, trying to understand and the applications that might be done(particularly on Master-(multi-Slave/Multi-master)) are very interesting...

    Regards,
    tacbanon
    Last edited by tacbanon; - 29th April 2012 at 03:26.

  26. #106
    Join Date
    Sep 2005
    Location
    Campbell, CA
    Posts
    1,107


    Did you find this post helpful? Yes | No

    Default Re: I2C Salve with a PIC

    Although my slave example may not be as robust as AN734, I have systems running that have 14 slaves running. All 14 slaves are polled on 2 second intervals. The master uses bit-banging (I2CWrite). I have never had trouble with the code below. I have tested it with -
    18F8723, 18F2221, 18F2321, 18F2523 and had excellent results.

    Code:
    '****************************************************************
    '*  Name    : I2C slave                                         *
    '*  Author  : Charles Linquist                                  *
    '*  Notice  : Copyright (c) 2010 [select VIEW...EDITOR OPTIONS] *
    '*          : All Rights Reserved                               *
    '*  Date    : 10/20/2010                                        *
    '*  Version : 1.0                                               *
    '*  Notes   : Transmits 100 bytes in ~14 ms (Master SEND)       *
    '*          : Recives 100 bytes in ~12 ms (Master RECEIVE)      *  
    '*          : Could possibly go faster.  Master used for  the   *
    '*          : test used bit-banging (I2CREAD/I2CWRITE           *
    '*          : settings on that end were                         *
    '*          :  DEFINE I2C_SLOW 1 ,DEFINE I2C_HOLD 1             * 
    '****************************************************************
    ASM
        ifndef __18F2221
            error "18F2221 not selected"
        endif
    ENDASM 
           
    ASM
           movlw 0x62                              ; %0110 0010  = 4 Mhz, internal osc block
           movwf OSCCON
           movlw 0x80                              ; %1000 0000  = PLL disabled
           movwf OSCTUNE
    ENDASM       
        
               
            DATA @0,0      ; programming flag
                          
            DEFINE OSC 4                                                          
            DEFINE NO_CLRWDT 1                                                      ' Don't waste cycles clearing WDT  
            Define USE_LFSR 1
            define USE_LOWPRIORITY 1
    ;---------------- Alias the bits ------------------------------------
        
        SSPIF               VAR PIR1.3    ' SSP (I2C) interrupt flag
        SSPIE               VAR PIE1.3    ' Int Enable
       
        SSPUA               VAR SSPSTAT.1
        SSPS                VAR SSPSTAT.3
        SSPP                VAR SSPSTAT.4
        SSPSMP              VAR SSPSTAT.7
        
        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 SSPCON1.4  ' SSP (I2C) SCK Release Control
        SSPEN               VAR SSPCON1.5  ' SSP (I2C) Enable
        SSPOV               VAR SSPCON1.6  ' SSP (I2C) Receive Overflow Indicator
        WCOL                VAR SSPCON1.7  ' SSP (I2C) Write Collision Detect
        GENCALL             VAR SSPCON2.7  ' General Call enabled
        
        MainTimer           var word bankA System
        I2CTimer            var word bankA System
        I2CTimerGate        var byte bankA System
        I2CErr              var byte bankA System
    ;-------------------------------------------------------------------------  
    ;Alias pins
        SCL     VAR     PORTC.3         ' I2C clock input
        SDA     VAR     PORTC.4         ' I2C data input
        LED     VAR     PORTB.5
        
     
    '------------------- Rx Buffer defintion --------------------
        RxBufferLEN         con 10         
        RxBuffer            var BYTE[Rxbufferlen + 1]    
        TxBufferLEN         CON 10
        TXBuffer            VAR BYTE[TxBufferLEN + 2]
        InBuff              VAR BYTE
       
        GeneralCall         VAR BIT
        RXBufferOverFlow    VAR BIT
        TxBufferUnderFlow   VAR BIT
        RXBufferPointer     VAR Byte
        TXBufferPointer     VAR Byte
        address             VAR BYTE
        x                   VAR BYTE
        dummy               var byte
        I2CAddress          VAR BYTE
        WCOLCounter         VAR BYTE
    ;-------------------------------------------------------------    
        TXBuffer[TxBufferLen + 1] = $FF  ; Char to send if requestor asks for too much.
        
        I2CDeviceAddress    VAR BYTE
        
        I2CMajorAddress     CON $3
        I2CDeviceAddress =  $8   
         
        I2CAddress = (I2CMajorAddress <<4) | I2CDeviceAddress 
    ;---------------------------------------------------------------       
        SSPADD = I2Caddress ' Set our address
        SSPCON2.0 = 1      ; Stretch the clock
        SSPSTAT = 0
        SSPEN = 1             
        SSPIE = 1 
        SSPIF = 0 
        GenCall = 1           ; Turn general call on
        SSPCON2.7 = 1         ' General call address ENABLED
        SSPCON1 = $36    ' Set to I2C slave with 7-bit address    
           
    ;---------------------------------------------------------------
        TRISA = %11111111
        TRISB = %11011111
        TRISC = %11111111
           
    ' -------------- Turn on Ints  ------------------------
        INTCON.7 = 1  ; global ints
        INTCON.6 = 1  ; peripheral ints
       
    ;------------------  Clear parameters --------------
        RXBufferPointer = 0
        TxBufferPointer = 0
        GeneralCall = 0 
        RxBufferOverFlow = 0
        TXBufferUnderFlow = 0
        WCOLCounter = 0
    ;---------------------------------------------------------------------  
       
    INCLUDE "DT_INTS-18.bas"    ' Base Interrupt System
    INCLUDE "ReEnterPBP-18.bas"     ' Use PBP interrupts
    include "ReEnterPBP-18LP.bas"
    ASM
    INT_LIST  macro    ; IntSource,         Label,  Type, ResetFlag?
            INT_Handler    TMR0_INT, TimerInt,    ASM,  yes
           
        endm
        INT_CREATE               ; Creates the interrupt processor
        
    INT_LIST_L  macro    ; IntSource,        Label,  Type, ResetFlag?
         INT_Handler    SSP_INT,  _I2C_Int,   PBP,  yes
         endm
         INT_CREATE_L               ; Creates the LP interrupt processor    
        
        
    endasm
    ''----------------- Initialization Done! -----------------------------
        Goto OverInt ; jump over ISR
    
    asm
    TimerInt
          
          infsnz MainTimer
          incf   MainTimer + 1
          btfsc  I2CTimerGate,0        ; Don't count if low bit is clr
          incf   I2CTimer
          btfss  I2CTimer,2            ; Bit 2 is set , we have at least 4 counts, we must be hung
          bra    NoProb
          bcf    PIR1,3                ; Clear Int flag
          bcf    SSPCON1,5             ; Stop the 
          bsf    SSPCON1,5
          bsf    I2CErr,0
          clrf   I2CTimer
    NoProb      
          bcf INTCON,2
                
          INT_RETURN
    endasm
    '------------------------- I2C subroutine  -------------------------------- 
    I2C_Int:
      ; We don't get here uless someone has matched our address register.
    @ bsf I2CTimerGate,0    ; start the counter
    If R_W = 0 then             'This is a WRITE by the master to us
        IF BF = 0 Then goto i2CEXIT   ; Nothing for us!
        if D_A = 0 then         'We have an address
          address = SSPBUF     'Need to READ to satisfy Microchip
           IF Address = 0 THEN
               GeneralCall = 1
           ELSE
               GeneralCall = 0      
           ENDIF
               
        else            
            IF WCOL OR SSPOV THEN I2CExit
           
              RXBuffer [RxBufferPointer] = SSPBuf   ; 
              RxBufferPointer = RXBufferPointer + 1
               
              IF RXBufferPointer > RxBufferLen  THEN
                    RXBufferOverFlow = 1
                    RXBufferPointer = 0
              ENDIF 
                  
            ENDIF
              
              
        else   ' R_W = 1 Master wants to read FROM us
              IF !D_A Then                          
                    TxBufferPointer = 0  ' Mark as first read
                    RXBufferPointer = 0
              EndIF
            
              IF CKP THEN I2CExit
                  dummy = SSPBUF  ;NECESSARY!
              
              If TXBufferPointer < TxbufferLen THEN
    SENDI2C:
                  WCOL = 0
                      SSPBUF = TXBuffer[TXBufferPointer] ' Get data from array
                       IF WCOL THEN 
                           WCOLCounter = WCOLCounter + 1            ; Don't hang the bus with infinite WRITES!
                           IF WColCounter = 0 Then goto I2CExit     ; Rolled over
                          Goto SendI2C       ; Rety
                        ELSE
                           WColCounter = 0
                        ENDIF   
                       TXBufferPointer = TXBufferPointer +1
                       TXBufferPointer  = TXBufferPointer MIN TXBufferLen + 1 ; Don't let it get larger than this
                       ; Send FFs if requestor asks for too much data  
                  ELSE
                      TXBufferPointer = 0
                      TXBufferUnderflow = 1
              ENDIF 
        ENDIF
              
    I2CEXIT:
    Asm
        bcf SSPCON1,6
        bcf SSPSTAT,0 
        bcf PIR1,3
        bsf SSPCON1,4
        
        bcf I2CTimerGate,0      ; stop the counter    
        INT_ENABLE SSP_INT      ; probably don't need this, but want to make certain it gets reenabled
        INT_RETURN
    endasm
    ' -------------------------end I2C subroutine  -------------------------------- 
    '--------------------[ main program loop]---------------------------------------
    OverInt:
    Asm
       clrf MainTimer
       clrf I2CTimer      
       bcf INTCON,2 
       bcf PIR1,3  ; Clear the I2C flag before we turn on the INT.
       movlw 0x83
       movf T0CON
       INT_ENABLE  SSP_INT     
       INT_ENABLE TMR0_INT
    endasm
    
    
    
    MAIN PROGRAM LOOP GOES HERE!
    Charles Linquist

  27. #107
    Join Date
    Jun 2011
    Location
    Philippines
    Posts
    223


    Did you find this post helpful? Yes | No

    Default Re: I2C Salve with a PIC

    Hi Charles, thanks for sharing..I will try it out..


    tacbanon

  28. #108
    Join Date
    Jun 2011
    Location
    Philippines
    Posts
    223


    Did you find this post helpful? Yes | No

    Default Re: I2C Salve with a PIC

    @Charles
    Sorry I was not able to make it work on my setup..I'm not really sure what the following code is doing, so I tried to comment it and assign a value, but no effect.
    Code:
    I2CMajorAddress     CON $3
    I2CDeviceAddress =  $8     
    'I2CAddress = (I2CMajorAddress <<4) | I2CDeviceAddress 
    I2CAddress =$14
    I hope it will be alright if you share the master side code?

    Thanks,
    tacbanon

  29. #109
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default Re: I2C Salve with a PIC

    At this point, I'm thinking Al (aratti) was right.

    AN734 didn't work either.
    Bytes are being put in the SSPBUF without an address match.
    So the slaves that aren't being accessed are overflowing during reads from other devices.

    The code I gave earlier works because it's resetting the overflow in the main loop, but that's just not right.

    I'm trying to get some more info from Labcenter.
    DT

  30. #110
    Join Date
    Sep 2005
    Location
    Campbell, CA
    Posts
    1,107


    Did you find this post helpful? Yes | No

    Default Re: I2C Salve with a PIC

    I am using a slight variant of the code I posted, and it is working fine. The only major change is that I'm sending a packet length byte, and I'm handling the entire receive packet inside the ISR. This is safe because I have my ( higher priority) timer interrupt watching over the whole process.
    Charles Linquist

  31. #111
    Join Date
    Jun 2011
    Location
    Philippines
    Posts
    223


    Did you find this post helpful? Yes | No

    Default Re: I2C Salve with a PIC

    Hi,
    Just want to ask if anyone tried to extend say 50meters communication between master and slave using I2C bus extender P82B715PN or similar?

    Regards,
    tacbanon

  32. #112
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default Re: I2C Salve with a PIC

    tacbannon,

    The problem with Proteus and multiple I2C slaves has been fixed by Labcenter.
    If you update Proteus to 7.10 SP1, you should have better luck.
    DT

  33. #113
    Join Date
    Jun 2011
    Location
    Philippines
    Posts
    223


    Did you find this post helpful? Yes | No

    Default Re: I2C Salve with a PIC

    @ DT, Thanks for the update..I will find time to play with it(I2C multiple slaves) this weekend(so many work, little time to play )

    Kind regards,
    tacbanon

  34. #114
    Join Date
    Nov 2008
    Posts
    48


    Did you find this post helpful? Yes | No

    Default Re: I2C Salve with a PIC

    Hi all,
    for info to all: I have the code from Aretti here on a 18F25K22, works fine with one slave on one master. When i connect more slaves (up to 31) i get the effect that a NACK comes right behind the address, the SDA line is high during the 9th clock cycle... my bus is about 70cm long (long backplane) and i use a 3.3k on the i2c bus. It seems that this "NACK" effect is coming sporadic, does someone tried to do the same like me?
    Regards,
    Ralf

  35. #115
    Join Date
    Nov 2008
    Posts
    48


    Did you find this post helpful? Yes | No

    Default Re: I2C Salve with a PIC

    Hi again,
    found the bug: the bus i am using is splitted in two 2 x 25cm long busses which is not the best solution. Sometimes because of layout reasons it must be done this way. In this case two 100 Ohm resistors close to the Master in series with SDA and SCL and pullup's 2 x 10kOhm at both ends of the splittet bus make the bus working fine. I checked the timing with a logic analyser and the quality of the signals with a scope, both ok, no glitches or other dirty effects. Hope this help others having same trouble. I must say best solution is always making the bus from one end to the other end in one direction, i tested this also with 80cm. Adding also two 100 Ohm resitors in series with SDA and SCL close to the master makes the signal quality better also.
    Both versions run with 80kHz very fine now.
    Regards,
    Ralf

  36. #116
    Join Date
    Jan 2014
    Posts
    2


    Did you find this post helpful? Yes | No

    Default Re: I2C Salve with a PIC

    Excuse me for my English.
    How can I send data from a PIC 16F876 to four slaves
    using the I2C bus protocol, with the same address?
    Could you help me, a piece of code would be welcome!
    mimie64.

  37. #117
    Join Date
    Jun 2009
    Location
    Sc*nthorpe, UK
    Posts
    333


    Did you find this post helpful? Yes | No

    Default Re: I2C Salve with a PIC

    I2C bus protocol requires unique addresses for each slave. Just code the address into each slave if you are building the slaves yourself of course.

  38. #118
    Join Date
    Feb 2007
    Posts
    37


    Did you find this post helpful? Yes | No

    Default Re: I2C Salve with a PIC

    Thanks to all of you for your greath wok!

    ... just to avoid to have trouble in future and have a clear view of a new project, I have in plan to use the slave routine on almost 12 PIC of 18F2550 and one Master with 18F4550.

    The idea is that:
    I shall have the Master far from the first slaves at about two to three meters and the second slave is far from the first slave around 50 cm, and all other slaves are distanced 50 cm between them.

    At the end the total length shall be more than 10 meters. but less that 12 meters.

    Also, I would use the RJ45 connectors to make interconnection between the PCBs and use the preassembled CAT5 Ethernet patch cable to carry the supply voltage from the Master to the slaves.

    I have thinked to put on pin 1, 2 and 3 the VCC, on pin 4 the Clk, on pin 5 the Dat and on pin 6. 7 and 8 the GND?

    The lenght of the cables can be a problem?

    The idea to use the RJ45 with the CAT5 patch cable is good?

    Leo
    Last edited by Wirecut; - 27th March 2016 at 13:19. Reason: typo error
    Leo

  39. #119
    Join Date
    May 2013
    Location
    australia
    Posts
    2,383


    Did you find this post helpful? Yes | No

    Default Re: I2C Slave with a PIC

    WIKI I2C
    The maximum number of nodes is limited by the address space, and also by the total bus capacitance of 400 pF, which restricts practical communication distances to a few meters.
    CAT5 CAPACITANCE
    52pF / metre

    cat5 balanced cable / i2c unbalanced signal.
    cat5 characteristic impedence of 100 ohms is probably a big load for the i2c pins also.
    its not a good match , and won't go far

  40. #120
    Join Date
    Aug 2011
    Posts
    408


    Did you find this post helpful? Yes | No

    Default Re: I2C Slave with a PIC

    A regular CAT5 RJ45 has 4 twisted pairs, but they're not "in order"

    1,2 orange,orange/wht
    3,6 green,green/wht
    4,5 blue,blue/wht
    7,8 brown,brown/wht

    I'd pair the SDA and SCL signals each with a GND (ie 1=GND, 2=SDA, and 7=SCL, 8=GND) and use the others for PWR/GND.

    10 meters is a long way for a single-ended TTL level signal. They make I2C bus extenders for this sort of thing.

Similar Threads

  1. Problem with PICto PIC I2C MASTER-SLAVE
    By juanen19 in forum mel PIC BASIC Pro
    Replies: 2
    Last Post: - 11th June 2013, 03:58
  2. PIC as I2C Slave
    By Mainul in forum General
    Replies: 4
    Last Post: - 5th January 2013, 14:23
  3. I2C Slave, config Vref - + in pic with ADC
    By sebapostigo in forum PBP Wish List
    Replies: 4
    Last Post: - 5th March 2007, 04:21
  4. Pic as an i2c slave
    By Robert Soubie in forum mel PIC BASIC Pro
    Replies: 1
    Last Post: - 25th January 2007, 22:11
  5. Use pic as slave in I2C
    By robert0 in forum General
    Replies: 2
    Last Post: - 3rd February 2006, 20:26

Members who have read this thread : 6

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts