Flash memory Problem - Please Help

Thread Starter

amjad2000in

Joined Sep 3, 2009
14
Hi,

I tried to writing to Flash memory of PIC16F877A device. But, tried all the ways. Failed again and again. I know how to write the EEPROM locations. But, writing to Flash memory is not working.

The link of the datasheet I am referring is given below :

http://ww1.microchip.com/downloads/en/DeviceDoc/39582b.pdf

In the "Writing to Flash Program Memory" section in the above datasheet I have seen that "Flash program memory may only be written to if the destination address is in a segment of memory that is not write-protected, as defined in bits WRT1:WRT0 of the device configuration word (Register 14-1)."

What does this mean? How can I configure these settings in the program using the _CONFIG Statement? I have configured like this. Please check, whether this is correct or not.

__CONFIG _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_ON & _HS_OSC & _WRT_OFF & _LVP_OFF & _CPD_OFF


I have followed the sample program given in the above datasheet. Page #40.


I have placed the registers in these locations :

cblock 0x70

ADDRH
ADDRL
DATAADDR

endc


I am giving some parts of my program. The register inizializing sections....



Actually I want to start writing from location 0x300. The data which has to be written in to this location is assigned in variables as given below :


cblock 0x30
Data1
Data2
Data3
Data4
Data5
Data6
Data7
Data8
endc



These variables are assigned with value 0xFF. So, from location 0x300 it will write with this value.

movlw 0xFF
movwf Data1
movwf Data2
movwf Data3
movwf Data4
movwf Data5
movwf Data6
movwf Data7
movwf Data8


*******************************************************************************************************************************************
banksel ADDRH
movlw 0x03
movwf ADDRH

movlw 0x00
movwf ADDRL

movlw 0x30
movwf DATAADDR

BSF STATUS,RP1 ;
BCF STATUS,RP0 ; Bank 2
MOVF ADDRH,W ; Load initial address
MOVWF EEADRH ;
MOVF ADDRL,W ;
MOVWF EEADR ;
MOVF DATAADDR,W ; Load initial data address
MOVWF FSR ;
LOOP
MOVF INDF,W ; Load first data byte into lower
MOVWF EEDATA ;
INCF FSR,F ; Next byte
MOVF INDF,W ; Load second data byte into upper
MOVWF EEDATH ;
INCF FSR,F ;
BSF STATUS,RP0 ; Bank 3
BSF EECON1,EEPGD ; Point to program memory
BSF EECON1,WREN ; Enable writes
; BCF INTCON,GIE ; Disable interrupts (if using)
MOVLW 55h ; Start of required write sequence:
MOVWF EECON2 ; Write 55h
MOVLW 0AAh ;
MOVWF EECON2 ; Write AAh
BSF EECON1,WR ; Set WR bit to begin write
NOP ; Any instructions here are ignored as processor
; halts to begin write sequence
NOP ; processor will stop here and wait for write complete


; after write processor continues with 3rd instruction
BCF EECON1,WREN ; Disable writes
; BSF INTCON,GIE ; Enable interrupts (if using)
BCF STATUS,RP0 ; Bank 2
INCF EEADR,F ; Increment address
MOVF EEADR,W ; Check if lower two bits of address are ‘00’
ANDLW 0x03 ; Indicates when four words have been programmed
XORLW 0x03 ;
BTFSC STATUS,Z ; Exit if more than four words,
GOTO LOOP ; Continue if less than four words
*******************************************************************************************************************************************

In the above program, I am not using any interrupts so I have disabled that in the subroutine. Rest all I exactly followed as given in the datasheet. But, nothing is working. After executing the program, I have checked the microcontroller using the Programmer. And I can see that, the program location starting from 300 does not have any changes happenend. What Is the mistake I have made? Please help me.


Also, I tried placing the below code:
TH
btfsc EECON1, WR
goto TH


I have placed in below the two "nop instructions to check the completion of the write operation. assuming that once the write operation is completed the "WR" bit becomes low.

But, any how data is not getting programmed to the location.

