Friday, March 22, 2013

A Crash Course Introduction to C

Previously, I mentioned the Assembly programming language.  Assembly is a great tool for writing programs which directly control the system hardware.  The problem with assembly is that, as programs become more complex, assembly gets hard to manage.  Program flow becomes difficult to control and errors are difficult and tedious to find.
Enter C.  C is a high-level language, which means that it's easier for humans to understand.  C also has clearly defined rules and is considered "portable".  Not in the sense that you can pick C up and take it with you to the bar after work (although... I suppose you could in a way) but rather, a program we write for one microcontroller can be easily installed into a different microcontroller with only minimal adjustments to the program (if any).  A program written in Assembly however, is written for a specific MCU and cannot be ported to another without significant changes.  After we write our program in C, an intermediary computer (your desktop) is used to translate C into machine code via a Compiler, in our case Microchip's XC8 Compiler.

Introduction to the C Language

 The C language is made up of a number of elements including Keywords, Variables, Operators, Functions, Statements, and Preprocessor Macros.  Each will be explained, and figure 1 below shows some examples.
Figure 1
Keywords are words whose meanings have already been declared to the C compiler to define data types, or for use in loops.

A variable is a name we give to a certain memory location which can hold various values.  All variables must be declared before they can be used.  There are different variable data types which we will learn and become familiar with later.

Operators are basically used to perform some operation on a variable, such as arithmetic or a comparison between two variables.

A preprocessor macro is a command given to the compiler (XC8) rather than our C program.  They are not actually part of the C language, but accepted as such because of their use and familiarity.  Preprocessing is a separate step from compilation and happens before compiling begins.  The most common preprocessor macros are #define and #include.  Preprocessor macros allow the programmer to include text from other files, such as header files (used in every C program), define macros which reduce programming effort and improve readability of the program code, and issue compiler specific directives to optimize compilation.

A function is a set of instructions that can be used more than once in a program.  Functions are also referred to as subroutines or procedures.  Functions are the basic building blocks of C, and all statements must be within a function.  As programs are written, and functions are developed to perform a specific task, they can be used again and again, and even saved in a separate file and called to other programs using the #include preprocessor macro.

Statements are used to control the flow of your program.  Statements allow your program to move from function to function so long as certain conditions are met, which is why you can see them referred to as Conditional Statements.

To aide in making program code more readable to humans, we have the ability to insert comments into our program.  Any comments you wish to write in your code must be preceded by a double forward slash "//".  Additionally, a forward slash and an asterisk "/*" can precede a comment so long as an asterisk and a forward slash "*/" follows the comment.  We will see more examples of comments used shortly, but it is important to remember that anything you write in a program will be considered part of the program by the compiler unless you tell the compiler to ignore it.  Using the slashes and asterisks is how you instruct the compiler to ignore your comments.

Looking at our First C Program

Below is a very simple example of a C program that does pretty much nothing, but it will introduce us to the structure of a C program.  Let's take a look.

Figure 2

Lines 1 through 3 show some examples of comment usage, using both the double slash and slash-asterisk combinations.  You'll notice that we skip line 4.  Skipping lines in the IDE is okay, the compiler will just ignore blank lines, and using them can help break up a wall of code to make reading it easier.  It's important to keep your program code as readable as possible using blank lines, indents, and comments.

Line 5 shows our first example of the usage of a preprocessor macro, #include, followed by another comment.  The #include preprocessor macro tells the compiler to include a file named "xc.h", which is a header file.  We place the name of the file inside the <> symbols to indicate to the compiler what the file name is.  Header files are very important in C, as they include all the definitions for all the special function registers and their bits in each PIC chip.  The xc.h header file is something of a catch-all for header files, as it directly includes the chip specific header file for the MCU you're programming for.  All of the header files associated with the XC8 compiler can be found in the XC8 directory on your hard drive: program files>microchip>xc8>version#>include.  The include directory is full of all the header (.h) and include (.inc) files.  These files can be opened with notepad and are pretty interesting to look through.  We'll dig through some of them in later lessons to get you familiar with how they can be useful.

Line 7 shows our first function, the "main()" function.  Every program we write in C must have this function.  Program execution begins and is contained within the main function.  Functions allow data to be passed to them from the program, and also allow data to be returned from the function back into the program.  In the case of the main function, the entire program resides within main, so there is no data to be passed.  The C keyword void is used in front of the main function name to indicate that no return data is expected.  The set of parenthesis is where our arguments would go, which are a type of conditional operator.  In other words, data that we want to pass to the function.  Again, in the case of main, there are none, so we can either leave the parenthesis blank, or we could have written void inside of them, for example, void main (void).

Following the main function on line 8, we see the usage of a left brace "{".  The braces are used to group the instructions that belong inside a function.  Each function has a set of braces, so as you write a C program, especially one with many functions, your number of braces will grow rapidly.  Many functions can reside within another function and yet inside another function.  When one function resides within another, it is called "nesting".  To help keep track of where one function ends and another function begins, it is good practice to indent each set of braces so that the opening brace lines up with the closing brace vertically.  The nice thing about MPLAB X is that it will do this for us.

