Problem Writing into EEPROM of PIC16f690

Status
Not open for further replies.

Ken Ho

New Member
Hi, I am having problem writing into the EEPROM of pic16f690. When I read the EEPROM address I have tried to write into, it returns a value FF which means no data have been written into the address. Can someone please help? Below is my source code that I almost copied completely from the data sheet. I do not know what is missing. Thanks.

#include <p16F690.inc>
__config (_INTRC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF & _BOR_OFF & _IESO_OFF & _FCMEN_OFF)


cblock 0x20
Delay1 ; Assign an address to label Delay1
Delay2
OnDelayLoop
OffDelayLoop
WRITE_ERR
WRITE_OK
Dcycle_add
Dcycle_data
endc




org 0
Start

bsf STATUS, RP0 ; select Register Page 1
movlw 0xFF
movwf TRISA ; Make PortA all input
movlw 0x00
movwf TRISC
bcf STATUS, RP0 ; back to Register Page 0
clrf PORTC




MainLoop

movlw 0x10
movwf Dcycle_add
movlw 0x0A
movwf Dcycle_data



WRITE

BANKSEL EEADR ;
MOVF Dcycle_add, W;
MOVWF EEADR ;Data Memory Address to write


MOVF Dcycle_data, W;
MOVWF EEDAT ;Data Memory Value to write

BANKSEL EECON1 ;
BCF EECON1, EEPGD ;Point to DATA memory

BSF EECON1, WREN ;Enable writes
BCF INTCON, GIE ;Disable INTs.
BTFSC INTCON, GIE ;SEE AN576
GOTO $-2
MOVLW 0x55 ;
MOVWF EECON2 ;Write 55h
MOVLW 0xAA ;
MOVWF EECON2 ;Write AAh
BSF EECON1, WR ;Set WR bit to begin write

BSF INTCON, GIE ;Enable INTs.
;SLEEP ;Wait for interrupt to signal write complete (optional)
BCF EECON1, WREN ;Disable writes
BANKSEL 0x00 ;Bank 0

;verify
BANKSEL EEDAT ;
MOVF EEDAT, W ;EEDAT not changed
;from previous write
BANKSEL EECON1 ;
BSF EECON1, RD ;YES, Read the
;value written
BANKSEL EEDAT ;
XORWF EEDAT, W ;
BTFSS STATUS, Z ;Is data the same
goto $ +4
movlw 0x02
movwf PORTC
goto $-2
BANKSEL 0x00 ;Bank 0

READ
BANKSEL EEADR ;
MOVF Dcycle_add, W;
MOVWF EEADR ;Data Memory
;Address to read
BANKSEL EECON1 ;
BCF EECON1, EEPGD ;Point to DATA memory
BSF EECON1, RD ;EE Read
BANKSEL EEDAT ;
MOVF EEDAT, W ;W = EEDAT
BCF STATUS, RP1 ;Bank 0

movwf PORTC
btfsc PORTA,3
goto $ -1
clrf PORTC
movlw 0x05
movwf PORTC

btfss PORTA,3
goto $ -1
goto READ


end
 
Please look into the program

Could someone with experience with writing into EEPROM of the PIC please look into the pogram? As I really need to get it working. Thanks.
 
BSF INTCON, GIE ;Enable INTs.
;SLEEP ;Wait for interrupt to signal write complete (optional)
BCF EECON1, WREN ;Disable writes
BANKSEL 0x00 ;Bank 0
I think you need to wait where the commented out sleep instruction is. Put a delay here so that the data has time to be written to EEPROM.
This should do it:

BTFSC EECON1, WR ;Test WR bit for end of write
GOTO $-1
 
BTFSC EECON1, WR ;Test WR bit for end of write
GOTO $-1[/QUOTE]

I have already tried this test before. And I tried it again just now still doesn't work. It seems WR has been cleared which means data has been written into the address I've specified. But When I tried to read the data, the data at the specific address returns FF. Have you written into internal EEPROM before?
 
Code:
#include <p16F690.inc>
    __config (_INTRC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF & _BOR_OFF & _IESO_OFF & _FCMEN_OFF)


cblock  0x20
Delay1      ; Assign an address to label Delay1
Delay2
OnDelayLoop
OffDelayLoop
WRITE_ERR
WRITE_OK
Dcycle_add
Dcycle_data
    endc




    org 0
Start

    bsf STATUS, RP0  ; select Register Page 1
    movlw   0xFF
    movwf   TRISA       ; Make PortA all input
    movlw   0x00
    movwf   TRISC
    bcf STATUS, RP0  ; back to Register Page 0
    clrf  PORTC




MainLoop

   movlw 0x10
   movwf Dcycle_add
   movlw 0x0A
   movwf Dcycle_data



WRITE

BANKSEL EEADR ; [color="RED"]Switch to Bank 2[/color]
MOVF Dcycle_add, W; [color="RED"]But DCycle_add is in Bank 0[/color]
MOVWF EEADR ;Data Memory Address to write


MOVF Dcycle_data, W;   [color="RED"]Same error again[/color]
MOVWF EEDAT ;Data Memory Value to write

BANKSEL EECON1 ;
BCF EECON1, EEPGD ;Point to DATA memory

BSF EECON1, WREN ;Enable writes
BCF INTCON, GIE ;Disable INTs.
BTFSC INTCON, GIE ;SEE AN576  [color="RED"]???[/color]
GOTO $-2 
MOVLW 0x55 ;
MOVWF EECON2 ;Write 55h
MOVLW 0xAA ;
MOVWF EECON2 ;Write AAh
BSF EECON1, WR ;Set WR bit to begin write

BSF INTCON, GIE ;Enable INTs.
;SLEEP ;Wait for interrupt to signal write complete (optional)
BCF EECON1, WREN ;Disable writes
[color="RED"];You need to poll for PIR2<EEIF> to become set indicating the write is complete, before continueing...[/color]
[color="RED"];...Then clear PIR2<EEIF> yourself[/color]
BANKSEL 0x00 ;Bank 0  [color="RED"]questionable use of banksel, better use a variable name... Furthermore...[/color]

;verify
BANKSEL EEDAT ; [color="RED"]...2 banksel's in a row is useless[/color]
MOVF EEDAT, W ;EEDAT not changed [color="RED"]I can't see the 16f690 datasheet specifically say EEDAT is unchanged after a write - Better not to assume things[/color]
[color="RED"]; You need to reload EEADR - Datasheet clearly states EEADR contents are unreliable after a write operation[/color]
BANKSEL EECON1 ;
[color="RED"]; BCF EECON1, EEPGD ? [/color]
BSF EECON1, RD ;YES, Read the
;value written
BANKSEL EEDAT ;
XORWF EEDAT, W ;
BTFSS STATUS, Z ;Is data the same
goto $ +4
	movlw 0x02
	movwf PORTC
goto $-2
BANKSEL 0x00 ;Bank 0  [color="RED"]Same as before, use a label[/color]

READ
     BANKSEL EEADR ;  [color="RED"]Bank 2...[/color]
MOVF Dcycle_add, W; [color="RED"]Dcycle_add is in Bank 0[/color]
MOVWF EEADR ;Data Memory
;Address to read
BANKSEL EECON1 ;
BCF EECON1, EEPGD ;Point to DATA memory
BSF EECON1, RD ;EE Read
BANKSEL EEDAT ;
MOVF EEDAT, W ;W = EEDAT
BCF STATUS, RP1 ;Bank 0

     movwf PORTC
     btfsc PORTA,3
     goto $ -1
     clrf PORTC
     movlw 0x05
     movwf PORTC
     
     btfss PORTA,3
     goto $ -1
     goto READ


end

Just a quick peek , there might be more errors.
 
I suspected it was a banking issue (it often is with EEProm problems) but it's difficult to justify spending time to look at someones code if they don't make an effort to format the code to make it easier to read.

Sorry, I really don't mean to complain. I just hope other people may catch on before they post code when asking for help.

Mike
 
Have you written into internal EEPROM before?
Yes, but not on the pic16f690
One of your problems is the verify code below as Exo pointed out:

;verify
BANKSEL EEDAT ;
MOVF EEDAT, W ;EEDAT not changed
;from previous write Yes it has changed to what you loaded into it to write!
BANKSEL EECON1 ;
BSF EECON1, RD ;YES, Read the
;value written
BANKSEL EEDAT ;
XORWF EEDAT, W ;
BTFSS STATUS, Z ;Is data the same It always will be because of above in bold

For testing this code, why not just compare EEDAT to the literal value that you are expecting?
 
Last edited:
Hey I have solved the Problem. A big thank you go to all of you, Exo, Mike and kchriste. I was so happy that I shouted out in joy when I saw the data read out in the LED is the correct data. The problem is really with banking issues. After I saved the Dcycle_add and Dcycle_data into Bank 2, everything went well. Thank you so much. I have been dwelling onto this problem for the past few days.
 
I think we forgot to tell him about the 70h through 7Fh GPR locations available across all four banks. Oops!
 
When I write

cblock 0x20
Delay1 ; Assign an address to label Delay1
Delay2
OnDelayLoop
OffDelayLoop
WRITE_ERR
WRITE_OK
Dcycle_add
Dcycle_data
endc

does it mean that I have saved my general purpose registers starting from 20h? So you are saying it is better for me to use the general purpose registers starting from 70h to 7Fh? I'm sorry I copied this part from somewhere so I dun really understand this part.
 
does it mean that I have saved my general purpose registers starting from 20h?
I don't think you can say "saved" more like "assigned some labels to some memory locations starting at 0x20"
So you are saying it is better for me to use the general purpose registers starting from 70h to 7Fh?
You can use them. You generally save these locations for frequently used variables. That way you don't have to worry about bank switching because they appear in all banks. They are also used for context saving in ISRs because you don't know what bank is active when you enter your ISR and you need to save W and the STATUS registers before they are altered by your ISR code.
 
Great. I fully understand what you are trying to say. I changed assigned the labels to 70h onwards and I dun need to worry about putting the variables in the wrong bank. Thanks. You guys have been really helpful
 
Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…