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

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

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

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

Добавлен: 15.06.2025

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

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

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

112 The Quintessential PIC Microcontroller

TEMP[i] - MAXIMUM

skip

No

btfss

STATUS,NB

Borrow?

goto

NEXT

(TEMP[i]>=MAXIMUM)

{MAXIMUM=TEMP[i]}

NEXT

MAXIMUM = TEMP[i]

Yes (TEMP[i]<MAXIMUM) goto

NEXT

Fig. 5.3 The ith section of the compare-update sequence.

ment in the temperature array is tested each time. A much more e cient approach is to execute this sequence inside a loop and use an advancing pointer to target Temp[i] as the process unfolds. This technique leads to the task list:

1.Clear Maximum.

2.Point to Temp[0] (i = 0).

3.DO

(a)IF Temp[i] > Maximum THEN Maximum = Temp[i].

(b)Increment i.

(c)Repeat WHILE i < 24.

4.End.

The implementation of Program 5.2 uses the same compare-update sequence, but this time with the Indirect address mode to access the data byte Temp[i]. The contents of the File Select Register here holds the address of Temp[i] and is initialized in Task 2. After each loop pass, this pointer is incremented and then compared by subtraction from the first address beyond the array; that is TEMP_0 + 24. If they are equal then the Z flag will be set and the goto LOOP instruction skipped over out of the loop.

This Indirect mode coding takes 14 instructions; that is 10% of the linear version. However, it does take rather longer to execute, due to the overhead of incrementing the pointer1 and checking for range on each

1The PIC 17CXXX and 18CXXX series have auto incrementing and decrementing versions of Indirect addressing and more than one Indirect pointer register.

THE ESSENCE OF THE PIC MICROCONTROLLER 113

Program 5.2 Finding the maximum temperature using a loop structure.

INDF

equ

0

; INDirect File register

STATUS

equ

3

; Status register is File 3

FSR

equ

4

; File Status Register

TEMP_0

equ

30h

; Array starts @ File 30h

MAXIMUM

equ

48h

; Maximum value to be in File 48h

Z

equ

2

; Zero flag is bit2 of STATUS

NB

equ

0

; Carry/Not Borrow flag is bit0

; Task1: Clear maximum

MAX_DAILY

clrf

MAXIMUM

; Task2: Point to Temp[0]

movlw

TEMP_0

; Put address of first temp byte

movwf

FSR

; in the pointer register

;Task3: DO

;Task3A: IF Temp[i] > Maximum THEN Maximum = Temp[i]

LOOP

movf

MAXIMUM,w

; Get current maximum temperature

subwf

INDF,w

; Temp[i] - Maximum

btfss

STATUS,NB

; IF no borrow (NB==1) THEN update

goto

NEXT

; Skip update

movf

INDF,w

; Update by getting Temp[i]

movwf

MAXIMUM

; which is the new maximum

; Task3B: Increment i

NEXT

incf

FSR,f

; i++

; Task3C: REPEAT WHILE i <

24

movf

FSR,w

; Get pointer address

sublw

TEMP_0+18h

; Take away end address (Temp[24])

btfss

STATUS,Z

; IF equal THEN end

goto

LOOP

; ELSE repeat

; Task4: END

loop pass. The worst-case run time is 291 µs against 188 µs, assuming a 4 MHz crystal.

One advantage of the Indirect address mode is that the pointer address is eight bits wide. Thus it is not necessary to use the RP0 bit to switch between Bank 0 and Bank 1 of the Data store. The full 14-bit core model allows for four 128-byte banks of register files. The Status register of Fig. 5.1 shows the IRP (Indirect Register Page) bit which is used for family members with three or four register file banks. In such a device, if the temperature array of Program 5.2 were located in File 130h through File 147h then IRP would need to be set to 1 at the beginning of the routine (bsf STATUS,7) and cleared at the end. The rest of the code is unaltered. Microchip recommend that the IRP (and RP1) bits in


114 The Quintessential PIC Microcontroller

the Status register are left in their zero reset state in family members, such as the PIC16F84, that do not have data storage above Bank 1.

Bit

01 ?? nnn f

Four instructions (as specified by the two ?? bits above) either alter or test the state of a single bit within a register file. In this situation the instruction word has an embedded 3-bit code nnn defining the bit number from 0 through 7, as well as the file address coded in the normal way. Thus the instruction bcf 20h,7 (Bit Clear bit 7 in File 20h) is coded as 01 00 111 0100000. The other instructions are bsf (Bit Set in File, coded as 01), btfsc (Bit Test File and Skip if Clear, coded as 10) and btfss (Bit Test File and Skip if Set, coded as 11).

Absolute

10 ? aaaaaaaaaaa

Two instructions allow the program to jump to another instruction anywhere in the Program store. These are goto and call (CALL or goto a subroutine, see Chapter 6). The 14-bit core allocates eleven bits of the instruction word to this absolute instruction address2 in the Program store. Thus goto 400h would be coded as 10 1 10000000000. Similarly call 530h is 10 0 10100110000.

12 11

0

Program Countera a a a a a a a a a a

goto aaaaaaaa

7

4

3

0

PCLATH

File 0Ah

Fig. 5.4 Generating a 13-bit Program-store address for the goto and call instructions.

This 11-bit address can directly locate any instruction in a Program store of up to 211 = 2 Kbyte capacity. However, the mid-range core has

2Don’t confuse this with the register file address in the Data store – in the Havard structure the two stores are logically distinct with di erent address spaces.

THE ESSENCE OF THE PIC MICROCONTROLLER 115

a 13-bit Program Counter which can potentially address a Program store of up to 8 Kbyte instructions; for example the PIC16C74 has a 4 Kbyte store. To cope with this situation, when a goto or call instruction is executed, the absolute 11-bit address is transferred into the PC together with bits 3:4 of the PCLATH (Program Counter LATch High) to make up an e ective 13-bit Program-store address. This process is shown in Fig. 5.4

– see also Fig. 4.3 on page 86.

PCLATH is cleared on Reset, so the goto range is normally 000 – 7FFh. This covers all the address range for a 2 Kbyte store. For members with larger Program stores then a far goto and far call (i.e. beyond 7FFh) has to be implemented by twiddling bits PCLATH[4:3]. For example, in the PIC16C74 a goto 800h is coded as:

bsf

PCLATH,3

;

Make PCLATH(4:3) = 01

bcf

PCLATH,4

goto

800h

;

Go to it!

So far we have classified instructions by the method they pin-point their operands. The alternative approach is to catalog the instruction set by function. On this basis the 14-bit core PIC’s instruction set can conveniently be divided into six groups, of which four will be examined here. Those relevant to subroutines and interrupts are listed in the next two chapters, and control instructions pertaining to internal operation of the MCU hardware are left to Chapter 10. The complete instruction set is given for reference in Appendix A on page 475.

Movement instructions

Around one in three instructions move data around without alteration. With this in mind the instructions in Table 5.1 will be the most used in the repertoire.

All three Move instructions can copy byte data to or from the Working register.

Table 5.1: Move instructions.

Flags

Operation

Mnemonic

Z

DC

C

Description

Move

Copies a datum byte

Literal to W

movlw

k

[W] <- #kk

File

movf

f,d

[d] <- [f]

W to file

movwf

f

[f] <- [W]

Swap

Interchanges file nybbles

File

swapf

f,d

[d] <- [F(3:0)][F(7:4)]

• Flag not a ected W Working register [ ] Contents of

#kk 8-bit constant

√ Flag operates in the normal way

fFile register

dDestination, W or a file register


116 The Quintessential PIC Microcontroller

movlw copies the specified 8-bit constant (or literal) to W. For example, movlw 80h initializes W to 10000000b. This instruction only a ects the Working register and thus cannot be used directly to set up a file register to a constant value.

movwf is used to copy out or store the contents of W into a register file. For example, the following code fragment will initialize the contents of

File 22h to 80h:

movlw 80h ; Set contents of W to 80h movwf 22h ; and copy to File 22h

movf can copy (or load) the contents of any register file into W. For example, movf 22h,w loads W with the contents of File 22h.

