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

📄 pic12ce518_eeprom.asm

📁 读区PIC12CE518内部EEPROM的程序
💻 ASM
字号:
;Exam.ple Code for Reading/Writing to EEPROM Data Memory
;TITLE "PIC with EEPROM Data Memory Interface"

LIST P=12CE518 ; Change to 12CE519 if using PIC12CE519

#include <p12CE518.inc>


; Program: EEPROM.ASM
; Revision Date:
; 10-10-97 Adapted to 12CE51x parts
;
; PIC12CE51X EEPROM communication code. This code should be linked in
; with the application. These routines provide the following functionality:
; write byte random address
; read byte random address
; read byte next address
;
; read sequential is not supported.
;
; If the operation is successful, bit 7 of PC_OFFSET will be set, and
; the functions will return W=1. If the memory is busy with a write
; cycle, it will not ACK the command. The functions will return with
; bit 7 of PC_OFFSET cleared and and W will be set to 0.
;
; Based on Franco code.
;
; Must reside on the lower half of code page (address 0-FF).
;
; This provides users with highly compressed assembly code for
; communication between the EEPROM and the Microcontroller, which
; leaves a maximum amount of code space for the core application.
;
; NOPs have been added to meet the timing specs for the memory at 4 MHz
; and low voltage. Applications running at slower clock rates and those
; operating within 4.5-5.5V may be able to remove some of the NOPs.
;
; This code is specifically written for the interface hardware of the
; 12CE51x parts. See AN571 for the unmodified routines.
;***************************************************************************
;*************************** EEPROM Subroutines **************************
;***************************************************************************
; Communication for EEPROM based on I2C protocol, with Acknowledge.
;
; Byte_Write: Byte write routine
; 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
;***************************************************************************
;
; OPERATION:
; Byte Write:
; load EEADDR and EEDATA
; then CALL BYTE_WRITE
;
; Read Random:
; Load EEADDR
; then CALL READ_RANDOM
; data read returned in EEDATA
;
; Read Current
; no setup necessary
; CALL READ_CURRENT
; data read returned in EEDATA
;
;***************************************************************************
;
; These functions consume:
; 77 words Programming Memory
; 5 file registers which are overlayable. That is, they can share with
; other functions as long as they are mutually exclusive in time. See
; udata_ovr in the linker manual.
; 1 stack level (the call to the function itself. These functions do not
; call any lower level functions).
;
;

;***************************************************************************
;*************************** Variable Listing ****************************
;***************************************************************************
OK         EQU    01H
NO         EQU    00H
I2C_PORT   EQU    GPIO    ; Port B control register, used for I2C
SCL        EQU    07H     ; EEPROM Clock, SCL (I/O bit 7)
SDA        EQU    06H     ; EEPROM Data, SDA (I/O bit 6)
EE_OK      EQU    07H     ; Bit 7 in PC_OFFSET used as OK flag for EE udata_ovr

PC_OFFSET  RES     1      ; PC offset register (low order 4 bits),
                        ; value based on operating mode of EEPROM.
                        ; Also, bit 7 used for EE_OK flag
EEADDR     res     1      ; EEPROM Address
EEBYTE     res     1      ; Byte sent to or received from
                        ; EEPROM (control, address, or data)
COUNTER    res     1      ; Bit counter for serial transfer udata
EEDATA     res          1 ; EEPROM Data

;***************************************************************************

global READ_CURRENT
global READ_RANDOM
global WRITE_BYTE
global EEADDR
global EEDATA
global PC_OFFSET

;***************************************************************************
;********************** Set up EEPROM control bytes ************************
;***************************************************************************
        code
READ_CURRENT
        MOVLW     B'10000100'        ; PC offset for read current addr. EE_OK bit7='1'
        MOVWF     PC_OFFSET          ; Load PC offset
        GOTO      INIT_READ_CONTROL
WRITE_BYTE
        MOVLW     B'10000000'        ; PC offset for write byte. EE_OK: bit7 = '1'
        GOTO      INIT_WRITE_CONTROL
READ_RANDOM
        MOVLW     B'10000011'        ; PC offset for read random. EE_OK: bit7 = '1'
INIT_WRITE_CONTROL
        MOVWF     PC_OFFSET          ; Load PC offset register, value preset in W
        MOVLW     B'10100000'        ; Control byte with write bit, bit 0 = '0'
START_BIT
        BCF       I2C_PORT,SDA       ; Start bit, SDA and SCL preset to '1'

;***************************************************************************
;******* Set up output data (control, address, or data) and counter ********
;***************************************************************************
PREP_TRANSFER_BYTE
        MOVWF     EEBYTE             ; Byte to transfer to EEPROM already in W
        MOVLW     .8                 ; Counter to transfer 8 bits
        MOVWF     COUNTER

;***************************************************************************
;************ Clock out data (control, address, or data) byte ************
;***************************************************************************
OUTPUT_BYTE
        BCF       I2C_PORT,SCL       ; Set clock low during data set-up
        RLF       EEBYTE, F          ; Rotate left, high order bit into carry bit
        BCF       I2C_PORT,SDA       ; Set data low, if rotated carry bit is
        SKPNC                        ; a '1', then:
        BSF       I2C_PORT,SDA       ; reset data pin to a one, otherwise leave low
        NOP
        BSF       I2C_PORT,SCL       ; clock data into EEPROM
        DECFSZ    COUNTER, F         ; Repeat until entire byte is sent
        GOTO      OUTPUT_BYTE
        NOP                          ; Needed to meet Timing (Thigh=4000nS)
