ES101 - Lesson 2 : printf

From Embedded Systems Learning Academy
Jump to: navigation, search

Pre-Requisite

You need to read these article(s) to get an idea of where to write your code:

Lecture

Variable Types & ASCII Table

Before learning about how to perform input/output using the microcontroller, you need to first learn about declaring and using variables. In C Programs, variables are those that reserve memory space so that you can use that memory space by referencing it by a name. Common variable types are the following:

  • char - Used to declare a single character, 8-bit type
  • int - Used to declare an integer type (0, 1, 2 ... -1, -2 etc).
  • float - Used to declare decimal digit numbers (0.11, 341.231)

Have you ever heard the phrase “a little bit”? It comes from the computer world, because a bit is the smallest possible storage space. One bit can count from 0 to 1 since a bit can either be 0 or 1. Two bits can count from 0 to 3 (00, 01, 10, 11). Similarly, eight bits can count from 0-255 using the formula 2^8 -1. A char is the smallest storage space that can be allocated in a C program because it only uses 8-bits, however, it is usually not used for counting. Instead, it is used to store human readable characters. All the computers in the world use an ASCII table, which is a representation of an integer value corresponding to the ASCII character, which might be A, B, C, 1, 2, 3, <semicolon>, <question mark> etc.

Computers translate numbers to human readable characters using this ASCII Table

Each variable type has a limit to the minimum and maximum value that it can represent; shown in the next table are the limits of some variable types. The asterisk (*) represents that in a typical programming environment, like your PC, the number of bits may be different, however, due to 32-bit processor you may be using, it may use lower number of bits for some variable types. Note that the integer types can only hold whole numbers, whereas the floating-point type can hold decimal numbers, such as 1.23456. If you try to set an integer equal to a decimal number, the decimal portion is truncated. Also, due to the maximum precision possible using a 32-bit float, it can only hold up to six decimal places, such as 0.123456, however, if the left hand side increases in the value of the number, the right had side decimal precision is reduced. In conclusion, various variables are suitable for various scenarios, and it is up to you to choose the appropriate type of variable by determining if it will be for whole numbers, or decimal numbers, or for human readable ASCII characters.

Variable Type # Bits on 32-bit CPU Minimum Maximum Purpose
signed char 8 -128 +127 Human Readable Characters
unsigned char 8 0 255 Human Readable Characters
signed int* 32 -2,147,483,648 +2,147,483,647 Integers (whole numbers)
unsigned int* 32 0 4,294,967,296 Positive Integers (whole numbers)
float 32 -3.4028234 × 10^38 3.4028234 × 10^38 Fractional numbers

Variable Declaration

A variable must be declared before it can be used. To declare a variable, you simply specify the type, and the variable name. A meaningful name should be given to your variables. A variable name cannot contain spaces, and must start with a letter or underscore. Using a floating-point numbers is discouraged unless necessary because it is typically very slow to process floating-point numbers (such as add or divide) when compared to integers. Below are some examples of variable declarations.

/* ALWAYS set variables to 0 when declaring them */
int i;             // Declare UNINITIALIZED variable i (not recommended)
float myFloat = 0; // Declare fractional number and set to 0
int myInt = 3;     // Declare signed int and set to to 3


Operators

C/C++ has many "operators", but here are the basic assignment operators and examples:

int my_int;
my_int = 1;      // Assignment
my_int = 1 + 2;  // Addition
my_int = 2 - 1;  // Subtraction
my_int = 2 * 2;  // Multiplication
my_int = 2 / 1;  // Division
my_int = 3 % 2;  // Modulus (covered in later lab)

Operator Precedence

Operator precedence for +, -, *, / describes the order of evaluation. Multiplication and division take precedence over addition or subtraction. Operators with the same precedence are evaluated from left-to-right. Parenthesis can be used to change and/or clarify the order of precedence, just as in math equations.

int my_int;
my_int = 1 * 2 + 3 * 2 / 1 - 3 + 2 * 3;

// Apply precedence rules:
my_int = (1 * 2) + (3 * 2 / 1) - 3 + (2 * 3);

// Simplify
my_int = 2 + 6 - 3 + 6;

Operator Shortcuts

You can also use shortcuts to use common techniques used in programming. See examples below

int x = 1;
x += 2; // same as x = x + 2
x -= 1; // same as x = x - 1
x /= 1; // same as x = x / 1
x *= 2; // same as x = x * 2

x++; // same as x = x+1
x--; // same as x = x-1


Variable Assignment

First, a variable must be declared before it can be used. Variables can be assigned a value either when declared, or anytime as part of a line of code. The important note to remember is that you should only assign the value that is intended for the variable type. For example, you should not try to assign a value greater than 255 to a char, or a value greater than 2,147,483,647 to a signed integer type.

The variable assignment is straight forward except for character data types. Since the character data type typically uses ASCII table, you have to inform the compiler of the assignment type.

char my_char_1 = 'A'; // ASCII must be in single quotes
char my_char_2 = 65;  // Same assignment as previous line of code
// From the ASCII Table, remember that 'A' is the value of 65

Let's work with more assignments. Notice that when truncated_result is set to 1.23, but since it cannot hold decimal numbers, the decimal portion is simply and actual assignment is rounded down to the value of 1.

char my_int = 1;
my_int = my_int * 5;

float my_float = 2;
my_float = (1.22 / 2.34) * 100;

int truncated_result = 1.23.


printf

The printf function can be used to output information from a program. In this class, the processor outputs the printf data to the USB Port, and you will open the USB Port in Hercules to view the data. But if you were writing your code on Windows PC, a DOS-based window would output the data.

printf is used to output a string, or text, to the screen in addition to character variables, integer numbers, and floating point numbers. printf translates a number‟s representation using the ASCII table and outputs the results. See the next section on how to output one or more integers on the screen.

char my_int = 1;
float my_float = 2;

printf("Value of my_int = %i\n", my_int);     
// In place of %i, printf prints value of variable after the comma

printf("Value of my_float = %f\n", my_float);
// Intuitively, just like %i prints integer, %f printf floating-point number

// Let's print them both using single printf:
printf("Value of my_int = %i and value of my_float = %f\n", my_int, my_float);
// The order of % should match order of variables on the right hand side after the comma

// printf() can also print any number, not just variables
// We can also tell printf() to print the result of a calculation
printf("%i + %i = %i\n", 1, 2, (1 + 2));

Normally, printf will output anything inside double quotes, except when it encounters the % symbol. When the % symbol is encountered, print doesn't print %i, but instead, looks on its right hand side to convert a number to its ASCII representation and prints out the number. The sequence of %i corresponds to the sequence of arguments given after the end of the double quotes. %i is to print an integer, however, if you wish to print other types of numbers, the %i needs to be changed. See the table below to find out the various different variables you can print. There are more specifiers, and you can reference your textbook for details.

Specifier Result
 %i Integer
 %u Unsigned Integer
 %f float
 %c char
 %s array of chars

Formatted printf

The printf can also print formatted numbers, or numbers padded with certain number of spaces. For example, you can print an integer specifying to consume at least 10 characters, so if a number is only 3 digits, it will pad with 7 spaces, and then print 3 numbers. Similarly, you can control how many decimals to print in a floating-point number. This can be accomplished by typing in a format specifier after the % symbol.

char my_int = 1;
float my_float = 2.345678;

printf("Padded Integer: %5i\n", my_int);      // Prints 4 spaces and then 1
printf("Formatted float: %0.2f\n", my_float); // Prints only 2 decimal digits

Note the characters \n were not printed to the screen. The character: \n has a special meaning – it tells printf to print a newline; that is, cursor is placed at the beginning of next line. The \ character is called an escape character, which tells printf do something out of ordinary. The following are some of the escape sequences:

Specifier Result
\n Newline
\\ Print single backslash
\" Prints double quotes
 %% Prints percent symbol


Assignment

To provide output from the Board to your computer's PC, you need to open Hercules Program at 38400bps by going to the Serial Tab. Also note that after you open the COM Port in Hercules, the reset button should be pressed on the Board.

  1. Declare and print a few char variables :
    • Declare a char variable and set it to the value of 75.
    • Declare another char variable and set it to the value of 'K'.
    • Print these variable using printf using %c and %i using a single printf statement.
      Example print-out: "The variables are K and K with integer value of 75 and 75"
  2. Design a midterm percentage calculator :
    • Declare "float" variables to hold the following information:
      Maximum score, user's score, and percentage
    • Set the maximum score variable to 50
    • Set the user's score variable to 45
    • Calculate the percentage, store it to the percentage variable and print it out.
      Note that you should only print 2 decimal digits of the percentage and also print the percent symbol :
      Example: "Based on 45/50, your percentage is: 90.00%"


Sample Code

int main()
{
    int my_integer = 0;

    printf("Hello World!\n");
    printf("My Integer = %i\n", my_integer);

    my_integer = my_integer + 4;
    printf("My Integer now: %i\n", my_integer);

    return -1;
}

Questions you need to answer during the demo

  • What is the output if you try to print an integer, but use %f instead of %i ?
  • What happens if you try to printf a variable that hasn't been declared?