Download presentation
Presentation is loading. Please wait.
1
Introduction to C Programming
Embedded Workshop Microcontrollers April 26, 2017
2
Baseline This is NOT an introduction to programming class.
I will probably repeat this class outside of the Embedded Workshop series. We can pause to try running test code on the Arduino.
3
History C is like a high level assembler.
Designed for system programming, namely implementing UNIX. Originally targeted DEC PDP series minicomputers. Ability to express optimization by accessing the special capabilities of the processor.
4
The Preprocessor Essentially a language around a language.
Start the line with a ‘#’. Uses Header file inclusion. Macro substitution. Conditional compilation. Compiler control.
5
Header File Inclusion #include <file name> #include “file name”
Searches for the file in standard system directories. #include “file name” Searches for the file in the directory where the file containing the #include statement resides, then in system directories.
6
Macro Substitution #define NAME value literally replaces “NAME” with “value”.
7
Macro Substitution #define BLINK_LED(pin) digitalWrite(pin, HIGH); \ delay(500); \ digitalWrite(pin, LOW); expands this code in place.
8
Conditional Compilation
#ifdef DEBUG stuff #endif #if VERSION >= 2 stuff #else other stuff #endif
9
Compiler Control #pragma Special instructions to the compiler.
10
Syntax These are the rules for writing code.
C is free form – white space is ignored except within a character string. C is case sensitive. A ‘\’ at the end of a line treats the next line as part of the current line. This is usually only needed for defining a complicated macro.
11
Comments /* comment */ /* * comment */ // comment
12
Block Structured { declarations statements }
13
Block Structured { int foo; foo = 1; }
14
Source File Structure comment block header file interface global variable declarations int function () { } int anotherFunction () { }
15
Indentation Not enforced by the language.
Useful to make structure of your code clearer. Some people feel very strongly about the particular indentation style. Pick a style and stick to it.
16
K & R Indentation Style int function() { if (foo == 0) { statement; } }
17
Some Like This Indentation Style
int function() { if (foo == 0) { statement; } }
18
My Indentation Style int function() { if (foo == 0) { statement; } }
19
Naming Defined names in all caps #define LED 13 Variable names
multiple_word_name multipleWordName MultipleWordName Again, pick a style and stick to it.
20
Standard C versus Arduino C
21
Standard C int main() { do stuff; }
22
Arduino C void setup() { initialization stuff } void loop() { repeated stuff }
23
The missing link int main() { setup(); while (1) loop(); }
24
Variables and Types Base types are categorized by the data format
Integer Real Pointer Character
25
Integer Whole numbers only. int is the default base type.
unsigned means there is no sign bit. The sizes of a short and a long are implementation specific. A short is no longer than a long. Newer compilers implement long long. Plain int is usually the most efficient variable type.
26
Real A number consisting of a magnitude and an exponent. Think scientific notation, but in binary. float is a single precision number. double is a double precision number.
27
Pointers This is simply the address of something.
ptr++ increments the pointer by the size of type pointed to. Similarly for pointer arithmetic: ptr + 2 compiles as ptr + 2 * sizeof(type)
28
Arrays Index 0 is the first element
int foo[N] allocates foo[0], …, foo[N-1] Elements are stored in row-major order. Elements in a row are next to each other. int array[column][row];
29
Characters and Strings
char represents a single letter, digit or symbol. May be signed or unsigned when not specified, depending on the compiler. A string is an array of characters terminated by a character with a binary 0 value. A string cannot contain a binary 0 (duh!).
30
Enum Short for enumerated type. A list of related constants.
Similar to a series of #define statements, except the compiler can automatically assign the numerical value.
31
Typedef Allows assigning a simple name to a complicated type.
32
Type casting Directs the compiler how to interpret or convert a variable. Of the form (type) Examples (unsigned) x (char *) p
33
Const Tells the compiler that a variable is not intended to be changed after initialization. const int ratio = 3;
34
Volatile Tells the compiler that a variable may change at any time.
This situation arises in embedded programming: The variable is an input port mapped to an address. The variable may be changed by an interrupt handler.
35
Register Tells the compiler that a variable is heavily used and suggests that it be kept in a register. This is mostly obsolete because compilers are now much better at code optimization and do not need the hint.
36
Void void is used when declaring functions to indicate it takes no arguments or returns no value. void is also used to declare a generic pointer to an unspecified type. Type cast it to use it to access data.
37
Struct Groups related variables together.
A union is a special form of struct which allows overlaying more than one variable definition on the same memory location.
38
Scope int programGlobalVariable; int function () { }
39
Scope static int fileGlobalVariable; int function () { }
40
Scope int function () { int functionLocalVariable; }
41
Scope int function() { if (foo == 0) { int blockLocalVariable; statement; } }
42
Scope int whichOneIsVisible; int function () { int whichOneIsVisible; statements }
43
Static static int fileGlobalVariable; int function () { static int persistentLocalVariable; }
44
Operators Unary Arithmetic Relational Logical Bitwise Assignment
Special
45
Unary Operators -a a++ ++a a— --a Get the negative of a
Get the value of a, then increment a Increment a, then take its value Get the value of a, then decrement a Decrement a, then take its value
46
Arithmetic Operators a + b a – b a * b a / b a % b
Get the sum of a and b Get the difference of b from a Get the product of a and b Get the quotient of b into a Get the remainder after dividing b into a
47
Relational Operators a == b a != b a > b a < b a >= b
True if a is equal b True if a is not equal b True if a is greater than b True if a is less than b True if a is greater than or equal to b True if a is less than or equal to b
48
Logical Operators a && b a || b !a (a) ? b : c
True if a and b are both true True if either a or b is true True if a is false; false if a is true If a is true, do b else do c
49
Bitwise Operators a & b a | b a ^ b ~a a << b a >> b
The bits of a anded with b The bits of a ored with b The bits of a exclusive ored with b The bits of a inverted a shifted left b bit positions a shifted right b bit positions
50
Assignment Operators a = b a += b a -= b a *= b a /= b a %= b
Assign b to a Add b to a Subtract b from a Multiply b to a Divide b into a Assign remainder of a / b to a Shift a left b bit positions Shift a right b bit positions And b to a Exclusive or b to a Or b to a
51
Special Operators sizeof(a) &a *a a.b
Get the number of bytes occupied by a Get the address of a Get the data at the address in a Get member b of data structure a
52
More Special Operators
a[b] a->b , Get element b of array a, short for *(a+b) Get member b of data structure at the address in a; short for (*a).b Evaluate a series of expressions from left to right; the value is that of the rightmost expression
53
Operator Precedence There are way too many levels of precedence.
Some of them do not make sense. Find a precedence chart you like and keep a copy of it handy. When in doubt, use parenthesis, but too many of them makes code difficult to read.
54
Operator Precedence Example
100 – 25 * 3 % 4 100 – 75 % 4 100 – 3 97
55
Truth table for NOT P NOT P 1
56
Truth table for AND P Q P AND Q 1
57
Truth table for OR P Q P OR Q 1
58
Truth table for EXCLUSIVE OR
P Q P XOR Q 1
59
Flow of Control if (foo == 0) doSomething();
if (foo == 0) doSomething(); else doTheOther();
60
Flow of Control while (foo == 0) doThisSeveralTimes();
do doThisSeveralTimesButAtLeastOnce(); while (foo == 0);
61
Flow of Control for (initialization; condition; step) doThisSeveralTimes(); is equivalent to initialization; while (condition) { doThisSeveralTimes(); step; }
62
Flow of Control switch (foo) { case 0: doSomething(); break; default: otherwiseDoThis(); }
63
Functions Standard C requires functions be defined before they are referenced, or a function prototype be provided. Arduino C automatically generates function prototypes.
64
the "standard library“ This was originally the set of UNIX system calls “Compatible” compilers supported them so that code can be ported from UNIX to more systems. Useful for formatting, data conversion, math functions. Not so good for memory management on the Arduino.
65
a little bit of C++ A class is a struct with added features.
Hidden data members. Methods are functions to manipulate the object. Some Arduino library code such as Serial uses C++ classes. Serial.print
66
language traps to avoid
I can write an entire book on why C is not my favorite programming language, but it is what it is = versus == Forgetting break in switch // comment in #define Not understanding operator precedence
67
debugging techniques Unfortunately, there is no Arduino debugger
Use print statements Use Serial.print to display information Divide and conquer
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.