Файл: The quintessential PIC microcontroller (S. Katzen, 2000).pdf

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

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

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

Добавлен: 15.06.2025

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

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

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

120 The Quintessential PIC Microcontroller

[W] Higher than or equal

[f]

: [W]−[f] gives no borrow; (C = 1).

[W] Equal to

[f]

:

[W]−[f] gives Zero;

(Z = 1).

[W] Lower than

[f]

:

[W]−[f] gives a borrow;

(C = 0).

Consider as an example a fuel tank with a capacity of 255 liters, with a sensor at the bottom of the tank indicating the remaining volume of fuel as a linear function of pressure. Assume that the sensor represents the capacity as a byte that can be accessed at Port B (see page 95), which we give the name FUEL. We wish to write a routine that will light an ‘empty’ light (at bit 0 at Port A) if the capacity is below 20 liters and ring an alarm buzzer (bit 1 at Port A) if below 5 liters. Both output peripherals are active on logic 0. This is how it could be coded:

STATUS

equ

3

;

File

3 is the Status register

C

equ

0

;

Bit0

is the Carry flag

Zequ 2 ; and bit2 is the zero flag

FUEL

equ

6

;

File 6 is

Port B

DISPLAY

equ

5

;

File 5 is Port A

LAMP

equ

0

;

Bit0 of

which is the warning lamp

BUZZER

equ

1

;

and bit1 is the buzzer

ALARM

movf

FUEL,w

; Read fuel gauge into W

addlw

-5

; W-5 to compare.

IF C==1 THEN

btfss

STATUS,C

; no borrow & FUEL HIGHER OR SAME

bcf

DISPLAY,BUZZER

; and sound buzzer

movf

FUEL,w

; Get fuel gauge again into W

addlw

-14h

; W-20 to compare.

IF C==1 THEN

btfss

STATUS,C

; no borrow & FUEL HIGHER OR SAME

bcf

DISPLAY,LAMP

; and light lamp

NEXT: .....

.....

; Continue

After each subtraction the Carry/borrow flag will be logic 1 (that is no borrow) if the datum in the Working register (the fuel reading) is higher or the same as the literal being subtracted – it is being compared with. The addlw -k instruction can be replaced by the more obvious sublw k.4 Remembering that this subtracts W from the constant, that is k − W, then the following Skip on Set (btfss) instructions must be replaced by Skip on Clear (btfsc) to give the same sense of magnitude.

The contents of the Working register can be tested for zero in the same way, that is addlw 0 or sublw 0. If W were zero then the outcome of this tstw type of instruction will set the Z flag. We have already seen that the instruction movf xx,f can be used in the same way as a tst f instruction to test File xx for zero. Note the use of the bcf (Bit Clear in File) instruction to clear the appropriate bit in Port A, which we assume to

4The Compare instruction of most MPU/MCUs is a subtract which sets the flags in the appropriate way, but which ‘throws away’ the di erence outcome; that is does not overwrite the operand. A type of non-destructive subtract.


THE ESSENCE OF THE PIC MICROCONTROLLER 121

be initially set to output. In the same manner the bsf instruction could be used to turn o the lamp and buzzer at the beginning of the routine, as shown on page 125.

Logic and Shifting instructions

All four basic logic operations are provided, as shown in Table 5.3. The simplest of these is comf which inverts (or 1’s COMplements) all bits in a file register. For example:

10001110

comf22h,f

01110001

File 22h

File 22h

Alternatively the outcome can be placed in W with the original contents being unchanged; eg. comf 22h,w. There is no instruction comw to explicitly invert the contents of the Working register, but this can be accomplished in one bus cycle by subtracting from 11111111b; eg. sublw 0FFh: For example:

11111111

Literal 0FFh

− 10001110

Working register

01110001

1’s complement of W

Table 5.3: Logic instructions.

Flags

Operation

Mnemonic

Z

DC

C

Description

AND

Logic bitwise AND

Literal to

andlw k

[W] <- [W]

#kk

W

·

to File

W

andwf

f,d

[d] <- [W]

· [f]

Complement

Invert or NOT (1’s complement)

File

comf

f,d

[d] <-

[f]

Inclusive-OR

Logic bitwise inclusive-OR

Literal to

W

iorlw k

[W] <- [W] + #kk

W

to File

iorwf f,d

[d] <- [W] + [f]

eXclusive-OR

Logic bitwise exclusive-OR

Literal to

xorlw k

[W] <- [W]

#kk

W

to File

W

xorwf

f,d

[d] <- [W]

[f]

Rotate file shift

Circular shift into Carry

Left

rlf

f,d

b7

C

7

file

0

Right

rrf

f,d

b0

7

file

0

C

·

Boolean bitwise AND

+

Boolean bitwise inclusive-OR

Boolean bitwise exclusive-OR

[f]

Bitwise inverse of the file contents

The andwf instruction bitwise ANDs the Working register together with the contents of any file register, with the outcome being placed either in that same file or in W. Similarly the andlw instruction bitwise ANDs W with a byte literal.


122 The Quintessential PIC Microcontroller

ANDing an input with a 0 always gives a 0 output, whilst with a 1 does not change the logic value. For example:

10001110

andlw 0Fh

00001110

W

W

which zeros the upper nybble of the Working register. ANDing is normally used to clear any bit or bits in the destination operand. Thus andlw b’00000011’5 clears the upper six bits in the Working register and leaves the lower two bits untouched. Of course, the bcf instruction can be used to clear a single bit in a file register.

Another use of ANDing is to check the state of any bit or bits in a datum; for example:

andlw

b’11000000’

; Check bits 7 &

6

btfsc

STATUS,Z

;

IF not both

zero

THEN skip

goto

ALL_ZERO