If any one could help me, I will be really thankfull....[:(]


Regards,

Amjad A.R.
[;)]
 

n9352527

Joined Oct 14, 2005
1,198
The write protect is turned off by _WRT_OFF config statement, which you already use.

I can't see anything wrong with that portion of program. Please post the complete program listing so we can get the big picture (and use the
Rich (BB code):
 tag to preserve identation).
 

Thread Starter

amjad2000in

Joined Sep 3, 2009
14
Hi Sir,

I am pasting here the complete code as section by section. Please check.


Rich (BB code):
errorlevel -203, -205, -209, -302		; no message 302 and 306
	list		p=16f877A	; list directive to define processor
	#include	<p16f877A.inc>	; processor specific variable definitions
	
	
	__CONFIG _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_ON & _HS_OSC & _WRT_OFF & _LVP_OFF & _CPD_OFF

#define 		TEST_LED		PORTB,7
Rich (BB code):
cblock 0x20
d0
d1
d2
EEPROM_COUNTER
W_TEMP
STATUS_TEMP
PCLATH_TEMP
endc

cblock 0x30
Data1
Data2
Data3
Data4
Data5
Data6
Data7
Data8
endc


cblock 0x70

ADDRH
ADDRL
DATAADDR

endc

cblock 0x120
DATA_EE_ADDR
FLASH_DATA
temp
ROW_COUNTER
delay_var
FLASH_COUNT
endc

Rich (BB code):
;=======================================================================================================================
	ORG     0x000               ; processor reset vector
	goto    start               ; go to beginning of program

	ORG     0x004             	; interrupt vector location
	MOVWF W_TEMP 				;Copy W to TEMP register
	SWAPF STATUS,W 				;Swap status to be saved into W
	CLRF STATUS 				;bank 0, regardless of current bank, Clears IRP,RP1,RP0
	MOVWF STATUS_TEMP 			;Save status to bank zero STATUS_TEMP register
	MOVF PCLATH, W 				;Only required if using pages 1, 2 and/or 3
	MOVWF PCLATH_TEMP 			;Save PCLATH into W
	CLRF PCLATH 				;Page zero, regardless of current page
	goto	ISR

			
start
	bsf STATUS, RP0				; to select Bank 1
	bcf STATUS, RP1
	movlw 0x06 
    movwf ADCON1 				; to make portA digital
	movlw	B'00000000			
	movwf	TRISA
	movlw	B'00000001
	movwf	TRISB
	movlw	B'00000000
	movwf	TRISD
	movlw	B'00000000
	movwf	TRISE
	movlw	B'11000000
	movwf	TRISC

	

	bcf STATUS, RP0				; to select bank 0
	bcf STATUS, RP1

	clrf PORTA
	clrf PORTB
	clrf PORTC
	clrf PORTD
	clrf PORTE
;=======================================================================================================================
Rich (BB code):
;=======================================================================================================================
	
	
	banksel Data1

	movlw 0xFF
	movwf Data1
	movwf Data2
	movwf Data3
	movwf Data4
	movwf Data5
	movwf Data6
	movwf Data7
	movwf Data8
	


OS

	call TEST

	btfss PORTB, 0                          ; PUSH switch connected here for testing
	goto FLASH_WRITE

	goto OS
;=======================================================================================================================

Rich (BB code):
ISR


MOVF PCLATH_TEMP, W 			;Restore PCLATH
MOVWF PCLATH 					;Move W into PCLATH
SWAPF STATUS_TEMP,W 			;Swap STATUS_TEMP register into W
								;(sets bank to original state)
MOVWF STATUS 					;Move W into STATUS register
SWAPF W_TEMP,F 					;Swap W_TEMP
SWAPF W_TEMP,W 					;Swap W_TEMP into W
retfie
;=======================================================================================================================

TEST

bsf TEST_LED
return