;***************************************************************************
;************************** Acknowkedge Check *****************************
;***************************************************************************
        BCF       I2C_PORT,SCL       ; Set SCL low, 0.5us < ack valid < 3us
        NOP                          ; Needed to meet Timing (Tlow= 4700nS)
        BSF       I2C_PORT,SDA
        GOTO      $+1                ;
               ; NOP ; Necessary for SCL Tlow at low voltage,
               ; NOP ; Tlow=4700nS
        BSF       I2C_PORT,SCL       ; Raise SCL, EEPROM acknowledge still valid
        BTFSC     I2C_PORT,SDA       ; Check SDA for acknowledge (low)
        BCF       PC_OFFSET,EE_OK    ; If SDA not low (no ack), set error flag
        BCF       I2C_PORT,SCL       ; Lower SCL, EEPROM release bus
        BTFSS     PC_OFFSET,EE_OK    ; If no error continue, else stop bit
        GOTO      STOP_BIT
;***************************************************************************
;***** Set up program counter offset, based on EEPROM operating mode *****
;***************************************************************************
        MOVF      PC_OFFSET,W
        ANDLW     B'00001111'
        ADDWF     PCL, F
        GOTO      INIT_ADDRESS       ;PC offset=0, write control done, send address
        GOTO      INIT_WRITE_DATA    ;PC offset=1, write address done, send data
        GOTO      STOP_BIT           ;PC offset=2, write done, send stop bit
        GOTO      INIT_ADDRESS       ;PC offset=3, write control done, send address
        GOTO      INIT_READ_CONTROL  ;PC offset=4, send read control
        GOTO      READ_BIT_COUNTER   ;PC offset=5, set counter and read byte
        GOTO      STOP_BIT           ;PC offset=6, random read done, send stop
;***************************************************************************
;********** Initalize EEPROM data (address, data, or control) bytes ******
;***************************************************************************
INIT_ADDRESS
        INCF      PC_OFFSET, F       ; Increment PC offset to 2 (write) or to 4 (read)
        MOVF      EEADDR,W           ; Put EEPROM address in W, ready to send to EEPROM
        GOTO      PREP_TRANSFER_BYTE
INIT_WRITE_DATA
        INCF      PC_OFFSET, F       ; Increment PC offset to go to STOP_BIT next
        MOVF      EEDATA,W           ; Put EEPROM data in W, ready to send to EEPROM
        GOTO      PREP_TRANSFER_BYTE
INIT_READ_CONTROL
        BSF       I2C_PORT,SCL       ; Raise SCL
        BSF       I2C_PORT,SDA       ; raise SDA
        INCF      PC_OFFSET, F       ; Increment PC offset to go to READ_BIT_COUNTER next
        MOVLW     B'10100001'        ; Set up read control byte, ready to send to EEPROM
        GOTO      START_BIT          ; bit 0 = '1' for read operation
;***************************************************************************
;************************** Read EEPROM data *****************************
;***************************************************************************
READ_BIT_COUNTER
        BSF       I2C_PORT,SDA       ; set data bit to 1 so we're not pulling bus down.
        NOP
        BSF       I2C_PORT,SCL
        MOVLW     .8                 ; Set counter so 8 bits will be read into EEDATA
        MOVWF     COUNTER
READ_BYTE
        BSF       I2C_PORT,SCL       ; Raise SCL, SDA valid. SDA still input from ack
        SETC                         ; Assume bit to be read = 1
        BTFSS     I2C_PORT,SDA       ; Check if SDA = 1
        CLRC                         ; if SDA not = 1 then clear carry bit
        RLF       EEDATA, F          ; rotate carry bit (=SDA) into EEDATA;
        BCF       I2C_PORT,SCL       ; Lower SCL
        bsf       I2C_PORT,SDA       ; reset SDA
        DECFSZ    COUNTER, F         ; Decrement counter
        GOTO      READ_BYTE          ; Read next bit if not finished reading byte
        BSF       I2C_PORT,SCL
        NOP
        BCF       I2C_PORT,SCL
;***************************************************************************
;****************** Generate a STOP bit and RETURN ***********************
;***************************************************************************
STOP_BIT
        BCF       I2C_PORT,SDA       ; SDA=0, on TRIS, to prepare for transition to '1'
        BSF       I2C_PORT,SCL       ; SCL = 1 to prepare for STOP bit
        GOTO      $+1                ; equivalent 4 NOPs neccessary for I2C spec Tsu:sto = 4.7us
        GOTO      $+1
        BSF       I2C_PORT,SDA       ; Stop bit, SDA transition to '1' while SCL high
        BTFSS     PC_OFFSET,EE_OK    ; Check for error
        RETLW     NO                 ; if error, send back NO
        RETLW     OK                 ; if no error, send back OK
;****************************************************************************
;************************ End EEPROM Subroutines **************************
        end

⌨️ 快捷键说明

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