|
The MACRO
Page 20
INDEX
Macro,
in computer
applications, a set of keystrokes and instructions recorded and saved
under a short key code. When the key code is typed, the program
carries out the instructions of the macro. Program users create macros
to save time by replacing often-used, sometimes lengthy, series of
strokes with shorter versions. Doing this eliminates frequent
retyping, minimizes inadvertent typing errors, and enables users who
are unfamiliar with a program to play back sets of instructions pre-recorded
by someone more adept with the application. If the application
also includes a macro language that responds to variables and
conditional statements, the user can also control the outcome of a
procedure by having the macro respond differently under different
conditions. |
Don't get upset with a new term.
A MACRO is just like a SUB-ROUTINE.
It is a set of instructions that can be CALLed from the Main routine -
or from any routine, and are generally instructions that are called a
number of times.
In a future article we will show some of the advanced features of a macro, such
as performing a decision according to certain conditions.
In this section we will show how to "set-up" a MACRO.
BACK TO THE BEGINNING . .
.
A program is written with lines of code in NOTEPAD or TEXTPAD
and created on a template having 3 columns.
Each line of code is called a STATEMENT.
The first column contains the LABELS.
The second column contains the INSTRUCTIONS, (consisting of OP-CODES,
and OPERANDS.)
and the third column contains COMMENTS. (your notes describing
each line)
Here is an example of a STATEMENT:
|
Label: |
Instruction: |
Comment: |
|
Test1 |
MOVLW 0F |
;Put 15 into the
working register |
A Label is an identifier at the commencement of a statement to
identify the start of a section of code.
A section of code is called a ROUTINE or SUB-ROUTINE. It begins
with a Label (such as Test1) and ends with a RETURN (such as RETLW 00).
An Instruction is an operation to be carried out by a microcontroller. It
is written in mnemonics and consists of OP-CODES,
and OPERANDS. (The op-codes are mnemonics.) A mnemonic is a half-English,
half-computer word that both can understand. A space must be inserted between the
op-code and operand.
The value after the OP-CODE is called the OPERAND. The operand
can consist of a literal (also called a number or constant), a file or a
Label.
e.g: MOVLW C8 - the operand is a literal
MOVWF 1E - the operand is a
file
GOTO Test1 - the operand is a label
When the Instruction operates on a file, the result of the operation can be
placed in the file itself, or in W (the WORKING REGISTER). This is
called the DESTINATION of the operation and can be written as 0 or 1,
where 0 puts the result in W and 1 puts the result in the file.
Some assemblers (not MPASM) prefer the more-readable destinations of the
operands: ",w" and ",f" to specify the destination
register. When no destination is specified, the file itself is selected
by the assembler. The letter in the destination operand can be upper or lower
case. The letters 0, 1, f and w are called DESTINATION DESIGNATORS.
e.g: INCF 1E,1 - the result is placed in the file
INCF 1E,0 - the
result is placed in W
INCF 1E,f - the
result is placed in the file
INCF 1E,w - the
result is placed in W
The layout of the OPERAND (including the DESTINATION DESIGNATOR)
is called SYNTAX.
The information written in the first and second columns of the template is called DIRECTIVES
and is acted upon by the assembler to produce code. (Directives can also consist of assembler
pseudo-ops and controls and may not produce code).
A semicolon ";" must be placed before any comments so they are not assembled.
Comments can be placed in any column. The semicolon is detected by the
assembler and anything after it on the same line is not assembled.
Literals (also called values or numbers) can be decimal or HEXADECIMAL. Hexadecimal numbers
containing letters must have a leading digit (e.g. 0FFh) for the assembler to
recognise it correctly, followed by the letter "h". Hexadecimal values can be either upper or lower case.
A LABEL is the name of a SUB-ROUTINE. It is
placed at the beginning of a line and assigned an address-value (the current
address), by the assembler.
Examples of labels:
Table1
ToneA
DelayB
A program must finish with an END statement in the second column. This will
terminate assembly by the assembler.
|
Label: |
Instructions: |
Comments: |
|
|
END |
;end of program |
When a PROGRAM is written and complete, the file is called a SOURCE FILE and will be assembled by an ASSEMBLER
into "0's" and "1's" for "burning" (also called
"downloading") into a microcontroller. This file is viewed as a HEX
FILE. (It is very difficult to view a block of "0's" and "1's.")
THE MACRO
A MACRO is laid out in the same way as a sub-routine. Instead of
the word "label", a macro is identified by the word "name."
The name of a MACRO is placed in the first column.
Examples of macro names:
Input1
Swap2
Count1
The second column contains the word macro followed by a list of parameters
called ARGUMENTS, with a comma separating each. The word macro is called
a DIRECTIVE.
Here is an example of how to layout the first line of a macro:
|
Name: |
pseudo-op: |
Comments: |
|
Count1 |
MACRO arg1, arg2, arg3 |
;the variables to count
|
A macro must end with ENDM in the second column.
|
|
pseudo-op: |
Comments: |
|
|
ENDM |
;end macro
|
Between these two pseudo-ops (directives), we place
normal PIC instructions.
Here is an example of a macro:
|
Name: |
pseudo-op: |
Comments: |
|
Gyro1 |
MACRO |
;start of macro
|
|
|
MOVLW 08 |
;Put 8 into W
|
|
|
MOVWF 1A,1 |
;Put 8 into file 1A
|
|
|
MOVWF INDF |
;Uses value in FSR to put 8 into a location
|
|
|
DECF FSR,1 |
;Decrement where INDF will put 8
|
|
|
ENDM |
;End macro
|
The Main routine (or a sub-routine) can CALL a macro by
including the name of the macro in the Main routine: (this is not a
functioning Main routine)
|
Label: |
Instructions: |
Comments: |
|
Main |
MOVLW 0F |
;Put 15 into the
working register |
|
|
MOVWF 0C,1 |
;Put 15 into file
0C |
|
|
Gyro1 |
;Call Gyro1 macro |
|
|
DECFSZ 1E,1 |
;Decrement file
1E and if it is zero, Loop Main. |
|
|
CALL Count1 |
;Call a
sub-routine |
|
|
GOTO Main |
;Loop Main |
The following shows how to set up a macro and call it from a sub-routine:
The full details of how the 8x8 routine works can be found on
page
11 of the PIC Theory course.
The sub-routine 8x8 multiplies two 8-bit numbers and puts the
result into two files (0D and 0B)
by calling macro 8 times. (The macro routine is called: Multiply).
(You can loop the macro routine, as shown below.)
Example: multiply 8E(in file 0A) by 6C(in file 0B)
Answer: high byte in 0D, low byte
in 0B (file 0B contains the low-byte answer!)
|
Multiply |
MACRO |
|
|
|
BTFSC
03,0 |
;Test the
carry bit in the STATUS register |
|
|
ADDWF 0D,1 |
|
|
|
RRF 0D,1 |
|
|
|
RRF 0B,1 |
|
|
|
ENDM
|
|
|
|
|
|
|
8x8 |
MOVF 0A,0 |
;Put the value in file 0A (8E) into W. (1
cycle) |
|
|
CLRF 0D |
;Clear the
high-byte answer file (1
cycle) |
|
|
RRF 0B,1 |
(1 cycle) |
|
|
Multiply |
(4 cycles) |
|
|
Multiply |
(4 cycles) |
|
|
Multiply |
(4 cycles) |
|
|
Multiply |
(4 cycles) |
|
|
Multiply |
(4 cycles) |
|
|
Multiply |
(4 cycles) |
|
|
Multiply |
(4 cycles) |
|
|
Multiply |
(4 cycles) |
|
|
RETLW 00 |
(2 cycles) |
The following shows how to loop the macro:
|
Multiply |
MACRO |
|
|
|
BTFSC
03,0 |
;Test the
carry bit in the STATUS register |
|
|
ADDWF 0D,1 |
|
|
|
RRF 0D,1 |
|
|
|
RRF 0B,1 |
|
|
|
ENDM
|
|
|
|
|
|
|
8x8 |
MOVLW 08 |
|
|
|
MOVWF 0E |
|
|
|
MOVF 0A,0 |
;Put the value in file 0A (8E) into W. |
|
|
CLRF 0D |
;Clear the
high-byte answer file |
|
|
RRF 0B,1 |
|
|
Loop |
Multiply |
|
|
|
DECFSZ 0E,1 |
|
|
|
GOTO Loop |
|
|
|
RETLW 00 |
|
BE CAREFUL . . .
There are a number of sites that suggest you add their list of macros to your
programming library.
The main problem with their concept is the addition of new wording. Words like
CASE, BNE, POLL, WAITWHILE, all need to be fully understood before adding them
to your program.
The whole idea of learning PIC language is the small number of terms that
needs to be understood.
All that is being done by the introduction of a "library of macro's" is to
make things more complex!
Nothing offered in any of the routines cannot be done in exactly the same
number of steps via PIC code and if you write the code yourself, you will be
able to fault-find it MUCH QUICKER.
For simple or medium-complex designs, the easiest and best way to write a
program is via our LINEAR APPROACH.
This involves using very simple sub-routines and doesn't involve macros or
complex Boolean expressions.
I know it's wonderful (and clever) to produce a program that gets you thinking
at each line of code but one day you will be required to modify a design and you
will appreciate the simple approach.
For the moment, keep everything simple. As soon as you get into complex
programming, things will have to change. Face that later.
NEXT
|