Файл: Microcontroller Programming. Thi Micro Chip PIC (Julio Sanchez, 2007).pdf

ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 14.06.2025

Просмотров: 8570

Скачиваний: 0

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.

Digital Logic, Arithmetic, and Conversions

63

Note in Figure 4-3 that the contents of the carry flag are first copied to the low-order bit of the destination operand, then the individual bits of the source (in gray in the illustration) are shifted left and moved to the destination. Finally the high-order bit of the source is copied to the carry flag.

There are several possible variations of the rotate operation. The Intel microprocessors distinguish between arithmetic and logic rotates. In the arithmetic rotation the high-order bit is preserved in order to maintain the sign of the operand. The rotate shown in Figure 4-3 is the one most common in microcontroller hardware. Clearing the carry flag before the rotate takes place makes the operation identical to a shift.

4.3.2 Comparison Operations

An interesting property of subtraction is its use in finding the relative size of two operands. This interesting action of subtraction is based on the following logic:

1.If the result of a subtraction is zero, then both operands were of the same size.

2.If the result of a subtraction is a positive number, then the subtrahend was smaller than the minuend.

3.If the result of a subtraction is a negative number, the subtrahend was larger than the minuend.

In a binary/digital device the result of a subtraction operation can be determined by observing the flags. If the zero flag is set, then the operands were the same (case 1, above). If the carry flag is set, then the subtrahend was larger than the minuend (case 3, above). If neither the carry nor the zero flag is set, then resulting subtrahend was smaller than the minuend (case 2, above). Since all microcontrollers offer some mechanism for re-directing execution according to the state of the flags, a program can use subtraction to make these decisions.

The one objection to the use of subtraction in comparing the size of two operands is that the process will change one of them. To use subtraction in comparison operations the programmer has to find some way of preserving the minuend. Alternatively, some devices contain a comparison operator that sets the flags as if a subtraction had taken place but without changing the operands. High-end microcontrollers are equipped with dedicated comparison operators, but the middle- and low-range devices usually are not.

4.3.3 Other Support Operations

Midand high-range microcontrollers contain other auxiliary bitwise, arithmetic, and logic operators that can be useful to the programmer. These include instructions to:

1.Increment and decrement operands

2.Clear registers or storage locations

3.Swap nibbles

4.Clear and set individual bits

5.Test individual bits

64

Chapter 4

Usually instructions to increment and decrement and to test individual bits are also capable of redirecting execution according to the result. For example, a special decrement can be followed by a jump if decrementing sets the zero flag. Or a bit test instruction can include a jump that is taken if the tested bit is set or reset.

4.4 Unsigned Binary Arithmetic

Since microcontrollers are not used in data processing, microcontroller programming does not usually require the development of powerful or sophisticated numerical routines. At the same time, because microcontrollers often lack primitive support for even the most essential calculations, the programmer makes up for this deficiency. For example, mid-range PIC microcontrollers contain primitive instructions for signed and unsigned addition and subtraction of byte-size operands. Unsigned addition and subtraction operations that exceed one byte, as well as unsigned multiplication and division, must be provided in software.

In unsigned arithmetic all bits of the binary encoding are interpreted as magnitude bits and all numbers are positive. Addition of unsigned binary numbers is limited by the machine’s word size. For example, a mid-range PIC microcontroller performs unsigned addition on 8-bit operands. An overflow of the sum is reported by the carry flag set. In this case the carry flag clear indicates that the sum is within the storage capacity of the format. In unsigned arithmetic processing, routines for extending operations to multiple bytes are straightforward and relatively simple.

4.4.1 Multi-byte Unsigned Addition

Many microcontrollers are one-byte machines, so operands and results for arithmetic operations must be contained within eight bits. The largest unsigned value that can be represented in a single byte is the decimal number 255. But often applications require adding operands that are larger than a single byte and storing results that exceed this limit. In these cases multi-byte routines become necessary.

The simplest case is the addition of two unsigned byte-size operands whose sum exceeds 255 decimal. This case requires storing the result in a two-byte area and detecting those cases in which there is a carry into the high-order byte. In this case the largest possible operands for byte addition are the hexadecimal numbers FF. Addition is as follows:

Binary:

1 1 1 1 1 1 1 1

+1 1 1 1 1 1 1 1

---------------

11 1 1 1 1 1 0

C <=

In this example the symbol C <= represents a carry out of the high-order bit, the case when the sum exceeds the capacity of a single byte. In hexadecimal, the sum of HFF + HFF = H1FE. You can add two byte-size operands into a two-byte storage area by using byte addition to determine the low-order byte of the result and testing for a carry out of the high-order bit. If there is a carry, then the high-order byte of the result is 1; otherwise the high-order byte is 0.


Digital Logic, Arithmetic, and Conversions

65

first 4-byte

second 4-byte

possible

5-byte

operand

operand

carry

result

+

+

=

0

+

+

=

0/1

+

+

=

0/1

+

+

=

0/1

+

=

0/1

Figure 4-4 Unsigned Multi-byte Addition

The same logic can be generalized to add more than two byte-size operands as long as the storage area for the result exceeds the size of the operands by one byte. For example, two word-size operands (16 bits each) can be added into a 3-byte (24-bit) storage area, or two double-word operands (32 bits) into a 5-byte storage area. The general algorithm for multi-byte addition is shown in Figure 4-4.

