Flash memory Problem - Please Help

Discussion in 'Embedded Systems and Microcontrollers' started by amjad2000in, Sep 9, 2009.

  1. amjad2000in

    Thread Starter New Member

    Sep 3, 2009
    14
    0
    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.
    [;)]
     
  2. n9352527

    AAC Fanatic!

    Oct 14, 2005
    1,198
    4
    And what is the value that you read with the programmer? 0x3FFF?
     
  3. amjad2000in

    Thread Starter New Member

    Sep 3, 2009
    14
    0
    NO, its zeros..... Because, I have programmed these location with zeroes with the programmer previously. Please help me sir.
     
  4. n9352527

    AAC Fanatic!

    Oct 14, 2005
    1,198
    4
    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
    Code ( (Unknown Language)):
    1.  tag to preserve identation).
     
  5. amjad2000in

    Thread Starter New Member

    Sep 3, 2009
    14
    0
    Hi Sir,

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


    Code ( (Unknown Language)):
    1. errorlevel -203, -205, -209, -302       ; no message 302 and 306
    2.     list        p=16f877A   ; list directive to define processor
    3.     #include    <p16f877A.inc>  ; processor specific variable definitions
    4.    
    5.    
    6.     __CONFIG _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_ON & _HS_OSC & _WRT_OFF & _LVP_OFF & _CPD_OFF
    7.  
    8. #define         TEST_LED        PORTB,7
    Code ( (Unknown Language)):
    1. cblock 0x20
    2. d0
    3. d1
    4. d2
    5. EEPROM_COUNTER
    6. W_TEMP
    7. STATUS_TEMP
    8. PCLATH_TEMP
    9. endc
    10.  
    11. cblock 0x30
    12. Data1
    13. Data2
    14. Data3
    15. Data4
    16. Data5
    17. Data6
    18. Data7
    19. Data8
    20. endc
    21.  
    22.  
    23. cblock 0x70
    24.  
    25. ADDRH
    26. ADDRL
    27. DATAADDR
    28.  
    29. endc
    30.  
    31. cblock 0x120
    32. DATA_EE_ADDR
    33. FLASH_DATA
    34. temp
    35. ROW_COUNTER
    36. delay_var
    37. FLASH_COUNT
    38. endc

    Code ( (Unknown Language)):
    1. ;=======================================================================================================================
    2.     ORG     0x000               ; processor reset vector
    3.     goto    start               ; go to beginning of program
    4.  
    5.     ORG     0x004               ; interrupt vector location
    6.     MOVWF W_TEMP                ;Copy W to TEMP register
    7.     SWAPF STATUS,W              ;Swap status to be saved into W
    8.     CLRF STATUS                 ;bank 0, regardless of current bank, Clears IRP,RP1,RP0
    9.     MOVWF STATUS_TEMP           ;Save status to bank zero STATUS_TEMP register
    10.     MOVF PCLATH, W              ;Only required if using pages 1, 2 and/or 3
    11.     MOVWF PCLATH_TEMP           ;Save PCLATH into W
    12.     CLRF PCLATH                 ;Page zero, regardless of current page
    13.     goto    ISR
    14.  
    15.            
    16. start
    17.     bsf STATUS, RP0             ; to select Bank 1
    18.     bcf STATUS, RP1
    19.     movlw 0x06
    20.     movwf ADCON1                ; to make portA digital
    21.     movlw   B'00000000         
    22.     movwf   TRISA
    23.     movlw   B'00000001
    24.     movwf   TRISB
    25.     movlw   B'00000000
    26.     movwf   TRISD
    27.     movlw   B'00000000
    28.     movwf   TRISE
    29.     movlw   B'11000000
    30.     movwf   TRISC
    31.  
    32.    
    33.  
    34.     bcf STATUS, RP0             ; to select bank 0
    35.     bcf STATUS, RP1
    36.  
    37.     clrf PORTA
    38.     clrf PORTB
    39.     clrf PORTC
    40.     clrf PORTD
    41.     clrf PORTE
    42. ;=======================================================================================================================
    Code ( (Unknown Language)):
    1.  
    2. ;=======================================================================================================================
    3.    
    4.    
    5.     banksel Data1
    6.  
    7.     movlw 0xFF
    8.     movwf Data1
    9.     movwf Data2
    10.     movwf Data3
    11.     movwf Data4
    12.     movwf Data5
    13.     movwf Data6
    14.     movwf Data7
    15.     movwf Data8
    16.    
    17.  
    18.  
    19. OS
    20.  
    21.     call TEST
    22.  
    23.     btfss PORTB, 0                          ; PUSH switch connected here for testing
    24.     goto FLASH_WRITE
    25.  
    26.     goto OS
    27. ;=======================================================================================================================
    28.  

    Code ( (Unknown Language)):
    1. ISR
    2.  
    3.  
    4. MOVF PCLATH_TEMP, W             ;Restore PCLATH
    5. MOVWF PCLATH                    ;Move W into PCLATH
    6. SWAPF STATUS_TEMP,W             ;Swap STATUS_TEMP register into W
    7.                                 ;(sets bank to original state)
    8. MOVWF STATUS                    ;Move W into STATUS register
    9. SWAPF W_TEMP,F                  ;Swap W_TEMP
    10. SWAPF W_TEMP,W                  ;Swap W_TEMP into W
    11. retfie
    12. ;=======================================================================================================================
    13.  
    14. TEST
    15.  
    16. bsf TEST_LED
    17. return
    18.  
    19. ;=======================================================================================================================
    20. FLASH_WRITE
    21.  
    22.  
    23.     banksel ADDRH
    24.     movlw 0x03
    25.     movwf ADDRH
    26.  
    27.     movlw 0x00
    28.     movwf ADDRL
    29.  
    30.     movlw 0x30
    31.     movwf DATAADDR
    32.  
    33.     BSF STATUS,RP1          ;
    34.     BCF STATUS,RP0          ; Bank 2
    35.     MOVF ADDRH,W            ; Load initial address
    36.     MOVWF EEADRH            ;
    37.     MOVF ADDRL,W            ;
    38.     MOVWF EEADR             ;
    39.     MOVF DATAADDR,W         ; Load initial data address
    40.     MOVWF FSR               ;
    41. LOOP
    42.     MOVF INDF,W             ; Load first data byte into lower
    43.     MOVWF EEDATA            ;
    44.     INCF FSR,F              ; Next byte
    45.     MOVF INDF,W             ; Load second data byte into upper
    46.     MOVWF EEDATH            ;
    47.     INCF FSR,F              ;
    48.     BSF STATUS,RP0          ; Bank 3
    49.     BSF EECON1,EEPGD        ; Point to program memory
    50.     BSF EECON1,WREN         ; Enable writes
    51. ;   BCF INTCON,GIE          ; Disable interrupts (if using)
    52.     MOVLW 55h               ; Start of required write sequence:
    53.     MOVWF EECON2            ; Write 55h
    54.     MOVLW 0AAh              ;
    55.     MOVWF EECON2            ; Write AAh
    56.     BSF EECON1,WR           ; Set WR bit to begin write
    57.     NOP                     ; Any instructions here are ignored as processor
    58.                             ; halts to begin write sequence
    59.     NOP                     ; processor will stop here and wait for write complete
    60.  
    61. TH
    62.     btfsc EECON1, WR
    63.     goto TH
    64.                             ; after write processor continues with 3rd instruction
    65.     BCF EECON1,WREN         ; Disable writes
    66. ;   BSF INTCON,GIE          ; Enable interrupts (if using)
    67.     BCF STATUS,RP0          ; Bank 2
    68.     INCF EEADR,F            ; Increment address
    69.     MOVF EEADR,W            ; Check if lower two bits of address are ‘00’
    70.     ANDLW 0x03              ; Indicates when four words have been programmed
    71.     XORLW 0x03              ;
    72.     BTFSC STATUS,Z          ; Exit if more than four words,
    73.     GOTO LOOP               ; Continue if less than four words
    74.  
    75.  
    76.  
    77. SD
    78.     goto SD
    79. ;   return
    80. ;=======================================================================================================================
    81.  
    82. 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
     
  6. n9352527

    AAC Fanatic!

    Oct 14, 2005
    1,198
    4
    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.
     
  7. amjad2000in

    Thread Starter New Member

    Sep 3, 2009
    14
    0
    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
     
  8. n9352527

    AAC Fanatic!

    Oct 14, 2005
    1,198
    4
    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.
     
Loading...