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

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

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

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

Добавлен: 15.06.2025

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

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

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

CHAPTER 5

The Instruction Set

If you like to think of writing a program as analogous to preparing an elaborate meal, then for any given cooking appliance, such as a microwave oven or electric stove (the hardware) there are a range of processes. These processes – for example, steaming, frying, boiling – are analogous to the instruction set which can be implemented by the CPU. The various ingredients that can be handled by a process are the instruction’s data. Such data may lie in an internal register or out in the Data store. There are several di erent ways of specifying the e ective address (ea) of an operand. These are known as address modes.

In keeping with the PIC microcontrollers’ RISC-like philosophy, the mid-range core have a total of only 35 instructions. Each instruction code is contained in a 14-bit word which holds the instruction operation code, address or data and destination bit. We have covered most of these instructions and address modes when discussing our BASIC computer back in Chapter 3; now would be a good time to go over this material. As we will begin this chapter by examining PIC’s address modes and how they are incorporated into an instruction’s binary word, we will use BASIC’s instruction set listed in Table 3.1 on page 53 for our illustrative examples. The latter part of the chapter looks at the full instruction set in some detail.

After reading this chapter you will:

Know that an address mode is the way an instruction pin-points its data.

Understand how Inherent, Literal, Register Direct, File Direct, File Indirect, Bit and Absolute address modes permit an instruction to target an operand for processing.

Know that Movement instructions, copying data in-between the Working register and the Data store, are the most used of the instruction categories.

Appreciate that the processor can directly implement the common arithmetic operations of Addition, Subtraction, Incrementation and Decrementation.

Know that data in the Data store can be rotate-shifted through the C flag.

106 The Quintessential PIC Microcontroller

Understand how to use the four basic logic instructions to invert, set, clear, toggle, bit test and di erentiate data.

Know how to compare or test data for di erences and relative magnitude, and take appropriate action.

Understand how the program flow can be diverted, based on the state of any bit or a zero value in a Data file.

Recognize how the binary structure of the instruction word impacts on the usage of instructions.

Virtually all instructions act on data; either outside in its Data or Program memory space, or inside in an internal CPU register. Thus the 14bit instruction code must include bits which inform the CPU’s instruction decoder where this data is being held. The exception to this are the few Inherent instructions, such as nop (No Operation) and return (RETURN from subroutine). Before looking at the instruction set we will discuss the various techniques used to specify the location of any operands.

The general symbolic form of an instruction is:

instruction mnemonic <operand A>,<operand B>

where operand A is the source data or its location and operand B the destination. For example movf 20h,w (MOVe File) which copies data source out of File 20h to its destination in the Working register.

There are some variations on this structure. 212 -operand instructions are common. For example, addwf FILE,d adds the W register’s contents to the specified file’s contents and deposits the result either in W or back in the file register itself. Thus addwf 20h,f means “add the contents of W to that of File 20h and put the outcome in File 20h” or in Register Transfer Language (rtl, see page 49) (f20) <- W + (f20). Of course this is not a true 3-operand instruction as the destination must be one of the two source locations; that is W or File 20h. A few instructions have only a destination specified; for example, clrf 20h, and the inherent instructions have no explicit operands.

Instructions can be classified by their address mode.

Inherent

0000000 ???????

The instructions listed in Appendix A, clrwdt (CLeaR WatchDog Timer), retfie (RETurn From Interrupt and Enable), nop, return and sleep do not explicitly refer to operands in memory or in the Working register. At the binary code level, all these instructions are coded with the upper seven bits zero. For example, clrwdt has a machine code of 00000000000100b.


THE ESSENCE OF THE PIC MICROCONTROLLER 107

Register Direct

?????? 0 ???????

The PIC series has only one CPU register that can be explicitly specified by an instruction; the Working register. Where the destination is to be W then bit 7 of the instruction code is always 0. For example clrw is coded as 0000000000011b. Many instructions can either use W or the source file as the destination, and this is coded by setting bit 7 to 0 or 1 respectively. In Appendix A, bit 7 is marked as d for destination (see also File Direct addressing) for applicable instructions.

Where W is one of the source operands, the instruction normally shows this as part of the mnemonic. Thus movwf f copies W to the specified file register.

Literal

11 ???? LLLLLLL

Literal instructions use the lower eight instruction word bits to specify a source operand which is constant data rather than data in a register. For example addlw 06 is coded as 11111000000110b. The destination of this type of instruction is always the Working register, and this is shown in the mnemonic. Thus in our example, the sum W +6 is copied back into W. In rtl this is expressed as W <- W + #6 where the # (pound or hash) symbol denotes that the following number is a constant or literal rather than a file address.

File Direct

00 ???? d f

Instructions that specify that their source or destination operand lies in a file register use this address mode. The value of the file address is coded into the lower seven bits; denoted as f. For instance the code for clrf 20h is 00 0001 1 0100000.

Most instructions altering the contents of a file register can ‘dump’ the outcome either in the Working register or else back in the file. Bit 7 of the instruction code, labelled d, can specify the destination as in the following example:

incf 20h,w ; Coded as 00 1010 0 0100000 incf 20h,f ; Coded as 00 1010 1 0100000

In both cases the contents of File 20h (File 01000000b) are incremented. In the former instance, the outcome is put in W leaving the file contents unchanged (d = 0), whilst in the latter the original data is overwritten (d = 1).

108 The Quintessential PIC Microcontroller

The main characteristic of this type of address mode is that the location of the operand is fixed as an integral part of the program, and thus cannot be altered as the program progresses. In some cases, such as in Program 5.1, this technique is rather inflexible.

As only seven bits of the instruction code are reserved for the file address, only files from 00 – 7Fh may be directly accessed using this technique. However, from Fig. 4.6 on page 92 we see that the PIC16F84’s Data store maps the register files in the range 00 – FFh, requiring an 8-bit address. The PIC16F84 gets round this by employing the RP0 bit in the Status register as a surrogate most-significant address bit – see Fig. 4.5 on page 89. This Register Page control bit can be altered, like any other read/write file register bit, to switch back and forth between Bank 0 (RP0 = 0) and Bank 1 (RP0 = 1).

The full 14-bit core CPU model has the capability of interacting with a 512-register file Data store. Devices with this size of Data store, such as the PIC16F87X line, have to deal with four banks of up to 128 register files. This requires a 9-bit address. Here the Status register, shown in Fig. 5.1, has two page select bits, RP1:RP0 which must be set up prior to using the File Direct address mode. For example, in such a Data store with a file address range 000 – 1FFh, in order to clear File 17Fh (File 10 111 1111b) we need to set RP1:RP0 to 10:

bsf

STATUS,6

; Make RP1

=

1

bcf

STATUS,5

;

Make RP0

=

0

(Bank 2)

clrf

17Fh

;

Clear File

17Fh

Program 15.4 on page 442 is an example making use of this extended bank switching.

File Indirect

00 ???? d 0000000

Where data in the Data store is to be accessed, specifying its location directly as an address constant seems the obvious way to go; for example, clrf 20h. However, as we saw back in Program 3.1 on page 56, this may not always be the most e cient approach. This is especially the case when an array of data, such as a sequential set of readings, is to be processed.

Most MPU/MCU devices have one or more Address registers, sometimes known as Index registers. These are designed to hold the address in memory of the operand; that is they act as a pointer. Such processors use one or more Indexed or Indirect address modes which look to the appropriate pointer register to specify the operand location, rather than have the address as a fixed part of the instruction code. The advantage of this indirect approach of addressing a data operand is that the address can easily be altered as the program progresses. Thus, for example, an


THE ESSENCE OF THE PIC MICROCONTROLLER 109

Bank 3

(File 180 - 1FFh)

X/Y

3

Bank 2

(File 100 - 17Fh)

2

Bank 1

(File 080 - 0FFh)

1

Status

register (SR)

Bank 0

(File 000 - 07Fh)

0

1

0

File 3

Register

File Bank

Select

7

6

5

4

3

2

1

0

decoder

IRP

RP1

RP0

TO

PD

Z

DC

C

(R/W 0)

(R/W 0)

(R/W 0)

(R 1)

(R 1)

(R/W ?)

(R/W ?)

(R/W ?)

Indirect Register File Bank Select

Carry/Borrow

Bank 0/1

(File 000 - 0FFh)

0

Digit Carry/Borrow

Bank 2/3

(File 100 - 1FFh)

1

Zero

Time-Out Watchdog time-out 0 clrwdt/sleep instructions 1

Power Down

By sleep instruction 0

By clrwdt instruction 1

Fig. 5.1 General 14-bit core Status register.

array of data may be cleared by using an address register to point to the target location, and repeating in a loop while incrementing that pointer register.

The PIC family does not have dedicated CPU Address/Index registers to perform this indirect holding function. Instead, the pointer address is that contained in the File Select Register (FSR), which is File 4 in the Data store, see Fig. 4.6 on page 92. To activate the indirect mechanism, the normal File Direct address mode is used, but with File 0 as the target

directly

instructionreferencing

this

Any

INDF

F0 actually

virtual location

sends

File

store

the

FSR

to

out

F4

this address

Pointer

Fig. 5.2 The indirect mechanism.


110 The Quintessential PIC Microcontroller

