View previous topic :: View next topic |
Author |
Message |
bwhiten
Joined: 26 Nov 2003 Posts: 151 Location: Grayson, GA
|
RAM Memory locations |
Posted: Thu Jun 26, 2008 8:37 am |
|
|
The compiler says I am running out of contiguous RAM space to store LCD data in a 16F887. I have relocated the array to 0x300 and it compiles and when I look at the .sym file it "appears" this is in RAM space, not ROM. Cool! But I can't prove it is RAM by looking at the Microchip datasheet. Can someone describe to me how to determine the RAM locations in the memory maps of the datasheet? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Jun 26, 2008 11:36 am |
|
|
Every PIC data sheet has a chart that shows the register addresses and
the blocks of general purpose RAM. Look in the 16F887 data sheet,
in this section:
Quote: | FIGURE 2-6: PIC16F886/PIC16F887 SPECIAL FUNCTION REGISTERS |
Make sure you're looking at that specific section. The other smaller PICs
have similar figures in the data sheet. You want the one for the 16F887. |
|
|
bwhiten
Joined: 26 Nov 2003 Posts: 151 Location: Grayson, GA
|
Still confused |
Posted: Thu Jun 26, 2008 12:04 pm |
|
|
I definitely looked at this figure but it made little sense in terms of direct versus indirect addressing. This is the statement I have in the program:
Code: |
struct {
int8 left[64];
int8 right[64];
} displayData;
#locate displayData = 0x300
|
And this is a small section from the .sym file:
Quote: |
1FF @INTERRUPT_AREA
27F @INTERRUPT_AREA
2FF @INTERRUPT_AREA
300-37F displayData
37F @INTERRUPT_AREA
3FF @INTERRUPT_AREA
ROM Allocation:
04FD @delay_ms1
1800 banner
1810 header
182A company
1844 dateText
01C1 glcd_update
0265 glcd_init
02F1 glcd_pixel
0220 glcd_fillScreen
019A @MUL88
0164 glcd_writeByte
185D FONT1
1963 FONT2
1A46 FONT3
035A glcd_text57
0531 spi_bgetc
0511 blight_adjust
003C clock_isr
0155 ssp_isr
0800 MAIN
0800 @cinit
|
Based on the mapping figure, how does this relate to user RAM? It doesn't show as being assigned to ROM in any way. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
|
bwhiten
Joined: 26 Nov 2003 Posts: 151 Location: Grayson, GA
|
I think I'm OK but.... |
Posted: Thu Jun 26, 2008 12:19 pm |
|
|
Sorry to be unclear. This was done to find more room in RAM. It appears to be locating this structure in RAM at 0x300, just like I wanted, but I can't determine why 0x300 is a legal RAM address from looking at the datasheet. Paranoid I guess.
Can you tell by looking at what I show above that 0x300 is a legal RAM address and if so how do I translate that back to the addresses I see in Figure 2-6?
Thanks again for struggling with my issues. |
|
|
Ttelmah Guest
|
|
Posted: Thu Jun 26, 2008 2:48 pm |
|
|
I'm afraid all you have done, is find a shortcoming in the memory testing.
Figure 2-6. Your chip, has a total of 368 bytes of RAM, organised as 96bytes at 0x20 to 0x7F, then 80bytes at 0xA0, to 0xEF, then 96bytes from 0x110, to 0x16F, and finally 96 bytes from 0x190, to 0x1EF.
0x300, is not a legitimate location for the chip.
If you try to #locate the variable anywhere inside the legitimate memory, the compiler will tell you it has not got enough contiguous locations, for the array, since it is bigger than any of the available blocks (array needs 128 consecutive locations). However, some of the chips in the same family, support you adding external memory, so the #locate, accepts that _you_ know what you are doing when you give it a location, and will allow you to put the array at 0x300. Unfortunately, you don't have any memory there...
Best Wishes |
|
|
bwhiten
Joined: 26 Nov 2003 Posts: 151 Location: Grayson, GA
|
Makes more sense |
Posted: Thu Jun 26, 2008 8:48 pm |
|
|
Obviously my code didn't run. I did make some progress however, by splitting the array in to two and #locate-ing one at 0x110 and one at 0x190. This allowed the design to fit where as without these locates the RAM never fit. |
|
|
Ttemah Guest
|
|
Posted: Fri Jun 27, 2008 1:51 am |
|
|
Normally, the compiler will do this OK, with the following comments:
1) You must split the array (since the largest contiguous piece of memory is not large enough for the 128 element entry.
2) You must have #device *=16. Otherwise the compiler will only access the first bank.
3) Though on 'speed' grounds, it is better to declare much used variables first, you may well find that the compiler will fit the two arrays in OK, if you declare them first. It finds it easier to fit the 'big lumps', and then fit the smaller stuff 'round' these.
#locating as you have done, is a good choice if you have just a couple of large elements like this.
Best Wishes |
|
|
bwhiten
Joined: 26 Nov 2003 Posts: 151 Location: Grayson, GA
|
Original Reason for this madness |
Posted: Fri Jun 27, 2008 8:14 am |
|
|
The reason I started down this path was that I was not satisfied with the speed of the LCD updates using the "slow" version of the GLCD text generating code. I was using the slow version because the 16F887 does not have enough RAM to utilize the FAST_GLCD code as written. I worked around this now by modifying the code to store and fast write a single "text line" of the LCD at a time. This fits in the available RAM and reduces the display-a-line-of-text function from a sequence of writing the LCD memory 2048 times with an overhead of 2048 reads and 2048 writes, to reading RAM 128 times and writing the LCD memory 128 times with an overhead of 4 writes. Do this across all 8 lines and the LCD updates quite a bit faster! |
|
|
|