Fall 1999 - LEGO Project, Basic C Programming, Part 2
This handout explains C functions.
In the last handout, Basic C Programming, the usage for the WriteChar robotics library function was incorrect. It should say:
This function does not have a flag to provide padding.
Function Specification WriteChar(c, d) Write a character c in position d
Sometimes you'd like to give a constant value a name, so you can
remember why you used a particular value. This can be done using the
#define syntax. For example,
#define PADDING 1 #define NO_PADDING 0will define the name PADDING to have value 1 and NO_PADDING to have value 0. Now we can use the display routines like so:
right = BumpRight();
left = BumpLeft ();
WriteString ("Bumps:", 0, PADDING);
WriteInt (right, 8, NO_PADDING);
WriteInt (left, 12, NO_PADDING);
Sometimes you want to write notes to yourself about what the
program is doing. This can be done by using comments which
begin with /* and end with */. Everything between
these marks is ignored. So for example,
/* This is a comment and will be ignored */
A function is a subprogram. When a function is used, we say it is called, and the subprogram that uses the function the caller. When a function is called, the caller can pass data to it called the arguments, and when the function is finished, it can return a result.
To define a function, there are two parts. First, you need to
tell the program the name, the type of the returned result, and the
types of the data that can be passed to it. (The names of the data
can be given, too, but this is optional.) This is done in a function
prototype, that is given before the main program. The syntax
of a prototype is:
return-type name ( parameter-list ) ;Where parameter-list is a comma-separated list of types (and names). So for example, robotics.h contains all the prototypes for the functions you've been using. The one to get a value from the A to D converter looks like:
unsigned char GetAtoD (unsigned char channel);Which says that the function GetAtoD is passed an unsigned char as an argument and returns an unsigned char as a result.
Sometimes a function doesn't have a result to return, for example,
the function to display a string on the display. Its prototype is:
void WriteString (unsigned char *str, unsigned char dpos, unsigned char fill);Since it doesn't need to return a result, its return type is set to void.
Once a prototype is written, the main program and any other
functions can call the prototyped function. But, of course, we also need
to write the actual subprogram to make it work. These are called function
definitions and are usually written after the main program. Each
function has its own definition. The syntax for the function definition is:
return-type name ( parameter-list )The first line looks just like the prototype (with parameter names) except it doesn't have a semicolon at the end. The rest looks just like the main program. If the the function should return a result, at least one of the executable statements will be a return statement which has the syntax:{
variable-declarations
executable-statements}
return expression ;And causes the value of the expression to be sent back to the caller as the result of the function call.
In robotics.c, we can see the function definitions of
the functions in the robotic library. For example, the A to D
conversion function:
unsigned char GetAtoD (unsigned char channel)
{
unsigned char i;
/* OR 8 with channel for single ended entry */
XBYTE[0x8000] = (channel | 8);
/* Delay to allow for read */
for(i=0; i<255; i++);
/*Get the data and return it */
return XBYTE[0x8000];
} /* end GetAtoD */
A function call is just the name of the function and a
comma-separated list of arguments you want to pass to the function.
The syntax is:
function-name ( argument-list ) ;An argument can be a constant, an expression, or a variable. If the function returns a result, you need to assign it to a variable to save it.
Here is a full program to print out the values of channels 0-3
of the A to D converter:
/* atodtest.c
This program inputs data from 4 channels of the A to D converter and
displays the 8-bit results in hex (2 digits) on the LCD display using
the robotics library.
*/
#include "robotics.h" /* Provides the prototypes for robotics functions */
#define PADDING 1
int main (void)
{
unsigned char channel, value;
MotorsOff();
InitializeDisplay();
while (1)
{
for (channel = 0; channel < 4; channel++)
{
value = GetAtoD(channel);
WriteInt (value, channel*3, PADDING);
} /* end for */
Delay (25);
} /* end while */
} /* end main */