Software for I2 C Communication
|
The data transfer in I2C mode is not automatically controlled by hardware unlike UART. The Master has to be programmmed by suitable software to generate 'Start' / 'Stop' conditions, various data bits from sending / receving , acknowledgement bit and clock signal. Here, we will discuss some examples of I2C software. |
Since SDA (RC4) and SCL (RC3) are both open drain pins, they can be configured either as an output or as an input. When a PIC Processor is configured is I2C master, the SCL pin will function as open drain output while the SDA pin can be either an input or an open drain output. Hence, the software I 2C will repeatedly access TRISC, the data direction register for PORT C. However, TRISC is located in bank-1 at an address 87H, which cannot be accessed by direct addressing without changing RP0 bit to 1 as given in the following instruction. |
bsf STATUS, RP0 |
Then required bit of TRISC can be changed followed by clearing RP0 and reverting back to Bank-0. |
bcf STATUS, RP0 |
Alternately, the indirect pointer FSR can have the address of TRISC and the required bit setting and bit clearing can be done indirectly. |
Consider the following definitions. |
SCL equ 3
SDA equ 4
|
The instruction bsf INDF, SDA will release the SDA line(as RC4/SDA pin is configured as an input, hence tristated), letting the external pullup resister pull it high or some I 2C Slave device/Chip pull it low. |
When FSR is used for indirect addressing, care should be taken to restore FSR value when subroutine is completed and the program returns to the main line program. |
I 2 C Subroutine
|
SDA equ 4
SCL equ 3
|
The following subroutine DATA_OUT transfers out three bytes, i.e., ADDRDEV, ADDR8, and DATAWRTE |
DATA_OUT: call START ; Generate start condition
movf ADDRDEV, W ; Sends 7-bit peripheral address with R/ =0
call TRBYTE ; Transmit
movf ADDR8, W ; Send 8-bit internal address
call TRBYTE
movf DATAWRTE, W ; Send data to be written
call TRBYTE
call STOP ; Generate Stop condition
return |
The DATA_IN subroutine, which is given below transfers out ADDRDEV (with R/ =0) and ADDR8, restarts and transfers out ADDRDEV (with R/ =1) and read one byte back into RAM variable DATARD. |
DATA_IN: call START
movf ADDRDEV, W ; Send 7-bit peripheral address R/ =0
call TRBYTE
movf ADDR8, W ; Send int. address
call TRBYTE
call START1 ; Restart
movf ADDRDEV, W ; Send 7-bit peripheral address R/ =1
iorlwl 01H
call TRBYTE
bsf TRBUF, 7 ; Generate NO ACK
call RCVBYTE
movwf DATARD
call STOP
return |
The 'START' subroutine initializes I2C bus and then generates START condition on the I 2C bus. START1 bypasses the initialization of I 2C. |
START: movlw 3BH ;enables I2C master mode by programming SSPCON
movwf SSPCON
bcf PORTC, SDA ; drive SDA low when it is an o/p
movlw TRISC ;set indirect pointer to TRISC
movwf FSR
START1:
bsf INDF, SDA ; SDA=1
bsf INDF , SCL ; SCL=1
call DELAY ; Generates a suitable delay
bcf INDF, SDA ; SDA=0
call DELAY ; Generate a suitable delay
bcf INDF, SCL ;SCL=0
return
STOP:
bcf INDF, SDA ;SDA=0
bsf INDF, SCL ; SCL=1
call DELAY ; Generate a suitable delay
bsf INDF, SDA ;SDA=1
return |
The subroutine 'TRBYTE' send out the byte available in w. It returns with Z=1 if ACK occurs. It returns with Z=0 if NOACK occurs.
TRBUF is an 8-bit RAM variable used for temporary storage. The bits are shifted to carry flag (C) and the carry bit transmitted successively. Data transfer is complete when all 8-bits are transmitted. Setting C = 1 initially sets an index for 8-bits to be transferred. C is rotated through TRBUF. After transmitting C, C-bit is cleared. When TRBUF is completely cleared, all 8-bis are transmitted. |
TRBYTE: |
movwf TRBUF
bsf STATUS,C
|
TR_1: |
|
rlf TRBUF, F
movf RBUF,F
btfss STATUS, Z
call out_bit ; Send a bit available in C
btfss STATUS, Z
goto TR_1
call in_bit ; Get the ACK bit in RCBUF<0>
movlw 01H ;
andwf RCBUF, W ; Store the complement of ACK bit in Z flag
return
|
The RCVBYTE subroutine receives a byte from I2 C into W using a RAM variable RCBUF buffer. |
Call RCVBYTE with bit 7 of TRBUF clear for ACK
Call RCVBYTE with bit 7 of TRBUF set for NOACK
RCBUF is an 8-bit RAM variable used for recieving the data. the bit is recieved in the RCBUF<0> and is rotated successively through RCBUF as shown. The reception ends when all 8-bits are recieved. |
RCVBYTE: |
movlw 01H
movwf RCBUF ; Keep an index for 8-bits to be recieved.
|
|
RCV_1: |
rlf RCBUF, F
call In_bit
btfss STATUS, C
goto RCV_1
rlf TRBUF, F
call Out_bit
movf RCBUF,w
return
|
The out_bit subroutine transmits carry bit, then clears the carry bit. |
Out_bit: |
bcf INDF, SDA
btfsc STATUS, C
bsf INDF, SDA ; Send carry bit
bsf INDF, SCL
call DELAY
bcf INDF, SCL
bcf STATUS,C ; Clear carry bit
return
|
The in_bit subroutine receives one bit into bit-0 of RCBUF. |
In_bit: |
bsf INDF,SDA
bsf INDF, SCL
bcf RCBUF, 0
btfsc PORTC, SDA ; Check SDA line for data bit
bsf RCBUF, 0
bcf INDF, SCL
return
|
Example of I 2 C interfacing |
DAC interfacing on I 2 C bus: |
MAX518 is a dual 8-bit Digital to Analog Converter (DAC) with I2C interface. The address of the device is selectable through two pins AD1 and AD0 . This device works in I2C slave mode. The connection diagram is shown as follows. |
|
Fig 27.1 I2C Interface for DAC
|
The 7-bit device address is given as |
|
For the present connection AD1 = 0 and AD0 = 1
The device address is 010 1101
Three bytes are sent to output an analog voltage. |
First byte (Address of the DAC and R/ bit ) |
|
Second byte (DAC Configuration) |
|
Third byte (The 8-bit digital data(B) to be converted to analog voltage)
B |
Analog output voltage = V DD x B/256 |
|
No comments:
Post a Comment