Storing constant data in program memory
Original Assignment
Your PIC has a relatively large amount of program memory (32 Kbytes) but relatively little data memory (1536 bytes). For some applications, we want to have lookup tables or calibration data stored on our PIC, but we don't want it hogging data memory. This project is to demonstrate how to write a program that stores constant data in program memory. Test your ability to do this by creating a look-up table for the sin function. This is a 1-d array with integer index corresponding to an angle (e.g., numbers 0 to 89 if the index is in degrees; angles in other quadrants can be determined by simple transformations). Depending on your choice of int8, int16, or float to represent the number, what angle resolution can you use for the index before you reach the limits of program memory?
See p. 43 of the PIC MCU C Compiler book.
Finally, give sample code for storing data in the EEPROM, too.
Overview
The PIC has a relatively large amount of program memory (32 Kbytes) but relatively little data memory (1536 bytes). For some applications, we want to have lookup tables or calibration data stored on our PIC, but we don't want it hogging data memory. The CCS C Compiler provides a few different ways to use program memory for data, discussed below. We have also provided an example of how to create a look-up table for the sin function to illustrate one of these methods.
Constant Data
The CONST qualifier will place variables into program memory. If the keyword CONST is used before the identifier, the identifier is treated as a constant. These constants need to be initialized and cannot be changed at run-time.
The ROM qualifier puts data in program memory with 3 bytes per instruction space. The address used for ROM data is a true byte address not a physical address. The & operator can be used on ROM variables even though the address is logical not physical.
The syntax is: const type id[cexpr] = {value}
You must initialize the constant variable when you declare it or the compiler will spit out an error at you. Which means, unfortunately, you can't do something like:
for (i = 0; i < 100; i++) const float listOfNumbers[i] = i; end
#ROM Directive
Another method that can be used to assign data to program memory is the #ROM directive.
The syntax is: #rom address = {data, data, ... , data}
The following example places the numbers 1, 3, 5, 7, 9 into ROM addresses starting at 0x2000:
#rom 0x2000 = {1, 3, 5, 7, 9}
You can also put strings into program memory using the #ROM directive:
#rom 0x3000 = {"mechatronicsrocks"}
Built-in Functions
The compiler provides built in functions to place data in program memory.
write_program_eeprom(address,data);
- Writes data to program memory
write_program_memory(address, dataptr, count);
- Writes count bytes of data from dataptr to address in program memory.
- Every fourth byte of data will not be written, this needs to be filled with 0x00.
Circuit
Creating a look-up table for the sin function
Code
Constant Data Example
Placing data into ROM
- const int table[16]={0,1,2...15}
Placing a string into ROM
- const char cstring[6]={"hello"}
Creating pointers to constants
- const char *cptr;cptr = string;
#ROM Directive Example
Places 1,2,3,4 to ROM addresses starting at 0x1000
- #rom 0x1000 = {1,2,3,4}
Places null terminated string in ROM
- rom 0x1000 = {"hello"}
- This method can only be used to initialize the program memory.
Creating a look-up table for the sin function
With values of sine from 0-89°, we can calculate sine values for all 360°. Below is code storing a table of sine values from 0-89° with a angle resolution of 1°.
const float sineTable[90] = {0,0.017452,0.034899,0.052336,0.069756,0.087156,0.104528,0.121869,0.139173,0.156434, 0.173648,0.190809,0.207912,0.224951,0.241922,0.258819,0.275637,0.292372,0.309017,0.325568, 0.34202,0.358368,0.374607,0.390731,0.406737,0.422618,0.438371,0.45399,0.469472,0.48481,0.5, 0.515038,0.529919,0.544639,0.559193,0.573576,0.587785,0.601815,0.615661,0.62932,0.642788, 0.656059,0.669131,0.681998,0.694658,0.707107,0.71934,0.731354,0.743145,0.75471,0.766044, 0.777146,0.788011,0.798636,0.809017,0.819152,0.829038,0.838671,0.848048,0.857167,0.866025, 0.87462,0.882948,0.891007,0.898794,0.906308,0.913545,0.920505,0.927184,0.93358,0.939693, 0.945519,0.951057,0.956305,0.961262,0.965926,0.970296,0.97437,0.978148,0.981627,0.984808, 0.987688,0.990268,0.992546,0.994522,0.996195,0.997564,0.99863,0.999391,0.999848};
This table stores values as floats and is ____ in size. Since the PIC has __KB of program memory, we could theoretically hold a sine lookup table precise to ___°.
insert table of data types and angle resolution possible int8, int16, float, double?