Data table storage inside flash memory

Status
Not open for further replies.
Jay.slovak said:
How about passing a parameter from Interrupt (remember this will not act as RETFIE, as GIE is not being enabled automatically) or other Sub-routine?

EDIT: That interupt passing thingy is kind of useless :lol:

Oh yeah I think it will contribute under certain circumstances.This solution is also implemented in other microcontroller families.


:roll: Don't worry,my friend.I can handle that.I will consider all related registers that have something to do with the boundaries.Actually there is a section describing such circumstances in detail in my text book.I may use it as a reference.



Hm....I wouldn't agree with what you said about how difficult it is to manage data table in program memory for Harvard architectured processors.Actually when we talk about tables within a microcontroller,we ARE talking about data stored inside program memory.Besides MCS-51 and AVR microcontrollers are also Harvard architecture based microcontrollers.They both deal with tables well,through a certian instructions(MOVC A,@A+DPTR for 8051&LPM for AVR).As Jay said,PIC18 has similar and even more powerful instructions,too-"TLRD t,f" and "TLWT t,f".For some reason this instruction is not implemented on all PIC chips.But it doesn't mean it can't be done.Presumably it's what makes PIC special,that makes PIC the real RISC microcontrollers.

Anyway I'm happy with the DT directive.It will make generating RETLW tables a lot easier.With this directive I don't feel too sorry about instructions like TLRD when I use 16F and there isn't any.

BTW,I tried opening the FTP,but each time I hit enter the IE freezes.Is there an http link for the info?Thanks!

Regards,Alex.[/quote]
 
Pommie said:
I don't understand why people are trying to make this sound complicated. As you originally posted, store your data as DB, DW, DATA, whichever gets it in a way you need it and then just read it back via the flash read registers.

Mike.

Oh yes,now it does sound complicated. :roll: And we were just trying to figure out different ways of doing a same thing.

The two solutions are concluded as below:

A:

Code:
	ORG	0x00
	.
	.
	.
	MOVLW	HIGH(Table)
	MOVWF	PCLATH
	MOVLW	Index
	CALL	Table
	.
	.
	.
	ORG	0x820
Table
	ADDWF	PCL
	RETLW	'A'
	RETLW	'3'
	RETLW	0xF7
	RETLW	'G'
	RETLW	'x'
	RETLW	'8'
	.
	.
	.

B:
Code:
Table	DW 0x3FE,0xE2,0x2CA,0x55,........
	.
	.
	.
Get_data
	BSF	STATUS,RP1
	BCF	STATUS,RP0
	MOVF	ADDRL,W
	MOVWF	EEADR
	BSF	STATUS,RP0
	BSF	EECON1,EEPGD
	BSF	EECON1,RD
	NOP
	NOP
	BCF	STATUS,RP0
	MOVF	EEDATA,W
	MOVWF	DATAL
	MOVF	EEDATH
	MOVWF	DATAH

Of course I have to watch out for memory boundaries whenever neccessary.Is that right?

Regards,Alex.
 

oops!Guess it's the url that freezed my IE.I went to the exact location and clicked on World Clock,and then the window froze :shock:

Thank you all the same,Nigel.You've been very helpful.Now I need to donwload the application note which Jay has mentioned.I'm sure I can dig up something useful from there too.

Regards,Alex.
 
Alex_rcpilot said:
You can go to http://www.epemag.wimborne.co.uk, click on Download, from there select PICS, then look for WorldClock - I can't post the exact link because it doesn't update the URL.

oops!Guess it's the url that freezed my IE.I went to the exact location and clicked on World Clock,and then the window froze :shock:
[/quote]

PM me your email address, and I'll send you the file!.
 
Alex_rcpilot said:
Of course I have to watch out for memory boundaries whenever neccessary.Is that right?

Regards,Alex.

You don't have to watch out for page boundaries. They get taken care of in the way you increment a 16 byte pointer.