The destination of this instruction can also be the file itself, giving rise to seemingly useless instructions, such as movf 22h,f which copies the contents of File 22h back on top of itself! However, the process does activate the Z flag, which will be set if the file contents are zero, and of course this datum is not a ected by the instruction. Thus movf FILE,f is equivalent to the missing tstf FILE instruction; that is TeST File for zero, that is commonly available in other MPU/MCUs. Thus the contents of any file register can be checked for zero by this means using a single instruction. An alternative technique needs to be used to test the contents of the Working register for zero.

Given that most instructions acting on a file can specify either the same file or the Working register as the destination, then a Move operation can be considered an implicit part of such instructions. As an example, for some situations to increment the contents of a file and then move it to W could be coded either as:

incf

22h,f

;

Increment File 22h’s contents

movf

22h,w

;

and copy it into W

or

incf 22h,w ; Copy the incremented File 22h’s contents to W

Of course the latter does not actually change the state of the file.

The final instruction swapf swaps the top and bottom 4-bit nybbles in a file. Thus, for example, if File 22h was 1001 0111b then swapf 22h,f will yield 0111 1001b. If desired, the outcome destination could be specified as W, eg. swapf 22h,w. As swapf does not a ect any flag, this latter form can be used as a transparent replacement for movf 22h,w which does alter the Z flag. Of course it does interchange the two nybbles in the process. Program 7.2 on page 183 shows this swap instruction used in this role.

Arithmetic

The PIC processors implement the normal byte-sized binary Add and Subtract instructions, as discussed on page 47, to add or subtract register

THE ESSENCE OF THE PIC MICROCONTROLLER 117

file contents to/from the Working register. In addition the W register may be added to or subtracted from an 8-bit constant.

Table 5.2: Arithmetic.

Flags

Operation

Mnemonic

Z

DC

C

Description

Add

Binary addition

Literal to W

addlw k

[W] <- [W] + #kk

W to File

addwf f,d

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

Clear

Zeroes destination byte or bit

File

clrf

f

[f] <- #00

W

clrw

[W] <- #00

Bit

bcf

f,n

[fn] <- #0

Decrement

Subtract one, produce no borrow

File

decf

f,d

[f] <- [f] - #01

Increment

Add one, produce no carry

File

incf

f,d

[f] <- [f] + #01

Set

Sets any bit in a file to one

Bit

bsf

f,n

[fn] <- #1

Subtract

Binary subtraction

W from literal

sublw k

[W] <- #kk - [W]

W from File

subwf f,d

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

#0

Single zero bit

#1

Single one bit

#00

Zero byte

#01

Byte 01h

#kk

8-bit constant

n

3-bit bit specifier 0 – 7

fn

Bit n of file

As an example that uses most of the instructions in Table 5.2 consider the problem of dividing the contents of File 24h by an 8-bit divisor in W. The simplest way of doing this is to continually subtract the divisor from the dividend, keeping a count until a borrow is generated. The residue left after this last subtraction is the remainder with one divisor subtraction to many. Thus adding the divisor once can restore the remainder if this is needed.

A possible implementation based on this approach is given in Program 5.3. Here the quotient is cleared before entering the loop, using the clrf instruction. The loop itself simply increments the quotient using the incf instruction and then subtracts W (the divisor) from File 24h – subwf 24h,f. Both Subtract instructions generate a complement borrow out, which is represented by the C flag in the Status register – labelled NB for Not Borrow in the program. Thus the loop is exited when the Carry flag is clear after the subtract, which represents a borrow out.

On leaving the loop, the contents of File 20h needs to be decremented, as the last subtract was one too many. Using the decf instruction allows this correction to be applied directly on the file register.


118 The Quintessential PIC Microcontroller

Program 5.3 Division by repetitive subtraction.

STATUS

equ

3

;

Status register

is File 3

NB

equ

0

;

Carry/Not

Borrow

flag is bit0

QUOTIENT

equ

20h

;

Quotient is held

in File 20h

REMAINDER

equ

21h

;

The remainder is

put

here

DIVIDEND

equ

24h

;

