Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

PIC16F877 EEPROM problem

Status
Not open for further replies.

nicknamefrank

New Member
I am trying to write into EEPROM. I am using MPLAB IDE.

cblock 0x110 ;bank 2
VALUE
ADDR
endc


movlw "B"
movwf VALUE
movlw 0x00
movwf ADDR

I am basically using the code given in the data sheet

-->Write Function
BSF STATUS, RP1 ;
BSF STATUS, RP0 ;Bank 3
BTFSC EECON1, WR ;Wait for
GOTO $-1 ;write to finish
BCF STATUS, RP0 ;Bank 2
MOVF ADDR, W ;Address to
MOVWF EEADR ;write to
MOVF VALUE, W ;Data to
MOVWF EEDATA ;write
BSF STATUS, RP0 ;Bank 3
BCF EECON1, EEPGD ;Point to Data memory
BSF EECON1, WREN ;Enable writes
;Only disable interrupts
BCF INTCON, GIE ;if already enabled,
;otherwise discard
MOVLW 0x55 ;Write 55h to
MOVWF EECON2 ;EECON2
MOVLW 0xAA ;Write AAh to
MOVWF EECON2 ;EECON2
BSF EECON1, WR ;Start write operation
;Only enable interrupts
BSF INTCON, GIE ;if using interrupts,
;otherwise discard
BCF EECON1, WREN ;Disable writes

--->Read
BSF STATUS, RP1 ;
BCF STATUS, RP0 ;Bank 2
MOVF ADDR, W ;Write address
MOVWF EEADR ;to read from
BSF STATUS, RP0 ;Bank 3
BCF EECON1, EEPGD ;Point to Data memory
BSF EECON1, RD ;Start read operation
BCF STATUS, RP0 ;Bank 2
MOVF EEDATA, W ;W = EEDATA

I assume that W has the data that was just written.
But after calling to write on the LCD, W doesn't contain anything

Does anyone see a problem with this?
 
Have you tried it in the MPLAB simulator?

I can connect to my PIC and see the results using the LCD. I assumed that it would be sufficient.
I haven't used the simulator, but since this was the most basic write/read operation, I was just curious whether there is an error in the data sheet or something I have missed.

Using the code from the data sheet, the program doesn't even execute anything after the EEPROM operation.
 
Hi,
If you use 16F877 (no A prefix)
base on MPlab File registers then addres 0x110-0x11f has no memory

When you write to EEProm it need a time to complete work
default around 10 mSec/write
better put code below to end of write or before read to check if write complete
Code:
;bank 3
     BTFSC EECON1, WR ;Wait for
     GOTO $-1 ;write to finish
 
Hi,
If you use 16F877 (no A prefix)
base on MPlab File registers then addres 0x110-0x11f has no memory

When you write to EEProm it need a time to complete work
default around 10 mSec/write
better put code below to end of write or before read to check if write complete

Ok i assumed that 0x110-0x11f was bank 2.
I have switched the address to 0x30. But from what I see, any code that appear after the write function does not become executed. It seems like the program just gets "stuck" during the write operation.
does that have anything to do with the bank selection?
 
Last edited:
Try moving your variables into the common area at 0x70-0x7f as I'm unsure what bank you are in when you write "B" etc to them. Also, as mentioned earlier move the test of WR to after the write as otherwise the hardware will still be busy when you do the read.

Code:
		cblock	0x[COLOR="Red"]70[/COLOR]
VALUE
ADDR
		endc


		movlw	"B" 
		movwf	VALUE
		movlw	0x00
		movwf	ADDR


-->Write	Function 
		bsf	STATUS,RP1	;
		bsf	STATUS,RP0	;Bank 3
		bcf	STATUS,RP0	;Bank 2
		movf	ADDR,W		;Address to
		movwf	EEADR		;write to
		movf	VALUE,W		;Data to
		movwf	EEDATA		;write
		bsf	STATUS,RP0	;Bank 3
		bcf	EECON1,EEPGD	;Point to Data memory
		bsf	EECON1,WREN	;Enable writes
;Only disable interrupts  
		bcf	INTCON,GIE	;if already enabled,
;otherwise discard 
		movlw	0x55		;Write 55h to
		movwf	EECON2		;EECON2
		movlw	0xAA		;Write AAh to
		movwf	EECON2		;EECON2
		bsf	EECON1,WR	;Start write operation
;Only enable interrupts  
		bsf	INTCON,GIE	;if using interrupts,
;otherwise discard 
		bcf	EECON1,WREN	;Disable writes

[COLOR="red"]		btfsc	EECON1,WR	;Wait for
		goto	$-1		;write to finish[/COLOR]
--->Read
		bsf	STATUS,RP1	;
		bcf	STATUS,RP0	;Bank 2
		movf	ADDR,W		;Write address
		movwf	EEADR		;to read from
		bsf	STATUS,RP0	;Bank 3
		bcf	EECON1,EEPGD	;Point to Data memory
		bsf	EECON1,RD	;Start read operation
		bcf	STATUS,RP0	;Bank 2
		movf	EEDATA,W	;W = EEDATA

Mike.
 
Try moving your variables into the common area at 0x70-0x7f as I'm unsure what bank you are in when you write "B" etc to them. Also, as mentioned earlier move the test of WR to after the write as otherwise the hardware will still be busy when you do the read.

Thanks I think that will help.
However, I just realized that simply by adding in the code
" BSF STATUS, RP1"
It freezes my entire program. Nothing after that line of code even becomes executed :(
 
The only way that can cause a problem is if an interrupt comes along. Do you have interrupts running? Can you post a complete file that exhibits the problem?

Mike.
 
Apparently it was because of the bank selection.
I needed to change the bank to zero after each write/read operation
BCF STATUS, RP1 ;
BCF STATUS, RP0 ;
and it becomes functional :)

But thank you very much for being helpful

as a side note, how do you guys know so much about these subjects? Especially with different types of PICs and various different languages?
 
as a side note, how do you guys know so much about these subjects? Especially with different types of PICs and various different languages?

PIC's all use pretty well the same code, and the language here is all just PIC assembler, so it's not much of a problem. PIC's been RISC devices are so simple, you cam learn them in just a few days.
 
oops for some reason, I just found out that the read function can only read the last entry of the write function.

I stored A in 0x00 B in 0x01 C in 0x02 respectively (by incrementing ADDR)
Then I attempted to read 0x00.
All I get is C.
Does anyone know how that works?
 
Use your programmer to read back the EEPROM to see if the problem is with the read or write. The problem is most likely bank related. Post your code and I'm sure someone will spot the problem. Post your complete code rather than the bit you think is wrong.

Mike.
 
Code:
cblock 0x70
ADDR
VALUE
endc


writeEEPROM macro reg, address

 BSF STATUS, RP1 ;
 BSF STATUS, RP0 ;Bank 3
 BTFSC EECON1, WR ;Wait for
 GOTO $-1 ;write to finish
 BCF STATUS, RP0 ;Bank 2
 banksel address 
 MOVF address, W 
 MOVWF EEADR 
 banksel reg
 MOVF reg, W
 MOVWF EEDATA
 BSF STATUS, RP0 ;Bank 3
 BCF EECON1, EEPGD ;Point to Data memory
 BSF EECON1, WREN ;Enable writes
 ;Only disable interrupts
 BCF INTCON, GIE ;if already enabled,
 ;otherwise discard
 MOVLW 0x55 ;Write 55h to
 MOVWF EECON2 ;EECON2
 MOVLW 0xAA ;Write AAh to
 MOVWF EECON2 ;EECON2
 BSF EECON1, WR ;Start write operation
 ;Only enable interrupts
 BSF INTCON, GIE ;if using interrupts,
 ;otherwise discard
 BCF EECON1, WREN ;Disable writes  bank0
 BCF STATUS, RP1 ;
 BCF STATUS, RP0 ;Bank 0

 endm

 readEEPROM macro address
 BSF STATUS, RP1 ;
 BCF STATUS, RP0 ;Bank 2
 banksel address
 MOVF address, W ;Write address bank2
 MOVWF EEADR ;to read from
 BSF STATUS, RP0 ;Bank 3
 BCF EECON1, EEPGD ;Point to Data memory
 BSF EECON1, RD ;Start read operation
 BCF STATUS, RP0 ;Bank 2
 MOVF EEDATA, W ;W = EEDATA

 BCF STATUS, RP1 
 BCF STATUS, RP0 
 endm


setID						
	movlw	B'00000100'
	movwf	counter
	movlw	0x19
	movwf	ADDR

	repeatID

	call keyRelease
	call keySelect		;takes in a letter
	movwf	VALUE
	
	call KPHexToChar	;converts to character
	call WrtLCD		;display on LCD

	
	writeEEPROM VALUE, ADDR	;store the character in EEPROM
	readEEPROM ADDR
	call KPHexToChar
	call WrtLCD
	incf	ADDR, F
	decfsz	counter, F
		goto repeatID
	endSetID

	movlw	0x19
	movwf	ADDR
	readEEPROM ADDR
	call KPHexToChar
	call WrtLCD

	return

this is not the entire code but the code that is most relevant.
If I were to write and read right away, then it works.
But the read function only reads the last data that was written.
 
Last edited:
You are writing to EEADR in bank zero and so it is not getting changed.
Code:
 banksel address
 MOVF address, W ;Write address bank2
 MOVWF EEADR ;to read from

The reason I suggested placing your variables in the common area is so you wouldn't have the pain of constant bank switching. Delete the banksel line and it should work correctly.

Mike.
 
Last edited:
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top