How to write to flash memory using inline assembly?

隐身守侯 提交于 2019-12-11 04:00:01

问题


I am using MPLAB C18 compiler with PIC18F87J11 and I am trying to save some values to flash memory, using inline assembly, which is a combination of C and assembly code.

It looks like I can write and read to flash memory correctly, but as soon as I power cycle my PIC and then attempt to read what I previous saved from a specific address, I don't get the same value. I am saving 0x09 to 0xB22A address. Like I said, if I save the value then read it immediately, everything comes up correctly, but upon resetting the PIC I get 0x00.

Am I not saving permanently to flash memory or what is really happening here?

This is my code:

Erase memory row

_asm 
MOVLW 0x00
MOVWF TBLPTRU,BANKED
MOVLW 0xB2
MOVWF TBLPTRH,BANKED
MOVLW 0x2A
MOVWF TBLPTRL,BANKED  
_endasm
EECON1bits.FREE = 1; 
INTCONbits.GIE = 0;

_asm 
MOVLW 0x55
MOVWF EECON2,BANKED
MOVLW 0xAA
MOVWF EECON2,BANKED
_endasm
EECON1bits.WR = 1;
INTCONbits.GIE = 1;

Write to flash memory

_asm 
MOVLW    0x00
MOVWF    TBLPTRU,BANKED
MOVLW    0xB2
MOVWF    TBLPTRH,BANKED
MOVLW    0x2A
MOVWF    TBLPTRL,BANKED
MOVLW    0x09
MOVWF    TABLAT,BANKED
TBLWTPOSTINC
MOVLW    0x09
MOVWF    TABLAT,BANKED
TBLWT
_endasm

EECON1bits.WPROG = 1;
EECON1bits.WREN = 1;
INTCONbits.GIE = 0; 
_asm 
MOVLW 0x55
MOVWF EECON2,BANKED  
MOVLW 0xAA
MOVWF EECON2,BANKED 
 _endasm
EECON1bits.WR = 1;
INTCONbits.GIE = 1;
EECON1bits.WPROG = 0; 
EECON1bits.WREN = 0;

Read from flash memeory

_asm  
 MOVLW 0x00
 MOVWF TBLPTRU,BANKED  
 MOVLW 0xB2 
 MOVWF TBLPTRH,BANKED
 MOVLW 0x2A 
 MOVWF TBLPTRL,BANKED 
READ_WORD: 
 TBLRDPOSTINC  
 MOVF TABLAT, 0,BANKED 
 MOVWF WORD_EVEN,ACCESS
 TBLRDPOSTINC  
 MOVF TABLAT, 0,BANKED
 MOVWF WORD_ODD,ACCESS
 _endasm

printf("\r\n");
PrintChar(WORD_EVEN);
printf("\r\n");
PrintChar(WORD_ODD);

The original code can be found in the datasheet on chapter 6, but remember I had to modify it a little bit to be able to use it with C. I am not sure what the difference is between ACCESS and BANKED as I suspect they might be related to the problem.


回答1:


It looks like you arrived at the solution already: the problem is in using BANKED.

EECON2 and the like are Special Function Registers (SFRs) that reside in bank 15. The fastest way to access them is to use ACCESS, which ignores the bank register in computing the address.

It looks like in the assembly language you are using, ACCESS means 0 and BANKED means 1. One of these values is required in the movwf instruction. The datasheet uses the actual numbers in its examples, instead of symbolic constants.

The datasheet also explains the how the RAM is banked.

Basically, there is as register that holds 4 bits representing banks 0 to 15. This number gets prepended to the 8 bit number given to the instruction, to give all 12 bits. This allows faster execution. To store in the correct location, you need to set this register to the correct bank first.

Two of the banks, 0 and 15, are mapped to the General Purpose registers and Special Function Registers as well. Since these are used most often, the fast way to get to them is to use a flag in the instruction to ignore the bank register in computing the address, and go straight to the GPR or SFR you want.

Your problem is that you were setting the flag to use a different bank of memory from where the register reside.



来源:https://stackoverflow.com/questions/18179070/how-to-write-to-flash-memory-using-inline-assembly

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!