Файл: The quintessential PIC microcontroller (S. Katzen, 2000).pdf
ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 15.06.2025
Просмотров: 5292
Скачиваний: 0
8. Assembly language 209
tions actually used by the program. Any macros defined in the included file but not used will have no e ect on the final machine code.
One of the major advantages of using an assembler over machine code programming is the use of names for the various file registers and bits therein; for example, INTCON instead of File 0Bh and GIE in place of 7. In code, such as Program 7.1 on page 181, these equivalences are listed at the head of the source code using equ directives. Although the GPRs will have name labels unique to the particular program, the SPRs and their constituent bits are the same for all programs targeted to a particular type of PIC. Microchip provide files for each PIC, listing all SPRs and bits which can be included in the program’s heading; for example
Table 8.4: Part of Microchip’s file p16f84.inc.
;This header file defines configurations, registers, and other
;useful bits of information for the PIC16F84 microcontroller.
;These names match the data sheets as closely as possible.
;----- |
Register Files |
------------------------------------------ |
|
INDF |
EQU |
H’0000’ |
|
TMR0 |
EQU |
H’0001’ |
|
PCL |
EQU |
H’0002’ |
|
STATUS |
EQU |
H’0003’ |
|
FSR |
EQU |
H’0004’ |
|
PORTA |
EQU |
H’0005’ |
|
PORTB |
EQU |
H’0006’ |
|
EEDATA |
EQU |
H’0008’ |
|
EEADR |
EQU |
H’0009’ |
|
PCLATH |
EQU |
H’000A’ |
|
INTCON |
EQU |
H’000B’ |
|
OPTION_REG |
EQU |
H’0081’ |
|
TRISA |
EQU |
H’0085’ |
|
TRISB |
EQU |
H’0086’ |
|
EECON1 |
EQU |
H’0088’ |
|
EECON2 |
EQU |
H’0089’ |
|
;----- |
STATUS Bits -------------------------------------------- |
||
IRP |
EQU |
H’0007’ |
|
RP1 |
EQU |
H’0006’ |
|
RP0 |
EQU |
H’0005’ |
|
NOT_TO |
EQU |
H’0004’ |
|
NOT_PD |
EQU |
H’0003’ |
|
Z |
EQU |
H’0002’ |
|
DC |
EQU |
H’0001’ |
|
C |
EQU |
H’0000’ |
|
;----- |
INTCON Bits -------------------------------------------- |
||
GIE |
EQU |
H’0007’ |
|
EEIE |
EQU |
H’0006’ |
|
T0IE |
EQU |
H’0005’ |
|
INTE |
EQU |
H’0004’ |
|
RBIE |
EQU |
H’0003’ |
|
T0IF |
EQU |
H’0002’ |
|
INTF |
EQU |
H’0001’ |
|
RBIF |
EQU |
H’0000’ |
|
8. Assembly language 213
Relocatable |
|||||
assembler |
rms.lst |
||||
main.asm |
main.o |
||||
Linker |
|||||
sqr.asm |
sqr.o |
+ |
rms.hex |
||
rms.map |
|||||
root2.asm |
root2.o |
||||
Linker |
script |
||||
pic16f84.lkr
Fig. 8.4 Linking three source files to implement a root mean square program.
(a)Square NUM_1.
(b)Square NUM_2.
(c)Add NUM_12 + NUM_22
(d)Square root item (c).
2.Design of a subroutine to square a byte number in the Working register to give a double-byte outcome in two GPRs.
3.Design of a subroutine to evaluate the square root of a double-byte sum and return it in W.
The process based on this decomposition of the task is shown diagrammatically in Fig. 8.4.
The main function is shown in Program 8.2. The program commences with the Reset goto instruction and is located in the VECTORS code stream. From the MAIN label onwards, code is located in the TEXT code stream using the directive TEXT code. We see from the map file output by the linker in Table 8.6 that MAIN is located at 005h.
The main routine uses four variables located in general-purpose file. These are placed in uninitialized RAM with the directives udata and res. A single file register is reserved for each of the two input variables NUM_1 and NUM_2 respectively. Two bytes are reserved for SUM which is used to hold the sum NUM_1 + NUM_2. As this is to be the input for the subroutine SQR_ROOT, it is declared global at the end of the file. This means that the location is public, that is additional files that are linked together can use the label SUM by declaring it extern – i.e. external to the file. Variables not declared thus are ‘hidden’ from the outside world, i.e. are private (or local) variables. In this manner the directive extern at the head of Program 8.2 allows the main routine to call the subroutines SQR_ROOT and SQR without knowing in advance where they are. In the same way the variable SQUARE is used by subroutine SQR to return the square of the byte sent to it in W. Space for this is reserved in a GPR in subroutine SQR and its exact whereabouts is not known by main.asm but will be allocated later by the linker. From the map file of Table 8.6 it is finally located in File 11h.
214 The Quintessential PIC Microcontroller
Program 8.2 The main relocatable source file main.asm.
include |
"p16f84.inc" |
|||
extern |
SQR_ROOT, SQR, SQUARE |
|||
udata |
; |
Reserve static data |
||
NUM_1 |
res |
1 |
; |
The first number |
NUM_2 |
res |
1 |
; |
The second number |
SUM |
res |
2 |
; |
Two bytes HI:LO for the sum |
RMS |
res |
1 |
; |
One byte for the outcome |
VECTORS |
code |
|||
goto |
MAIN |
; |
The Reset vector |
|
TEXT |
code |
|||
MAIN |
movf |
NUM_1,w |
; |
Get Number 1 |
call |
SQR |
; |
Square it |
|
movf |
SQUARE+1,w |
; |
Get lower byte |
|
movwf |
SUM+1 |
; |
Is the low byte of sum |
|
movf |
SQUARE,w |
; |
Get upper byte |
|
movwf |
SUM |
; |
Is the high byte of sum |
|
movf |
NUM_2,w |
; |
Now get Number 2 |
|
call |
SQR |
; |
Square it |
|
movf |
SQUARE+1,w |
; |
Get lower byte |
|
addwf |
SUM+1,f |
; |
Add to the low byte of sum |
|
btfsc |
STATUS,C |
; |
Check if produces carry |
|
incf |
SUM,f |
; |
Add the carry |
|
movf |
SQUARE,w |
; |
Get upper byte |
|
addwf |
SUM,f |
; |
Add to the high byte of sum |
|
call |
SQR_ROOT |
; |
Work out the square root |
|
movwf |
RMS |
; |
which is the root mean square |
|
global |
SUM |
|||
end |
||||
The main body of the code follows the task list enumerated above. The value NUM_12 is placed in file registers SUM:SUM+1 to which the computed NUM_22 is added. The outcome is then used as input to subroutine SQR_ROOT to return the root-mean square byte in W. Finally this is copied to the file register named RMS, for which a single byte has been reserved in the Data stream.
The subroutine sqr.asm of Program 8.3 is based on the subroutine of Program 6.5 on page 152, which multiplies two byte numbers. In this case on entry the contents of the Working register are copied to a file register labelled X and a 16-bit version constructed in X_COPY_H:X_COPY_L. The shift and add algorithm then evaluates X × X = X2. These three file registers are allocated with the directive udata_ovr (OVeRlay Uninitialized