location. File 0, the INDF (INDirect File) register, is a virtual location, that is it is not physically implemented. Its sole use is to trigger the use of the contents of the FSR as the operand address, as shown in Fig. 5.2. Thus the instruction clrf 0 will actually clear the file whose 8-bit address is that in File 4. Of course the contents of the Special-Purpose Register (SPR) FSR can be altered at any time, for example incremented on each pass through a loop. This is the approach taken in Program 3.2 on page 57, which clears an array of Data-store memory. Although this approach to indirect addressing may seem rather convoluted, it does not require additional clock cycles to execute, unlike the alternative techniques used by other MPU/MCUs.

A more sophisticated example than that of Program 3.2 involves the sampling of temperature hourly over a daily period. With the assumption that the resulting array of 24 byte values are in situ in the Data store between File 30h and File 47h, we are required to scan through the array looking for the maximum temperature. By the end of the routine this is to be in File 48h.

To implement this procedure we first need a strategy or task list. One possibility would be:

1.Initialize Maximum as Temp[0].

2.IF Temp[1] > Maximum THEN Maximum = Temp[1].

3.IF Temp[2] > Maximum THEN Maximum = Temp[2].

4.IF Temp[3] > Maximum THEN Maximum = Temp[3]…….

5.…etc.

6.IF Temp[23] > Maximum THEN Maximum = Temp[23].

7.End.

How can we code Temp[i] > Maximum? If we subtract Maximum from Temp[i], that is Temp[i] − Maximum, then if a borrow is not generated (C flag set) we know that the former is higher than the latter and Maximum needs updated. Based on this, a possible coding is given in Program 5.1.

In this linear coding the comparison is implemented by first bringing the current maximum into the Working register (movf MAXIMUM,w), then subtracting it from the appropriate direct address, eg. for Temp[2] or File 32h, subwf TEMP_0+2,w. This subtraction will set the C flag (that is N) if there is no borrow out, and in that situation the instruction btfss will skip to the update sequence. This simply copies down the appropriate temperature byte and copies it again up to the register file holding

Maximum, eg. movf TEMP_0+2,w – movwf MAXIMUM.

The process outlined here has to be coded 24 times, with some small saving in the initial setting of Maximum to Temp[0] and the fact that this value is already in W for the Temp[1] comparison. This gives a total of 139 instructions. Execution time depends a little on the number of times Maximum has to be updated. However, taking a worse-case scenario and remembering that goto takes two cycles to implement as does btfss

THE ESSENCE OF THE PIC MICROCONTROLLER 111

Program 5.1 Finding the maximum temperature the linear way.

STATUS

equ

3

;

Status register is File 3

TEMP_0

equ

30h

;

Array starts @ File 30h

MAXIMUM

equ

48h

;

Maximum value to be in File 48h

NB

equ

0

;

Carry/Not Borrow flag is bit0

; Task1: Initialize Maximum

as Temp[0]

MAX_DAILY movf

TEMP_0,w

;

Get it

movwf

MAXIMUM

;

and put it in as first maximum

; Task2: Check is Temp[1] >

Maximum?

subwf

TEMP_0+1,w

;

Temp[1] - Maximum

btfss

STATUS,NB

;

IF no borrow (NB==1) THEN update

goto

TASK3

;

Skip update

movf

TEMP_0+1,w

;

Update by getting Temp[1]

movwf

MAXIMUM

;

which is the new maximum

; Task3: Check is Temp[2] >

Maximum?

TASK3

movf

MAXIMUM,w

;

Get current maximum

subwf

TEMP_0+2,w

;

Temp[2] - Maximum

btfss

STATUS,NB

;

IF no borrow (NB==1) THEN update

goto

TASK4

;

Skip update

movf

TEMP_2,w

;

Update by getting Temp[2]

movwf

MAXIMUM

;

which is the new maximum

; Task4: Check is Temp[3] >

Maximum?

TASK4

movf

MAXIMUM,w

;

Get current maximum

subwf

TEMP_0+3,w

;

Temp[3] - Maximum

btfss

STATUS,NB

;

IF no borrow (NB==1) THEN update

goto

TASK5

;

Skip update

movf

TEMP_0+3,w

;

Update by getting Temp[3]

movwf

MAXIMUM

;

which is the new maximum

; Task5

and so

on

TASK5

..... ......

; Task24: Check

is Temp[23] >

Maximum?

TASK24

movf

MAXIMUM,w

;

Get current maximum

subwf

TEMP_0+23,w

;

Temp[23] - Maximum

btfss

STATUS,NB

;

IF no borrow (NB==1) THEN update

goto

FINI

;

Skip update

movf

TEMP_0+23,w

;

Update by getting Temp[23]

movwf

MAXIMUM

;

which is the new maximum

FINI

..... ......

when a skip occurs, then this gives 188 clock cycles to execute; that is 188 µs for a 4 MHz crystal.

Now Program 5.1 is rather a long program for a small task. This is because the complete sequence of compare-update instructions have to be implemented 23 times. Each sequence is identical, except the next ele-