-
Notifications
You must be signed in to change notification settings - Fork 8
hi2creceive
Anobium edited this page Oct 18, 2020
·
1 revision
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>