The following is work done by the first satellite team.

Tutorial-PIC Programming Basics

Tutorial-ADC Setup Using the 18F452 or 18F4520


The C compiler used on CAPE1 was the [ Microchip] C18 compiler. This software has many issues that veteran programmers know about.

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.

for loop

  • When using a for loop, declare the int outside the for command. For example, do not do the following:
1:  for(int i=0; i<sourcedatacount; i++)
3:  {
5:  }

Instead, do the following:

1:  int i;
3:  for(i=0; i<sourcedatacount; i++)
5:  {
7:  }

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.

1:  #pragma udata myuaryscn
2:  unsigned char buoyA[100];
3:  #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.

1:  #pragma udata myuary2
2:  unsigned char buoyB[100];
3:  char Ycommand[50];
4:  char Yvalue[4];
5:  char Xcommand[50];
6:  char Xvalue[4];
7:  #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:

 1:  ACCESSBANK NAME=accessram  START=0x0            END=0x5F
 2:  DATABANK   NAME=gpr0       START=0x60           END=0xFF
 3:  DATABANK   NAME=gpr1       START=0x100          END=0x1FF
 4:  DATABANK   NAME=gpr2       START=0x200          END=0x2FF
 5:  DATABANK   NAME=gpr3       START=0x300          END=0x3FF
 6:  DATABANK   NAME=gpr4       START=0x400          END=0x4FF
 7:  DATABANK   NAME=gpr5       START=0x500          END=0x5FF
 8:  DATABANK   NAME=gpr6       START=0x600          END=0x6FF
 9:  DATABANK   NAME=gpr7       START=0x700          END=0x7FF
10:  DATABANK   NAME=gpr8       START=0x800          END=0x8FF
11:  DATABANK   NAME=gpr9       START=0x900          END=0x9FF
12:  DATABANK   NAME=gpr10      START=0xA00          END=0xAFF
13:  DATABANK   NAME=gpr11      START=0xB00          END=0xBFF
14:  DATABANK   NAME=gpr12      START=0xC00          END=0xCFF
15:  DATABANK   NAME=gpr13      START=0xD00          END=0xDFF
16:  DATABANK   NAME=gpr14      START=0xE00          END=0xEFF
17:  DATABANK   NAME=gpr15      START=0xF00          END=0xF5F
18:  ACCESSBANK NAME=accesssfr  START=0xF60          END=0xFFF          PROTECTED

Change the line:

3:  DATABANK   NAME=gpr1       START=0x100          END=0x1FF


3:  DATABANK   NAME=gpr1       START=0x100          END=0x2FF

and delete or comment the line

4:  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.

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.

 1:  void Check(void);
 2:  #pragma code low_vector = 0x0018
 3:  void low_interrupt(void)
 4:  {
 5:      Check();
 6:  }
 7:  #pragma code
 8:  void Check(void)
 9:  {
10:      INTCONbits.GIE = 0;      //Turns interrupts off temporarily
12:      //Replace this line with the function to jump to
14:      INTCONbits.GIE = 1;      //Turns interrupts back on
15:  }

C18 Libraries

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:

duty free alcohol airport duty free cigs uk buy duty free cuban cigars where to buy cosmetics duty free fragrances buy tobacco duty free