Here is some code I have used in the past to read and write to EEPROM on a PIC16f876
*****************************************************************************
;
; subroutine to read from EEPROM
;
; Function : EEREAD
;
; Input: EEPROM address to read from (In "W" register)
;
; Output: Date read from EEPROM (In "W" register)
;
;*****************************************************************************
; subroutine to read EEPROM memory (For PIC16F876)
EEREAD
bcf STATUS,RP0
bsf STATUS,RP1 ; select memory bank 2
movwf EEADR ; write EEADR
BSF STATUS,RP0 ; Bank 3
BCF EECON1, EEPGD ;Select data memory
bsf EECON1,RD ; read EEPROM
bcf STATUS,RP0 ; select bank 2
movfw EEDATA ; EEPROM value in w
BCF STATUS,RP1 ;Select bank 0
return
;*****************************************************************************
;
; subroutine to write to EEPROM
;
; Function : EWRITE
; Writes data in "W" register to internal EEPROM
; Address of EEPROM to be written must first be put in EEADR register
;
; Input: Value to write to internal EEPROM
;
;*****************************************************************************
; subroutine to write to EEPROM (For PIC16F876)
EWRITE
BCF INTCON,GIE ;Disable INTs.
BSF STATUS,RP1 ;
BSF STATUS,RP0 ;Select bank 3
BTFSC EECON1,WR ;Wait for write
GOTO $-1 ;to complete
BCF STATUS, RP0 ;select Bank 2
BCF STATUS,RP1 ;Select bank 0
MOVF DATA_EE_ADDR,W ;Data Memory
BSF STATUS,RP1 ;Select bank 2
MOVWF EEADR ;Address to write
BCF STATUS,RP1 ;Select bank 0
MOVF DATA_EE_DATA,W ;Data Memory Value
BSF STATUS,RP1 ;Select bank 2
MOVWF EEDATA ;to write
BSF STATUS,RP0 ;Select Bank 3
BCF EECON1,EEPGD ;Point to DATA memory
BSF EECON1,WREN ;Enable writes
MOVLW 0x55 ;
MOVWF EECON2 ;Write 55h
MOVLW 0xAA ;
MOVWF EECON2 ;Write AAh
BSF EECON1,WR ;Set WR bit to begin write
BCF EECON1,WREN ;Disable writes
BCF STATUS,RP1 ;Select bank 2
BCF STATUS,RP0 ;Select bank 0
BSF INTCON,GIE ;Enable INTs.
RETURN
I seem to remember the sequence of writing 0x55 and 0xAA to EECON2 was important
Les.