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

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

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

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

Добавлен: 15.06.2025

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

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

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

194 The Quintessential PIC Microcontroller

Program 7.6 Incrementing a packed-BCD byte with maximum value of 99.

; ************************************************************

; *

FUNCTION:

Adds onto

packed BCD

byte,

maximum value 99

*

;

*

ENTRY

:

FSR

points

to byte

*

;

*

EXIT

:

BCD

byte incremented;

W and

STATUS altered

*

; ************************************************************

BCD_INC

incf

0,f

; Add one onto pointed-to BCD byte

movf

0,w

; Get it down

addlw

6

; Add six

btfss

STATUS,DC

; Check Decimal half Carry

goto

BCD_EXIT

; IF none THEN OK to exit

movwf

0

; ELSE corrected value put away

BCD_EXIT

return

simply binary incremented in situ using Indirect addressing. It is then corrected as described. The subroutine assumes that the pointed-to datum is already in a packed-BCD format on entry; it does not convert a natural binary byte to BCD.

Self-assessment questions

7.1Rewrite Programs 7.1 and 7.2 to deal with a packing quantity of one gross (144). The count is to be kept in packed BCD (Hundreds and Tens:Units) which can be used by the background software to display the can tally.

7.2What changes to Example 7.1 would you have to make to allow for a maximum value in the oven of 1000?

7.3Based on Fig. 7.1 design an ISR to perform the following tasks:

Copy the 16-bit count into two GPRs labelled TEMP_H and TEMP_L.

Deduct from the previous count reading located in LAST_COUNT_H and LAST_COUNT_L and place the di erence in DIFFERENCE_H and

DIFFERENCE_L.

Update the previous count with the new count.

Set a GPR labelled NEW to a non-zero value to signal the background software that a new reading is available. The background routine will clear NEW when it has processed the data.

7.4The speed of a rotating shaft can be measured by using a coded disk to generate a pulse on each angular advance of 10◦, which can be used to interrupt a PIC. If the top speed is 20,000 revolutions per minute, what is the absolute maximum duration of the ISR in this


7. Interrupt Handling 195

worst-case situation to avoid missing pulses? You may assume a crystal frequency of 4 MHz.

7.5 An electronic tape measure determines distance by pulsing an ultrasonic transmitter and detecting the time it takes for the echo return. The hardware for this echo sounder is shown in Fig. 7.6 and is based on that of Fig. 7.5.

The maximum range is specified as 2.5 meters with a resolution of 1 cm. The speed of sound in air is 344 meters per second at 20◦C, which gives a go-return time for one meter of 5.813 ms. Using a 1.72 kHz oscillator as a time base gives one interrupt per 5.813 ms; that is a Ji y per cm.

Ultrasonic receiver

1.72 kHz timebase

Ultrasonic transmitter

Interrupt request

INT/RB0

RX

flag

’1’

1D

RA0

C1

R

Cancel

RX

RA2

TB

flag

’1’

1D

RA1

C1

R

Cancel

TB

RA3

RB7

Fig. 7.6 Echo sounding hardware.

196 The Quintessential PIC Microcontroller

Based on this hardware, the software must implement the following task list:

Background routine

1.Zero Ji y count and New flag.

2.Pulse the sounder.

3.Wait until New flag is non zero.

4.Display reading.

5.Repeat forever.

Foreground routine.

1.IF oscillator THEN increment Ji y count.

2.IF receiver THEN set New flag to non-zero to tell background program that the Ji y count is the final value.

3.Repeat until neither is active.

4.Return

Code the foreground ISR tasked above using a GPR as a flag labelled NEW to tell the background program that the echo has returned and to read the Ji y count as the required value. Use Program 7.3 as your model.

7.6It is proposed to increase the range of the digital echo sounder to 10 meters and resolution to 1 mm. What change in the hardware and software would be required?

