I2C Slave with a PIC


Closed Thread
Results 1 to 40 of 130

Hybrid View

  1. #1
    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 10:07.

  2. #2
    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

  3. #3
    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 16:27.

  4. #4
    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: 3041
Size:  120.2 KB
    Last edited by tacbanon; - 26th April 2012 at 12:56.

  5. #5
    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

  6. #6
    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 11:53.

  7. #7
    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

  8. #8
    Join Date
    Aug 2016
    Posts
    1


    Did you find this post helpful? Yes | No

    Default Re: I2C Slave with a PIC

    I need Working I2C Slave code for PIC16LF1513 in C program with some instructions.


  9. #9
    Join Date
    Oct 2009
    Posts
    583


    Did you find this post helpful? Yes | No

    Default Re: I2C Slave with a PIC

    Quote Originally Posted by Address View Post
    I need Working I2C Slave code for PIC16LF1513 in C program with some instructions.

    So why post on a BASIC forum -

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, 02:58
  2. PIC as I2C Slave
    By Mainul in forum General
    Replies: 4
    Last Post: - 5th January 2013, 13:23
  3. I2C Slave, config Vref - + in pic with ADC
    By sebapostigo in forum PBP Wish List
    Replies: 4
    Last Post: - 5th March 2007, 03:21
  4. Pic as an i2c slave
    By Robert Soubie in forum mel PIC BASIC Pro
    Replies: 1
    Last Post: - 25th January 2007, 21:11
  5. Use pic as slave in I2C
    By robert0 in forum General
    Replies: 2
    Last Post: - 3rd February 2006, 19:26

Members who have read this thread : 2

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