Creating Large Memory Arrays
The C18 compiler does not support data buffers over 256 bytes without a modification to the linker script to define a larger bank of microcontroller ram.
Copy the default linker script for your PIC18 device from:
C:\Program Files (x86)\Microchip\MPASM Suite\LKR
into your projects directory. Add the file to your MPLAB project so that it is used in place of the default file.
Find the section listing each of the databanks for your device, e.g.
DATABANK NAME=gpr0 START=0x60 END=0xFF
DATABANK NAME=gpr1 START=0x100 END=0x1FF
DATABANK NAME=gpr2 START=0x200 END=0x2FF
DATABANK NAME=gpr3 START=0x300 END=0x3FF
DATABANK NAME=gpr4 START=0x400 END=0x4FF
DATABANK NAME=gpr5 START=0x500 END=0x5FF
DATABANK NAME=gpr6 START=0x600 END=0x6FF
DATABANK NAME=gpr7 START=0x700 END=0x7FF
DATABANK NAME=gpr8 START=0x800 END=0x8FF
DATABANK NAME=gpr9 START=0x900 END=0x9FF
DATABANK NAME=gpr10 START=0xA00 END=0xAFF
DATABANK NAME=gpr11 START=0xB00 END=0xBFF
DATABANK NAME=gpr12 START=0xC00 END=0xCFF
#IFDEF _DEBUGDATASTART
DATABANK NAME=gpr13 START=0xD00 END=_DATAEND
DATABANK NAME=dbgspr START=_DEBUGDATASTART END=_DEND PROTECTED
#ELSE //no debug
DATABANK NAME=gpr13 START=0xD00 END=0xDFF
#FI
DATABANK NAME=gpr14 START=0xE00 END=0xE40
The number will relate to the number of gpr banks your PIC18 device has.
Now select as many consecutive databanks as you will need to be able to hold your array from somewhere in the middle of the available banks. If you need a multiple of 256bytes then you will use the complete banks, or otherwise you will use just part of the final bank. You want to delete those databanks (and just edit the START address for the final bank if not using a 256byte multiple) and then add your own new databank which will hold your array:
DATABANK NAME=my_ram_section START=0x#00 END=0x#FF
Where ‘0x#00’ is the start address of the first removed bank and ‘0x#FF ‘ is the end address of the last removed bank. E.g. for a 512 byte databank in this example:
DATABANK NAME=gpr0 START=0x60 END=0xFF
DATABANK NAME=gpr1 START=0x100 END=0x1FF
DATABANK NAME=gpr2 START=0x200 END=0x2FF
DATABANK NAME=gpr3 START=0x300 END=0x3FF
DATABANK NAME=gpr4 START=0x400 END=0x4FF
DATABANK NAME=gpr5 START=0x500 END=0x5FF
DATABANK NAME=gpr6 START=0x600 END=0x6FF
DATABANK NAME=dmx_512_byte_ram_section START=0x700 END=0x8FF
DATABANK NAME=gpr9 START=0x900 END=0x9FF
DATABANK NAME=gpr10 START=0xA00 END=0xAFF
DATABANK NAME=gpr11 START=0xB00 END=0xBFF
DATABANK NAME=gpr12 START=0xC00 END=0xCFF
#IFDEF _DEBUGDATASTART
DATABANK NAME=gpr13 START=0xD00 END=_DATAEND
DATABANK NAME=dbgspr START=_DEBUGDATASTART END=_DEND PROTECTED
#ELSE //no debug
DATABANK NAME=gpr13 START=0xD00 END=0xDFF
#FI
Save the linker script. This defines the new block of memory and you can now use the name you assigned to declare your array:
#pragma udata dmx_512_byte_ram_section //This is the PIC C18 compiler command to use the specially defined section in the linker script (uses a modified linker script for this)
BYTE dmx_tx_buffer[512]; //(C18 large array requirement to use a special big section of ram defined in the linker script)
#pragma udata
Accessing The Array
Its OK to use pointers like this:
BYTE *buffer_pointer;
buffer_pointer = &my_array[0] + some_value;
*buffer_pointer = 0x01;