I2C Master/Slave 16F88/16F767 working code


Closed Thread
Results 1 to 3 of 3
  1. #1

    Thumbs up I2C Master/Slave 16F88/16F767 working code

    Hi Guys,

    After a few days of trying, I got this code to work. One 16F88 as master, and two 16F767 as slaves, just to test that the address is working fine. I only test to send one byte. I will have to test to read one, but wanted to share the code anyway:

    Code:
    '--- MASTER BEGINS ----------------------------------------------------------------------------
    
    @ device pic16f88, intrc_osc_noclkout    ; system clock options
    @ device pic16f88, wdt_on                 ; watchdog timer
    @ device pic16f88, pwrt_on                 ; power-on timer
    @ device pic16f88, mclr_off             ; master clear options (internal)
    @ device pic16f88, protect_off            ; code protect off
    
    '---
    DEFINE OSC 8
    
    DEFINE I2C_HOLD 1
    DEFINE I2C_SLOW 1
    
    osccon = %01111000 '8mhz
    
    '---
    cmcon = 7
    ansel = 0
    
    '---
    
    scl VAR PORTB.4        ' i2c clock input
    sda VAR PORTB.1        ' i2c data input
    
    '---
    
    main:
          High PORTA.6
          Pause 500
    
          Low PORTA.6
          Pause 500
    
          ' First 16f767 - address 6
    
          I2CWrite sda, scl, $06, [15], bogus
          Pause 100
    
          I2CWrite sda, scl, $06, [30], bogus
          Pause 100
    
          ' Second 16f767 - address 8
          
          I2CWrite sda, scl, $08, [45], bogus
          Pause 100
    
          I2CWrite sda, scl, $08, [60], bogus
          Pause 100
    
          GoTo main
    
    '---
    
    bogus:
           GoTo main
    
    '---
    
    End
    
    '--- MASTER ENDS ----------------------------------------------------------------------------
    Code:
    '--- FIRST SLAVE STARTS ----------------------------------------------------------------------------
    
    @ DEVICE PIC16F767, INTRC_OSC_NOCLKOUT    ; System Clock Options
    @ DEVICE PIC16F767, WDT_ON                 ; Watchdog Timer
    @ DEVICE PIC16F767, PWRT_ON             ; Power-On Timer
    @ DEVICE PIC16F767, MCLR_OFF             ; Master Clear Options (Internal)
    @ DEVICE PIC16F767, PROTECT_OFF            ; Code Protect Off
    
    '---
    
    DEFINE OSC 8
    OSCCON = %01110000
    
    '---
    
    CMCON = 7 ' Comparators Off
    ADCON0 = 0 ' A/D Modules Off
    ADCON1 = %11111111 ' All Digital Pins
    TRISA = %00000000
    
    '---
    
    DEFINE I2C_HOLD 1
    DEFINE I2C_SLOW 1
    
    '---
    
    ' Alias pins
    scl     VAR     PORTC.3         ' I2C clock input
    sda     VAR     PORTC.4         ' I2C data input
    
    '---
    
    ' Define used register flags
    SSPIF   VAR     PIR1.3          ' SSP (I2C) interrupt flag
    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
    
    '---
    
    ' Define constants
    I2Caddress CON 6                ' Make our address 6
    
    '---
    
    LEDA VAR PORTB.2
    LEDB VAR PORTB.6
    LEDC VAR PORTB.7
    
    '---
    
    ' Allocate RAM
    
    datain     VAR     BYTE            ' Data in 
    readcnt    VAR     BYTE 
    dataout    VAR     BYTE[8]
    
    '---
    
    ' Initialize I2C slave mode
    SSPADD = I2Caddress        ' Set our address
    SSPCON2 = 0             ' General call address disabled
    SSPCON = $36             ' Set to I2C slave with 7-bit address
    
    '---
    
    ' POST
    
    Low leda
    Pause 100
    
    High leda
    Pause 100
    
    Low leda
    Pause 100
    
    High leda
    Pause 100
    
    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 != 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 data into array
            GoTo i2cexit
    
    '---
    
    i2crd:                            ' I2C read data from us
            IF D_A = 0 Then
                    readcnt = 0        ' Mark as first read
            EndIF
    
            SSPBUF = dataout[readcnt]    ' Get data from array
            CKP = 1                     ' Release SCL line
            readcnt = readcnt + 1       ' Move along read count
            
            GoTo i2cexit                ' That's it
    
    '---
    
    i2cexit:
    
            Return
    
    '---
    
    main:
          IF SSPIF = 1 Then
    
             GoSub i2cslave
    
             Low leda
             Pause 10
    
             High leda
             Pause 10
    
             IF datain = 15 Then
                Low ledb
                Pause 10
                High ledb
                Pause 10
             EndIF
    
             IF datain = 30 Then
                Low ledc
                Pause 10
                High ledc
                Pause 10
             EndIF
    
          EndIF
    
          SSPOV = 0
          WCOL = 0
    
          GoTo main
    
    '---
    
    End
    
    '--- FIRST SLAVE ENDS ----------------------------------------------------------------------------
    Code:
    '--- SECOND SLAVE STARTS ----------------------------------------------------------------------------
    
    @ DEVICE PIC16F767, INTRC_OSC_NOCLKOUT    ; System Clock Options
    @ DEVICE PIC16F767, WDT_ON                 ; Watchdog Timer
    @ DEVICE PIC16F767, PWRT_ON             ; Power-On Timer
    @ DEVICE PIC16F767, MCLR_OFF             ; Master Clear Options (Internal)
    @ DEVICE PIC16F767, PROTECT_OFF            ; Code Protect Off
    
    '---
    
    DEFINE OSC 8
    OSCCON = %01110000
    
    '---
    
    CMCON = 7 ' Comparators Off
    ADCON0 = 0 ' A/D Modules Off
    ADCON1 = %11111111 ' All Digital Pins
    TRISA = %00000000
    
    '---
    
    DEFINE I2C_HOLD 1
    DEFINE I2C_SLOW 1
    
    '---
    
    ' Alias pins
    scl     VAR     PORTC.3         ' I2C clock input
    sda     VAR     PORTC.4         ' I2C data input
    
    '---
    
    ' Define used register flags
    SSPIF   VAR     PIR1.3          ' SSP (I2C) interrupt flag
    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
    
    '---
    
    ' Define constants
    I2Caddress CON 8                ' Make our address 8
    
    '---
    
    LEDA VAR PORTB.2
    LEDB VAR PORTB.6
    LEDC VAR PORTB.7
    
    '---
    
    ' Allocate RAM
    
    datain     VAR     BYTE            ' Data in 
    readcnt    VAR     BYTE 
    dataout    VAR     BYTE[8]
    
    '---
    
    ' Initialize I2C slave mode
    SSPADD = I2Caddress        ' Set our address
    SSPCON2 = 0             ' General call address disabled
    SSPCON = $36             ' Set to I2C slave with 7-bit address
    
    '---
    
    ' POST
    
    Low leda
    Pause 100
    
    High leda
    Pause 100
    
    Low leda
    Pause 100
    
    High leda
    Pause 100
    
    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 != 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 data into array
            GoTo i2cexit
    
    '---
    
    i2crd:                            ' I2C read data from us
            IF D_A = 0 Then
                    readcnt = 0        ' Mark as first read
            EndIF
    
            SSPBUF = dataout[readcnt]    ' Get data from array
            CKP = 1                     ' Release SCL line
            readcnt = readcnt + 1       ' Move along read count
            
            GoTo i2cexit                ' That's it
    
    '---
    
    i2cexit:
    
            Return
    
    '---
    
    main:
          IF SSPIF = 1 Then
    
             GoSub i2cslave
    
             Low leda
             Pause 10
    
             High leda
             Pause 10
    
             IF datain = 45 Then
                Low ledb
                Pause 10
                High ledb
                Pause 10
             EndIF
    
             IF datain = 60 Then
                Low ledc
                Pause 10
                High ledc
                Pause 10
             EndIF
    
          EndIF
    
          SSPOV = 0
          WCOL = 0
    
          GoTo main
    
    '---
    
    End
    
    '--- SECOND SLAVE ENDS ----------------------------------------------------------------------------
    Hope it helps.

    Regards,
    Daniel.
    Last edited by ScaleRobotics; - 2nd July 2010 at 16:58. Reason: added code tags

  2. #2


    Did you find this post helpful? Yes | No

    Default Re: I2C Master/Slave 16F88/16F767 working code

    Can you put up your wiring diagram please

    Thanks

  3. #3


    Did you find this post helpful? Yes | No

    Default Re: I2C Master/Slave 16F88/16F767 working code

    I'm afraid I don't have them anymore, but you only need two wires between each PIC and a pull-up resistor on each...

Similar Threads

  1. decoding quadrature encoders
    By ice in forum mel PIC BASIC Pro
    Replies: 93
    Last Post: - 28th February 2017, 10:02
  2. Another I2C Slave Routine Problem
    By DanPBP in forum mel PIC BASIC Pro
    Replies: 4
    Last Post: - 19th February 2009, 06:50
  3. Making Program Code Space your playground...
    By Melanie in forum Code Examples
    Replies: 15
    Last Post: - 19th July 2008, 09:26
  4. Writing code for battery operated projects
    By jessey in forum mel PIC BASIC Pro
    Replies: 15
    Last Post: - 16th June 2005, 04:39
  5. i2c master/slave
    By lab310 in forum mel PIC BASIC Pro
    Replies: 4
    Last Post: - 8th April 2005, 23:23

Members who have read this thread : 4

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