7.7The system in SAQ 7.6 has been built and tested. However, readings seem to shift slowly with time. Oscillator drift is suspected but has been proven to be stable. Thinking laterally, one student wonders if the speed of sound varies with atmospheric conditions. After some research he arrives at the formula for temperature dependence as:

Vt = V0 1 + 273∆t

where V0 is the propagation velocity at 20◦C and Vt is the velocity at a temperature of t. How much change in temperature ∆t will there be to cause an error of 1 mm with the sounder measuring at its maximum range?


CHAPTER 8

Assembly language

We have now been writing programs with gay abandon since Chapter 3. For clarity these listings have been written in a human-readable form. Thus instructions have been represented as a short mnemonic, such as return instead of 00000000001000b; the file registers similarly have names, such as INTCON; lines have been labelled and comments attached. Such symbolic representations are only for human consumption. The MCU knows nothing beyond the binary codes making up operation codes and data, such as shown on page 45.

With the help of the device’s instruction set, see Appendix A, it is possible to translate from the human-readable symbolic form to machinereadable binary. This is not particularly di cult for a device such as a PIC that has a reduced set of instructions (RISC) and few address modes. However, it is slow and tedious, especially where programs of a significant length are being coded. Furthermore, it is error prone and di cult to maintain whenever there are changes to be made.

Computers are good at doing boring things quickly and accurately; and translating from symbolic to machine code definitely falls into this category. Here we will briefly look at the various software packages that aid in this translation process.

After reading this chapter you will:

Know what assembly-level language is and how it relates to machine code.

Appreciate the advantages of a symbolic representation over machinereadable code.

Understand the function of the assembler.

Understand the di erence between absolute and relocatable assembly.

Understand the role of a linker.

Appreciate the process involved in translating and locating an assemblylevel language program to absolute machine code.

Understand the structure of a machine-code file and the role of the loader program.

Understand the role of a simulator.

198 The Quintessential PIC Microcontroller

Appreciate the use of the integrated development environment to automate the interaction of the various software tools needed to convert source code into a programmed MCU device.

The essence of the conversion process is shown in Fig. 8.1. Here the program is prepared by the tame human in symbolic form, digested by the computer and output in machine-readable form. Of course this simple statement belies a rather more complex process, and we want to examine this in just enough detail to help you in writing your programs.

incf

COUNT,f

Translate

00101010100000

movf

COUNT,w

00100000100000

addlw

6

11111000000110

btfsc

STATUS,DC

01100100000101

movwf

COUNT

00000010100000

return

00000000001000

Fig. 8.1 Conversion from assembly-level source code to machine code.

In general the various translator and utility computer packages are written and sold by many software companies, and thus the actual details and procedures di er somewhat between the various commercial products. In the specific case of PIC MCU devices, Microchip Technology Inc. as a matter of policy has always provided their assembly-level software tools free of charge, a large factor in their popularity. For this reason commercial PIC software is relatively rare and what there is usually conforms to the Microchip syntax. For this reason we will illustrate this chapter with the Microchip suite of computer-aided coding tools.