The dividend is

here

at the start

DIV

clrf

QUOTIENT

; Zero

the loop count

LOOP

incf

QUOTIENT,f

; Record one

loop

pass

subwf

DIVIDEND,f

; DIVIDEND -

DIVISOR

btfsc

STATUS,NB

; IF a

borrow

(NB==0) THEN exit loop

goto

LOOP

; ELSE

do another

subtract/count

decf

QUOTIENT,f

; Compensate

for one inc too many

addwf

DIVIDEND,w

; Add divisor

to residue

movwf

REMAINDER

; which gives

the

remainder

.....

......

; Next

routine

The remainder can be determined from the residue left in the original dividend file. This represents one divisor subtracted too many. Thus, addwf DIVIDEND,w cancels this last action and this remainder outcome, now in W, is copied into File 21h.

The addlw instruction can be used to add an 8-bit constant to W. Subtraction can also be carried out with this instruction by adding the 2’s complement of the literal subtrahend. For example. addlw F9h or addlw -7 will e ectively subtract seven from the contents of W. Thus if [W] was 88h before this operation then the state of W after is 81h:

1000 1000

W = 88h

+ 1111 1001

−7 = F9h

1000 0001

81h

Rather confusingly this is not the same as sublw 7 as this subtracts W from 7, that is [W] <- 7-[W].3

Although the arithmetic instructions act on byte operands, operations on word sizes of greater than 8-bit precision are possible with the help of the Carry/Not-Borrow flag. The process for the addition of two n-byte objects is given by the task list:

1.For = 0 to n − 1 DO

(a)Clear SUM.

(b)SUM[i] = NUM1[i] + NUM2[i].

(c)IF Carry[i] = 1 THEN increment SUM[i+1].

(d)Increment i.

2.End.

3This foible is a major cause of errors in programming, and you should think carefully before using this instruction.


THE ESSENCE OF THE PIC MICROCONTROLLER 119

Example 3.2 on page 64 gives a practical implementation of this algorithm. Multiple-precision subtraction is carried out in a similar manner, using the Not-Borrow flag. Example 5.4 implements a 16-bit − 8-bit subtraction.

Data in memory can be incremented or decremented apparently in situ, although in reality it is transferred from the Data store into a temporary register, incremented or decremented using the ALU and transferred back to the Data store – a type of read-modify-write action. However, it still takes only one bus cycle to implement.

These instructions are especially useful in counting passes through a loop, as in Program 5.3 where QUOTIENT is located in the Data store at File 20h. However, incf is not quite the same as a addlf 1,20h type of instruction as it does not alter the state of the Carry flag. Thus if you wanted to increment a 32-bit number in Data memory at File 22:3:4:5h then this is how you would have to do it:

QP_INC incf

22h,f

; Increment byte 1

btfss

STATUS,Z

; IF not overflowed to zero

goto

NEXT

; THEN finished

incf

23h,f

; Increment byte 2

btfss

STATUS,Z

; again IF not overflowed to zero

goto

NEXT

; THEN finished

incf

24h,f

; Increment byte 3

btfss

STATUS,Z

; IF not overflowed to zero

incf

25h,f

; increment byte 4

NEXT ..... ......

; Next code fragment

This depends on the algorithm IF when byte n is incremented it wraps around from FFh to zero THEN increment byte n +1. See Example 5.1 for a multiple-precision decrement routine.

One of the more important operations is the comparison of the magnitude of the two numbers. Mathematically this can be done by subtracting the datum (designated [f] for either a register file or a literal) from the contents of the Working register [W]. The outcome gives the actual magnitude di erence between the operands, but in most cases it is su cient to determine the relative magnitude of the quantities – eg. is W higher than the datum? This is determined by checking the state of the C and Z flags in the Status register.

Working register higher than datum . . . . . . . . . . . . . . . .No borrow, non-zero Working register equal to datum . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .Zero Working register lower than datum . . . . . . . . . . . . . . . . . . . . .Borrow, non-zero

In terms of our processor, the C flag represents the complement of the borrow after subtraction and the Z flag is set on a zero outcome. This gives: