ENGR/CS 101 - Introduction to Engineering/Computer Science

Fall 1999 - LEGO Project, Basic C Programming, Part 2

This handout explains C functions.

Errata and omissions

In the last handout, Basic C Programming, the usage for the WriteChar robotics library function was incorrect. It should say:

Function Specification
WriteChar(c, d) Write a character c in position d
This function does not have a flag to provide padding.


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 0
will 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 */

Functions

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 ) 

{
variable-declarations
executable-statements
}
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:

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 */



Converted using latex2html on Sun Jun 18 22:07:24 CDT 2000