Файл: 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.