⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pic12i2c.sdi

📁 proteus 仿真实例
💻 SDI
📖 第 1 页 / 共 2 页
字号:
,,,;       Inputs:  EEPROM Address   EEADDR
,,,;                EEPROM Data      EEDATA
,,,;       Outputs: Return 01 in W if OK, else return 00 in W
,,,;
,,,; READ_CURRENT: Read EEPROM at address currently held by EE device.
,,,;       Inputs:  NONE
,,,;       Outputs: EEPROM Data       EEDATA
,,,;                Return 01 in W if OK, else return 00 in W
,,,;
,,,; READ_RANDOM: Read EEPROM byte at supplied address
,,,;       Inputs:  EEPROM Address    EEADDR
,,,;       Outputs: EEPROM Data       EEDATA
,,,;                Return 01 in W if OK, else return 00 in W
,,,;
,,,; Note: EEPROM subroutines will set bit 7 in PC_OFFSET register if the
,,,;       EEPROM acknowledged OK, else that bit will be cleared.  This bit
,,,;       can be checked instead of refering to the value returned in W
,,,;***************************************************************************
,,,;********************** Set up EEPROM control bytes ************************
,,,;***************************************************************************
0022,,READ_CURRENT,READ_CURRENT
0022,0C84,,        MOVLW   B'10000100'   ; PC offset for read current addr.  EE_OK bit7='1'
0023,003A,,        MOVWF   PC_OFFSET     ; Load PC offset
0024,0A52,,        GOTO    INIT_READ_CONTROL
,,,
0025,,WRITE_BYTE,WRITE_BYTE
0025,0C80,,        MOVLW   B'10000000'   ; PC offset for write byte.  EE_OK: bit7 = '1'
0026,0A28,,        GOTO    INIT_WRITE_CONTROL
,,,
0027,,READ_RANDOM,READ_RANDOM
0027,0C83,,        MOVLW   B'10000011'   ; PC offset for read random.  EE_OK: bit7 = '1'
,,,
0028,,INIT_WRITE_CONTROL,INIT_WRITE_CONTROL
0028,003A,,        MOVWF   PC_OFFSET     ; Load PC offset register, value preset in W
0029,0CA0,,        MOVLW   B'10100000'   ; Control byte with write bit, bit 0 = '0'
,,,
002A,,START_BIT,START_BIT
002A,04C6,,        BCF     I2C_PORT,SDA  ; Start bit, SDA and SCL preset to '1'
,,,
,,,
,,,;******* Set up output data (control, address, or data) and counter ********
,,,;***************************************************************************
002B,,PREP_TRANSFER_BYTE,PREP_TRANSFER_BYTE
002B,003D,,        MOVWF   EEBYTE        ; Byte to transfer to EEPROM already in W
002C,0C08,,        MOVLW   .8            ; Counter to transfer 8 bits
002D,003E,,        MOVWF   COUNTER
,,,#ifdef  EMULATED
,,,        movlw   0x00            ; make sure both are outputs
,,,        tris    I2C_PORT
,,,#endif
,,,
,,,
,,,;************  Clock out data (control, address, or data) byte  ************
,,,;***************************************************************************
002E,,OUTPUT_BYTE,OUTPUT_BYTE
002E,04E6,,        BCF     I2C_PORT,SCL  ; Set clock low during data set-up
002F,037D,,        RLF     EEBYTE, F     ; Rotate left, high order bit into carry bit
0030,04C6,,        BCF     I2C_PORT,SDA  ; Set data low, if rotated carry bit is
0031,0603,,        SKPNC                 ;   a '1', then:
0032,05C6,,        BSF     I2C_PORT,SDA  ; reset data pin to a one, otherwise leave low
0033,0000,,        NOP
0034,05E6,,        BSF     I2C_PORT,SCL  ; clock data into EEPROM
0035,02FE,,        DECFSZ  COUNTER, F    ; Repeat until entire byte is sent
0036,0A2E,,        GOTO    OUTPUT_BYTE
0037,0000,,        NOP
,,,
,,,;**************************  Acknowledge Check *****************************
,,,;***************************************************************************
0038,04E6,,        BCF     I2C_PORT,SCL  ; Set SCL low, 0.5us < ack valid < 3us
0039,0000,,        NOP
003A,05C6,,        BSF     I2C_PORT,SDA
,,,#ifdef  EMULATED
,,,        movlw   (0x01 << SDA)   ; make SDA an input
,,,        tris    I2C_PORT
,,,#endif
003B,0A3C,,        GOTO    $+1             ; May be necessary for SCL Tlow  at low voltage,
003C,05E6,,        BSF     I2C_PORT,SCL  ; Raise SCL, EEPROM acknowledge still valid
003D,06C6,,        BTFSC   I2C_PORT,SDA  ; Check SDA for acknowledge (low)
003E,04FA,,        BCF     PC_OFFSET,EE_OK ; If SDA not low (no ack), set error flag
003F,04E6,,        BCF     I2C_PORT,SCL    ; Lower SCL, EEPROM release bus
0040,07FA,,        BTFSS   PC_OFFSET,EE_OK ; If no error continue, else stop bit
0041,0A69,,        GOTO    STOP_BIT
,,,#ifdef  EMULATED
,,,        movlw   0x00            ; SDA back to an output
,,,        tris    I2C_PORT
,,,#endif
,,,
,,,
,,,;*****  Set up program counter offset, based on EEPROM operating mode  *****
,,,;***************************************************************************
0042,021A,,        MOVF    PC_OFFSET,W
0043,0E0F,,        ANDLW   B'00001111'
0044,01E2,,        ADDWF   PCL, F
0045,0A4C,,        GOTO    INIT_ADDRESS      ;PC offset=0, write control done, send address
0046,0A4F,,        GOTO    INIT_WRITE_DATA   ;PC offset=1, write address done, send data
0047,0A69,,        GOTO    STOP_BIT          ;PC offset=2, write done, send stop bit
0048,0A4C,,        GOTO    INIT_ADDRESS      ;PC offset=3, write control done, send address
0049,0A52,,        GOTO    INIT_READ_CONTROL ;PC offset=4, send read control
004A,0A58,,        GOTO    READ_BIT_COUNTER  ;PC offset=5, set counter and read byte
004B,0A69,,        GOTO    STOP_BIT          ;PC offset=6, random read done, send stop
,,,
,,,
,,,;**********  Initalize EEPROM data (address, data, or control) bytes  ******
,,,;***************************************************************************
004C,,INIT_ADDRESS,INIT_ADDRESS
004C,02BA,,        INCF    PC_OFFSET, F ; Increment PC offset to 2 (write) or to 4 (read)
004D,021B,,        MOVF    EEADDR,W     ; Put EEPROM address in W, ready to send to EEPROM
004E,0A2B,,        GOTO    PREP_TRANSFER_BYTE
,,,
,,,
004F,,INIT_WRITE_DATA,INIT_WRITE_DATA
004F,02BA,,        INCF    PC_OFFSET, F ; Increment PC offset to go to STOP_BIT next
0050,021C,,        MOVF    EEDATA,W     ; Put EEPROM data in W, ready to send to EEPROM
0051,0A2B,,        GOTO    PREP_TRANSFER_BYTE
,,,
0052,,INIT_READ_CONTROL,INIT_READ_CONTROL
0052,05E6,,        BSF     I2C_PORT,SCL ; Raise SCL
0053,0000,,        nop
0054,05C6,,        BSF     I2C_PORT,SDA ; raise SDA
0055,02BA,,        INCF    PC_OFFSET, F ; Increment PC offset to go to READ_BIT_COUNTER next
0056,0CA1,,        MOVLW   B'10100001'  ; Set up read control byte, ready to send to EEPROM
0057,0A2A,,        GOTO    START_BIT    ;   bit 0 = '1' for read operation
,,,
,,,
,,,;**************************  Read EEPROM data  *****************************
,,,;***************************************************************************
0058,,READ_BIT_COUNTER,READ_BIT_COUNTER
0058,05C6,,        BSF     I2C_PORT,SDA
0059,0000,,        NOP
005A,05E6,,        BSF     I2C_PORT,SCL ; set data bit to 1 so we're not pulling bus down.
005B,0C08,,        MOVLW   .8           ; Set counter so 8 bits will be read into EEDATA
005C,003E,,        MOVWF   COUNTER
,,,#ifdef  EMULATED
,,,        movlw   (0x01 << SDA)
,,,        tris    I2C_PORT
,,,#endif
,,,
005D,,READ_BYTE,READ_BYTE
005D,05E6,,        BSF     I2C_PORT,SCL ; Raise SCL, SDA valid.  SDA still input from ack
005E,0503,,        SETC                 ; Assume bit to be read = 1
005F,07C6,,        BTFSS   I2C_PORT,SDA ; Check if SDA = 1
0060,0403,,        CLRC                 ; if SDA not = 1 then clear carry bit
0061,037C,,        RLF     EEDATA, F    ; rotate carry bit (=SDA) into EEDATA;
0062,04E6,,        BCF     I2C_PORT,SCL ; Lower SCL
0063,05C6,,        BSF     I2C_PORT,SDA ; reset SDA
0064,02FE,,        DECFSZ  COUNTER, F   ; Decrement counter
0065,0A5D,,        GOTO    READ_BYTE    ; Read next bit if not finished reading byte
,,,
0066,05E6,,        BSF     I2C_PORT,SCL
0067,0000,,        NOP
0068,04E6,,        BCF     I2C_PORT,SCL
,,,;******************  Generate a STOP bit and RETURN  ***********************
,,,;***************************************************************************
0069,,STOP_BIT,STOP_BIT
,,,#ifdef  EMULATED
,,,        movlw   0x00    ; set SDA as output
,,,        tris    I2C_PORT
,,,#endif
0069,04C6,,        BCF     I2C_PORT,SDA ; SDA=0, on TRIS, to prepare for transition to '1'
006A,05E6,,        BSF     I2C_PORT,SCL ; SCL = 1 to prepare for STOP bit
006B,0A6C,,        GOTO    $+1          ; 4 NOPs neccessary for I2C spec Tsu:sto = 4.7us
006C,0A6D,,        GOTO    $+1
006D,05C6,,        BSF     I2C_PORT,SDA ; Stop bit, SDA transition to '1' while SCL high
,,,
006E,07FA,,        BTFSS   PC_OFFSET,EE_OK ; Check for error
006F,0800,,        RETLW   NO              ; if error, send back NO
0070,0801,,        RETLW   OK              ; if no error, send back OK
,,,
,,,;Note: SDA and SCL still being driven by master, both set to outputs.
,,,;****************************************************************************
,,,;************************  End EEPROM Subroutines  **************************
,,,
,,,
,,,        END

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -