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.

Data table storage inside flash memory

Status
Not open for further replies.
Hi all,I would like to store a table of data inside the flash memory of a PIC16F877A.I'd like not to use the normal RETLW k structure to fetch data,but the slower 'read ROM word' operation instead.First I have to save the data into the flash.My text book doesn't describe how DB and DW does with a 14-bit ROM word in detail.So here are my questions:

what happens to the memory addr starting from 0x100 when I define bytes in sequence as below?

ORG 0x100
TABLE
DB 0xFD,0x35,0xDA,0xC4,0x0E........

Similarly,what would happen if I do this with DW?

ORG 0x100
TABLE
DB 0x1FFD,0x2E35,0x3DA,0x3F74,0xE0E........

BTW,is there a tutorial on MPASM pseudo instructions?I will appreciate if someone can share a link with me.Thank you.

Regards,Alex
 
Alex_rcpilot said:
Hi all,I would like to store a table of data inside the flash memory of a PIC16F877A.I'd like not to use the normal RETLW k structure to fetch data,but the slower 'read ROM word' operation instead.First I have to save the data into the flash.My text book doesn't describe how DB and DW does with a 14-bit ROM word in detail.So here are my questions:

what happens to the memory addr starting from 0x100 when I define bytes in sequence as below?

ORG 0x100
TABLE
DB 0xFD,0x35,0xDA,0xC4,0x0E........

Similarly,what would happen if I do this with DW?

ORG 0x100
TABLE
DB 0x1FFD,0x2E35,0x3DA,0x3F74,0xE0E........

Hey Alex,

There's a way for you to see what happens in program memory. In MPLAB, choose MPLAB SIM as your debugger. Assemble your code and then using the debugger tools step into your code and select View->Program Memory in MPLAB's menu.

Pay attention to what happens to 16 bits values during assembly...

BTW,is there a tutorial on MPASM pseudo instructions?I will appreciate if
someone can share a link with me.Thank you.

What do you mean by "pseudo instructions"? Assembler directives? They're all pretty well explained in MPLAB's help system, under the MPASM section. Or are you talking about the PIC16 instruction set? Or the mnemonics?
 
Alex_rcpilot said:
what happens to the memory addr starting from 0x100 when I define bytes in sequence as below?

Code:
             ORG    0x100
TABLE
             DB      0xFD,0x35,0xDA,0xC4,0x0E........

You will be in trouble on 16F parts. Apparantly MPASM would try to fit 0xFD,0x35 to a single program memory, ending up with 0x3D35 as the two MSB is discarded. So for 8-bit values, you have to place zero in between them like, 0,0xFD,0,0x35....

Code:
             ORG    0x100
TABLE
             DB      0x1FFD,0x2E35,0x3DA,0x3F74,0xE0E........

I think the same would be true. Each 16-bit word would be fitted to one 14-bit program memory word, with the higher bits chopped off.
 
Use the "DATA" directive

Code:
DATA – Create Numeric and Text Data 	 
Syntax 	 
[<label>] data 	<expr>,[,<expr>,...,<expr>] 	 
[<label>] data 	“<text_string>”[,“<text_string>”,...] 	 

Description 		 

Initialize one or more words of program memory with data. The data may be in the form of constants, relocatable or external labels, or expressions of any of the above. 	 

The data may also consist of ASCII character strings, <text_string>, enclosed in single quotes for one character or double quotes for strings. Single character items are placed into the low byte of the word, while strings are packed two to a word with the first character in the most significant byte of the word. If an odd number of characters are given in a string, the final byte is zero.

Example:

Code:
         ORG       300H

         DATA     12500
         DATA     12365
         DATA     12232
         DATA     12100
         DATA     11970

This will allow you to use the full 14-bits for data storage.
 
Like motion said use DATA or if storing strings use the DA - define ASCII. This packs two 7 bit ASCII values into one 14 bit location.

If you download and install MPLAB from microchip then the helpfiles that come with it contain a complete list of instructions / directives etc.

Mike.
 
Alex_rcpilot said:
Hi all,I would like to store a table of data inside the flash memory of a PIC16F877A.I'd like not to use the normal RETLW k structure to fetch data,but the slower 'read ROM word' operation instead.

But why would you want to do this?.
 
Joel Rainville said:
Hey Alex,

There's a way for you to see what happens in program memory. In MPLAB, choose MPLAB SIM as your debugger. Assemble your code and then using the debugger tools step into your code and select View->Program Memory in MPLAB's menu.

Pay attention to what happens to 16 bits values during assembly...

Thanks Joel,I tried it and found out what would happen.

It's interesting with the DB directive.In 16F877A where there's 14 bit in a program word,DB stores the first byte in the higher byte of a 16-bit word.Which means the 2 MSB are chopped off.If there's a second byte,it will fill the lower byte of the same word.

The DW stores a 14-bit word in each program word,and I don't have a problem with it now.

Joel Rainville said:
What do you mean by "pseudo instructions"? Assembler directives? They're all pretty well explained in MPLAB's help system, under the MPASM section. Or are you talking about the PIC16 instruction set? Or the mnemonics?

Well,please forgive me for being confusing."Pseudo instruction"is a poor translation found in an interpreter software.I'm a Chinese college student.Just not being professional enough to know all such technical terms.I was actually mentioning something like ORG,DW,_CONFIG,INCLUDE etc.They call them assembler directives?This will explain why I didn't find anything while I was searching for related issues in the MPLAB help file.I will search for "assembler directives" this time.Thank you!

eblc1388 said:
You will be in trouble on 16F parts. Apparantly MPASM would try to fit 0xFD,0x35 to a single program memory, ending up with 0x3D35 as the two MSB is discarded. So for 8-bit values, you have to place zero in between them like, 0,0xFD,0,0x35....

I think the same would be true. Each 16-bit word would be fitted to one 14-bit program memory word, with the higher bits chopped off.

Yes eblc1388,You were talking about the same thing as I observed.It's absolutely correct.Thank you.

to motion:
Thanks,I tried DATA directive and found it handy :) .Thank you for the advice.

The next thing I would like to know is how people usually get data from these data tables.What I'm trying to do is simple : store multiple tables in the flash memory,and write a subroutine to read any of these tables.And I just need to tell the subroutine the starting address of target table & the index to get the right data byte.
I used to do it in 8051 structure as following:

Get_table_data:
MOV DPTR,#TABLE
MOV A,INDEX
MOVC A,@A+DPTR
MOV DBYTE,A
RET

TABLE:
DB D5H,33H,8EH
..........

And for AVR microcontrollers where a program word has 16bits,I can do this:

Get_table_data:
LDI R30,low(CharTab)
LDI R31,high(CharTab)
CLC
ROL R30
ROL R31
ADD R30,R16 ;Index stored in R16
LDI R16,0
ADC R31,R16 ;2 byte addition
LPM ;Returned byte is stored in R0
RET

CharTab:
'Table content is a string of ASCII codes'

The code above will work no matter where the designated table is stored is the program memory.What should I do in PIC?

Regards,Alex.
 
Alex_rcpilot said:
The code above will work no matter where the designated table is stored is the program memory.What should I do in PIC?

I think I see what your problem is?, you're trying to force programming from other processors to a PIC?.

For a PIC you use RETLW for tables, it's really as simple as that! - don't try and use Von Neumann style programming on a Harvard architecture processor.
 
Nigel Goodwin said:
Alex_rcpilot said:
Hi all,I would like to store a table of data inside the flash memory of a PIC16F877A.I'd like not to use the normal RETLW k structure to fetch data,but the slower 'read ROM word' operation instead.

But why would you want to do this?.

Hi Nigel,I think there're circumstances under which such tables can be used.For example,a man who sells LCDs want me to build a demonstration board for a graphic LCD he offers.He would like me to display a small graph of 128 by 64 dots on the LCD.And I only need 1KB to save the graph......I would not save the graph inside EEPROM as most PIC don't have so much space in their EEPROMs.And I won't hook an external memory chip onto the PIC because there's more than enough space in the PIC flash memory.Consequently......here we are. :?

I'm new to PIC,so I would like to know how such problems are resolved by you people in here. :)
 
Interesting to see this discusion going,
I use two ways of storing data, depending on platform. For PIC16 I use multiple RETLW instructions (computed GOTO), and for PIC18 I use TBLRD with DB or DW directives (FLASH table reads). This works fine for me.
 
Nigel Goodwin said:
Alex_rcpilot said:
The code above will work no matter where the designated table is stored is the program memory.What should I do in PIC?

I think I see what your problem is?, you're trying to force programming from other processors to a PIC?.

For a PIC you use RETLW for tables, it's really as simple as that! - don't try and use Von Neumann style programming on a Harvard architecture processor.

Hm......actually I have read about the RETLW structure from my text book.And I think it's the most frequently used method for returning data from a table.

I don't know what you meant by force programming.Presumably you meant that I was trying to apply a program structure that doesn't fit into PIC hardware to a PIC?

As I read from sample routines,a RETLW table is always used by calling the entrance lable and adding the index to PCL.So I see problem arises when different tables are used.For example,there's an LCD,again.But this time it's a 1602.I would like to display 40 pages on the LCD.Normally with other processors I would store 40 tables and write only one subroutine to read any of them.I do this by initializing a certain pointers before calling the subroutine.And then all the process taking care of data from the table can be done inside the subroutine.And back to PIC,if I want to access different tables with a same subroutine,I have to call the table entrance outside the subroutine,which means the index also needs to be calculated preceding calling.It will be kinda tricky to write a universal subroutine that is capable of accessing different tables for me,even given the tables are stored within a same page.

And,there's another thing that bothers me.When this table is really big,like I said about the 1KB dot matrix table.The process of writing all these RETLW can be a tiring job.What can we do to take care of such big tables?

Regards,Alex
 
Actually there is an ASSEMBLER directive that makes writting RETLW style table easy!

Code:
dt - Data Table. 

Generates a series of RETLW instructions, one instruction for each expr. Each expr must be an 8-bit value. Each character in a string is stored in its own RETLW instruction.

Code:
Simple Example 
dt "A Message", 0
dt FirstValue, SecondValue, EndOfValues

This directive is used when generating a table of data for the PIC12/16 device family. If you are using a PIC18 device, it is recommended that you use the table read/write (TBLRD/TBLWT) features. See the device data sheet for more information.

How hard is that?
 
Jay.slovak said:
Interesting to see this discusion going,
I use two ways of storing data, depending on platform. For PIC16 I use multiple RETLW instructions (computed GOTO), and for PIC18 I use TBLRD with DB or DW directives (FLASH table reads). This works fine for me.

:D Just being curious about tables.Coz I used to process a LOT of tables with 8051.

The TLRD and TLWT are really handy for PIC18.And it makes PIC more like 8051 and AVR processors.I wish there could be such an instruction for lower PICs to use.As for the RETLW structure,I wonder how many ways it is used.Here's one of them in my text book:


;----------------------------------
Tab ADDWF PCL ;Index within 255 is stored inside W
RETLW 0xEE
RETLW 0xB1
RETLW 0x8D
RETLW 0x75
RETLW 0x64
RETLW 0x4D
;----------------------------------

I don't see GOTO in it.Could you offer me an example using GOTO?Thanks. :)

Regards,Alex.
 
Jay.slovak said:
Actually there is an ASSEMBLER directive that makes writting RETLW style table easy!

Code:
dt - Data Table. 

Generates a series of RETLW instructions, one instruction for each expr. Each expr must be an 8-bit value. Each character in a string is stored in its own RETLW instruction.

Code:
Simple Example 
dt "A Message", 0
dt FirstValue, SecondValue, EndOfValues

This directive is used when generating a table of data for the PIC12/16 device family. If you are using a PIC18 device, it is recommended that you use the table read/write (TBLRD/TBLWT) features. See the device data sheet for more information.

How hard is that?

Jay,I love that answer! :!:

With this there's nothing I shall be scared of while working on RETLW.

Anyway,I'm still curious about in how many ways RETLW can be used normally.Any clues?Thank you,again :)

Regards,Alex.
 
There is no GOTO instruction in that subrutine, it's just called "The computed GOTO" because you change PC to "Jump - GOTO" to the line of table you want.
 
Alex_rcpilot said:
Anyway,I'm still curious about in how many ways RETLW can be used normally.Any clues?Thank you,again :)

Regards,Alex.
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:
 
Jay.slovak said:
There is no GOTO instruction in that subrutine, it's just called "The computed GOTO" because you change PC to "Jump - GOTO" to the line of table you want.

:lol: oops!So we were talking about the same thing as the code I posted above.Anyway,is that all for RETLW?

What would you do with something like 10 or more tables,just as I described further above regarding the 1602LCD?


Regards,Alex.
 
Alex_rcpilot said:
With this there's nothing I shall be scared of while working on RETLW.

Nothing ? :D

Be careful when your table is larger than one page(256 bytes), not starting on a page boundary, larger than 512 bytes...etc..

It is getting messy with the correct PCL and PCLATH. Microchip AN556 is the document about what to watch out for with table read.
 
Alex_rcpilot said:
Hm......actually I have read about the RETLW structure from my text book.And I think it's the most frequently used method for returning data from a table.

As far as I know it's the only way?, apart from using EEPROM, or some kind of external memory?.

I don't know what you meant by force programming.Presumably you meant that I was trying to apply a program structure that doesn't fit into PIC hardware to a PIC?

Yes, that's what I meant, the Harvard architecture of the PIC keeps data and program completely seperate - which makes tables rather difficult, the RETLW instruction can be used to provide a program structure that contains data.

But the RETLW structure is perfectly capable of doing what you require, if you have a look at **broken link removed** then they use RETLW to store large amounts of data to generate maps on a graphic LCD.

As already suggested, you have to take account of the 256 byte boundary problems, but the EPE code does just that (using almost all the program space for data).
 
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.
 
Status
Not open for further replies.

New Articles From Microcontroller Tips

Back
Top