Software

From CAPE Wiki

Jump to: navigation, search

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 *char for ASCII character arrays. Use char[10] instead.

[edit] for loop

  • When using a for loop, declare the int outside the for command. 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);

Personal tools