ESE 123
Prelab 9
Stopwatch
Objec&ves:
In this prelab we will:
• Learn how to divide integer numbers
• Learn about IF condi@onal construct in C
• Learn how to write code to read pushbuBons
Integer division:
C is a typed language − numbers can be of an integral type (i.e. integers in all their various flavors − char, int, long, etc.), or of a floa@ng point type (float, double, and the like). The ‘/‘ division operator acts differently depending on its arguments. If at least one argument is a floa@ng point number, the ‘/‘ operator will return a floa@ng point results. For instance 5.2 / 4 would return a floa@ng point result (1.3) because 5.2 is a float.
Recall that most numbers can not be represented perfectly as floa@ng point numbers. For instance, 1/3 cannot be represented perfectly as a finite length decimal number. The closest we can do is 0.333 where the bar indicates repea@ng digits. Not so obvious is that 1/5 can be perfectly represented as a decimal number (0.2), but not as a binary float (0.00110011). The closest representa@on of 0.2 in a 32 bit binary float is
0.20000000298023223876953125. This means that:
5/1 × 5
Is not going to be exactly equal to 1. This can cause real problems in programming where you might have a loop that increments by 0.2 each @me and you expect the result to be exactly equal to 1 a\er five passes. Addi@onally, floa@ng point numbers take more space to store and take longer to process than integers.
There are advantages to handling the division of integers exactly. That is why C includes two mathema@cal operators for integer division: integer division produces an integer quo@ent and the modulo func&on returns the remainder of a division.
Integer division means that the dividend is divided by the divisor and any frac@onal part is simply thrown away. 15/3 is 5 in integer division, but 16/3 and 17/3 are also 5 in integer division.
The modulo func@on, denoted by the ‘%’ operator ignores the quo@ent, but returns the remainder. 15%3 is 0 because there is no remainder. 16%3 is 1, 17%3 is 2, and 18%3 is back to 0.
We have seen that the ‘/‘ operator returns a float if either argument is a float. If both arguments are integral types the ‘/‘ operator performs integer division.
Checking bu:ons:
A look at the schema@c diagram at the end of this document shows three buBons SW1 (labeled UP), SW2 (OK), and SW3 (DOWN). These are all connected to PORTE of the microcontroller. We have set up the microcontroller to make these inputs with a weak pull-up. This means that there is a resistor connected internally to +5V in the microcontroller so that the input will read as a logical 1 if nothing else is going on.
However, pushing the buBons can change that. The buBons are configured to short the input to ground thus forcing the input to a logical 0.
The switches are connected to the three least significant bits of PORTE: PE2 (DOWN), PE1 (OK), and PE0 (UP). We wish to check the condi@on of one switch at a @me and ignore the other bits of PORTE.
A two input AND logical func@on takes two bits in and generates one bit out. The output bit is TRUE (logical 1) if both of the inputs are TRUE. If any input is FALSE (logical 0) the output is FALSE.
The arithme@c logic unit (ALU) on our chip is 8 bits wide. That means that it contains 8 separate AND gates. Each AND gate takes one input from one operand and the other from the corresponding bit of the other operand.
Say we want to see if the UP buBon is pressed. This is connected to PE0 − the least significant bit of PORTE. If it is pressed PE0 will be a logical 0. If it is not pressed PE0 will be a logical 1.
If the UP buBon is pressed (PORTE_IN bit 0 is low) and we perform. this AND opera@on:
PORTE_IN 0b11011110
AND 0b00000001
0b00000000
The result is zero. Now suppose the buBon is the released and PORTE_IN bit 0 will be high:
PORTE_IN 0b11011111
AND 0b00000001
0b00000001
There are the only two possibili@es if we AND with PORTE_IN with 0b00000001. Zero if the buBon is presses and non-zero if it is released. The other bits of PORTE_IN have no bearing on the result.
This is called masking and it allows us to use the AND opera@on to ignore everything except for the bit or bits that interest us. If we were interested in isola@ng the OK buBon (PORTE_IN bit 1) we would AND PORTE_IN with 0b00000010 and the result would strictly depend on the OK buBon − we would get 0b00000000 if the buBon was pressed and 0b00000010 if not.
In C the bitwise AND operator is denoted with a single & symbol (the logical AND operator is denoted with two && symbols). The C code to mask the OK buBon would be:
PORTE_IN & 0b00000010
IF structure:
C can make decisions. You might want to check for equality in an IF structure. In this case you’ll need the ‘==‘ operator. In C the ‘=‘ operator is an assignment operator (it takes the data on its right side and stores it into the memory loca@on on the le\ side). The ‘==‘ is a rela@onal operator, it returns TRUE if the things on its right and le\ sides have the same value. If we wanted to check to see if a variable called test is equal to one:
There are @mes where you may need an ELSE clause. The code following the ELSE
executes only if the preceding IF was NOT performed. This allows us to run different
code depending on the state of something. In this example, we are checking to see if a buBon is pressed:
In this case we are checking the status of the UP buBon (PE0). PORTE_IN is ANDed with 0b00000001 so that only the rightmost bit of PORTE_IN (PE0) has any effect. If this
buBon is pressed the code following the IF will run. The ELSE code will run if the buBon is released. The ELSE code is op@onal.
You can test for OK buBon presses by just ANDing with a different constant. Use 0b00000010 for the OK buBon and 0b00000100 for the DOWN buBon.
You may place any C statement inside an IF statement. This includes … other IF statements. Consider the example below:
In the example above, the IF statement for b is inside the IF statement for a. If a is not equal to 1, the value of b will not be checked. If a is equal to 1, then if b is checked and, if it is equal to 1, the code in the nested IF statement will run. This arrangement is useful if you want something to happen only if two condi@ons are TRUE. If either a or b is not equal to 1, nothing happens.
Report:
Write a report with the answers to the following ques@ons:
1. What is 75 / 54 using integer division? (2 points)
2. What is 75 % 54? (2 points)
3. The modulo operator can be useful in an IF statement. Imagine that char variable X has already been declared. Write an IF statement that subtracts 1 from X if X is odd. Note that X%2 will be 1 if X is odd and 0 if X is even. (4 points)
4. Con@nuing with the previous ques@on, write an IF…ELSE statement that adds 2 to X if X is even, and subtracts 1 if X is odd. (4 points)
5. Write C masking code that will return a 0 if the DOWN buBon is pressed, and anything else if it is released (see the schema@c diagram at the end this document). (2 points)
6. Assume a char variable called hr has been declared. Write a C IF statement that subtracts 1 from hr if the DOWN buBon is pressed. (4 points)