Skip to content

hi2creceive

Anobium edited this page Oct 18, 2020 · 1 revision

HI2CReceive

Syntax:

    HI2CReceive data

    HI2CReceive data, ACK
    HI2CReceive data, NACK

Command Availability:

Only available for microcontrollers with the hardware I2C or TWI module.

Explanation:

The HI2CReceive command will send data through the I2C connection. If ack is TRUE, or no value is given for ack, then HI2CReceive will send an ack to the I2C bus.

If in master mode, HI2CReceive will read the data immediately. If in slave mode, HI2CReceive will wait for the master to send the data before reading.

Note:

This command is also available on microcontrollers with a second hardware I2C port.

    HI2C2Receive  _data_

    HI2C2Receive _data_, ACK
    HI2C2Receive _data_, NACK

Example 1:

    'This program reads an I2C register and sets an LED if it is over 100.

    'It will read from I2C device with an address of 83, register 1.
    ' Change the processor
    #chip 16F1937, 32
    #config MCLRE_ON


    ' Define I2C settings
    #define HI2C_BAUD_RATE 400

    #define HI2C_DATA PORTC.4
      #define HI2C_CLOCK PORTC.3

    'I2C pins need to be input for SSP module
    Dir HI2C_DATA in
    Dir HI2C_CLOCK in

    'MASTER I2C Device
    HI2CMode Master

    'Misc settings
    #define LED PORTB.0

    'Main loop
    Do
      'Send start
      HI2CStart

      'Request value
      HI2CSend 83
      HI2CSend 1

      'Read value
      HI2CReceive ValueIn

      'Send stop
      HI2CStop

      'Turn on LED if received value > 100
      Set LED Off
      If ValueIn > 100 Then Set LED On

      'Delay
      Wait 20 ms

    Loop

Example 2:

See the I2C Overview for the Master mode device to control this Slave mode device.

    ' I2CHardwareReceive_Slave.gcb - using a 16F88.
    ' This program receives commands from a GCB Master. This Slave has three LEDs attached.

    ; This Slave device responds to address 0x60 and may only be written to.
    ; Within it, there are three registers, 0,1 and 2 corresponding to the three LEDs. Writing a zero
    ; turns the respective LED off. Writing anything else turns it on.


    #chip 16F88, 4
    #config  MCLR_Off

    #define I2C_MODE    Slave     ;this is a slave device now
    #define I2C_CLOCK   portb.4   ;SCL on pin 10
    #define I2C_DATA    portb.1   ;SDA on pin 7
    #define I2C_ADDRESS 0x60      ;address of the slave device

    #define I2C_BIT_DELAY 20 us
    #define I2C_CLOCK_DELAY 10 us
    #define I2C_END_DELAY 10 us


    'Serial settings
    #define SerInPort PORTB.6
    #define SerOutPort PORTB.7

    #define SendAHigh Set SerOutPort OFF
    #define SendALow Set SerOutPort On
    'Set pin directions
    Dir SerOutPort Out
    Dir SerInPort In

    'Set up serial connection
    InitSer 1, r2400, 1 + WaitForStart, 8, 1, none, INVERT
    wait 1 s

    #define LED0  porta.2          ;pin 1
    #define LED1  porta.3          ;pin 2
    #define LED2  porta.4          ;pin 3

    ;----- Variables

    dim addr, reg, value,location as byte
    addr = 255
    reg = 255
    value = 255
    location = 0
    mempointer = 255

    ;----- Program

    dir LED0 out                  ;0, 1 and 2 are outputs (LEDs)
    dir LED1 out                  ;0, 1 and 2 are outputs (LEDs)
    dir LED2 out                  ;0, 1 and 2 are outputs (LEDs)

    set LED0 off
    set LED1 off
    set LED2 off

    #define SerialControlPort portb.3
    dir SerialControlPort in

    'Set up interrupt to process I2C

       dir I2C_CLOCK in           ; required to input for MSSP module
       dir I2C_DATA in            ; required to input for MSSP module
       SSPADD=I2C_ADDRESS         ; Slave address
       SSPSTAT=b'00000000'        ; configuration
       SSPCON=b'00110110'         ; configuration
       PIE1.SSPIE=1               ; enable interrupt


    repeat 3                      ;flash LEDs
      set LED0 on
      set LED1 on
      set LED2 on
      wait 50 ms
      set LED0 off
      set LED1 off
      set LED2 off
      wait  100 ms
    end Repeat

    oldvalue = 255                ; old value, set up value only
    oldreg = 255                  ; old value, set up value only

    UpdateLEDS                    ; call method to set LEDs
                    ; set up interrupt
    On Interrupt SSP1Ready call I2C_Interrupt

    do forever
       if reg <> oldreg then      ; only process when the reg is a new value
        oldreg = reg            ; retain old value
        show = 1                ; its time to show the LEDS!
        if  value <> oldvalue then    ; logic for tracking old values. You only want to update terminal once per change
          oldvalue = value
          show = 1
        end if
       end if

       UpdateLEDS                  ; Update date LEDs

                     ; update serial terminal
       if show = 1  and SerialControlPort = 1 then

        SerPrint 1, "0x"+hex(addr)
        SerSend 1,9

        SerPrint 1, STR(reg)
        SerSend 1,9

        SerPrint 1, STR(value)
        SerSend 1,10
        SerSend 1,13

        show = 0
       end if
    loop


    Sub I2C_Interrupt
      ' handle interrupt
      IF SSPIF=1 THEN                   ; its a valid interrupt

         IF SSPSTAT.D_A=0 THEN          ; its an address coming in!
          addr=SSPBUF
          IF addr=I2C_ADDRESS THEN    ; its our address

           mempointer = 0           ; set the memory pointer. This code emulates an EEPROM!

          end if
          IF addr = ( I2C_ADDRESS | 1 ) THEN    ; its our write address
           CKP = 0                            ; acknowledge command
                            ; If the SDA line was low (ACK), the transmit data must be loaded into
                            ; the SSPBUF register which also loads the SSPSR
                            ; register. Then, pin RB4/SCK/SCL should be enabled
                            ; by setting bit CKP.

           mempointer = 10                    ; set a pointer to track incoming write reqests
           if I2C_DATA = 0 then
            SSPBUF = 0x22
            CKP = 1
            readpointer = 0x55
           end if
          end if

         else

         if  SSPSTAT.P = 1 then             ' Stop bit has been detected - out of sequence
           ' handle event
         end if

         IF  SSPSTAT.S = 1 THEN             ' Start bit has been detected - out of sequence
           ' handle event
         END IF

         IF SSPSTAT.R_W = 0 THEN            ' Write operations requested

          SELECT CASE mempointer
               CASE 0
                reg = SSPBUF         ' incoming value
                mempointer++         ' increment our counter
               CASE 1
                value = SSPBUF       ' incoming value
                mempointer++         ' increment our counter
               CASE ELSE
                dummy = SSPBUF       ' incoming value
          END SELECT

         ELSE                                ' Read operations
          SSPBUF = readpointer             ' incoming value
          readpointer++                    ' increment our counter

         END IF
         END IF
         CKP = 1                               ' acknowledge command
         SSPOV = 0                             ' acknowledge command
      END IF
      SSPIF=0
    END SUB



    sub UpdateLEDS

      select case reg           ;now turn proper LED on or off
        case 0
        if value = 1 then
          set LED0 on
        else
          set LED0 off
        end if

        case 1
        if value = 1 then
          set LED1 on
        else
          set LED1 off
        end if

        case 2
        if value = 1 then
          set LED2 on
        else
          set LED2 off
        end if

      end select

    End Sub

Supported in <HI2C.H>

Clone this wiki locally