人狗畜禽COMPANY LIMITED|全是肉的高H文〈男男〉|全篇肉高H秘书被C办公室四爱|全黄H全肉共妻|全黄H全肉短篇禁乱NP慕浅浅|全黄H全肉短篇N男男

技術(shù)熱線: 4007-888-234
設(shè)計開發(fā)

專注差異化嵌入式產(chǎn)品解決方案 給智能產(chǎn)品定制注入靈魂給予生命

開發(fā)工具

提供開發(fā)工具、應(yīng)用測試 完善的開發(fā)代碼案例庫分享

技術(shù)支持

從全面的產(chǎn)品導(dǎo)入到強大技術(shù)支援服務(wù) 全程貼心伴隨服務(wù),創(chuàng)造無限潛能!

新品推廣

提供新的芯片及解決方案,提升客戶產(chǎn)品競爭力

新聞中心

提供最新的單片機資訊,行業(yè)消息以及公司新聞動態(tài)

PIC單片機的I2C應(yīng)用程序1

更新時間: 2019-03-21
閱讀量:458

Functionality:

;

; This code implements the basic functions for an I2C slave device

; using the SSP module. All I2C functions are handled in an ISR.

; Bytes written to the slave are stored in a buffer. After a number

; of bytes have been written, the master device can then read the

; bytes back from the buffer.

;

; Variables and Constants used in the program:

;

; The start address for the receive buffer is stored in the variable

; 'RXBuffer'. The length of the buffer is denoted by the constant

; value 'RX_BUF_LEN'. The current buffer index is stored in the

; variable 'Index'.

;

;--------------------------------------------------------------------

;

; The following files should be included in the MPLAB project:

;

; an734.asm-- Main source code file

;

; 16f872.lkr-- Linker script file

; (change this file for the device

; you are using)

;---------------------------------------------------------------------

#include; Change to device that you are using.

;---------------------------------------------------------------------

;Constant Definitions

;---------------------------------------------------------------------

#define NODE_ADDR 0x02 ; I2C address of this node

; Change this value to address that

; you wish to use.

;---------------------------------------------------------------------

; Buffer Length Definition

;---------------------------------------------------------------------

#define RX_BUF_LEN 32 ; Length of receive buffer

;---------------------------------------------------------------------

; Variable declarations

;---------------------------------------------------------------------

udata

WREGsave res 1

STATUSsave res 1

FSRsave res 1

PCLATHsave res 1

Index res 1 ; Index to receive buffer

Temp res 1 ;

RXBuffer res RX_BUF_LEN ; Holds rec'd bytes from master

; device.


;---------------------------------------------------------------------

; Vectors

;---------------------------------------------------------------------

STARTUP code

nop

goto Startup ;

nop ; 0x0002

nop ; 0x0003

goto ISR ; 0x0004

PROG code

;---------------------------------------------------------------------

; Macros

;---------------------------------------------------------------------

memset macro Buf_addr,Value,Length

movlw Length ; This macro loads a range of data memory

movwf Temp ; with a specified value. The starting

movlw Buf_addr ; address and number of bytes are also

movwf FSR ; specified.

SetNext movlw Value

movwf INDF

incf FSR,F

decfsz Temp,F

goto SetNext

endm

LFSR macro Address,Offset ; This macro loads the correct value

movlw Address ; into the FSR given an initial data

movwf FSR ; memory address and offset value.

movf Offset,W

addwf FSR,F

endm

;---------------------------------------------------------------------

; Main Code

;---------------------------------------------------------------------

Startup

bcf STATUS,RP1

bsf STATUS,RP0

call Setup

Main clrwdt ; Clear the WDT

goto Main ; Loop forever.


;---------------------------------------------------------------------

; Interrupt Code

;---------------------------------------------------------------------

ISR

movwf WREGsave ; Save WREG

movf STATUS,W ; Get STATUS register

banksel STATUSsave ; Switch banks, if needed.

movwf STATUSsave ; Save the STATUS register

movf PCLATH,W ;

movwf PCLATHsave ; Save PCLATH

movf FSR,W ;

movwf FSRsave ; Save FSR

banksel PIR1

btfss PIR1,SSPIF ; Is this a SSP interrupt?

goto $ ; No, just trap here.

bcf PIR1,SSPIF

call SSP_Handler ; Yes, service SSP interrupt.


banksel FSRsave

movf FSRsave,W ;

movwf FSR ; Restore FSR

movf PCLATHsave,W ;

movwf PCLATH ; Restore PCLATH

movf STATUSsave,W ;

movwf STATUS ; Restore STATUS

swapf WREGsave,F ;

swapf WREGsave,W ; Restore WREG


retfie ; Return from interrupt.


;---------------------------------------------------------------------

Setup

;

; Initializes program variables and peripheral registers.

;---------------------------------------------------------------------

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

;---------------------------------------------------------------------

; WriteI2C

;---------------------------------------------------------------------

WriteI2C

banksel SSPSTAT

btfsc SSPSTAT,BF ; Is the buffer full?

goto WriteI2C ; Yes, keep waiting.

banksel SSPCON ; No, continue.

DoI2CWrite

bcf SSPCON,WCOL ; Clear the WCOL flag.

movwf SSPBUF ; Write the byte in WREG

btfsc SSPCON,WCOL ; Was there a write collision?

goto DoI2CWrite

bsf SSPCON,CKP ; Release the clock.

return

;---------------------------------------------------------------------

ReadI2C

;---------------------------------------------------------------------


banksel SSPBUF

movf SSPBUF,W ; Get the byte and put in WREG

return


end ; End of file


开江县| 潮州市| 闻喜县| 论坛| 福安市| 综艺| 沁阳市| 瑞丽市| 襄垣县| 宁德市| 乌拉特后旗| 越西县| 丹寨县| 黄陵县| 阳春市| 陆丰市| 连州市| 泗阳县| 宁化县| 北宁市| 扎鲁特旗| 攀枝花市| 安阳市| 黎城县| 县级市| 元谋县| 札达县| 全州县| 龙泉市| 瓮安县| 页游| 社旗县| 绩溪县| 房山区| 株洲市| 乳源| 历史| 南京市| 台中县| 通许县| 疏附县|