;=======================================================================================================================
FLASH_WRITE


	banksel ADDRH
	movlw 0x03
	movwf ADDRH

	movlw 0x00
	movwf ADDRL

	movlw 0x30
	movwf DATAADDR

	BSF STATUS,RP1 			;
	BCF STATUS,RP0 			; Bank 2
	MOVF ADDRH,W 			; Load initial address
	MOVWF EEADRH 			;
	MOVF ADDRL,W 			;
	MOVWF EEADR 			;
	MOVF DATAADDR,W 		; Load initial data address
	MOVWF FSR 				;
LOOP 
	MOVF INDF,W 			; Load first data byte into lower
	MOVWF EEDATA 			;
	INCF FSR,F 				; Next byte
	MOVF INDF,W 			; Load second data byte into upper
	MOVWF EEDATH 			;
	INCF FSR,F 				;
	BSF STATUS,RP0 			; Bank 3
	BSF EECON1,EEPGD 		; Point to program memory
	BSF EECON1,WREN 		; Enable writes
;	BCF INTCON,GIE 			; Disable interrupts (if using)
	MOVLW 55h 				; Start of required write sequence:
	MOVWF EECON2 			; Write 55h
	MOVLW 0AAh				;
	MOVWF EECON2 			; Write AAh
	BSF EECON1,WR 			; Set WR bit to begin write
	NOP 					; Any instructions here are ignored as processor
							; halts to begin write sequence
	NOP 					; processor will stop here and wait for write complete

TH
	btfsc EECON1, WR
	goto TH
							; after write processor continues with 3rd instruction
	BCF EECON1,WREN 		; Disable writes
;	BSF INTCON,GIE 			; Enable interrupts (if using)
	BCF STATUS,RP0 			; Bank 2
	INCF EEADR,F 			; Increment address
	MOVF EEADR,W 			; Check if lower two bits of address are ‘00’
	ANDLW 0x03 				; Indicates when four words have been programmed
	XORLW 0x03 				;
	BTFSC STATUS,Z 			; Exit if more than four words,
	GOTO LOOP 				; Continue if less than four words



SD
	goto SD
;	return
;=======================================================================================================================

end
Also one more doubt sir. In the datasheet I saw that, Flash program memory must be written in four-word blocks. I didn't understand this completely till now. Just for testing I have copied the sample programming given in their datasheet.

In the EEPROM writing program, we can program any single location we want with any data. Is it different in the case of FLASH memory writing?

Also, I am not completely aware about the write PROTECT fuse in the CONFIG statement... Please tell me about these things sir.


Regards,

Amjad
 

n9352527

Joined Oct 14, 2005
1,198
Ah, I see where the error is. The check for four words write, it actually checks for only three words, because the EEADR is increased _before_ checking. Remove the XORLW 0x03 instruction and see what happen.

Four word blocks in this case mean four writes of 14 bits each. One instruction in PIC 16F is 14 bits, that is one word of program memory address. In one pass, the code above write 14 bits (loaded as two bytes) to program memory. At the end it checks the two last bits of address (EEADR) for 0x00 (4 words).

This is because the write buffer is 4 words long. And all 4 words get written to the program memory at one go. The address must be sequential and aligned to EEADR<1:0> = 00 as low address.

So, unlike writing to EEPROM, program memory write has to write 4 words at a time. If there is a need to write less than four words, then read the data from the existing addresses first and load them together with the new data to the 4 words buffer.

The config is detailed in section 14 in the datasheet. You can either set the config word manually during programming or in source code using CONFIG statement or the Configure - Configuration Bits menu in MPLAB.

To see the available CONFIG statement, look at the end of the corresponding include file for the microcontroller (in your case p16f877a.inc). These are bitwise and-ed together to make the final config word.
 

Thread Starter

amjad2000in

Joined Sep 3, 2009
14
Hi Sir,

I understood what you said. Dont knw why microchip have made such a mistake in their datasheet. I commented the line "XORLW 0x03" and tried the program. Now it will execute the loop exactly 4 times as wee need . But, the dissapointing thing is that, still its not working. Can you please check once again and help me?


Regards,

Amjad
 

n9352527

Joined Oct 14, 2005
1,198
I'm sorry, I've run the modified code on my board and it worked as it should. So, apart from checking your circuit, I can not do anything more.
 
Top