📄 flash62x.asm
字号:
TITLE "PIC with Flash EE data memory Interface"
LIST P=16CE625
#include <p16CE625.inc>
;#define TWENTYMHZ
;#define TENMHZ
#define FOURMHZ
;
; Program: FLASH625.ASM
; Revision Date:
; V1.00 30 June 1998 Adapted to 16CE62x parts
;
; PIC16CE62x EEPROM communication code. This code should be linked in
; with the application. Uses 6 file registers in the common area.
;
; 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.
;
; Conditional assembly delays are included to meet standard mode timing
; specs. For 4Mhz, define FOURMHZ at top of file. For 10 Mhz, define TENMHZ.
;
; 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/Delay calls.
;
;
; This code is specifically written for the interface hardware of the
; 16CE623/624/625 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
;
; Page_Write: Page write routine - writes up to 8 bytes at a time
; Inputs: FSR points to beginning of RAM buffer.
; W number of bytes to write
; 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
;
; EEinterface file registers (EEAddress, EEDATA) are in common ram.
; EEINTF file register is on Register Page 1. Upon exit, Register
; page is set to 0.
;***************************************************************************
;
; OPERATION:
; Byte Write:
; load EEADDR and EEDATA
; then CALL WRITE_BYTE
;
; Page Write:
; Load EEADDR
; Load FSR with address of 1st byte to transfer
; Load W with number of bytes to transfer (8 bytes max)
; then CALL WRITE_PAGE
;
; 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 Program 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).
; As the EE Interf
;
;
;***************************************************************************
;*************************** Variable Listing ****************************
;***************************************************************************
OK EQU 01H
NO EQU 00H
EE_OK EQU 07H ; Bit 7 in PC_OFFSET used as OK flag for EE
cram udata
EEADDR res 1 ; EEPROM Address
EEDATA res 1 ; EEPROM Data
EEBYTE res 1 ; Byte sent to or received from
; EEPROM (control, address, or data)
bytecount res 1 ; # of bytes to write
COUNTER res 1 ; Bit counter for serial transfer
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
global READ_CURRENT
global READ_RANDOM
global WRITE_BYTE
global WRITE_PAGE
global READ_PAGE
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
BSF STATUS,RP0 ; set register page 1
clrf PCLATH
GOTO INIT_READ_CONTROL
WRITE_BYTE
MOVLW B'10000000' ; PC offset for write byte. EE_OK: bit7 = '1'
GOTO INIT_WRITE_CONTROL
WRITE_PAGE
movwf bytecount ; save off number of bytes to send
MOVLW B'10000111' ; PC offset for write page. EE_OK bit = 1
goto INIT_WRITE_CONTROL
READ_PAGE
movwf bytecount ; save off number of bytes to send
MOVLW B'10001010' ; PC offset for read page. EE_OK bit = 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
BSF STATUS,RP0 ; set register page 1
clrf PCLATH
BCF EEINTF,EESDA ; Start bit, EESDA and EESCL 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
#ifdef FOURMHZ
NOP
#endif
#ifdef TENMHZ
call delay8 ; Tsu:sta, Thigh: 4700 nS (add 6 cycles at 10 Mhz)
#endif
#ifdef TWENTYMHZ
call delay16 ; Tsu:sta, Thigh: 4700 nS (add 6 cycles at 10 Mhz)
#endif
RLF EEBYTE, F ; Rotate left, high order bit into carry bit
BCF EEINTF,EESCL ; Set clock low during data set-up
BCF EEINTF,EESDA ; Set data low, if rotated carry bit is
SKPNC ; a '1', then:
BSF EEINTF,EESDA ; reset data pin to a one, otherwise leave low
#ifdef FOURMHZ
NOP
#endif
#ifdef TENMHZ
call delay8 ; Tlow 4700 nS (add 6 cycles at 10 Mhz)
#endif
#ifdef TWENTYMHZ
call delay16 ; Tlow 4700 nS (add 6 cycles at 10 Mhz)
#endif
BSF EEINTF,EESCL ; clock data into EEPROM
DECFSZ COUNTER, F ; Repeat until entire byte is sent
GOTO OUTPUT_BYTE
#ifdef FOURMHZ
NOP ; Needed to meet Timing (Thigh=4000nS)
#endif
#ifdef TENMHZ
call delay8
#endif
#ifdef TWENTYMHZ
call delay16 ; Tlow 4700 nS (add 6 cycles at 10 Mhz)
#endif
;************************** Acknowledge Check *****************************
;***************************************************************************
BCF EEINTF,EESCL ; Set EESCL low, 0.5us < ack valid < 3us
#ifdef FOURMHZ
NOP ; Needed to meet Timing (Tlow= 4700nS)
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -