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

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

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

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

Добавлен: 15.06.2025

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

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

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

referencing Instruction

3. Stored Program Processing 57

File

store

the

to

out

actually

F0

F4

this

address

sends

Fig. 3.6 The indirect mechanism.

circulating around the clrf instruction, which is ‘walked’ through the array of files by advancing the pointer in File 4, the FSR, on each pass through the loop. Eventually the pointer moves beyond the desired range and the program then exits the loop and continues onto the next section of code.

Program 3.2 has many new features, especially as we haven’t yet reviewed the instruction set.

Program 3.2 Clearing a block of files using a repeating loop.

; Name

the

various

registers & bits for

readibility

FSR

equ

4

; Give

File

4

the name FSR (File Select Reg.)

SR

equ

3

; Give

File

3

the name SR (Status Register)

Z

equ

2

; The Z flag is bit 2 of the

SR

Go here if FSR

; Now for

the program

proper

CLEAR_ARRAY

movlw 0Ch

; Put start address in W

30h

movwf FSR

; and into the FSR as a pointer

to

CLOOP

equal

; Now

not

is

clrf

0

;

Clear byte pointed to by

FSR

incf

FSR,f

;

Increment pointer in FSR

check, is

pointer

at top

yet?

movf

FSR,w

;

Copy the pointer

address

into W

sublw

40h

;

Compare

with the

end address (40h)

btfss

SR,Z

;

IF Zero

flag in SR is set THEN fini

goto

CLOOP

;

ELSE do

the next

pass thru the loop

....

....

;

Next part of the

program


58 The Quintessential PIC Microcontroller

Phase 1

From the point of view of readability, variables, registers and individual status and control bits should be given a relevant name. For example, btfss STATUS,Z (Bit Test File Skip if Set) which checks the Z flag (bit 2 in File 3) and skips the following instruction if set (that is the outcome of the previous instruction is zero) can be written in two ways; both of which are functionally identical:

btfss 3,2 ; IF bit 2 of File 3 is set THEN finished btfss STATUS,Z ; IF Zero flag in STATUS is set THEN finished

Obviously the latter is preferable. Although this might seem to be a cosmetic exercise, clarity reduces the chance of error and makes debugging and subsequent alteration easier. Realistic programs, rather than the code fragment illustrated here, use many variables and register bits, so lucidity is all the more important.

The three header lines of our program illustrate the means whereby the programmer tells the assembler translator program to substitute numbers for names. For example the line:

FSR equ 4

states that when the programmer uses the name FSR as an operand, it is to be substituted by the number 4 (that is File 4). The equ directive means “equivalent to”. A directive is a pseudo instruction in that it does not usually produce actual machine code but rather is a means of passing information from the programmer to the assembler program.

Phase 2

The first two proper instructions initialize the File Select Register to point to the first byte to be cleared, by moving the constant 0Ch into the Working register and then out to File 4. Nearly all loop instructions involve some setting up before entry.

Phase 3

The key Clear instruction uses the File Indirect address mode by specifying the phantom File 0 as the destination address. This line has a label associated with it called CLOOP. The assembler knows that this is a label and not an instruction as it appears in the leftmost column of the source file. Lines without labels should begin with an indent of at least one space.

Each pass around the loop involves an incrementation of the pointer. This is done by using the incf FSR,f instruction to increment the FSR file. Notice that the destination here is specified as a file and not the W register.

Phase 4

Unless you wish to go round the loop forever, we need a mechanism to eventually exit. In our case this is done by comparing the contents of the

3. Stored Program Processing 59

FSR pointer file with the constant 40h, that is with one over the top target file 3Fh. The comparison mechanism is to copy the contents of the FSR pointer into W and then subtract W from the literal 40h using sublw 40h. If they are equal then the Z flag will be set and in this event the next btfss instruction will skip over the following goto LOOP instruction, out of the loop. Until this happens, the goto instruction will move the execution back up to the beginning of the loop and the process is repeated with the FSR advanced to point to the next file to be cleared.

All together our loop version takes eight machine instructions against the 52 of the linear equivalent. However, it does take longer to execute as the six instructions in the loop are repeated 52 times!

Absolute

The goto instruction forces the execution to directly transfer to the specified address by simply overwriting the Program Counter with the e ective address – for example goto 145h puts 145h into the PC. It contrasts with the various Skip instructions (see page 61) which simply branch over the following instruction, wherever they are encountered. This latter type of branch is called relative, as opposed to the absolute transfer of execution used by the goto instruction.

Having covered the address modes, let us look briefly at the instruction set in Table 3.1. Instructions have been divided into four groups as follows.

Arithmetic

This covers the Addition, Subtraction, Incrementation, Decrementation and Clearing operations. Addition is possible between data in W and out in the File store, with the sum being placed either in the same file or in W. Similarly subtraction of W from a file is implemented, with the di erence being placed in the same file or W. Both instructions come in a literal version, where W is added to/subtracted from an 8-bit constant, with the outcome remaining in the Working register. Notice that in the latter case the variable in W is subtracted from the literal rather than the more obvious subtraction of the literal from W.

The contents of any file can be incremented or decremented using incf and decf respectively. The outcome is usually put back into the file but the Working register can alternatively be specified as the destination.

Any file can be cleared with clrf, for instance clrf 20h. In the same manner the Working register can be zeroed with clrw.

Movement

This category of instructions copy a datum from source to destination. In all cases the contents of the source remains unaltered. movf reads (loads) a byte from the File store, usually into the Working register; eg. movf 20h,w. It is possible to specify the seemingly useless operation of copying a file’s datum on top of itself, such as in move 20h,f. However,


60 The Quintessential PIC Microcontroller

this does have the side e ect of setting the Z flag if the datum is zero but in any case not altering a file’s contents. This can be used to implement a Test for Zero operation.

Other instructions in this category write (store) the contents of W out into the File store (eg. movwf 20h copies W into File 20h) or a literal into W (eg. movlw 6 puts the constant 06h into W).

Logic

The comf instruction inverts (complements or NOTs) all bits in the specified file (see Fig. 1.1 on page 12). For example:

10001110

comf 20h

01110001

F 20h

F 20h

The andwf instruction bitwize ANDs (see Fig. 1.2 on page 13) the contents of the Working register to that of a specified file, with the outcome being either in W or in the file. For example:

00001111

andwf 20h,f

10010111

00000111

W

F 20h

F 20h

It is also possible to AND a constant to W by using the andlw variant. Whilst the AND operation can be used to zero (mask) any bit or bits in

the specified file, the Inclusive-OR equivalent instructions can set to one any bit or bits in the destination. For example, ORing W with the literal

10000000b (80h):

00001110

iorlw 80h

10001110

W

W

remembering from Fig. 1.3 on page 13 that ORing with a logic 1 always results in a logic 1 outcome and ORing with zero does not alter the original data, leads to the outcome that the most significant bit position of W is set and the other bits remain unaltered.

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:

10001110

xorlw 81h

00001111

W

W

Two instructions are provided that can shift the contents of any file once left or right, with the outcome either remaining in the file or appearing in the W register. As shown in Fig. 3.7 the outgoing bit (bit 7 for rlf f,d and bit 0 for rrf f,d) is placed in the C flag, whilst the incoming bit at the opposite end is the previous value of C. Because of this ‘circular’ action these instructions are said to implement a Rotate data through the Carry operation.


3. Stored Program Processing 61

7 Bit

Bit 0, File 3

C

rrf

Bit

0

7 Bit

Bit 0, File 3

C

rlf

Bit

0

(a) Rotate Right File

(b) Rotate Left File

Fig. 3.7 Circular shifts.

Skip and Jump

These instructions alter the state of the Program Counter, e ectively interrupting the progressive flow of the program and causing processing to branch to another point in the code. The simplest of these instructions is goto. This overwrites the PC with the absolute destination address. For instance, goto 200h will change the PC to 200h and cause the program flow to ‘jump’ to whatever instruction is located at this address. Another example is instruction 8 in Program 3.2 where execution jumps back up to the beginning of the loop at address CLOOP.

The goto instruction causes an unconditional absolute jump in the program flow, implementing a ‘Jump Always’ operation. The remaining four instructions are conditional in that the smooth program progression is interrupted only if the outcome matches the specified state. For instance decfsz decrements the specified file contents and if and only if the outcome is zero the following instruction is skipped over.

Four instructions in our set come into this category, in that they increment the PC if some condition is fulfilled. Remembering that each instruction occupies one word in Program memory, incrementing the PC is equivalent to skipping over the following instruction. This relative skipover action is in contrast with the absolute always jump to the specified address action of the goto instruction.

The four relative instructions are:

btfsc

Bit Test File & Skip if Clear by-passes the next instruction if the specified bit in the file in question is zero. For example btfsc 3,02h skips if bit 2 in File 3 is clear.

btfss

Bit Test File & Skip if Set by-passes the next instruction if the specified bit in the file in question is one. For example btfss 3,02h skips if bit 2 in File 3 is one.

62 The Quintessential PIC Microcontroller

decfsz

DECrement File & Skip if outcome is Zero subtracts one from the specified file and by-passes the next instruction if the outcome is zero. For example decfsz 30h,f skips if the content of 30h once decremented is zero. The decremented value is placed back in the file in this example but W is an alternative destination, as in decfsz 30h,w.

incfsz

INCrement File & Skip if outcome is Zero adds one to the specified file and by-passes the next instruction if the outcome is zero. For example incfsz 30h,f skips if the content of 30h once incremented is zero. The incremented value is placed back in the file in this example but W is an alternative destination, as in incfsz 30h,w.

Actually the Program Counter is located in the Data store as File 2. Thus manipulating this file can implement a computed relative skip. For example:

movf

2,w

; Bring the current value of the PC into W

addlw

6

; Add six to it

movwf

2

; Update PC, that is hop forward six places

More details of this technique are given on page 86.

As more sophisticated example of the use of conditional Skip instructions and the absolute goto instructions, consider the problem of repeating a sequence 16 times. The most e cient approach to the coding is to construct a program loop and keep track of the number of times the processor executes the encapsulated instructions. In the following listing File 22h is used as the counter, initialised to 16 before the loop is entered. At the end of the sequence the count is decremented using decfsz and normally the next instruction, which transfers the PC back up to the start of the loop, is executed. However, eventually the count reaches zero and the goto LOOP instruction is skipped over, with execution consequently exiting the loop. Traditionally the potentially skipped over instruction is shown indented as a matter of style.

movlw 16 ; Set up constant #16

movwf 22h ; and put in File 22h for use as a counter

;Now for the sequence of instructions to be repeated 16 times LOOP ..... ... ; DO this

..... ... ; DO that

..... ... ; DO the other

;Count mechanism

decfsz

22h

;

Decrement count.

IF zero THEN exit loop --

goto

LOOP

;

ELSE repeat loop

|

|

..... ...

<--


3. Stored Program Processing 63

The incfsz instruction works in a similar manner, but for an up count, skipping when the target file overflows FF → 00h. As an exercise, repeat the example but using incfsz in place of decfsz.The ++(f) and --(f) rtl symbology used to describe the incfsz and decfsz instructions indicate that the contents of the designated file is augmented or decremented before testing for zero.

The other set of skip instructions uses the state of any bit b in any file to force a conditional skip. Thus if it is desired that the program transfers to an instruction located at label REAL_TIME if bit 2 of File 0Bh is logic 1, then we can use the btfsc (Bit Test File & Skip on Clear) instruction thus:

btfsc 0Bh,2 ; Bit Test File 0Bh bit 2. IF==0 THEN skip goto REAL_TIME ; ELSE == 1, GOTO REAL_TIME

In Table 3.1 the rtl language description of this instruction is given as b==0?PC++:PC, which can be read as:

1.Is the specified bit (b) equivalent to (==) zero (?).

2.If true then increment the PC (PC++), that is skip.

3.Else it is false, so leave the PC alone.

Similarly the -- rtl operator is used to indicate decrementation.

Examples

Example 3.1

Write a program to add the byte contents in File memory called NUM1 (File 20h) to NUM2 (File 21h). The outcome is to be in SUM_H and SUM_L (File 22h and File 23h respectively) in the order high:low byte.

Solution

This is similar to our load-add-store program on page 48 but the second operand is a byte variable in memory rather than a constant. The three instructions to implement this are shown in Program 3.3. The variable NUM1 is simply fetched down into the Working register and then added to variable NUM2. The outcome of this is then copied into the sum byte

SUM_L.

Of course this will only work if the outcome of the addition can fit into a single byte; that is no more than FFh (255d). If, for example, both NUM1 and NUM2 were FFh, then the outcome would be 1 FFh. Thus we need to reserve two bytes for the sum; an upper byte and a lower byte; named SUM_H and SUM_L in Program 3.4 in File 22h and File 23h respectively. In this implementation we simply zero the upper byte of the sum in advance, and after the addition skip around the Increment of instruction 6 if the

64 The Quintessential PIC Microcontroller

Program 3.3 Simple single-precision addition of two byte variables.

NUM1

equ

0020h

NUM2

equ

0021h

SUM_L

equ

0022h

SP_ADD

movf

NUM1,w

; Get the first memory byte

addwf

NUM2,w

; Add to it the second byte and put the

movwf

SUM_L

; outcome in memory as the lower sum byte

Program 3.4 A more accurate single-precision addition of two byte variables.

NUM1

equ

0020h

NUM2

equ

0021h

SUM_L

equ

0022h

SUM_H

equ

0023h

STATUS

equ

03

SP_ADD

clrf SUM_H

; Prepare the upper sum byte by zeroing it

movf

NUM1,w

; Get the first memory byte

addwf

NUM2,w

; Add to it the second byte and put the

movwf

SUM_L

; outcome in memory as the lower sum byte

btfsc

STATUS,0

; IF carry is clear (SR bit 0) THEN finish

incf

SUM_H,f

; ELSE increment higher sum byte

EXIT

...

.....

;

Next part of the program

Carry flag (bit 0 in File register 3) is Clear (Bit Test File and Skip on Clear). The upper sum byte can only ever be either 00h or 01h.

Example 3.2

Write a program routine that will add two 16-bit numbers giving a 17bit sum. The augend is located in the two memory locations F20h:F21h

F20h F21h

in the order high:low byte thus AUGEND_H AUGEND_L . The addend is similarly

F22h

F23h

situated

ADDEND_H

ADDEND_L

.

The sum is stored as three bytes in the order

F24h

F25h

F26h

high:middle:low thus

SUM_H

SUM_M

SUM_L

.

Solution

Although BASIC is only capable of directly implementing 8-bit arithmetic, operations of any length are possible by breaking down the process into byte-sized chunks. In the case of addition, this involves a sequence of byte operations from the least to the most significant digits with any carry from the nth digit byte being added into the n+1th summation. The least significant addition has a presumed carry-in of 0 and the carry-out from