中文字幕 另类精品,亚洲欧美一区二区蜜桃,日本在线精品视频免费,孩交精品乱子片免费

<sup id="3hn2b"></sup>

    1. <sub id="3hn2b"><ol id="3hn2b"></ol></sub><legend id="3hn2b"></legend>

      1. <xmp id="3hn2b"></xmp>

      2. 新聞中心

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

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

        作者: 時(shí)間:2011-02-24 來(lái)源:網(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



        評(píng)論


        相關(guān)推薦

        技術(shù)專(zhuān)區(qū)

        關(guān)閉