微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > PIC单片机的I2C应用程序1

PIC单片机的I2C应用程序1

时间:02-24 来源:互联网 点击:

banksel PCON
bsf PCON,NOT_POR
bsf PCON,NOT_BOR

banksel Index ; Clear various program variables
clrf Index

clrf PORTB
clrf PIR1
banksel TRISB
clrf TRISB

movlw 0x36 ; Setup SSP module for 7-bit
banksel SSPCON
movwf SSPCON ; address, slave mode
movlw NODE_ADDR
banksel SSPADD
movwf SSPADD
clrf SSPSTAT


banksel PIE1 ; Enable interrupts
bsf PIE1,SSPIE
bsf INTCON,PEIE ; Enable all peripheral interrupts
bsf INTCON,GIE ; Enable global interrupts

bcf STATUS,RP0
return

;---------------------------------------------------------------------
SSP_Handler
;---------------------------------------------------------------------
; The I2C code below checks for 5 states:
;---------------------------------------------------------------------
; State 1: I2C write operation, last byte was an address byte.
;
; SSPSTAT bits: S = 1, D_A = 0, R_W = 0, BF = 1
;
; State 2: I2C write operation, last byte was a data byte.
;
; SSPSTAT bits: S = 1, D_A = 1, R_W = 0, BF = 1
;
; State 3: I2C read operation, last byte was an address byte.
;
; SSPSTAT bits: S = 1, D_A = 0, R_W = 1, BF = 0
;
; State 4: I2C read operation, last byte was a data byte.
;
; SSPSTAT bits: S = 1, D_A = 1, R_W = 1, BF = 0
;
; State 5: Slave I2C logic reset by NACK from master.
;
; SSPSTAT bits: S = 1, D_A = 1, R_W = 0, BF = 0
;
; For convenience, WriteI2C and ReadI2C functions have been used.
;----------------------------------------------------------------------

banksel SSPSTAT
movf SSPSTAT,W ; Get the value of SSPSTAT
andlw b'00101101' ; Mask out unimportant bits in SSPSTAT.
banksel Temp ; Put masked value in Temp
movwf Temp ; for comparision checking.

State1: ; Write operation, last byte was an
movlw b'00001001' ; address, buffer is full.
xorwf Temp,W ;
btfss STATUS,Z ; Are we in State1?
goto State2 ; No, check for next state.....

memset RXBuffer,0,RX_BUF_LEN ; Clear the receive buffer.
clrf Index ; Clear the buffer index.
call ReadI2C ; Do a dummy read of the SSPBUF.
return

State2: ; Write operation, last byte was data,
movlw b'00101001' ; buffer is full.
xorwf Temp,W
btfss STATUS,Z ; Are we in State2?
goto State3 ; No, check for next state.....

LFSR RXBuffer,Index ; Point to the buffer.
call ReadI2C ; Get the byte from the SSP.
movwf INDF ; Put it in the buffer.
incf Index,F ; Increment the buffer pointer.
movf Index,W ; Get the current buffer index.
sublw RX_BUF_LEN ; Subtract the buffer length.
btfsc STATUS,Z ; Has the index exceeded the buffer length?
clrf Index ; Yes, clear the buffer index.
return

State3: ; Read operation, last byte was an
movlw b'00001100' ; address, buffer is empty.
xorwf Temp,W
btfss STATUS,Z ; Are we in State3?
goto State4 ; No, check for next state.....

clrf Index ; Clear the buffer index.
LFSR RXBuffer,Index ; Point to the buffer
movf INDF,W ; Get the byte from buffer.
call WriteI2C ; Write the byte to SSPBUF
incf Index,F ; Increment the buffer index.
return

State4: ; Read operation, last byte was data,
movlw b'00101100' ; buffer is empty.
xorwf Temp,W
btfss STATUS,Z ; Are we in State4?
goto State5 ; No, check for next state....

movf Index,W ; Get the current buffer index.
sublw RX_BUF_LEN ; Subtract the buffer length.
btfsc STATUS,Z ; Has the index exceeded the buffer length?
clrf Index ; Yes, clear the buffer index.
LFSR RXBuffer,Index ; Point to the buffer
movf INDF,W ; Get the byte
call WriteI2C ; Write to SSPBUF
incf Index,F ; Increment the buffer index.
return

State5:
movlw b'00101000' ; A NACK was received when transmitting
xorwf Temp,W ; data back from the master. Slave logic
btfss STATUS,Z ; is reset in this case. R_W = 0, D_A = 1
goto I2CErr ; and BF = 0
return ; If we aren抰 in State5, then something is
; wrong.

I2CErr nop
banksel PORTB ; Something went wrong! Set LED
bsf PORTB,7 ; and loop forever. WDT will reset
goto $ ; device, if enabled.
return

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top