<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > PIC單片機(jī)的I2C應(yīng)用程序1

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

          作者: 時(shí)間:2011-02-24 來源:網(wǎng)絡(luò) 收藏
          ; File: an734.asm
          ; data: feb.23.2001

          ; 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 p16f872.inc> ; 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



          評論


          相關(guān)推薦

          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();