o Assemblers o C compilers
o The Freeware 68HC12 Assembler
• Debuggers and Interpreters
• Simulators, Evaluation Boards, and In-circuit Emulation • Flowcharts and Pseudocode
Assemblers and Compilers
It is possible to program a microcontroller by writing the actual processor code; however this is rarely done because it is difficult for the following reasons:
• There are over 200 operation codes (opcodes) that must be either memorized or looked up.
• Operand encoding can be complex. It wasn't in the example we've seen, but take a look at sections 4.5 through 4.8 in the HCS12 Core Users Guide if you want to get frightened.
• If the program changes code and data move, so addresses often need to be recalculated.
• There is no convenient way to document the program.
Alternatives to writing the machine code exist; in fact they have existed for over 45 years. These include assemblers and compilers.
Assemblers
An assembler takes a symbolically represented program and converts it into machine code. The assembler itself is a program that either runs on the target system (there is a small one built into the evaluation boards used in the lab) or run on development systems, such as personal computers. The latter are often referred to as cross-assemblers. Opcodes are referred to by their mnemonics as shown in the Reference Manual. Memory locations of data and code can be labeled, giving that location a symbolic name whose value changes automatically if the target location moves. The assembler evaluates algebraic expressions, saving hand calculations, and generates correctly formatted operands. Comment text can be placed in the assembler source file to document the program. Assemblers maintain a location counter and assemble code and data at the memory
The basic syntax of all assemblers is similar, although they do vary in details. The free AS12 assembler, provided on the CD, is used in this text. Here is the assembler source code for the example program we have seen:
org $1000 ; Set current location to start of RAM p: db $25 ; First addend is at location p
q: db $37 ; Second addend is at location q r: ds 1 ; Sum will be stored at location r org $2000 ; Set current location to start in ROM ldaa p ; load value at p into accumulator a adda q ; add value at q into accumulator a deca ; decrement a
staa r ; store accumulator a at location r end ; signify end of source code
There is only one statement per line, where a statement is either an assembler directive or a CPU instruction. If the location is to be labeled, the symbol name appears in the first column of the statement, otherwise the first column is blank. The label ends with a colon. The next field in a statement is either the assembler directive or cpu instruction
mnemonic. This is then followed the operand field which consists of any operands separated by commas if there is more than one. All fields are separated by spaces or tab characters.
Comments appear at the end of lines, following a semicolon character. A line can also be blank, consist of only a comment, or contain only a label.
In the example above, the org db ds and end mnemonics are assembler directives.
Assembler directives are instructions for the assembler program and are not microcontroller instructions. These will be described later in this section.
Most assemblers have a macro facility. This provides a method so that a single statement, the macro invocation or call, can expand into any number of assembler statements. Using macros can reduce the amount of work required to write larger programs.
For particularly large programs, it can be a nuisance to have the entire program in a single source file. This is particularly the case in projects which involve more than one programmer. A linker program can be used to combine the output of several assembled files. The linker can resolve references to labels between separate files.
C compilers
It is also possible to program a microcontroller using a “high level language”, of which the language “C” is by far the most common. What makes the language “high level” is that programs can be written without knowing the underlying processor architecture or operation codes. Even for one familiar with the target microcontroller, using a compiler saves time because a single high level language statement can be the equivalent of a dozen machine instructions.
The negatives about a compiler center mainly about the efficiency of the generated code. An experienced assembly language programmer can write faster and more compact programs than a C compiler can generate. In microcontrollers, memory is often limited and the processors are slow. This often mandates the use of an assembler for at least the time-critical parts of a program.
The program example we have seen could be reduced to the following two statements in C:
char p=0x25, q=0x37, r; r = p+q-1;
Another disadvantage of using a compiler can be cost. Because sales volume is low, a good C compiler for a microcontroller can cost thousands of dollars. This expense can be justified based on engineering time saved on medium to large scale projects, but can be difficult for small projects and, needless to say, personal use.
A free C compiler and IDE (Integrated Development Environment) is available from http:// www.geocities.com/englere_geo. You might find it interesting to look at this compiler once you have become knowledgeable about the operation of the 68HC12. The remainder of this text assumes all programs will be written using an assembler, in
particular the freeware assembler described next. For those who know the C language, the text will occasionally show C equivalent code for assembler constructs to aid in the adoption of C in microcontroller programming.