The case shown in Figure 4-4 consists of adding two, 4-byte operands into a 5-byte sum. The addition of the first two operands assumes that there is no carry. In the remaining stages there can be a possible carry from the previous stage if the sum of the two byte-size operands, plus the previous carry, exceed the storage capacity of eight bits. The last byte of the result is determined solely by the possible carry from the previous stage.

In Figure 4-4 we see that multi-byte addition requires the sum of three values in all stages except the first and the last one. Some high-end microcontrollers have addition operators that accept a three-byte operand. Others have special addition opcodes that automatically add-in the carry flag. The latter operators are referred to as add-with-carry. However, in most lowand mid-range devices the software must take care of incrementing the sum if there is a carry from the previous stage. The actual multi-byte addition routines are developed in the context of programming the various microcontrollers, discussed later in this book.

4.4.2 Unsigned Multiplication

The case for multiplication cannot be generalized since high-end microcontrollers usually contain one or more multiplication operators; this is not the case in lowand mid-range devices. In the first case implementation is simply by using the correspond-


66

Chapter 4

ing operator. This section explains multiplication in devices that lack a dedicated multiplication operation code.

Arithmetically, multiplication is performed by repeated addition. The multiplier represents the number of times that the multiplicand must be added to itself. Therefore, 3 times 4 is the same as 3 + 3 + 3 + 3. This fact allows implementing multiplication routines in software as long as the device contains an addition operator. The logic is based on using the multiplier as a counter. This counter is decremented each time that the multiplicand is added to itself. The routine ends when the counter is exhausted, as shown in the flowchart in Figure 4-5.

START

A = MULTIPLICAND

B = MULTIPLIER

PERFORM P = A * B

P (PRODUCT) = 0

C (COUNTER) = B

YES

COUNTER = 0

DONE

?

NO

P = P + A

C = C - 1

YES

Figure 4-5 Unsigned Multiplication Flowchart

The beauty of the repeated addition algorithm is its simplicity and its main shortcoming is its slowness. An alternative way of performing multiplication is by shifting the bits of the operand. This method is based on the properties of a binary positional system, in which the value of each digit is a successive power of 2. Therefore, by shifting all digits to the left, the value 0001B (1 decimal) successively becomes 0010B (2 decimal), 0100B (4 decimal), 1000B (8 decimal), and so on.

Binary multiplication by means of bit shifting has the downside that the multiplier must be a power of 2. Otherwise, the software must shift by a power of 2 that is smaller than the multiplier and then add the multiplier as many times as necessary to complete the product. In this manner, to multiply by 5 we can shift left twice and add once the value of the multiplicand. To multiply by 7 we would shift left twice and then add three times the value of the multiplicand. As the multiplier gets larger and more distant from the smaller power of 2, the number of addition operations required is also larger, and the effectiveness of the algorithm diminishes.


Digital Logic, Arithmetic, and Conversions

67

A third approach is based on the manipulations performed during longhand multiplication. For example, the multiplication of 00101101B (45 decimal) by 01101101B (109 decimal) can be expressed as a series of products and shifts, in the following manner:

0 0 1 0

1

1

0

1

B = 45 decimal

times

0 1 1 0

1

1

0

1

B = 109 decimal

-----------------

0

0

1

0

1

1

0

1

0

0

0

0

0

0

0

0

0

0

1

0

1

1

0

1

0

0

1

0

1

1

0

1

0

0

0

0

0

0

0

0

0

0

1

0

1

1

0

1

0

0

1

0

1

1

0

1

0

0

0

0

0

0

0

0

-------------------------------

0 0 1 0 0 1 1 0 0 1 0 1

0

0

1

B = 4905 decimal

The actual calculations in this method of binary multiplication are quite simple since the product by a 0 digit is zero and the product by a 1 digit is the multiplicand itself. Consequently, the multiplication routine simply tests each digit in the multiplier. If the digit is zero no action need be performed; if the digit is one, the multiplicand is shifted left and added into an accumulator.

The storage allocation to hold the product of a multiplication operation is not the same as that to hold the sum. In multi-byte addition one additional byte is required to hold the sum. In multiplication the storage allocation must be twice the size of the operands. For example, byte multiplication requires a two-byte storage, while multiplying two double-byte operands requires a four-byte storage allocation.

4.4.3 Unsigned Division

If multiplication can be reduced to repeated addition, then division can be conceptualized as repeated subtraction. In the case of division, the quotient (result) is the number of times the divisor must be subtracted from the dividend before zero or a negative value results from the subtraction. The flowchart in Figure 4-6 (in the following page) shows the logic steps in unsigned division.

In Figure 4-6 note that the logic tests for a zero divisor, since division by zero is mathematically undefined. Also, since the operation is unsigned, the result cannot be negative; therefore, the divisor must be larger than the dividend. Finally, the logic must consider the case in which subtracting the divisor from the reminder produces a negative value, in which case an adjustment is necessary to produce a valid quotient. This adjustment avoids the need for searching for a trial divisor, as in the case in the common longhand division algorithm. In machine code the negative result is detected as an overflow (carry flag set) from the subtraction.

4.5 Signed Binary Arithmetic

In two’s complement and sign-magnitude representations the high-order bit represents the sign of the operand, while its magnitude is represented in the remaining bits. Therefore, in the case of signed numbers, a carry out of the high-order bit is meaning-