The code you posted above doesn't write the high byte of the address. It should read.
Code:
        BSF    STATUS, RP1   ;
        BCF    STATUS, RP0   ;Bank 2
        MOVF   ADDRL, W      ;Write the
        MOVWF  EEADR         ;address bytes
        MOVF   ADDRH,W       ;for the desired  <---------
        MOVWF  EEADRH        ;address to read  <---------
        BSF    STATUS, RP0   ;Bank 3
        BSF    EECON1, EEPGD ;Point to Program memory
        BSF    EECON1, RD    ;Start read operation
        NOP                  ;Required two NOPs
        NOP                  ;
        BCF    STATUS, RP0   ;Bank 2
        MOVF   EEDATA, W     ;DATAL = EEDATA
        MOVWF  DATAL         ;
        MOVF   EEDATH,W      ;DATAH = EEDATH
        MOVWF  DATAH         ;


Of course, once the first byte is read then subsequent bytes can just increment the address pointer.

A more elegant approach, would be to initialise the address first and then have a routine which post increments the address after reading each byte.

Code:
INIT    BSF    STATUS, RP1   ;
        BCF    STATUS, RP0   ;Bank 2
        MOVF   Low(Table)    ;Write the
        MOVWF  EEADR         ;address bytes
        MOVF   High(Table)   ;for the desired
        MOVWF  EEADRH        ;address to read
        BCF    STATUS, RP0   ;Bank 2
        BCF    STATUS, RP1   ;Bank 0
        RETURN


FETCH   BSF    STATUS, RP1   ;
        BSF    STATUS, RP0   ;Bank 3
        BSF    EECON1, EEPGD ;Point to Program memory
        BSF    EECON1, RD    ;Start read operation
        NOP                  ;Required two NOPs
        NOP                  ;
        BCF    STATUS, RP0   ;Bank 2
        INCFSZ EEADR,F       ;inc address
        DEC    EEADRH,F      ;dec high if not crossed page boundary.
        INC    EEADRH,F      ;inc high byte
        BCF    STATUS, RP1   ;Bank 0
        RETURN               ;

Table   data   1234,"a"

HTH

Mike.
 

I reviewed some of the PIC16F877 code I had done a long time ago and here's how I had done it. The address of the table is loaded to two consecutive locations PROG_ADD and PROG_ADD+1. The data read is stored in two loactions TEMP1 and TEMP2.

Code:
PROG_READ:
         BANKISEL PROG_ADD
         MOVLW    PROG_ADD
         MOVWF    FSR
;
         MOVF     INDF,W          ; PROG_ADD
         BSF      STATUS,RP1      ; BANK 0 -> BANK 2
         MOVWF    EEADR
;
         INCF     FSR,F
         MOVF     INDF,W          ; PROG_ADD+1
         MOVWF    EEADRH
;
         BSF      STATUS,RP0      ; BANK 2 -> BANK 3
         BSF      EECON1,EEPGD    ; Point to program memory
         BSF      EECON1,RD       ; GO Read!
         NOP                      ; 2 NOPs needed
         NOP                      ; by PROG_READ
         BCF      STATUS,RP0      ; BANK 3 -> BANK 2
         MOVF     EEDATA,W
         BCF      STATUS,RP1      ; BANK 2 -> BANK 0
         MOVWF    TEMP1
;
         MOVLW    LOW EEDATH
         BANKISEL EEDATH
         MOVWF    FSR
         MOVF     INDF,W
         ANDLW    3Fh
         MOVWF    TEMP2
;
         RETURN

Using the full 14-bits can be quite handy if you are storing a lot of data. It will be worth the extra programming. Using the FSR and INDF registers should be familiar to 8051 assembly programmers.

BTW, I also checked some of my code and DW works just as well as the DATA directive.
 

Ha!You're right.The higher addr byte must be taken care of to avoid boundary problems.And it's the addr word that should be incremented.Thank you for the code example!


Thank you motion.The BANKISEL directive is interesting.I just viewed its introduction in MPLAB help file.I better practise a little to get used to it. Indirect addressing IS handy.I love it!

Thank you guys.Now I have all the answers required.You've been of great help!

Regards,Alex.
 
I have often used FLASH to store jump tables. There is one big advantage - on the 16F877 you can have a jump table that can point to ANYWHERE in program memory - since the program memory is 14 bits wide.
Admittedy, the code overhead, reading the FLASH and moving the info to the PCLATH and the PCL, might be too much for some applications, but if you are reading the FLASH for some other purpose, such as text strings, then I think it's a good idea. I have also used a similar system to "embed" the address of some executable code in a menu item structure.
Using RETLW for data storage in FLASH is very inefficient in some case - 7 bit ASCII for example can be stored in pairs in a 14 bit word.
 
Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…