;

ELSE == 00,

so

go to ALL_ZERO routine

By ANDing the Working register with 11000000b, the outcome will be all zero only if both bits 7 and 6 of W are 0. In this case the Z flag will be set and the following Bit Test File Skip on Clear will not be taken and the program will transfer to ALL_ZERO. If a single bit in a file register is being tested for zero then the btfsc instruction (see Table 5.4) is a more e cient process.

The iorwf and iorlw instructions implement the Inclusive-OR operation in the same way as for AND. ORing with a 0 leaves the source bit unchanged whereas ORing with a 1 sets the bit to a 1 irrespectively. Thus ORing is normally used to set any group of bits in the destination operand. For example:

10001110

iorlw 03

10001111

W

W

sets the two least significant bits to one.

The xorwf and xorlw instructions provide for the eXclusive-OR operation. You will recall from page 14 that XORing with a 0 leaves a data bit unchanged, whilst XORing with a 1 inverts (or toggles) that bit. Thus, for example if we wished to invert both bits 0 and 7 of W:

For example:

10001110

xorlw 81h

00001111

W

W

Another use for XOR is to isolate changes between two bit patterns. From the truth table on page 14 we see that only when the two inputs di er is the output 1. Consider as an example a program routine that continually monitors Port B to which has been connected eight switches. This routine is waiting until someone moves a switch.

5Notice the assembler notation used to represent numbers in binary, see page 223.


THE ESSENCE OF THE PIC MICROCONTROLLER 123

START

movf

PORTB,w

; Get initial state of switches

movwf

20h

; Put away at File 20h

S_LOOP

movf

PORTB,w

; Sample switches

xorwf

20h,w

; Check for alterations

btfsc

STATUS,Z

; Skip out if check gives non zero

goto

S_LOOP

; ELSE check again

Two possible scenarios are:

10011110

xorwf 20h,w

10011110

W

File 20h

10001110

xorwf 20h,w

10011110

W

File 20h

=

00000000

W

Z = 1

=

00010000

W

Z = 0

The outcome in W reflects any changes. In the first case there are no di erences between the latest sample and the original switch settings put away in File 20h. In the second situation Switch 4 has just been thrown from 1 to 0. You can determine which switch changed by shifting the outcome (the change byte) right, counting until the residue is zero. You can also determine the type of change (0 → 1 or 1 → 0) by ANDing the change byte to the original switch settings in File 20h, i.e. andwf 20h,w. If the outcome at bit 4 is a 0, then the change must have been 0 → 1, and vice versa.

The PIC 12/14-bit cores have two instructions which can shift a datum byte in a file register one place left or right. Both rlf and rrf are known as Circular or Rotate instructions. These shift left or right respectively with the incoming bit injected in from the Carry flag and outgoing bit popped out into the same C flag. This circular action is emphasized in Fig. 3.7 on page 61.6

One use of the shifting operation is to bitwise examine a datum. Suppose you want to determine the position of the leftmost logic 1 bit in File 20h, with this information being put in the Working register. For example, if the pattern is:

00101111

File 20h

00000101

W

(bit 5)

This can be realised by continually shifting the pattern under investigation right, counting the number of times until the residue is zero. The coding given in Program 5.4 uses the Working register as a counter. The data byte in File 20h is successively shifted right and the count incremented. As the Carry flag is cleared each time before the shift, logic 0s are brought in from the left.7 Eventually the residue will become all zeros

6The PIC17CXXX series use the mnemonics rlcf and rrcf for Rotate Left/Right through Carry. The change allows for rlnc and rrnc for Rotate Left/Right Not through Carry.

7MPU/MCUs that have Logic Shift instructions always shift in 0s irrespective of the state of the C flag.


124 The Quintessential PIC Microcontroller

and the process terminated. Thus 00010111 (1) 00001011 (2)

00000101 (3) 00000010 (4) 00000001 (5) 00000000.

Program 5.4 Shifting to find the highest set bit.

; Data is

in File 20h, position of highest set bit to be in W

HIGH_BIT

clrw

; Zero the count

; WHILE data is

not zero,

shift right and increment count

HLOOP

bcf

STATUS,C

; Carry flag cleared

rrf

20h,f

; Shift rightmost bit into Carry

btfsc

STATUS,Z

; IF not zero THEN continue

goto

FINI

; ELSE exit

addlw

1

; Continue by adding one to count

goto

HLOOP

; and do another shift

FINI

..... ......

Shifting right pops out the rightmost bit into the Carry flag. Replacing btfsc STATUS,Z by btfsc STATUS,C would determine the position of the rightmost bit. In many situations repetitively shifting into the Carry flag can be used to examine the data on a bit by bit basis. For instance, we could modify our program to totalize the number of set bits in the byte, as in Program 5.5.

Program 5.4 did not distinguish between no bits set (00000000b) and bit 0 set (00000001b). How could you modify the program to do so?

The Rotate instructions can be used for multiple-precision shifting operations. Remembering that a Rotate takes in the Carry bit and in turn saves its ejected bit in C, consider as an example a 24-bit word stored in

the data store at

24

File 30h

16

15

File 31h

8

7 File 32h 0

which can be shifted

right once by the sequence:

bcf

STATUS,C

; Zero Carry

0

C

rrf

30h,f

;

0

File 30h

b16

C

File 31h

b8

rrf

31h,f

;

b16/

C

C

File 32h

rrf

32h,f

;

b8 /

C

b0

C

Consider that we wish to count the number of bits set to 1 in this triple-byte datum. One solution is shown in Program 5.5. Here the 24-bit word is shifted right (it could equally well have been left) until the word is all zero with the state of the Carry flag controlling the incrementation of the Working register. The multiple-precision zero test is implemented