Software
From CAPE Wiki
The following is work done by the first satellite team.
Tutorial-PIC Programming Basics
Tutorial-ADC Setup Using the 18F452 or 18F4520
Contents |
[edit] C18
The C compiler used on CAPE1 was the Microchip C18 compiler. This software has many issues that veteran programmers know about.
[edit] Declaring an Array
Here is a list of things programmers must be wary of with C18.
- Avoid using
*charfor ASCII character arrays. Usechar[10]instead.
[edit] for loop
- When using a
forloop, declare theintoutside theforcommand. For example, do not do the following:
for(int i=0; i<sourcedatacount; i++)
{
}
Instead, do the following:
int i;
for(i=0; i<sourcedatacount; i++)
{
}
[edit] Creating a large array >256 bytes
No more than 256 bytes can be allocated to a variable even though 1K of memory is available. The way to overcome this is to seperate variables into multiple banks using the #pragma udata command. If you receive the error similar to .udata_main.o' can not fit the section, then you have run out of memory. You can use the following to access more memory and add more variables. Here's an example where I opened up more memory and created a new char array called buoyA[100]. Notice the #pragma udata statements located before and after. The myuaryscn is trivial and can be called anything.
#pragma udata myuaryscn unsigned char buoyA[100]; #pragma udata
If you fill up this bank with memory also, you can open up another one. Here I've filled memory with several variables.
#pragma udata myuary2 unsigned char buoyB[100]; char Ycommand[50]; char Yvalue[4]; char Xcommand[50]; char Xvalue[4]; #pragma udata
You can continue to do this until all RAM has been used up.
See MPLAB C18 C Compiler Getting Started Guide.
See .udata_main.o can not fit the section - C18 Memory Settings.
See char buf(512) - can not fit the section.
Another way of doing this is by increasing the bank size in the linker file. By openening up the linker file, you can edit the contents allowing you to increase the size.
Quick and dirty way is to copy the linker file to your local directory (it's best not to edit it directly) and change the appropriate ram allocation line.
In the following section:
ACCESSBANK NAME=accessram START=0x0 END=0x5F 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 DATABANK NAME=gpr13 START=0xD00 END=0xDFF DATABANK NAME=gpr14 START=0xE00 END=0xEFF DATABANK NAME=gpr15 START=0xF00 END=0xF5F ACCESSBANK NAME=accesssfr START=0xF60 END=0xFFF PROTECTED
Change the line:
DATABANK NAME=gpr1 START=0x100 END=0x1FF
to:
DATABANK NAME=gpr1 START=0x100 END=0x2FF
and delete or comment the line
DATABANK NAME=gpr2 START=0x200 END=0x2FF
This gives you the attached linker file which creates a 512 byte section as the first section in RAM. If you were creating a larger than 256 byte variable such as a 512 byte array, it would be better to actually name the section and use a #pragma statement to put the array in said section. Typically it's better to not have a variable span multiple banks due to access times (probably trivial in your application) and forcing the variables to lie completely within via pragma statements is the best way to go.
[edit] Interrupt Service Routine (ISR)
The following code is needed in order to have the PIC jump to a function when an interrupt occurs. Here is an example used on the Microchip PIC18LF452.
void Check(void);
#pragma code low_vector = 0x0018
void low_interrupt(void)
{
Check();
}
#pragma code
void Check(void)
{
INTCONbits.GIE = 0; //Turns interrupts off temporarily
//Replace this line with the function to jump to
INTCONbits.GIE = 1; //Turns interrupts back on
}
[edit] C18 Libraries
[edit] 18F4520 ADC call
The libraries file might be missing some key information (depending on the version you have). The OpenADC() function, its important to know that ADC_VREFMINUS_VSS is available which means VREF- gets set to an external negative reference.
Code Example:
OpenADC(ADC_FOSC_32 & ADC_RIGHT_JUST & ADC_20_TAD, ADC_CH0 & ADC_INT_OFF & ADC_VREFPLUS_VDD & ADC_VREFMINUS_VSS, 0);
