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

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

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

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

Добавлен: 14.06.2025

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

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

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

58

Chapter 4

but by selecting the XOR mask, the programmer can control which bits of the operand are inverted and which are preserved.

In this manner it is possible to invert the four high-order bits of an operand by XORing with a mask that has these bits set. If the four low-order bits of the mask are clear, then the original values of the bits in the other operand are preserved in the result. For example:

hexadecimal

binary

55

0101

0101

XOR

F0

1111

0000

mask

----

---------

A5

1010

0101

In the previous example, the XOR operation inverts the bits that are 1 in the mask and preserves the bits that are masked 0. Consequently, the XOR mask 11110000B inverts the four high-order bits.

4.1.4 Logical NOT

In contrast with the other logical operators which require two operands, the NOT instruction acts on a single value. Its action is consistent with a Boolean NOT function, which converts all 1-bits to 0 and all 0-bits to 1. Arithmetically, the result is the one’s complement of the original value. This instruction can be useful in obtaining the two’s complement representation by performing the logical NOT and then adding one to the results.

4.2 Microcontroller Arithmetic

Microcontrollers are not designed for intensive numeric processing; therefore, they are not equipped with many arithmetic operators usually found in microprocessors. A typical mid-range microcontroller has instructions to add and subtract integers and perhaps to increment and decrement. Hardware multiplication is rarely available and even more so is division. Likewise, there is usually no hardware support for decimal and floating-point arithmetic. For this reason the microcontroller programmer is often challenged to provide most arithmetic and data processing operations in software.

In this discussion we assume a mid-range microcontroller, such as the PIC 16f8x. These devices contain primitives for adding and subtracting integers, shifting and rotating bits, incrementing and decrementing machine registers, some support for decimal operations and conversions, as well as the basic logic primitives AND, OR, XOR, and NOT. Multiplication and division operators, as well as floating-point operators, are not available in the mid-range devices.

4.2.1 Unsigned and Two’s Complement Arithmetic

In Chapter 3 we discussed the various representations for signed and unsigned binary and decimal numbers. Arithmetic operations of unsigned operands are the simplest. In this case we assume that the encoding always represents a positive number and that all bits relate to the number’s magnitude.

Digital Logic, Arithmetic, and Conversions

59

Unsigned arithmetic can be binary or decimal. In a machine with 8-bit words binary arithmetic on unsigned numbers use the entire range of the format. This is true even when the primitive operations are valid in two’s complement form; in fact, it is one of the great advantages of two’s complement representation. Table 4.1 shows a 4-bit binary in several numeric formats.

Table 4.1

Interpretations of 4-bit Binary Numbers

DECIMAL VALUES

BINARY

1’S COMPLEMENT

2’S COMPLEMENT

UNSIGNED

0111

7

7

7

0110

6

6

6

0101

5

5

5

0100

4

4

4

0011

3

3

3

0010

2

2

2

0001

1

1

1

0000

0

0

0

1111

-0

-1

15

1110

-1

-2

14

1101

-2

-3

13

1100

-3

-4

12

1011

-4

-5

11

1010

-5

-6

10

1001

-6

-7

9

1000

-7

-8

8

Assume a machine with a 4-bit word size and consider addition of two unsigned numbers:

BINARY

DECIMAL

0111

7

+ 0110

6

------

----

1101

13

Note, in the previous example, that if the encoding were in two’s complement form, the addition of the positive values 6 plus 7 would produce a result that overflows the capacity of the representation. In 4-bit two’s complement representation there is no way of encoding the value 13.

The question that arises is: in a device that performs two’s complement addition, must we always assume that the operands are in two’s complement form? The answer is: no. Signed addition of two’s complement operands and the unsigned addition of integer operands can be performed with identical processing and by the same electronic circuitry. It is the software that must take into account the encoding of the operands in order to interpret the results. For example, in the 4-binary digit device previously considered, the two’s complement addition of the values 6 and 7 produce an overflow, which can be detected by observing the change in the high-order bit (the sign bit) of the result. Therefore, in this case, the result of the addition operation is invalid. However, if the same decimal values represent unsigned operands, then the addition of 7 plus 6 produce the valid result 13. In either case the binary values of the operands, as well as the result, are the same.


60

Chapter 4

Microcontrollers usually support the fundamental operations of addition and subtraction on signed and unsigned integer operands with a single primitive operation. The addition and subtraction operators in lowand mid-range devices allow two operands. The more powerful microcontrollers support addition and subtraction of three operands, which is useful in implementing multi-digit routines. In either case, the software determines if the result is signed or unsigned by interpreting the changes in the high-order bit of the operands and by evaluating the status flags if these are available.

4.2.2 Operations on Decimal Numbers

Although microcontrollers are binary devices, the instruction set often includes operations for performing arithmetic on binary coded decimal numbers. In Chapter 3 we saw that BCD numbers can be stored in packed or unpacked form. In packed format two BCD digits are contained in each byte. The low-order BCD digit takes up bits 0 to 3 and the high-order BCD digit takes up bits 4 to 7. Unpacked BCD digits are stored one digit per byte; in this case the high-order nibble is unused. The packed and unpacked binary coded decimal formats can be seen in Figure 3-9.

Microcontroller designers usually adopt the packed BCD format for representing decimal operands. One advantage of packed BCDs is that the two decimal digits encoded in a single byte can be represented as hexadecimal digits. For example, the values H24 and H99 represent the packed BCD digits 24 and 99 respectively. Note that each hex digit is preceded by the letter H to indicate radix 16. In actual microcontroller programming other ways are often used for representing numbers in hexadecimal notation.

The addition and subtraction of decimal numbers represented in packed BCD can be performed with binary primitive operations, complemented with some additional adjustments. In some cases the addition of two BCD numbers in packed format may produce a valid result, for example:

H23

H31

H56

+

H12

H38

H22

----

----

----

H35

H69

H78

In the previous examples the results are valid because the sum of each digit does not exceed the range of the BCD format. However, the following additions do not produce valid BCD results:

H33

H31

H56

+

H27

H59

H27

----

----

----

H5A

H8A

H7D

In the case of the first operation the valid BCD result would be: 33 + 27 = 60, in the second one 31 + 59 = 90, and in the third one 56 + 27 = 83. A simple adjustment corrects the error, as follows:


Digital Logic, Arithmetic, and Conversions

61

H33

H31

H56

+

H27

H59

H27

---

---

---

H5A

H8A

H7D

+

H 6

H 6

H 6

---

---

---

H60

H90

H83

In all three cases adding 6 to the previous sum produces the expected result. The logic for deciding when the value 6 must be added is simple: if the sum of the low-order digit is greater than 9 or if the sum produced a carry out of the low-order nibble, then add 6 to the sum to perform the decimal adjustment. Some high-end microcontrollers contain a primitive instruction that executes the decimal adjustment automatically, that is, without having to test the sum. However, this instruction is not available in lowand mid-range devices.

Also note that the largest number that can be encoded in packed BCD format is the decimal 99. When adding two BCD digits the high-order digit of the sum cannot be greater than 9. If so, then the capacity of the format has been exceeded and the result cannot be adjusted by the simple addition of 6. Here again, a multi-byte processing routine can be developed in order to accommodate the result of BCD addition when the sum exceeds a single byte.

Many microcontrollers are equipped with a flag that indicates overflow from binary digit number 3. This flag, sometimes called the digit carry or the half carry flag, can be used to detect that a calculation has overflowed the storage capacity of four binary digits. The availability of this flag simplifies the logic necessary for adjusting binary addition of decimal operands since the value 6 must be added when the digit in the low-order nibble is larger than 9, or when there has been a carry to the next digit. The following flowchart shows this processing.

START

A = FIRST PACKED BCD

B = SECOND PACKED BCD

PERFORM C = A + B

LOW-ORDER NIBBLE

YES

C = C + 6

> 9

?

NO

LOW-ORDER NIBBLE

YES

OVERFLOW

?

NO

YES

HIGH-ORDER NIBBLE

ERROR

> 9

?

NO

END

Figure 4-1 Flowchart for Two-byte BCD Addition


62

Chapter 4

4.3 Bit Manipulations and Auxiliary Operations

In addition to basic logic and arithmetic, microcontrollers contain primitive operators to manipulate individual bits, to compare operands, to make decision based on the state of individual bits and flags, and to convert data to other formats. As always, presence or absence of some of these operations, as well as their degree of power and sophistication, varies with the individual microcontroller. In the following subsections we describe the most commonly available primitives.

4.3.1 Bit Shift and Rotate

The fundamental operators to shift and rotate are useful in developing BCD and binary arithmetic routines. One interesting use of bit shifting is in implementing binary multiplication and division routines.

Shift operations consist of transposing to the left or right all the bits in the operand. In microcontrollers the operand is usually a processor register. For example, after a right shift operation all the bits in the value 01110101B (75H) are moved one position to the right, resulting in the value 00111010B (3AH). Note that on a right shift the right-most bit disappears and a zero comes into the high-order bit. By the same token, in a left shift the high-order bit disappears and a zero comes into the low-order bit. Figure 4-2 shows the action of a left-shift operation.

7

6

5

4

3

2 1 0

lost

BEFORE SHIFT

bit

AFTER SHIFT

0

7 6 5 4

3

2

1

0

Figure 4-2 Left Shift Operation

The rotate operation differs from the shift in that in the rotate the low-order bit is either a copy of the high-order bit or of the carry flag. In the first case the operation is a pure rotate, in the second case the rotate is referred to as rotate-through-carry. Figure 4-3 shows the action of a left-rotate-through-carry flag.

7 6 5 4 3 2 1 0

FIRST STEP

CF 7 6 5 4 3 2 1 0

7 6 5 4 3 2 1 0

CF

SECOND STEP

Figure 4-3 Rotate-through-carry Left Operation