In line 9, we define a variable and give it a decimal value.  In this case, I have defined the variable "name" and assigned it the "char" (short for character) data type.  We'll talk about data types in just a minute, but for now, just understand that "char" is a keyword which defines a type of data.  The name of the variable, "name" can be anything we want it to be as long as it is not a C keyword.  For instance, if I wanted to define a variable to keep track of a number counter, I could name my variable "number_counter" to help me remember what it's for.  The use of spaces in a variable name is not allowed, so we must use the underscore instead.  After I defined the data type "char" and gave my variable a name "name", I have used the operator "=" (the equal sign) to indicate that I want to assign a value to my variable.  As indicated, that value is zero.  So basically what this line is telling the program is that I want a char data type variable named "name" and I want it to equal the decimal number 0.  Since defining a variable is a statement, it must be ended with a semicolon.  All statements end in a semicolon just like all sentences end with a period.  If you don't use the semicolon, the compiler won't know it's a statement.

Line 11 is another function.  This function resides within the main function, so it can be considered a nested function.  Notice my second set of braces are indented further to help me keep track of my functions.  This is a while function, and basically says that "while a condition is true, do this function".  Most applications need to run continuously until the processor is turned off or reset.  The program will run through a loop to the end and then start over again.  The while function offers a means of doing this.  There are 2 conditions that a while loop can have, either true, or false.  False is always 0, and true is any number but 0.  The condition for continuing to repeat the while function is contained within the parenthesis following the while keyword.  The function block is repeated continuously as long as the value, or result of the expression in the parenthesis is not zero.  In the case of our example, placing a "1" inside the parenthesis ensures that the result is always true, and therefore repeats forever.

Line 12 is simply the function block beginning brace for the while function.

Line 13 is nothing but a semicolon.  This is completely useless code as it contains no statement.  It's basically saying "do nothing".  However, the example is there to show where instructions within a function would go.  The block of statements (instructions) for the endlessly repeating while loop would go here.

Lines 14 and 15 contain the right braces "}" to close the while function and main function respectively.  Remember to keep track of your braces, and always close your function blocks.  One of the nice things about the MPLAB X IDE is that when you place a left brace to add a function block, the IDE will automatically add a closing brace for you.

Data Types

Variables are defined as a specific data type depending on how big a number we need our variable to hold.  If we want a variable that we can use to simply set as either a zero or a one, we would want to use a different data type than if we wanted to use a variable to count from 1 to 1,000.  We could use a data type that is capable of holding the number 1,000 to simply set 1 or 0, but this would waste memory space inside the MCU because 1,000 requires more space than 1.  Let's look at the table in figure 3 to see the different data types.
Figure 3
The table in figure 3 shows the data type definitions, the name of the type, the size required in memory for the data type in bits and (bytes), and finally the decimal range the type is capable of storing.  Why am I saying decimal range when most of these are whole numbers?  Because in C, we use binary numbers, hexadecimal numbers, octal numbers, and decimal numbers.  Personally, I've never used octal numbers in any of my programs, but I have used the other three types.  The last data type on the list is the Floating Point.  This is the data type used for calculations that require fractions of numbers, in other words, numbers with decimal points.  We're not going to see any of these for a while, so I'll hold off on the rather complex explanation until later.

In our next lesson, we'll introduce you to the programming environment (the IDE) and start setting up for our first project.  As always, comments are welcome if you care to share.  Thanks for reading.

13 comments:

  1. This comment has been removed by a blog administrator.

    ReplyDelete
  2. This comment has been removed by a blog administrator.

    ReplyDelete
  3. This comment has been removed by a blog administrator.

    ReplyDelete
  4. This comment has been removed by a blog administrator.

    ReplyDelete
  5. This comment has been removed by a blog administrator.

    ReplyDelete
  6. This comment has been removed by a blog administrator.

    ReplyDelete
  7. This comment has been removed by a blog administrator.

    ReplyDelete
  8. This comment has been removed by a blog administrator.

    ReplyDelete
  9. This comment has been removed by a blog administrator.

    ReplyDelete
  10. This comment has been removed by a blog administrator.

    ReplyDelete
  11. I was reading a thread at a big Fast Fat Burner forum yesterday this made this claim. Ultra Fast Pure Keto I'm certain a good many of you will gather of Quick Fat Burner differently. That can be all the more powerful if taken within the context of Weight Loss Tips. You ought to have a look at the dark aspect of Weight Loss and you ought to offer it an attempt because I expect you may be happy you probably did.

    https://www.healthysuppreviews.com/ultra-fast-pure-keto-boost/

    https://www.healthysuppreviews.com/keto-slim-7/

    ReplyDelete
  12. When does Essential CBD Extract need its own Essential CBD Extract Review? I have been reading as this touches on it for a couple of days now and found out a lot. Nevertheless, I speak with a slight accent. This article is a monster. I didn’t need to pay an arm and leg. That’s far better way to look at it. This occasionally is like an accident waiting to happen but it was eye catching. Here are several essential elements. Folks from around the world are talking about this respecting this technique in order that you probably struggled a bit on concentrating on this advantage. This was exciting news. What about them? That is easy and my wizards as of now know this whenever it’s always good to sit and chat with friends in the matter of supporters using that. How do pupils arrive at desirable Essential CBD Extract catalogs?

    http://www.essentialextractcbd.org/
    https://www.facebook.com/Painreliefcbdoil/
    https://www.facebook.com/Painreliefcbdoil/photos/a.101119604827980/101116534828287/
    https://www.facebook.com/pg/Painreliefcbdoil/offers/

    ReplyDelete