Using the computer to aid in translating code from more user-friendly forms (known as source code) to machine-friendly binary code (known as object code or machine code and loading this into memory began in the late 1940s for mainframe computers. At the very least it permitted the use of higher-order number bases, such as hexadecimal.1 In this base the code fragment of Fig. 8.1 becomes:

0AA0

0820

3E06

1905

00A0

0008

A hexadecimal loader will translate this into binary and put the code in designated memory locations. This loader might be part of the software

1Actually base-8 (octal) was the popular choice for several decades.


8. Assembly language 199

in your PIC-EPROM programmer. Hexadecimal coding has little to commend it, except that the number of keystrokes is reduced – but there are more keys – and it is slightly easier to spot certain types of errors.

As a minimum, a symbolic translator, or assembler,2 is required for serious programming. This allows the programmer to use mnemonics for the instructions and internal registers, with names for constants, variables and addresses. The symbolic language used in the source code is known as assembly language. Unlike high-level languages, such as C or PASCAL, assembly language has a one-to-one relationship with the generated machine code, i.e. one line of source code produces one instruction. As an example, Program 8.1 shows a slightly modified version of Program 6.11 on page 163. This subroutine computes the square root of a 16-bit variable called NUM which has been allocated two bytes in the Data store.

Giving names to addresses and constants is especially valuable for longer programs, which may easily exceed 1000 lines. Together with the use of comments, this makes code easier to debug, develop and maintain. Thus, if we wished to alter the file registers holding the variable NUM from File 20:21h to, say, File 36:37h, then we need only alter the line:

cblock 20h

to:

cblock 36h

and then retranslate to machine code. In a program with, say, 50 references to the variable NUM, the alternative of altering all these addresses manually from 20h or 21h (high:low byte) to 36h or 37h respectively is laborious and error prone. In the body of our source code the high byte is referenced as NUM (that is the contents of File 20h) and the lower byte in File 21h as NUM+1, as assemblers can do simple arithmetic on symbolic constants – see page 223.

The pseudo instruction cblock is an example of an assembler directive. A directive is a command from the programmer to the assembler concerning its operation or giving a constant a name. We list a small subset of the Microchip assembler directives at the end of the chapter, on page 222; the reader should reference the o cial manual for a detailed description. Briefly the directives used in Program 8.1 are:

cblock - endc

Rather like a block of equ directives, giving the encapsulated list of label constants starting either at the specified value, eg. 20h, or following on from the last cblock if no address is given. Labelled entities can be deemed to occupy more than one byte by using a colon-delimited size field; for instance NUM:2 for a 2-byte allocation and are normally used to name General-Purpose registers (GPRs).

2The name is very old; it refers to the task of translating and assembling together the various modules making up a program.

200 The Quintessential PIC Microcontroller

Program 8.1 Absolute assembly-level code for our square-root module.

; Global declarations

STATUS

equ

3

;

Status register is File 3

C

equ

0

;

Carry/Not Borrow flag is bit0

cblock 20h

Number: high byte, low byte

NUM:2

;

endc

MAIN

goto

SQR_ROOT

;************************************************************

;* FUNCTION: Calculates the square root of a 16-bit integer *

; *

EXAMPLE

: Number

= FFFFh

(65,535d), Root = FFh (255d)

*

;

*

ENTRY

: Number

in File

NUM:NUM+1

*

;

*

EXIT

: Root in W. NUM:NUM+1; I:I+1 and COUNT altered

*

;************************************************************

;Local declarations

cblock

I:2, COUNT ; Magic number hi:lo byte & loop count endc

org

200h

; Code to begin @ 200h in Program store

SQR_ROOT

clrf

COUNT

; Task 1: Zero loop count

clrf

I

; Task 2: Set magic number I to one

clrf

I+1

incf

I+1,f

; Task 3: DO

SQR_LOOP

movf

I+1,w

; Task 3(a): Number - I

subwf

NUM+1,f

; Subtract lo byte I from lo byte Num

movf

I,w

; Get high byte magic number

btfss

STATUS,C

; Skip if No Borrow out

addlw

1

; Return borrow

subwf

NUM,f

; Subtract high bytes

; Task 3(b): IF

underflow THEN exit

btfss

STATUS,C

; IF No Borrow THEN continue

goto

SQR_END

; ELSE the process is complete

incf

COUNT,f

; Task 3(c): ELSE inc loop count

movf

I+1,w

; Task 3(d): Add 2 to the magic number

addlw

2

btfsc

STATUS,C

; IF no carry THEN done

incf

I,f

; ELSE add carry to upper byte I

movwf

I+1

goto

SQR_LOOP

SQR_END

movf

COUNT,w

; Task 4: Return loop count as the root

return

end

end

Tells the assembler that this is the end of the source code. equ

Associates a value to a symbol. For instance the assembler replaces the name STATUS by the value 3 anywhere it appears in an instruction operand. Normally used for Special-Purpose registers (SPRs) and bits within file registers.