MPLAB and PIC16F628A, basic EEPROM functions wont work

Hello all
Ive got a query about the simulator in MPLAB.  I'm using a PIC16F628A-IP and Ive written a couple of subs to run the EEPROM functions, but when I try and run the program in the simulator and observe the registers, I'm noticing that EECON1 is not accepting bit changes, and when reading from the EEPROM, i get as far as getting the correct value into W register (MOVFW EEDATA), then the next step, simply a RETURN command, for no reason wipes the W register back to 0 and hence the routine always returns a 0
Can somebody have a look and see whats going wrong, this is one of the easiest routines to write as there are so many examples on the web, Ive even used code straight from Microchip's Code Library and that didnt work either, its driving me MAD!!!

All I am trying to do with the following code is simply read the EEPROM contents of address 05, display the returned contents to PORTB, wait a second, then increment the contents by 1 and resave into the EEPROM at address 05, so by rights on power up I should see FF then 00 then 01 then 02, etc, incrementing every second, on PORTB....I'm a bit of a stickler for custom keywords so sorry if its a bit confusing, makes perfect sense to me of course!

;  GENERIC PROGRAMMING HEADER

 LIST P=16F628A   ; DETERMINE CORE TYPE
 INCLUDE "P16F628A.INC" ; INCLUDE DEFAULT ASSEMBLY FILE FOR THIS CORE
 ORG 00H     ; START PROGRAM AT LINE 0
 RADIX HEX    ; ASSUME HEX UNLESS SPECIFIED
 ERRORLEVEL -302  ; NO BANK WARNINGS DURING ASSEMBLY
 
;  SET BURN CONIFGURATION FOR NO WDT AND INTERNAL OSC AT 4MHZ

 __CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _BODEN_OFF &_INTRC_OSC_NOCLKOUT & _MCLRE_OFF & _LVP_OFF

;  CONSTANTS AND VARIABLES

OPT  EQU 81H  ; OPTION REGISTER

NN  EQU 02AH ; GENERAL N REGISTER FOR COUNTING DELAYS
XX  EQU 02BH ; GENERAL X REGISTER FOR COUNTING DELAYS
YY  EQU 02CH ; GENERAL Y REGISTER FOR COUNTING DELAYS

TEMP EQU 02DH ; GENERAL TEMPORARY FOLDER 1
TMP  EQU 02EH ; GENERAL TEMPORARY FOLDER 2

FLAGS EQU 020H ; MISCELLANEOUS PROGRAM SPECIFIC FLAGS

N  EQU 021H
X  EQU 022H ; GENERAL TEMP STORES
Y  EQU 023H


;  CUSTOM INSTRUCTIONS
#DEFINE   BANK0     BCF       STATUS,RP0          ; Sel Bank 0
#DEFINE   BANK1     BSF       STATUS,RP0          ; Sel Bank 1
#DEFINE   READNVM CALL READ
#DEFINE   WRITENVM CALL WRITE
#DEFINE   W10MS  CALL DELAY
#DEFINE   W1S  CALL DELAY1S


;-----------------------------------------------------------------
;  INITIALISE MICRO
;-----------------------------------------------------------------


INIT

  BANK1

  CLRF  TRISB ; PORT B DEFINED ALL OUTPUTS
  MOVLW 0FFH
  MOVWF TRISA ; PORT A ALL INPUTS
  BANK0

;  SET TO MIMIC 16F84 BY TURNING OFF COMPARATOR

  MOVLW 07H
  MOVWF CMCON

;  PURGE GENERAL RAM FILES

  CLRF NN
  CLRF XX
  CLRF YY
  CLRF TEMP 
  CLRF TMP 
  CLRF FLAGS
  CLRF N
  CLRF X
  CLRF Y
  CLRF PORTA
  CLRF PORTB
  CLRF OPT
  CLRF INTCON
 
;-------------------------------------------------------------------
;  MAIN PROGRAM
;-------------------------------------------------------------------

MAIN; ORIGIN

  MOVLW 05
  READNVM

  MOVWF PORTB
  W1S

  MOVLW 05
  MOVWF EEADR
  MOVF PORTB,W
  INCF W,1
  MOVWF EEDATA
  WRITENVM

  GOTO  MAIN

;---------------------------------------------------------------------------
;  END OF MAIN PROGRAM BODY
;---------------------------------------------------------------------------

  GOTO FINISH  ; PROGRAM LOOP FALLOUT

;---------------------------------------------------------------------------
;  SUBROUTINES
;---------------------------------------------------------------------------

; LIST OF AVAILABLE SUBS:
; DELAY  = 10mS DELAY
; DELAY1S  = 1 sec DELAY
; WRITE  = WRITE TO EEPROM, MUST BE LOADED WITH EEDATA AND EEADR B4 ENTRY
; READ  = READ FROM EEPROM ADDRESS HELD IN W BEFORE ENTRY, RETURN RESULT IN W

;  10mS DELAY

DELAY  
 
  MOVLW 0AH
  MOVWF XX
OUTER

  MOVLW 0C7H
  MOVWF YY

INNER   NOP
        NOP
        DECFSZ  YY,1
        GOTO    INNER        
        DECFSZ  XX,1
        GOTO    OUTER
  NOP
  NOP
  NOP
  NOP
  NOP
  NOP
  NOP
        RETURN

DELAY1S   ; 100x10mS DELAYS
  MOVLW  064H
  MOVWF NN
D1L  W10MS
  DECFSZ NN,1
  GOTO D1L 
  RETURN

 

WRITE    
  BANK1
        CLRF EECON1               
        BSF EECON1,WREN            ; enable write
  W10MS
  W10MS
  BCF INTCON,GIE
        MOVLW H'55'                ; magic sequence
        MOVWF EECON2              
        MOVLW H'AA'                 
        MOVWF EECON2              
        BSF EECON1,WR
  W10MS
  W10MS            
eeloop BTFSC EECON1,WR            ; wait for WR to go low
        GOTO eeloop                ; not yet
        BCF EECON1,WREN           
        BCF INTCON,GIE           ; clear the interrupt flag
        BANK0
  W10MS
  W10MS
        RETURN


READ BCF EECON1,WREN
  MOVWF EEADR                ; set up eeprom address from W
        BANK1
  BSF EECON1,RD              ; set the read bit
        BANK0
  MOVFW EEDATA              ; return value in W
        RETURN  

;  PROGRAM ENDS
FINISH 
 END

Note, this will probably make more sense if its copied and pasted into an ASM in MPLAB, as the tab stops and comments become more apparent

THanks for looking
 


foile6 years ago
Hi i dont know if you aleady fount the answer to your problem but i'll try to help anyways.

MAIN; ORIGIN

MOVLW 05
READNVM

MOVWF PORTB
W1S

MOVLW 05
MOVWF EEADR
MOVF PORTB,W
INCF W,1
MOVWF EEDATA ;you can't change eedata here it must be done on the
WRITENVM ;write function

this is the write function i'm using and is working just fine:

movf CANT,w ;in this case CANT has the # i want to write to eeprom
BANKSEL EECON1 ;use this instead of the BANK1 function
MOVWF EEDATA ;move the contents of W into eedata, it has to be here after banksel
MOVLW .001 ;addres were you are writing
MOVWF EEADR ; move to eeadr
BSF EECON1,WREN ; the rest i guess you aready know it.
MOVLW 0X55
MOVWF EECON2
MOVLW 0XAA
MOVWF EECON2
BSF EECON1,WR
eeloop BTFSC EECON1,WR ; wait for WR to go low
GOTO eeloop ; not yet
BCF EECON1,WREN
BCF STATUS,RP0
BCF PORTA,2

hope you find it useful.
whitebakecase (author) 7 years ago
ALSO JUST NOTICED THAT "BSF EECON1,RD" DOES NOT CHANGE THE EECON1 REGISTER???
whitebakecase (author) 7 years ago
OK IVE DABBLED A BIT MORE AND TRIMMED THINGS DOWN FOR EASIER READING

THIS IS THE EEPROM READ ROUTINE THAT I AM USING
IVE FOUND THAT THE INSTRUCTION MOVWF EEADR IS NOT WORKING, W REGISTER IS PRE LOADED BEFORE CALLING THE ROUTINE AND AT THE POINT OF MOVWF EEADR,  EEADR DOES NOT CHANGE FROM 0 HENCE THE ROUTINE IS CONSTANTLY LOADING THE CONTENTS OF ADDRESS 0, BUT W STILL HOLDS CORRECT ADDRESS VALUE OK??
MY BANK1/BANK0 COMMANDS ARE PRE-DEFINED, AND REFER TO RAM PAGE SWAPPING, IVE ALSO TRIED REPLACING MY COMMANDS WITH THE FULL VERSIONS (BCF STATUS,RP0 ETC) AND ALSO TRIED BOTH BANKS PER INSTRUCTION WITH NO EFFECT

READ:
 
  BCF EECON1,WREN      ; CANCEL ANY CURRENT WRITES
  MOVWF EEADR                ; W COMES PRELOADED FROM MAIN PROG       

  BANK1
  BSF EECON1,RD              ; set the read bit
  BANK0

  MOVFW EEDATA              ; return value in W
       
  RETURN