Chapters of Assembly Language 2
Chapters of Assembly Language 2
Chapters of Assembly Language 2
TOC
Chapter 1
Chapter 2
Chapter 3
Chapter 4
Chapter 5
Chapter 6
Chapter 7
Introduction
The process of writing program for the microcontroller mainly consists of giving instructions
(commands) in the specific order in which they should be executed in order to carry out a
specific task. As electronics cannot understand what for example an instruction if the push
button is pressed- turn the light on means, then a certain number of simpler and precisely
defined orders that decoder can recognise must be used. All commands are known as
INSTRUCTION SET. All microcontrollers compatibile with the 8051 have in total of 255
instructions, i.e. 255 different words available for program writing.
At first sight, it is imposing number of odd signs that must be known by heart. However, It is not
so complicated as it looks like. Many instructions are considered to be different, even though
they perform the same operation, so there are only 111 truly different commands. For example:
ADD A,R0, ADD A,R1, ... ADD A,R7 are instructions that perform the same operation (additon
of the accumulator and register). Since there are 8 such registers, each instruction is counted
separately. Taking into account that all instructions perform only 53 operations (addition,
subtraction, copy etc.) and most of them are rarely used in practice, there are actually 20-30
abbreviations to be learned, which is acceptable.
Arithmetic Instructions
Branch Instructions
Logic Instructions
Bit-oriented Instructions
The first part of each instruction, called MNEMONIC refers to the operation an instruction
performs (copy, addition, logic operation etc.). Mnemonics are abbreviations of the name of
operation being executed. For example:
LAB5);
JNZ LOOP - Means: Jump if Not Zero LOOP (if the number in the accumulator is
The other part of instruction, called OPERAND is separated from mnemonic by at least one
whitespace and defines data being processed by instructions. Some of the instructions have no
operand, while some of them have one, two or three. If there is more than one operand in an
instruction, they are separated by a comma. For example:
marked as TEMP;
CJNE A,#20,LOOP - compare accumulator with 20. If they are not equal, jump
Arithmetic instructions
Arithmetic instructions perform several basic operations such as addition, subtraction, division,
multiplication etc. After execution, the result is stored in the first operand. For example:
ADD A,R1
Mnemonic Description
Byt Cycl
e e
ADD A,Rn
ADD
A,direct
ADD
A,#data
ADDC A,Rn Adds the register to the accumulator with a carry flag 1
ADDC
A,direct
ADDC
A,@Ri
ADDC
A,#data
SUBB A,Rn
SUBB
A,direct
SUBB
A,@Ri
SUBB
A,#data
INC A
INC Rn
INC Rx
INC @Ri
DEC A
DEC Rn
DEC Rx
DEC @Ri
INC DPTR
MUL AB
Multiplies A and B
DIV AB
Divides A by B
DA A
BCD code
Branch Instructions
There are two kinds of branch instructions:
Unconditional jump instructions: upon their execution a jump to a new location from where the
program continues execution is executed.
Conditional jump instructions: a jump to a new program location is executed only if a specified
condition is met. Otherwise, the program normally proceeds with the next instruction.
Branch Instructions
Mnemonic
Description
Byt Cycl
e e
RET
RETI
AJMP addr11
Absolute jump
LJMP addr16
Long jump
SJMP rel
JC rel
JNC rel
JB bit,rel
JBC bit,rel
JZ rel
JNZ rel
CJNE
A,direct,rel
CJNE
A,#data,rel
CJNE
Rn,#data,rel
CJNE
Compares immediate data to indirect register and jumps if
@Ri,#data,rel not equal. Short jump.
DJNZ Rn,rel
DJNZ Rx,rel
NOP
No operation
Description
Byt Cycl
e e
MOV A,Rn
MOV A,direct
MOV A,@Ri
MOV A,#data
MOV Rn,A
MOV direct,A
MOV
direct,direct
MOV
direct,@Ri
MOV
direct,#data
MOV @Ri,A
MOV
@Ri,direct
MOV
@Ri,#data
MOV
DPTR,#data
MOVC
A,@A+DPTR
MOVC
A,@A+PC
MOVX A,@Ri
3-10
MOVX
A,@DPTR
3-10
MOVX @Ri,A
4-11
MOVX
@DPTR,A
4-11
PUSH direct
POP direct
XCH A,Rn
XCH A,direct
XCH A,@Ri
XCHD A,@Ri
Logic Instructions
Logic instructions perform logic operations upon corresponding bits of two registers. After
execution, the result is stored in the first operand.
Logic Instructions
Mnemonic
Description
Byt Cycl
e e
ANL A,Rn
ANL A,direct
ANL A,@Ri
ANL A,#data
ANL direct,A
ANL
direct,#data
ORL A,Rn
OR register to accumulator
ORL A,direct
ORL A,@Ri
ORL direct,A
ORL
direct,#data
XRL A,Rn
XRL A,direct
XRL A,@Ri
XRL A,#data
XRL direct,A
XORL
direct,#data
CLR A
CPL A
SWAP A
RL A
RLC A
RR A
RRC A
Bit-oriented Instructions
Similar to logic instructions, bit-oriented instructions perform logic operations. The difference is
that these are performed upon single bits.
Bit-oriented Instructions
Mnemo
Description
nic
Byt Cycl
e e
CLR C
CLR bit
SETB C
CPL C
CPL bit
ANL
C,/bit
ORL
C,bit
ORL
C,/bit
MOV
C,bit
MOV
bit,C
A - accumulator;
Rn - is one of working registers (R0-R7) in the currently active RAM memory
bank;
Direct - is any 8-bit address register of RAM. It can be any general-purpose
register or a SFR (I/O port, control register etc.);
addr11 - is an 11-bit address. May be within the same 2KB page of program
memory as the first byte of the following instruction;
rel - is the address of a close memory location (from -128 to +127 relative to
the first byte of the following instruction). On the basis of it, assembler
computes the value to add or subtract from the number currently stored in
the program counter;
A: accumulator
Direct: Arbitrary register with address 0 - 255 (0 - FFh)
Description: Instruction adds the direct byte to the accumulator. As it is direct addressing, the
direct can be any SFR or general-purpose register with address 0-7 Fh. The result is stored in the
accumulator.
Syntax: ADD A, register name;
Bytes: 2 (instruction code, direct byte address);
STATUS register flags: C, OV and AC;
EXAMPLE:
Before execution: A= C3h (195 dec.) R0= AAh (170 dec.) C=1
After execution: A= 6Eh (110 dec.) AC=0, C=1, OV=1
ADD A,#data - Adds the immediate data to the accumulator
A: accumulator
Data: constant within 0-255 (0-FFh)
Description: Instruction adds data (0-255) to the accumulator. After addition, the result is stored
in the accumulator.
Syntax: ADD A,#data;
Bytes: 2 (instruction code, data);
STATUS register flags: C, OV and AC;
EXAMPLE:
Description: Instruction adds the direct byte to the accumulator with a carry flag. As it is direct
addressing, the register can be any SFRs or general purpose register with address 0-7Fh (0127dec.). The result is stored in the accumulator.
Syntax: ADDC A, register address;
Bytes: 2 (instruction code, direct);
STATUS register flags: C, OV and AC;
EXAMPLE:
Before execution: A= C3h (195 dec.) TEMP = AAh (170 dec.) C=1
After execution: A= 6Eh (110 dec.) AC=0, C=1, OV=1
ADDC A,@Ri - Adds the indirect RAM to the accumulator with a carry flag
A: accumulator
Ri: Register R0 or R1
Description: Instruction adds the indirect RAM to the accumulator with a carry flag. RAM
address is stored in the Ri register (R0 or R1). After addition, the result is stored in the
accumulator.
Syntax: ADDC A,@Ri;
Byte: 1 (instruction code);
STATUS register flags: C, OV and AC;
EXAMPLE:
Before execution: X= C3h (11000011 Bin.) MASK= 55h (01010101 Bin.) After execution:
MASK= 41h (01000001 Bin.)
ANL C,bit - AND direct bit to the carry flag
C: Carry flag
Bit: any bit of RAM
Description: Instruction performs logic AND operation between the direct bit and the carry flag.
bi C AND
C
t
bit
0 00
0 10
1 00
1 11
Description: This instruction first decrements value in the register. If the result is 0, the program
proceeds with execution. Otherwise, a jump to the specified address in the program will be
executed. As it is direct addressing, the register must be within the first 255 locations of RAM.
This is a short jump instruction, which means that the address of a new location must be
relatively near the current one (-128 to +127 locations relative to the first following instruction).
Syntax: DJNZ direct,[jump address];
Bytes: 3 (instruction code, direct, jump address);
STATUS register flags: No flags are affected;
EXAMPLE:
be executed. This is a short jump instruction, which means that the address of a new location
must be relatively near the current one (- 128 to +127 locations relative to the first following
instruction).
Syntax: DJNZ Rn, [jump address];
Bytes: 2 (instruction code, jump address);
STATUS register flags: No flags are affected;
EXAMPLE:
Description: This instruction increments the value in the directly addressed register of RAM by
1. The register address is stored in the Ri Register (R0 or R1). If the register includes the number
255, the result of the operation will be 0.
Syntax: INC @Ri;
Byte: 1 (instruction code);
STATUS register flags: No flags are affected;
EXAMPLE:
Description: This instruction first checks if the bit is set. If set, a jump to the specified address is
executed and the bit is cleared. Otherwise, the program proceeds with the first following
instruction. This is a short jump instruction, which means that the address of a new location must
be relatively near the current one (-129 to + 127 locations relative to the first following
instruction).
Syntax: JBC bit, [jump address];
Bytes: 3 (instruction code, bit address, jump address);
STATUS register flags: No flags are affected;
EXAMPLE:
Description: Instruction moves the direct byte to another direct byte. As it is direct addressing,
both registers can be any SFRs or general-purpose registers with address 0-7Fh. (0-127 dec.).
The direct1 is not affected.
Syntax: MOV direct1,direct2;
Bytes: 3 (instruction code, direct1 address, direct2 address);
STATUS register flags: No flags are affected.
EXAMPLE:
Description: Instruction moves the carry flag to the direct bit. After executing the instruction,
the carry flag is not affected.
Syntax: MOV bit,C;
Bytes: 2 (instruction code, bit address);
STATUS register flags: No flags are affected;
EXAMPLE:
Before execution:
DPTR=1000:
A=0
A=1
A=2
A=3
After execution:
A=66h
A=77h
A=88h
A=99h
After the subroutine "Table" has been executed, one of four values is stored in the accumulator:
Before execution:
A=0
A=1
A=2
A=3
After execution:
A=66h
A=77h
A=88h
A=99h
Note: DB (Define Byte) is a directive in assembly language used to define constant.
MOVX @Ri,A - Moves the accumulator to the external RAM (8-bit address)
Ri: register R0 or R1
A: accumulator
Description: Instruction moves the accumulator to a register stored in external RAM. Its address
is stored in the Ri register.
Syntax: MOVX @Ri,A;
Byte: 1 (instruction code);
STATUS register flags: No flags affected;
EXAMPLE:
Note:
Register SUM is located in external RAM which is up to 64K in size.
MUL AB - Multiplies A and B
A: accumulator
B: Register B
Description: Instruction multiplies the value in the accumulator with the value in the B register.
The low-order byte of the 16-bit result is stored in the accumulator, while the high byte remains
in the B register. If the result is larger than 255, the overflow flag is set. The carry flag is not
affected.
Syntax: MUL AB;
Byte: 1 (instruction code);
STATUS register flags: No flags affected;
EXAMPLE:
Description: Instruction doesnt perform any operation and is used when additional time delays
are needed.
Syntax: NOP;
Byte: 1 (instruction code);
STATUS register flags: No flags affected;
EXAMPLE:
Such a sequence provides a negative pulse which lasts exactly 5 machine cycles on the P2.3. If a
12 MHz quartz crystal is used then 1 cycle lasts 1uS, which means that this output will be a lowgoing output pulse for 5 uS.
ORL A,@Ri - OR indirect RAM to the accumulator
Ri: register R0 or R1
A: accumulator
Description: Instruction performs logic OR operation between the accumulator and a register.
As it is indirect addressing, the register address is stored in the Ri register (R0 or R1). The result
is stored in the accumulator.
Syntax: ANL A,@Ri;
Byte: 1 (instruction code);
STATUS register flags: No flags affected;
EXAMPLE:
Description: Instruction performs logic OR operation between the immediate data and the direct
byte. As it is direct addressing, the direct byte can be any SFRs or general-purpose register with
address 0-7Fh (0-127 dec.). The result is stored in the direct byte.
Syntax: ORL [register address],#data;
Bytes: 3 (instruction code, direct byte address, data);
STATUS register flags: No flags affected;
EXAMPLE:
RLC A - Rotates the accumulator one bit left through the carry flag
A: accumulator
Description: All eight bits in the accumulator and carry flag are rotated one bit left. After this
operation, the bit 7 is rotated into the carry flag position and the carry flag is rotated into the bit 0
position.
Syntax: RLC A;
Byte: 1 (instruction code);
STATUS register flags: C;
EXAMPLE:
Syntax: RRC A;
Byte: 1 (instruction code);
STATUS register flags: C;
EXAMPLE:
EXAMPLE:
Ri: register R0 or R1
A: accumulator
Description: Instruction subtracts the indirectly addressed register of RAM from the
accumulator with a borrow. If the higher bit is subtracted from the lower bit then the carry flag is
set. As it is indirect addressing, the register address is stored in the Ri register (R0 or R1). The
result is stored in the accumulator.
Syntax: SUBB A,@Ri;
Byte: 1 (instruction code);
STATUS register flags: C, OV, AC;
EXAMPLE:
XCHD A,@Ri - Exchanges the low-order nibble indirect RAM with the accumulator
Ri: register R0 or R1
A: accumulator
Description: This instruction interchanges the low-order nibbles (bits 0-3) of the accumulator
with the low-order nibbles of the indirectly addressed register of RAM. High-order nibbles of the
accumulator and register are not affected. This instruction is mainly used when operating with
BCD values. As it is indirect addressing, the register address is stored in the register Ri (R0 or
R1).
Syntax: XCHD A,@Ri;
Byte: 1 (instruction code);
STATUS register flags: No flags are affected;
EXAMPLE:
Ri: Register R0 or R1
A: accumulator
Description: Instruction performs exclusive OR operation between the accumulator and the
indirectly addressed register. As it is indirect addressing, the register address is stored in the Ri
register (R0 or R1). The result is stored in the accumulator.
Syntax: XRL A,@Ri;
Byte: 1 (instruction code);
STATUS register flags: No flags are affected;
EXAMPLE:
Description: Instruction performs exclusive OR operation between the accumulator and the
immediate data. The result is stored in the accumulator.
Syntax: XRL A,#data;
Bytes: 2 (instruction code, data);
STATUS register flags: No flags are affected;
EXAMPLE:
CHAPTER-FIVE
Introduction
It was time that hardware-oriented to the core made compromise if they wanted to stay in the
game. Namely, unlike other circuits which only need to be connected to other components and
powered in order to be of any use, microcontrollers require to be programmed as well.
Fortunately, they still didn't progress so far in their evolution, so that all microcontroller families
understand only one language - machine language. That's a good thing. The bad one is that,
even primitive, this language of zeros and ones can only be understood by microcontrollers and
some of the experts working on its development. In order to bridge this gap between machine
and humans, the first high-level programming language called Assembly language was created.
The main problem of remembering codes recognized as instructions by electronics was solved
therefore, but another one, equally complicated to both us and them(microcontrollers) arose.
This problem was also easily solved by means of the program for a PC called assembler and a
simple device called programmer.
This program enables the PC to receive commands in the form of abbreviations and convert them
unerringly into so called executable file. The moment of compiling a program into machine
language is crucial as this file, called HEX file, represents a series of binary numbers
understandable to microcontrollers only. The program written in assembly language cannot be
executed practically unless this file is loaded into the microcontroller memory. This is the
moment when the last link in the chain - the programmer - appears on the scene. It is a small
device connected to a PC via some of the ports and has a socket for placing chip in.
Labels;
Orders;
Directives; and
Comments.
Text following the mark ; in a program line represents a comment ignored (not
compiled) by the assembler; and
All the elements of one program line (labels, instructions etc.) must be separated by at
least one space character. For the sake of better clearness, a push button TAB on a
keyboard is commonly used instead of it, so that it is easy to delimit columns with labels,
directives etc. in a program.
Numbers
If octal number system, otherwise considered as obsolite, is disregarded, assembly laguage
allows numbers to be used in one out of three number systems:
Decimal Numbers
If not stated otherwise, the assembly language considers all the numbers as decimal. All ten
digits are used (0,1,2,3,4,5,6,7,8,9). Since at most 2 bytes are used for saving them in the
microcontroller, the largest decimal number that can be written in assembly language is 65535. If
it is necessary to specify that some of the numbers is in decimal format, then it has to be
followed by the letter D. For example 1234D.
Hexadecimal Numbers
Hexadecimal numbers are commonly used in programming. There are 16 digits in hexadecimal
number system (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F). The largest hexadecimal number that
can be written in assembly language is FFFF. It corresponds to decimal number 65535. In order
to distinguish hexadecimal numbers from decimal, they are followed by the letter h(either in
upper- or lowercase). For example 54h.
Binary Numbers
Binary numbers are often used when the value of each individual bit of some of the registers is
important, since each binary digit represents one bit. There are only two digits in use (0 and 1).
The largest binary number written in assembly language is 1111111111111111. In order to
distinguish binary numbers from other numbers, they are followed by the letter b (either in
upper- or lowercase). For example 01100101B.
Operators
Some of the assembly-used commands use logical and mathematical expessions instead of
symbols having specific values. For example:
IF (VERSION>1)
LCALL Table_2
USING VERSION+1
ENDIF
...
As seen, the assembly language is capable of computing some values and including them in a
program code, thus using the following mathematical and logical operations:
Name
+
*
/
MOD
SHR
SHL
NOT
AND
OR
XOR
LOW
HIGH
EQ, =
NE,<>
GT, >
GE, >=
LT, <
LE,<=
Operation
Example
Addition
10+5
Subtraction
25-17
Multiplication
7*4
Division (with no remainder)
7/4
Remainder of division
7 MOD 4
Shift register bits to the right
1000B SHR 2
Shift register bits to the left
1010B SHL 2
Negation (first complement of number) NOT 1
Logical AND
1101B AND 0101B
Logical OR
1101B OR 0101B
Exclusive OR
1101B XOR 0101B
8 low significant bits
LOW(0AADDH)
8 high significant bits
HIGH(0AADDH)
Equal
7 EQ 4 or 7=4
Not equal
7 NE 4 or 7<>4
Greater than
7 GT 4 or 7>4
Greater or equal
7 GE 4 or 7>=4
Less than
7 LT 4 or 7<4
Less or equal
7 LE 4 or 7<=4
Result
15
8
28
1
3
0010B
101000B
1111111111111110B
0101B
1101B
1000B
0DDH
0AAH
0 (false)
0FFFFH (true)
0FFFFH (true)
0FFFFH (true)
0 (false)
0 (false)
Symbols
Every register, constant, address or subroutine can be assigned a specific symbol in assembly
language, which considerably facilitates the process of writing a program. For example, if the
P0.3 input pin is connected to a push button used to stop some process manually (push button
STOP), the process of writing a program will be much simpler if the P0.3 bit is assigned the
same name as the push button, i.e. pushbutton_STOP. Of course, like in any other language,
there are specific rules to be observed as well:
For the purpose of writing symbols in assembly language, all letters from alphabet (A-Z,
a-z), decimal numbers (0-9) and two special characters ("?" and "_") can be used.
Assembly language is not case sensitive.
START_ADDRESS_OF_TABLE_AND_CONSTANTS_1
START_ADDRESS_OF_TABLE_AND_CONSTANTS_2
TABLE_OF_CONSTANTS_1_START_ADDRESS
TABLE_OF_CONSTANTC_2_START_ADDRESS
Some of the symbols cannot be used when
Here is a list of symbols not allowed to be used during programming in assembly language:
A
ADDC
AR0
AR4
BIT
CJNE
CSEG
DBIT
DPTR
END
GT
ISEG
JMP
JZ
LOW
MOVC
NOP
ORL
R0
R4
RET
RR
SHL
SWAP
XDATA
AB
ACALL ADD
AJMP AND ANL
AR1
AR2
AR3
AR5
AR6
AR7
BSEG C
CALL
CLR
CODE CPL
DA
DATA DB
DEC DIV
DJNZ
DS
DSEG DW
EQ
EQU
GE
HIGH IDATA INC
JB
JBC
JC
JNB
JNC
JNZ
LCALL LE
LJMP
LT
MOD MOV
MOVX MUL NE
NOT OR
ORG
PC
POP
PUSH
R1
R2
R3
R5
R6
R7
RETI RL
RLC
RRC SET
SETB
SHR
SJMP SUBB
USING XCH XCHD
XOR XRL
XSEG
Labels
A label is a special type of symbols used to represent a textual version of an address in ROM or
RAM memory. They are always placed at the beginning of a program line. It is very complicated
to call a subroutine or execute some of the jump or branch instructions without them. They are
easily used:
A symbol (label) with some easily recognizable name should be written at the beginning
of a program line from which a subroutine starts or where jump should be executed.
It is sufficient to enter the name of label instead of address in the form of 16-bit number
in instructions calling a subroutine or jump.
During the process of compiling, the assembler automatically replaces such symbols with
appropriate addresses.
Directives
Unlike instructions being compiled and written to chip program memory, directives are
commands of assembly language itself and have no influence on the operation of the
microcontroller. Some of them are obligatory part of every program while some are used only to
facilitate or speed up the operation.
Directives are written in the column reserved for instructions. There is a rule allowing only one
directive per program line.
EQU directive
The EQU directive is used to replace a number by a symbol. For example:
MAXIMUM EQU 99
After using this directive, every appearance of the label MAXIMUM in the program will be
interpreted by the assembler as the number 99 (MAXIMUM = 99). Symbols may be defined this
way only once in the program. The EQU directive is mostly used at the beginning of the program
therefore.
SET directive
The SET directive is also used to replace a number by a symbol. The significant difference
compared to the EQU directive is that the SET directive can be used an unlimited number of
times:
SPEED SET 45
SPEED SET 46
SPEED SET 57
BIT directive
The BIT directive is used to replace a bit address by a symbol. The bit address must be in the
range of 0 to 255. For example:
TRANSMIT BIT PSW.7 ;Transmit bit (the seventh bit in PSW register)
;is assigned the name "TRANSMIT"
OUTPUT BIT 6 ;Bit at address 06 is assigned the name "OUTPUT"
RELAY BIT 81 ;Bit at address 81 (Port 0)is assigned the name ;"RELAY"
CODE directive
The CODE directive is used to assign a symbol to a program memory address. Since the
maximum capacity of program memory is 64K, the address must be in the range of 0 to 65535.
For example:
RESET CODE 0 ;Memory location 00h called "RESET"
TABLE CODE 1024 ;Memory location 1024h called "TABLE"
DATA directive
The DATA directive is used to assign a symbol to an address within internal RAM. The address
must be in the range of 0 to 255. It is possible to change or assign a new name to any register.
For example:
TEMP12 DATA 32 ;Register at address 32 is named ;as "TEMP12"
STATUS_R DATA D0h ;PSW register is assigned the name ;"STATUS_R"
IDATA directive
The IDATA directive is used to change or assign a new name to an indirectly addressed register.
For example:
TEMP22 IDATA 32 ;Register whose address is in register ;at address 32 is named
as "TEMP22"
TEMP33 IDATA T_ADR ;Register whose address is in ;register T_ADR is named as
"TEMP33"
XDATA directive
The XDATA directive is used to assign a name to registers within external (additional) RAM
memory. The addresses of these registers cannot be larger than 65535. For example:
TABLE_1 XDATA 2048 ;Register stored in external
;memory at address 2048 is named
;as "TABLE_1"
ORG directive
The ORG directive is used to specify a location in program memory where the program
following directive is to be placed. For example:
BEGINNING ORG 100
...
...
ORG 1000h
TABLE
...
...
This program starts at location 100. The table containing data is to be stored at location 1024
(1000h).
USING directive
The USING directive is used to define which register bank (registers R0-R7) is to be used in the
program.
USING
USING
USING
USING
0
1
2
3
;Bank
;Bank
,Bank
;Bank
0
1
2
3
is
is
is
is
used
used
used
used
(registers
(registers
(registers
(registers
R0-R7
R0-R7
R0-R7
R0-R7
at
at
at
at
RAM-addresses
RAM-addresses
RAM-addresses
RAM-addresses
0-7)
8-15)
16-23)
24-31)
END directive
The END directive is used at the end of every program. The assembler will stop compiling once
the program encounters this directive. For example:
...
END ;End of program
The CSEG segment is activated by default after enabling the assembler and remains active until
a new directive is specified. Each of these memory segments has its internal address counter
which is cleared every time the assembler is activated. Its value can be changed by specifying
value after the mark AT. It can be a number, an arithmetical operation or a symbol. For example:
DSEG
;Next segment refers to directly accessed registers; and
BSEG AT 32 ;Selects bit-addressable part of memory with address counter
;moved by 32 bit locations relative to the beginning of that
;memory segment.
A dollar symbol "$" denotes current value of address counter in the currently active segment.
The following two examples illustrate how this value can be used practically:
Example 1:
JNB FLEG,$ ;Program will constantly execute this
;instruction (jump instruction),until
;the flag is cleared.
Example 2:
MESSAGE DB ALARM turn off engine
LENGTH EQU $-MESSAGE-1
These two program lines can be used for computing exact number of characters in the message
ALARM turn off engine which is defined at the address assigned the name MESSAGE.
DS directive
The DS directive is used to reserve memory space expressed in bytes. It is used if some of the
following segments ISEG, DSEG or XSEG is currently active. For example:
Example 1:
DSEG
;Select directly addressed part of RAM
DS 32
;Current value of address counter is incremented by 32
SP_BUFF DS 16 ;Reserve space for serial port buffer
;(16 bytes)
IO_BUFF DS 8 ;Reserve space for I/O buffer in size of 8 bytes
Example 2:
ORG 100
;Start at address 100
DS 8
;8 bytes are reserved
LAB ......... ;Program proceeds with execution (address of this location is
108)
DBIT directive
The DBIT directive is used to reserve space within bit-addressable part of RAM. The memory
size is expressed in bits. It can be used only if the BSEG segment is active. For example:
BSEG ;Bit-addressable part of RAM is selected
IO_MAP DBIT 32 ;First 32 bits occupy space intended for I/O buffer
DB directive
The DB directive is used for writing specified value into program memory. If several values are
specified, then they are separated by a comma. If ASCII array is specified, it should be enclosed
within single quotation marks. This directive can be used only if the CSEG segment is active.
For example:
CSEG
DB 22,33,Alarm,44
If this directive is preceeded by a lable, then the label will point to the first element of the array.
It is the number 22 in this example.
DW directive
The DW directive is similar to the DB directive. It is used for writing a two-byte value into
program memory. The higher byte is written first, then the lower one.
IF, ENDIF and ELSE directives
These directives are used to create so called conditional blocks in the program. Each of these
blocks starts with directive IF and ends with directive ENDIF or ELSE. The statement or symbol
(in parentheses) following the IF directive represents a condition which specifies the part of the
program to be compiled:
If the statement is correct or if the symbol is equal to one, the program will include all
instructions up to directive ELSE or ENDIF.
If the statement is not correct or if the symbol value is equal to zero, all instructions are
ignored, i.e. not compiled, and the program continues with instructions following
directives ELSE or ENDIF.
Example 1:
IF (VERSION>3)
LCALL Table_2
LCALL Addition
ENDIF
...
If the program is of later date than version 3 (statement is correct), subroutines Table 2 and
Addition will be executed. If the statement in parentheses is not correct (VERSION<3), two
instructions calling subroutines will not be compiled.
Example 2:
If the value of the symbol called Model is equal to one, the first two instructions following
directive IF will be compiled and the program continues with instructions following directive
ENDIF (all instructions between ELSE and ENDIF are ignored). Otherwise, if Model=0,
instructions between IF and ELSE are ignored and the assembler compiles only instructions
following directive ELSE.
IF (Model)
MOV R0,#BUFFER
MOV A,@R0
ELSE
MOV R0,#EXT_BUFFER
MOVX A,@R0
ENDIF
...
Control directives
Control directives start with a dollar symbol $. They are used to determine which files are to be
used by the assembler during compilation, where the executable file is to be stored as well as the
final layout of the compiled program called Listing. There are many control directives, but only
few of them is of importance:
\$INCLUDE directive
This directive enables the assembler to use data stored in other files during compilation. For
example:
\$INCLUDE(TABLE.ASM)
\$MOD8253 directive
This $MOD8253 directive is a file containing names and addresses of all SFRs of 8253
microcontrollers. By means of this file and directive having the same name, the assembler can
compile the program on the basis of register names. If they are not used, it is necessary to specify
name and address of every SFRs to be used at the beginning of the program.
CHAPTER-SIX
Introduction
The purpose of this chapter is to provide basic information about microcontrollers that one needs
to know in order to be able to use them successfully in practice. This is why this chapter doesn't
contain any super interesting program or device schematic with amazing solutions. Instead, the
following examples are better proof that program writing is neither a privilege nor a talent issue,
but the ability of simply putting puzzle pieces together using directives. Rest assured that design
and development of devices mainly consists of the following method test-correct-repeat. Of
course, the more you are in it, the more complicated it becomes since the puzzle pieces are put
together by both children and first-class architects...
As seen in the figure above, in order to enable the microcontroller to operate properly it is
necessary to provide:
Power supply:
Reset signal: and
Clock signal.
Clearly, it is about very simple circuits, but it does not have to be always like that. If the target
device is used for controlling expensive machines or maintaining vital functions, everything gets
increasingly complicated. However, this solution is sufficient for the time being...
Power supply
Even though this microcontroller can operate at different power supply voltages, why to test
Murphys low?! A 5V DC is most commonly used. The circuit, shown in the figure, uses a
cheap integrated three-terminal positive regulator LM7805, and provides high-quality voltage
stability and quite enough current to enable the microcontroller and peripheral electronics to
operate normally (enough current in this case means 1Amp).
Reset signal
In order that the mucrocontroller can operate properly, a logic 0 (0V) must be applied to the reset
pin RS. The push button connecting the reset pin RS to power supply VCC is not necessary.
However, it is almost always provided because it enables the microcontroller safe return to
normal operating conditions if something goes wrong. 5V is brought to this pin, the
microcontroller is reset and program starts execution from the beginning.
Clock signal
Even though the microcontroller has a built-in oscillator, it cannot operate without two external
capacitors and quartz crystal which stabilize its operation and determines its frequency
(operating speed of the microcontroller).
Of course, it is not always possible to apply this solution so that there are always alternative
ones. One of them is to provide clock signal from a special source through invertor. See the
figure on the left.
Nevertheless, it is not so simple in practice... It is about contact bounce- a common problem with
m e c h a n i c a l switches. When the contacts strike together, their momentum and elasticity act
together to cause bounce. The result is a rapidly pulsed electrical current instead of a clean
transition from zero to full current. It mostly occurs due to vibrations, slight rough spots and dirt
between contacts. This effect is usually unnoticeable when using these components in everyday
life because the bounce happens too quickly. In other words, the whole this process does not last
long (a few micro- or miliseconds), but it is long enough to be registered by the microcontroller.
When using only a push-button as a pulse counter, errors occur in almost 100% of cases!
The simplest solution to this problem is to connect a simple RC circuit to suppress quick voltage
changes. Since the bounce period is not defined, the values of components are not precisely
determined. In most cases, it is recomended to use the values shown in figure below.
If complete stability is needed then radical measures should be taken. The output of the circuit,
shown in figure (RS flip-flop), will change its logic state only after detecting the first pulse
triggered by contact bounce. This solution is expensive (SPDT switch), but effecient, the
problem is definitely solved. Since the capacitor is not used, very short pulses can also be
registered in this way.
In addition to these hardware solutions, there is also a simple software solution. When a program
tests the state of an input pin and detects a change, the check should be done one more time after
a certain delay. If the change is confirmed, it means that a switch or push button has changed its
position. The advantages of such solution are obvious: it is free of charge, effects of noises are
eliminated and it can be applied to the poorer quality contacts as well. Disadvantage is the same
as when using RC filter, i.e. pulses shorter than program delay cannot be registered.
Optocoupler
Relay
A relays is an electrical switch that opens and closes under control of another electrical circuit. It
is therefore connected to ouput pins of the microcontroller and used to turn on/off high-power
devices such as motors, transformers, heaters, bulbs, antenna systems etc. These are almost
always placed away from the board sensitive components. There are various types of relays but
all of them operate in the same way. When a current flows through the coil, the relay is operated
by an electromagnet to open or close one or many sets of contacts. Similar to optocouplers, there
is no galvanic connection (electrical contact) between input and output circuits. Relays usually
demand both higher voltage and current to start operation, but there are also miniature ones
which can be activated by a low current directly obtained from a microcontroller pin.
The figure shows the solution specific to the 8051 microcontroller. A darlington transistor is used
here to activate relays because of its high current gain. This is not in accordance with rules, but
is necessary in the event that logic one activation is applied since the output current is then very
low (pin acts as an input).
In order to prevent the appearance of self-induction high voltage, caused by a sudden stop of
current flow through the coil, an inverted polarized diode is connected in parallel to the coil. The
purpose of this diode is to cut off the voltage peak.
Light-emitting diode (LED)
Light-emitting diodes are elements for light signalization in electronics. They are manufactured
in different shapes, colors and sizes. For their low price, low power consumption and simple use,
they have almost completely pushed aside other light sources, bulbs at first place. They perform
similar to common diodes with the difference that they emit light when current flows through
them.
It is important to limit their current, otherwise they will be permanently destroyed. For this
reason, a conductor must be connected in parallel to an LED. In order to determine value of this
conductor, it is necessary to know diodes voltage drop in forward direction, which depends on
what material a diode is made from and what colour it is. Typical values of the most frequently
used diodes are shown in table below. As seen, there are three main types of LEDs. Standard
ones get ful brightness at current of 20mA. Low Current diodes get ful brightness at ten times
lower current while Super Bright diodes produce more intensive light than Standard ones.
Color
Infrared
Red
Red
Red
Orange
Green
Yellow
Blue
White
Type
Since the 8051 microcontroller can provide only low output current and since its pins are
configured as outputs when voltage provided on them is 0V, direct connecting to LEDs is
performed as shown in figure on the right (Low current LED, cathode is connected to the output
pin).
LED displays
Basically, an LED display is nothing more than several LEDs moulded in the same plastic case.
There are many types of displays composed of several dozens of built in diodes which can
display different symbols.
Most commonly used is a so called 7-segment display. It is composed of 8 LEDs, 7 segments are
arranged as a rectangle for symbol displaying and there is an additional segment for decimal
point displaying. In order to simplify connecting, anodes and catodes of all diodes are connected
to the common pin so that there are common anode displays and common catode displays,
respectively. Segments are marked with the latters from A to G, plus dp, as shown in the figure
on the left. On connecting, each diode is treated separtely, which means that each must have its
own current limiting resistor.
Displays connected to the microcontroller usually occupy a large number of valuable I/O pins,
which can be a big problem especially if it is needed to display multy digit numbers. The
problem is more than obvious if, for example, it is needed to display two 6-digit numbers (a
simple calculation shows that 96 output pins are needed in this case). The solution to this
problem is called MULTIPLEXING. This is how an optical illusion based on the same operating
principle as a film camera is made. Only one digit is active at a time, but they change their state
so quickly making impression that all digits of a number are simultaneously active.
Here is an explanation on the figure above. First a byte representing units is applied on a
microcontroller port and a transistor T1 is activated at the same time. After a while, the transistor
T1 is turned off, a byte representing tens is applied on a port and a transistor T2 is activated. This
process is being cyclically repeated at high speed for all digits and corresponding transistors.
The fact that the microcontroller is just a kind of miniature computer designed to understand
only the language of zeros and ones is fully expressed when displaying any digit. Namely, the
microcontroller doesn't know what units, tens or hundreds are, nor what ten digits we are used to
look like. Therefore, each number to be displayed must be prepared in the following way:
First of all, a multy digit number must be split into units, tens etc. in a particular subroutine.
Then each of these digits must be stored in special bytes. Digits get familiar format by
performing masking. In other words, a binary format of each digit is replaced by a different
combination of bits in a simple subroutine. For example, the digit 8 (0000 1000) is replaced by
the binary number 0111 111 in order to activate all LEDs displaying digit 8. The only diode
remaining inactive in this case is reserved for the decimal point. If a microcontroller port is
connected to the display in such a way that bit 0 activates segment a, bit 1 activates segment
b, bit 2 segment c etc., then the table below shows the mask for each digit.
0 00 01 00
In addition to digits from 0 to 9, some letters of alphabet - A, C, E, J, F, U, H, L, b, c, d, o, r, t can also be displayed by performing appropriate masking.
If the event that common chatode displays are used all units in the table should be replaced by
zeros and vice versa. Additionally, NPN transistors should be used as drivers as well.
Liquid Crystal Displays (LCD)
An LCD display is specifically manufactured to be used with microcontrollers, which means that
it cannot be activated by standard IC circuits. It is used for displaying different messages on a
miniature liquid crysal display.
The model described here is for its low price and great capabilities most frequently used in
practice. It is based on the HD44780 microcontroller (Hitachi) and can display messages in two
lines with 16 characters each. It displays all the letters of alphabet, Greek letters, punctuation
marks, mathematical symbols etc. In addition, it is possible to display symbols made up by the
user. Other useful features include automatic message shift (left and right), cursor appearance,
LED backlight etc.
LCD Pins
There are pins along one side of a small printed board. These are used for connecting to the
microcontroller. There are in total of 14 pins marked with numbers (16 if it has backlight). Their
function is described in the table bellow:
Function
Ground
Power supply
Contrast
Control of operating
Data / commands
7
8
9
10
11
12
13
14
D0
D1
D2
D3
D4
D5
D6
D7
1
From 1 to 0
0/1
0/1
0/1
0/1
0/1
0/1
0/1
0/1
Normal operating
Data/commands are transferred to LCD
Bit 0 LSB
Bit 1
Bit 2
Bit 3
Bit 4
Bit 5
Bit 6
Bit 7 MSB
LCD screen
An LCD screen consists of two lines each containing 16 characters. Each character consists of
5x8 or 5x11 dot matrix. This book covers the most commonly used display, i.e. the 5x8 character
display.
Display contrast depends on the power supply voltage and whether messages are displayed in
one or two lines. For this reason, varying voltage 0-Vdd is applied on the pin marked as Vee.
Trimmer potentiometer is usually used for that purpose. Some LCD displays have built-in
backlight (blue or green LEDs). When used during operation, a current limiting resistor should
be serially connected to one of the pins for backlight power supply (similar to LEDs).
If there are no characters displayed or if all of them are dimmed when the display is on, the first
thing that should be done is to check the potentiometer for contrast regulation. Is it properly
adjusted? The same applies if the mode of operation has been changed (writing in one or two
lines).
LCD Memory
The LCD display contains three memory blocks:
DDRAM Memory
DDRAM memory is used for storing characters to be displayed. The size of this memory is
sufficient for storing 80 characters. Some memory locations are directly connected to the
characters on display.
The addresses of CGROM memory locations match the characters of ASCII. If the program
being currently executed encounters a command send character P to port, then the binary value
0101 0000 appears on the port. This value is the ASCII equivalent to the character P. It is then
written to LCD, which results in displaying the symbol from 0101 0000 location of CGROM. In
other words, the character P is displayed. This applies to all letters of alphabet (capitals and
small), but not to numbers.
As seen on the previous map, addresses of all digits are pushed forward by 48 relative to their
values (digit 0 address is 48, digit 1 address is 49, digit 2 address is 50 etc.). Accordingly, in
order to display digits correctly, each of them needs to be added a decimal number 48 prior to be
sent to LCD.
From their inception till today, computers can recognize only numbers, but not letters. It means
that all data a computer swaps with a peripheral device has a binary format, even though the
same is recognized by the man as letters (keyboard is an excellent example). Every character
matches the unique combination of zeroes and ones. ASCII is character encoding based on the
English alphabet. ASCII code specifies correspondance between standard character symbols and
their numerical equivalents.
CGRAM memory
Apart from standard characters, the LCD display can also display symbols defined by the user
itself. It can be any symbol in the size of 5x8 pixels. RAM memory called CGRAM in the size of
64 bytes enables it.
Memory registers are 8 bits wide, but only 5 lower bits are used. Logic one (1) in every register
represents a dimmed dot, while 8 locations grouped together represent one character. It is best
illustrated in figure below:
Symbols are usually defined at the beginnig of the program by simply writing zeros and ones to
registers of CGRAM memory so that they form desired shapes. In order to display them it is
sufficient to specify their address. Pay attention to the first coloumn in the CGROM map of
characters. It doesn't contain RAM memory addresses, but symbols being discussed here. In this
example, display 0 means - display , display 1 means - display etc.
LCD Basic Commands
All data transferred to LCD through the outputs D0-D7 will be interpreted as a command or a
data, which depends on the pin RS logic state:
RS = 1 - Bits D0-D7 are addresses of the characters to be displayed. LCD processor addresses
one character from the character map and displays it. The DDRAM address specifies the location
on which the character is to be displayed. This address is defined before the character is
transferred or the address of previously transferred character is automatically incremented.
RS = 0 - Bits D0 - D7 are commands which determine the display mode. The commands
recognized by the LCD are given in the table below:
Command
Clear display
Cursor home
Entry mode set
Display on/off control
Cursor/Display Shift
Function set
Set CGRAM address
Set DDRAM address
Read BUSY flag (BF)
Write to CGRAM or DDRAM
Read from CGRAM or DDRAM
RS RW D7 D6 D5 D4 D3 D2 D1 D0 Execution Time
0 0 0 0 0 0 0 0 0 1 1.64mS
0 0 0 0 0 0 0 0 1 x 1.64mS
0 0 0 0 0 0 0 1 I/D S 40uS
0 0 0 0 0 0 1 D U B 40uS
0 0 0 0 0 1 D/C R/L x x 40uS
0 0 0 0 1 DL N F x x 40uS
0 0 0 1 CGRAM address
40uS
0 0 1 DDRAM address
40uS
0 1 BF DDRAM address
1 0 D7 D6 D5 D4 D3 D2 D1 D0 40uS
1 1 D7 D6 D5 D4 D3 D2 D1 D0 40uS
S 1 = Display shift on
0 = Display shift off
DL 1 = 8-bit interface
0 = 4-bit interface
D 1 = Display on
0 = Display off
U 1 = Cursor on
0 = Cursor off
B 1 = Cursor blink on
0 = Cursor blink off
Compared to the microcontroller, the LCD is an extremely slow component. Because of this, it
was necessary to provide a signal which will, upon command execution, indicate that the display
is ready to receive a new data. That signal, called the busy flag, can be read from line D7. When
the BF bit is cleared (BF=0), the display is ready to receive a new data.
LCD Connection
Depending on how many lines are used for connecting the LCD to the microcontroller, there are
8-bit and 4-bit LCD modes. The appropriate mode is selected at the beginning of the operation.
This process is called initialization. 8-bit LCD mode uses outputs D0-D7 to transfer data in the
way explained on the previous page. The main purpose of 4-bit LED mode is to save valuable
I/O pins of the microcontroller. Only 4 higher bits (D4-D7) are used for communication, while
other may be left unconnected. Each data is sent to the LCD in two steps: four higher bits are
sent first (normally through the lines D4-D7), then four lower bits. Initialization enables the LCD
to link and interpret received bits correctly. Data is rarely read from the LCD (it is mainly
transferred from the microcontroller to LCD) so that it is often possible to save an extra I/O pin
by simple connecting R/W pin to ground. Such saving has its price. Messages will be normally
displayed, but it will not be possible to read the busy flag since it is not possible to read the
display either.
3. Display/Cursor on/off
o
D = 0 Display off
U = 0 Cursor off
4. Character entry
o
Automatic reset is in most cases performed without any problems. In most cases, but not always!
If for any reason the power supply voltage does not reach ful value within 10mS, the display will
start to perform completely unpredictably. If the voltage supply unit is not able to meet this
condition or if it is needed to provide completely safe operation, the process of initialization is
applied. Initialization, among other things, causes a new reset enabling display to operate
normally.
Refer to the figure below for the procedure on 8-bit initialization:
It is not a mistake!
In this algorithm, the same value is transferred three times in a row.
In case of 4-bit initialization, the procedure is as follows:
6.3 Examples
The schematic below is used in the several following examples:
Apart from components necessary for the operation of the microcontroller such as oscillator with
capacitors and the simplest reset circuit, there are also several LEDs and one push button. These
are used to indicate the operation of the program.
All LEDs are polarized in such a way that they are activated by driving a microcontroller pin low
(logic 0).
LED Blinking
The purpose of this example is not to demonstrate the operation of LEDs, but the operating speed
of the microcontroller. Simply put, in order to enable LED blinking to be visible, it is necessary
to provide sufficient amount of time to pass between on/off states of LEDs. In this example time
delay is provided by executing a subroutine called Delay. It is a triple loop in which the program
remains for approximately 0.5 seconds and decrements values stored in registers R0, R1 or R2.
After returning from the subroutine, the pin state is inverted and the same procedure is repeated...
;************************************************************************
;* PROGRAM NAME : Delay.ASM
;* DESCRIPTION: Program turns on/off LED on the pin P1.0
;* Software delay is used (Delay).
;************************************************************************
;BASIC DIRECTIVES
$MOD53
$TITLE(DELAY.ASM)
$PAGEWIDTH(132)
$DEBUG
$OBJECT
$NOPAGING
;STACK
DSEG
STACK_START:
AT
DS
;RESET VECTORS
CSEG
JMP
AT
0
XRESET
ORG
XRESET: MOV
MOV
LOOP:
03FH
040H
;Reset vector
100H
SP,#STACK_START
P1,#0FFh
CPL
LCALL
SJMP
P1.0
Delay
LOOP
MOV
MOV
MOV
DJNZ
DJNZ
DJNZ
R2,#20
R1,#50
R0,#230
R0,$
R1,F01
R2,F02
Delay:
F02:
F01:
END
;End of program
(state in registers remains unchanged), program starts execution from the beginning and the
number in register R3 is incremented by 1 and then copied to port P1.
LEDs display this number in binary format...
;************************************************************************
;* PROGRAM NAME : WatchDog.ASM
;* DESCRIPTION : After watch-dog reset, program increments number in
;* register R3 and shows it on port P1 in binary format.
;************************************************************************
;BASIC DIRECTIVES
$MOD53
$TITLE(WATCHDOG.ASM)
$PAGEWIDTH(132)
$DEBUG
$OBJECT
$NOPAGING
WMCON
WDTEN
PERIOD
1024ms
DATA
EQU
EQU
96H
00000001B
11000000B
;RESET
VECTOR
CSEG
JMP
AT
XRESET
; Reset vector
CSEG
ORG
100H
ORL
ORL
WMCON,#PERIOD
WMCON,#WDTEN
MOV
MOV
INC
A,R3
P1,A
R3
; R3 is moved to port 1
SJMP
LAB
XRESET:
LAB:
END
; Register R3 is incremented by 1
; End of program
Timer T0 in mode 1
This program spends most of its time in an endless loop waiting for timer T0 to count up a full
cycle. When it happens, an interrupt is generated, routine TIM0_ISR is executed and logic zero
(0) on port P1 is shifted right by one bit. This is another way of demonstrating the operating
speed of the microcontroller since each shift means that counter T0 has counted up 216 pulses!
;************************************************************************
;* PROGRAM NAME : Tim0Mod1.ASM
;* DESCRIPTION: Program rotates "0" on port 1. Timer T0 in mode 1 is
;* used
;************************************************************************
;BASIC DIRECTIVES
$MOD53
$TITLE(TIM0MOD1.ASM)
$PAGEWIDTH(132)
$DEBUG
$OBJECT
$NOPAGING
;DECLARATION OF VARIABLES
;STACK
DSEG
STACK_START:
AT
DS
03FH
040H
;RESET VECTORS
CSEG
JMP
AT 0
XRESET
; Reset vector
ORG
JMP
00BH
TIM0_ISR
ORG
100H
XRESET: MOV
MOV
MOV
MOV
SETB
MOV
CLR
SP,#STACK_START
TMOD,#01H
A,#0FFH
P1,#0FFH
TR0
IE,#082H
C
LOOP1: SJMP
LOOP1
; Remain here
TIM0_ISR:
RRC
MOV
PORT1
RETI
END
A
P1,A
; Timer T0 is enabled
; Interrupt enabled
If you press a push button T1 at some point, a logic zero (0) on the P3.2 output will disable
Timer T1.
;************************************************************************
;* PROGRAM NAME : Split.ASM
;* DESCRIPTION: Timer TL0 rotates bit on port P1, while TL1 determines
;* the rotation direction. Both timers operate in mode
;* 3. Logic zero (0) on output P3.2 disables rotation on port P1.
;************************************************************************
;BASIC DIRECTIVES
$MOD53
$TITLE(SPLIT.ASM)
$PAGEWIDTH(132)
$DEBUG
$OBJECT
$NOPAGING
;DECLARATION OF VARIABLES
BSEG
AT
;DECLARATION OF BIT-VARIABLES
SEMAPHORE:
DIRECTION
DBIT
BIT
8
SEMAPHORE
;STACK
DSEG
STACK_START:
AT
DS
03FH
040H
;RESET VECTORS
CSEG
JMP
ORG
AT
0
XRESET
00BH
; Reset vector
JMP
TIM0_ISR
ORG
JMP
01BH
TIM1_ISR
ORG
XRESET: MOV
MOV
MOV
MOV
MOV
SETB
SETB
MOV
CLR
CLR
100H
SP,#STACK_START
TMOD,#00001011B
A,#0FFH
P1,#0FFH
R0,#30D
TR0
TR1
IE,#08AH
C
DIRECTION
LOOP1:
LOOP1
SJMP
; TL0 is turned on
; TL1 is turned on
; Interrupt enabled
; Rotate to the right
; Remain here
TIM0_ISR:
DJNZ
R0,LAB3
JB
DIRECTION,LAB1
RRC
A
the right through
SJMP
LAB2
LAB1:
RLC
A
the left through
LAB2:
MOV
to port P1
LAB3:
RETI
TIM1_ISR:
DJNZ
256 times
DJNZ
direction
CPL
MOV
LAB4:
RETI
P1,A
R1,LAB4
R2,LAB4
SMER
R2,#30D
END
; End of program
BSEG
AT
;DECLARATION OF BIT-VARIABLES
SEMAPHORE:
DIRECTION
;STACK
DSEG
STACK_START:
DBIT
BIT
AT
DS
8
SEMAPHORE
03FH
040H
;RESET VECTORS
CSEG
AT
0
JMP
XRESET
; Reset vector
ORG
JMP
00BH
TIM0_ISR
ORG
JMP
01BH
TIM1_ISR
ORG
100H
XRESET: MOV
MOV
MOV
MOV
MOV
SETB
SETB
MOV
enabled
CLR
CLR
SP,#STACK_START
TMOD,#11H
A,#0FFH
P1,#0FFH
R0,#30D
TR0
TR1
IE,#08AH
C
DIRECTION
LOOP1:
LOOP1
; Remain here
SJMP
TIM0_ISR:
JB
DIRECTION,LAB1
RRC A
the right through
SJMP
LAB2
LAB1:
RLC
A
the left through
LAB2:
MOV
to port P1
RETI
TIM1_ISR:
DJNZ
direction
CPL
P1,A
R0 is initialized
TIMER0 is turned on
TIMER1 is turned on
Timer0 and Timer1 Interrupt
R0,LAB3
DIRECTION
LAB3:
MOV
RETI
END
R0,#30D
; Initialize R0
; End of program
Using Timer T2
This example describes the use of Timer T2 configured to operate in Auto-Reload mode. In this
very case, LEDs are connected to port P3 while the push button used for forced timer reset
(T2EX) is connected to the P1.1 pin.
Program execution is similar to the previous examples. When timer ends counting, an interrupt is
enabled and subroutine TIM2_ISR is executed, thus rotating a logic zero (0) in accumulator and
moving the contents of accumulator to the P3 pin. At last, flags which caused an interrupt are
cleared and program returns to the loop LOOP1 where it remains until a new interrupt request
arrives...
If push button T2EX is pressed, timer is temporarily reset. This push button resets timer, while
push button RESET resets the microcontroller.
;************************************************************************
;* PROGRAM NAME : Timer2.ASM
;* DESCRIPTION: Program rotates log. "0" on port P3. Timer2 determines
;* the speed of rotation and operates in auto-reload mode
;************************************************************************
;BASIC DIRECTIVES
$MOD53
$TITLE(TIMER2.ASM)
$PAGEWIDTH(132)
$DEBUG
$OBJECT
$NOPAGING
;DEFINITION OF VARIABLES
T2MOD
DATA
0C9H
DSEG
STACK_START:
AT
DS
03FH
040H
;RESET VECTORS
CSEG
JMP
AT
XRESET
;STACK
ORG
JMP
02BH
TIM2_ISR
ORG
100H
; Reset vector
; Timer T2 Reset vector
XRESET: MOV
MOV
MOV
MOV
MOV
CLR
SETB
SETB
MOV
CLR
SP,#STACK_START
A,#0FFH
P3,#0FFH
RCAP2L,#0FH
RCAP2L,#01H
CAP2
EXEN2
TR2
IE,#0A0H
C
LOOP1:
LOOP1
; Remain here
SJMP
TIM2_ISR:
RRC
the right through
to PORT3
MOV
P3,A
; Carry flag
; Move the contents of Accumulator A
CLR
CLR
RETI
TF2
EXF2
END
Here is another example of interrupt execution. An external iterrupt is generated when a logic
zero (0) is present on pin P3.2 or P3.3. Depending on which input is active, one of two routines
will be executed:
A logic zero (0) on the P3.2 pin initiates execution of interrupt routine Isr_Int0, thus
incrementing number in register R0 and copying it to port P0. Logic zero on the P3.3 pin initiates
execution of subroutine Isr_Int1, number in register R1 is incremented by 1 and then copied to
port P1.
In short, each press on push buttons INT0 and INT1 will be counted and immediately shown in
binary format on appropriate port (LED which emitts light represents a logic zero (0)).
;************************************************************************
;* PROGRAM NAME : Int.ASM
;* DESCRIPTION : Program counts interrupts INT0 generated by appearance of
high-to-low
;* transition signal on pin P3.2 Result appears on port P0. Interrupts INT1
are also
;* counted up at the same time. They are generated byappearing high-to-low
transition
;* signal on pin P3. The result appears on port P1.
;************************************************************************
;BASIC DIRECTIVES
$MOD53
$TITLE(INT.ASM)
$PAGEWIDTH(132)
$DEBUG
$OBJECT
$NOPAGING
;RESET VECTORS
CSEG
JMP
AT
0
XRESET
ORG
003H
JMP
Isr_Int0
ORG 013H
JMP
Isr_Int1
ORG
MOV
appearing
TCON,#00000101B
P3.2
appearing
LOOP:
100H
XRESET:
P3.3
; Reset vector
MOV
MOV
MOV
MOV
MOV
IE,#10000101B
R0,#00H
R1,#00H
P0,#00H
P1,#00H
; Interrupt enabled
; Counter starting value
SJMP
LOOP
; Remain here
Isr_Int0:
INC R0
counter
MOV P0,R0
RETI
Isr_Int1:
INC R1
counter
MOV P1,R1
RETI
END
; Reset port P0
; Reset port P1
; End of program
The following examples describe the use of LED displays. Common chatode displays are used
here, which means that all built-in LEDs are polarized in such a way that their anodes are
connected to the microcontroller pins. Since the common way of thinking is that logic one (1)
turns something on and logic zero (0) turns something of, Low Current displays (low power
consumption) and their diodes (segments) are connected serially to resistors of relatively high
resistance.
In order to save I/O pins, four LED displays are connected to operate in multiplex mode. It
means that all segments having the same name are connected to one output port each and only
one display is active at a time.
Tranzistors and segmenats on displays are quickly activated, thus making impression that all
digits are active simultaneously.
each of these new locations (digit 1 mask, digit 2 mask...digit 9 mask). When this combination is
transferred to the port, the display shows desired digit.
;************************************************************************
;* PROGRAM NAME : 7Seg1.ASM
;* DESCRIPTION: Program displays number "3" on 7-segment LED display
;************************************************************************
;BASIC DIRECTIVES
$MOD53
$TITLE(7SEG1.ASM)
$PAGEWIDTH(132)
$DEBUG
$OBJECT
$NOPAGING
;STACK
DSEG
STACK_START:
AT
DS
;RESET VECTORS
CSEG
JMP
AT
0
XRESET
XRESET:
LOOP:
number
03FH
040H
; Reset vector
ORG
100H
MOV
MOV
MOV
SP,#STACK_START
P1,#0
P3,#20h
MOV
LCALL
A,#03
Disp
MOV
SJMP
P1,A
LOOP
INC
MOVC
RET
DB
DB
DB
DB
DB
DB
DB
DB
DB
DB
END
A
A,@A+PC
Disp:
3FH
06H
5BH
4FH
66H
6DH
7DH
07H
7FH
6FH
;
;
;
;
;
;
;
;
;
;
;
Digit 0 mask
Digit 1 mask
Digit 2 mask
Digit 3 mask
Digit 4 mask
Digit 5 mask
Digit 6 mask
Digit 7 mask
Digit 8 mask
Digit 9 mask
End of program
This program is only an extended verson of the previous one. There is only one digit active- the
first one on the right, and there is no use of multiplexing. Unlike the previous example, all
decimal numbers are displayed (0-9). In order to enable digits to change at reasonable pace, a
soubroutine L2 which causes a short time delay is executed prior to each change occurs.
Basically, the whole process is very simple and takes place in the main loop called LOOP which
looks as follows:
1. R3 is copied to Accumulator and subroutine for masking digits Disp is executed;
2. Accumulator is copied to the port and displayed;
3. The contents of the R3 register is incremented;
4. It is checked whether 10 cycles are counted or not. If it is, register R3 is reset in order to
enable counting to start from 0; and
5. Instruction labeled as L2 within subroutine is executed.
;************************************************************************
;* PROGRAM NAME: 7Seg2.ASM
;* DESCRIPTION: Program writes numbers 0-9 on 7-segment LED display
;************************************************************************
;BASIC DIRECTIVES
$MOD53
$TITLE(7SEG2.ASM)
$PAGEWIDTH(132)
$DEBUG
$OBJECT
$NOPAGING
;STACK
DSEG
STACK_START:
AT
DS
03FH
040H
;RESET VECTORS
CSEG
JMP
AT
0
XRESET
; Reset vector
100H
MOV
MOV
MOV
MOV
SP,#STACK_START
R3,#0
P1,#0
P3,#20h
;
;
;
;
MOV
LCALL
A,R3
Disp
XRESET:
ORG
LOOP:
number in
; Accumulator
MOV
INC
P1,A
R3
R3
L2:
F02:
F01:
Disp:
CJNE
R3,#10,L2
MOV
R3,#0
MOV
MOV
MOV
DJNZ
DJNZ
DJNZ
SJMP
R2,#20
R1,#50
R0,#230
R0,$
R1,F01
R2,F02
LOOP
INC
MOVC
RET
DB
DB
DB
DB
DB
DB
DB
DB
DB
DB
A
A,@A+PC
3FH
06H
5BH
4FH
66H
6DH
7DH
07H
7FH
6FH
END
;
;
;
;
;
;
;
;
;
;
Digit
Digit
Digit
Digit
Digit
Digit
Digit
Digit
Digit
Digit
0
1
2
3
4
5
6
7
8
9
mask
mask
mask
mask
mask
mask
mask
mask
mask
mask
; End of program
DSEG
STACK_START:
AT
DS
03FH
040H
;RESET VECTORS
CSEG
JMP
AT
XRESET
XRESET:
LOOP:
digit
; Reset vector
ORG
MOV
100H
SP,#STACK_START
MOV
MOV
MOV
LCALL
P1,#0
P3,#20h
A,#03
Disp
;
;
;
;
MOV
MOV
MOV
MOV
LCALL
MOV
SJMP
P1,A
P1,#0
P3,#10h
A,#02
Disp
P1,A
LOOP
;
;
;
;
;
;
;
INC
MOVC
RET
DB
DB
DB
DB
DB
DB
DB
DB
DB
DB
A
A,@A+PC
Disp:
3FH
06H
5BH
4FH
66H
6DH
7DH
07H
7FH
6FH
END
;
;
;
;
;
;
;
;
;
;
Digit
Digit
Digit
Digit
Digit
Digit
Digit
Digit
Digit
Digit
0
1
2
3
4
5
6
7
8
9
mask
mask
mask
mask
mask
mask
mask
mask
mask
mask
; End of program
$MOD53
$TITLE(7SEG5.ASM)
$PAGEWIDTH(132)
$DEBUG
$OBJECT
$NOPAGING
;STACK
DSEG
STACK_START:
AT
DS
03FH
040H
;RESET VECTORS
CSEG
JMP
AT
0
XRESET
; Reset vector
ORG
100H
XRESET:
MOV
SP,#STACK_START
LOOP:
MOV
MOV
MOV
LCALL
MOV
MOV
MOV
MOV
LCALL
MOV
MOV
MOV
MOV
LCALL
MOV
MOV
MOV
MOV
LCALL
MOV
SJMP
P1,#0
P3,#20h
A,#04
Disp
P1,A
P1,#0
P3,#10h
A,#03
Disp
P1,A
P1,#0
P3,#08h
A,#02
Disp
P1,A
P1,#0
P3,#04h
A,#01
Disp
P1,A
LOOP
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
INC
MOVC
RET
DB
DB
DB
DB
DB
DB
DB
DB
DB
DB
A
A,@A+PC
Disp:
3FH
06H
5BH
4FH
66H
6DH
7DH
07H
7FH
6FH
;
;
;
;
;
;
;
;
;
;
Digit
Digit
Digit
Digit
Digit
Digit
Digit
Digit
Digit
Digit
0
1
2
3
4
5
6
7
8
9
mask
mask
mask
mask
mask
mask
mask
mask
mask
mask
DSEG
STACK_START:
AT
DS
03FH
040H
;RESET VECTORS
CSEG
JMP
AT
XRESET
XRESET:
ORG
100H
MOV
MOV
MOV
MOV
SP,#STACK_START
R2,#0
R3,#0
R4,#0
LOOP:
INC
R4
"refreshed" for 100 times
CJNE
R4,#20d,LAB1
MOV
R4,#0
MOV
P1,#0
INC
R2
units by 1
CJNE
R2,#10d,LAB1
MOV
R2,#0
INC
R3
1
CJNE
R3,#10d,LAB1
MOV
R3,#0
; Reset vector
LAB1:
to A
Delay:
F01:
MOV
MOV
P3,#20h
A,R2
; Activate display D4
; Copy Register containing units
LCALL
MOV
LCALL
MOV
MOV
MOV
Disp
P1,A
Delay
P1,#0
P3,#10h
A,R3
;
;
;
;
;
;
LCALL
MOV
LCALL
SJMP
Disp
P1,A
Delay
LOOP
MOV
MOV
DJNZ
DJNZ
RET
R1,#50
R0,#250
R0,$
R1,F01
; 5 ms delay
INC
MOVC
RET
DB
DB
DB
DB
DB
DB
DB
DB
DB
DB
A
A,@A+PC
Disp:
END
3FH
06H
5BH
4FH
66H
6DH
7DH
07H
7FH
6FH
;
;
;
;
;
;
;
;
;
;
Digit
Digit
Digit
Digit
Digit
Digit
Digit
Digit
Digit
Digit
0
1
2
3
4
5
6
7
8
9
mask
mask
mask
mask
mask
mask
mask
mask
mask
mask
; End of program
Handling EEPROM
This program writes data to on-chip EEPROM memory. In this case, the data is a hexadecimal
number 23 which is to be written to the location with address 00.
To make sure that this number is correctly written, the same location of EEPROM is read 10mS
later in order to compare these two numbers. If they match, F will be displayed. Otherwise, E
will be displayed on the LED display (Error).
;************************************************************************
;* PROGRAM NAME: EEProm1.ASM
;* DESCRIPTION: Programming EEPROM at address 0000hex and displaying message
;* on LED display.
;************************************************************************
;BASIC DIRECTIVES
$MOD53
$TITLE(EEPROM1.ASM)
$PAGEWIDTH(132)
$DEBUG
$OBJECT
$NOPAGING
WMCON
EEMEN
enabled
EEMWE
TEMP
DATA
EQU
96H
00001000B
EQU
DATA
00010000B
030H
THE END
ERROR
EQU
EQU
071H
033H
; Display "F"
; Display "E"
;STACK
DSEG
STACK_START:
AT
DS
;RESET VECTORS
CSEG
JMP
AT
0
XRESET
XRESET:
to
to TEMP,
ERROR
LOOP1:
ERROR:
LOOP2:
DELAY:
LOOP3:
03FH
040H
; Reset vector
ORG
100H
MOV
MOV
IE,#00
SP,#STACK_START
MOV
ORL
ORL
MOV
DPTR,#0000H
WMCON,#EEMEN
WMCON,#EEMWE
TEMP,#23H
;
;
;
;
MOV
MOVX
CALL
MOVX
A,TEMP
@DPTR,A
DELAY
A,@DPTR
;
;
;
;
CJNE
A,TEMP,ERROR
MOV
MOV
XRL
XRL
SJMP
A,#KRAJ
P1,A
WMCON,#EEMWE
WMCON,#EEMEN
LOOP1
; Display F (correct)
MOV
MOV
SJMP
A,#ERROR
P1,A
LOOP2
; Display E (error)
MOV
MOV
NOP
A,#0AH
R3,A
; Delay
LOOP4:
LOOP5:
DJNZ
DJNZ
DJNZ
RET
B,LOOP4
B,LOOP5
R3,LOOP3
END
; End of program
;************************************************************************
;* PROGRAM NAME : UartR.ASM
;* DESCRIPTION: Each data received from PC via UART appears on the port
;* P1.
;*
;************************************************************************
;BASIC DIRECTIVES
$MOD53
$TITLE(UARTR.ASM)
$PAGEWIDTH(132)
$DEBUG
$OBJECT
$NOPAGING
;STACK
DSEG
STACK_START:
;RESET VECTORS
CSEG
JMP
ORG
routine
JMP
AT
DS
03FH
040H
AT
0
XRESET
023H
; Reset vector
; Starting address of UART interrupt
IR_SER
ORG
100H
MOV
MOV
MOV
MOV
IE,#00
SP,#STACK_START
TMOD,#20H
TH1,#0FDH
MOV
MOV
CLR
CLR
SETB
SCON,#50H
IE,#10010000B
TI
RI
TR1
;
;
;
;
;
;
;
;
;
;
LOOP:
SJMP
LOOP
; Remain here
IR_SER:
JNB
RI,OUTPUT
OUTPUT
MOV
MOV
CLR
RETI
A,SBUF
P1,A
RI
XRESET:
END
;************************************************************************
;* PROGRAM NAME : UartS.ASM
;* DESCRIPTION: Sends values 0-255 to PC.
;************************************************************************
;BASIC DIRECTIVES
$MOD53
$TITLE(UARTS.ASM)
$PAGEWIDTH(132)
$DEBUG
$OBJECT
$NOPAGING
;STACK
DSEG
STACK_START:
AT
DS
;RESET VECTORS
CSEG
JMP
AT
0
XRESET
XRESET:
START:
LOOP1:
03FH
040H
ORG
100H
MOV
MOV
MOV
MOV
IE,#00
SP,#STACK_START
TMOD,#20H
TH1,#0FDH
MOV
CLR
CLR
MOV
SETB
SCON,#40H
TI
RI
R3,#00H
TR1
MOV
JNB
SBUF,R3
TI,LOOP1
CLR
INC
CJNE
;
;
;
;
;
;
;
;
;
;
TI
R3
;
;
;
;
;
R3,#00H,START
the
LOOP:
; Reset vector
; label START
SJMP
LOOP
END
; Remain here
; End of program
LCD needs to be initialized at the beginning of the program. Besides, parts of the program which
repeat in the program create special subroutines. All this may seem extremely complicated, but
the whole program basically performs several simple operations and displays
Mikroelektronika Razvojni sistemi.
*************************************************************************
;* PROGRAM NAME : Lcd.ASM
;* DESCRIPRTION : Program for testing LCD display. 4-bit communication
;* is used. Program does not check BUSY flag but uses program delay
;* between 2 commands. PORT1 is used for connection
;* to the microcontroller.
;************************************************************************
;BASIC DIRECTIVES
$MOD53
$TITLE(LCD.ASM)
$PAGEWIDTH(132)
$DEBUG
$OBJECT
$NOPAGING
;Stack
DSEG
Stack_Start:
AT
DS
0E0h
020h
Start_address
EQU
0000h
;Reset vectors
Inic:
CSEG
ORG
JMP
AT
0
Start_address
Inic
ORG
Start_address+100h
MOV
MOV
IE,#00
SP,#Stack_Start
CALL
LCD_inic
; Initialize LCD
;*************************************************
;* MAIN PROGRAM
;*************************************************
START:
MOV
the first
CALL
LCD display.
MOV
CALL
transmission.
MOV
CALL
MOV
CALL
MOV
CALL
MOV
CALL
MOV
CALL
MOV
CALL
MOV
CALL
MOV
CALL
MOV
CALL
MOV
CALL
MOV
CALL
MOV
CALL
MOV
CALL
MOV
CALL
MOV
CALL
MOV
the first
CALL
LCD display.
A,#80h
LCD_status
A,#'M'
LCD_putc
; Display character M.
; Call subroutine for character
A,#'i'
LCD_putc
A,#'k'
LCD_putc
A,#'r'
LCD_putc
A,#'o'
LCD_putc
A,#'e'
LCD_putc
A,#'l'
LCD_putc
A,#'e'
LCD_putc
A,#'k'
LCD_putc
A,#'t'
LCD_putc
A,#'r'
LCD_putc
A,#'o'
LCD_putc
A,#'n'
LCD_putc
A,#'i'
LCD_putc
A,#'k'
LCD_putc
A,#'a'
LCD_putc
; Display character i.
A,#0c0h
LCD_status
; Display character k.
; Display character r.
; Display character o.
; Display character e.
; Display character l.
; Display character e.
; Display character k.
; Display character t.
; Display character r.
; Display character o.
; Display character n.
; Display character i.
; Display character k.
; Display character a.
MOV
CALL
transmission.
MOV
CALL
MOV
CALL
MOV
CALL
MOV
CALL
MOV
CALL
MOV
CALL
MOV
CALL
MOV
CALL
MOV
CALL
MOV
CALL
MOV
CALL
MOV
CALL
MOV
CALL
MOV
CALL
MOV
CALL
MOV
CALL
MOV
MOV
CALL
MOV
CALL
JMP
A,#'R'
LCD_putc
; Display character R.
; Call subroutine for character
A,#'a'
LCD_putc
A,#'z'
LCD_putc
A,#'v'
LCD_putc
A,#'o'
LCD_putc
A,#'j'
LCD_putc
A,#'n'
LCD_putc
A,#'i'
LCD_putc
A,#' '
LCD_putc
A,#'s'
LCD_putc
A,#'i'
LCD_putc
A,#'s'
LCD_putc
A,#'t'
LCD_putc
A,#'e'
LCD_putc
A,#'m'
LCD_putc
A,#'i'
LCD_putc
; Display character a.
R0,#20d
Delay_10ms
DPTR,#LCD_DB
A,#6d
LCD_inic_status
R0,#10d
Delay_10ms
START
; Display character z.
; Display character v.
; Display character o.
; Display character j.
; Display character n.
; Display character i.
; Display character .
; Display character s.
; Display character i.
; Display character s.
; Display character t.
; Display character e.
; Display character m.
; Display character i.
;*********************************************
;* Subroutine for wait time (T= r0 x 10ms)
;*********************************************
Delay_10ms: MOV
approximately
MOV
MOV
DJNZ
instruction.
DJNZ
DJNZ
RET
R5,00h
; 1+(1+(1+2*r7+2)*r6+2)*r5
R6,#100d
R7,#100d
R7,$
; (if r7>10)
; 2*r5*r6*r7
; $ indicates current
R6,$-4
R5,$-6
;
******************************************************************************
********
;* SUBROUTINE: LCD_inic
;* DESCRIPTION: Subroutine for LCD initialization.
;*
;* (is used with 4-bit interface, under condition that pins DB4-7 on LCD
;* are connected to pins PX.4-7 on microcontrollers ports, i.e. four higher
;* bits on the port are used).
;*
;* NOTE: It is necessary to define port pins for controlling LCD operation:
;* LCD_enable, LCD_read_write, LCD_reg_select,similar to port for connection
to LCD.
;* It is also necessary to define addresses for the first character in each
;* line.
;
******************************************************************************
********
LCD_enable
LCD.
LCD_read_write
LCD.
LCD_reg_select
LCD.
LCD_port
Busy
appears.
BIT
P1.3
BIT
P1.1
BIT
P1.2
SET
BIT
P1
P1.7
00h
LCD_Start_I_red
character
EQU
display.
LCD_Start_II_red EQU
character
40h
display.
LCD_DB:
format
DB
00111100b
DB
00101100b
DB
00011000b
; 2 -Display/cursor shift,
DB
cursor blink off
DB
shift off
DB
DB
DB
cursor blink off
00001100b
00000110b
00000010b
00000001b
00001000b
; 5 -Display/cursor home
; 6 -Clear display
; 7 -Display OFF, cursor OFF,
format
right/left
LCD_inic:
;*****************************************
MOV
DPTR,#LCD_DB
beginning
supply is on
MOV
CALL
A,#00d
LCD_inic_status_8
MOV
CALL
A,#00d
LCD_inic_status_8
MOV
A,#00d
lcall LCD_inic_status_8
MOV
CALL
MOV
CALL
A,#1d
LCD_inic_status_8
A,#1d
LCD_inic_status
MOV
A,#3d
CALL
MOV
CALL
MOV
CALL
LCD_inic_status
A,#6d
LCD_inic_status
A,#4d
LCD_inic_status
executes in
;4-bit mode
RET
LCD_inic_status_8:
;******************************************
PUSH B
memorized
port
MOVC
CLR
CLR
A,@A+DPTR
LCD_reg_select
LCD_read_write
MOV
B,LCD_port
ORL
ORL
ANL
B,#11110000b
A,#00001111b
A,B
MOV
LCD_port,A
SETB
LCD_enable
CLR
LCD_enable
MOV
B,#255d
pin
reset
DJNZ B,$
DJNZ B,$
DJNZ B,$
POP B
RET
LCD_inic_status:
;****************************************************************************
MOVC A,@A+DPTR
CALL LCD_status
RET
;****************************************************************************
;* SUBROUTINE: LCD_status
;* DESCRIPTION: Subroutine for defining LCD status.
;****************************************************************************
LCD_status:
PUSH
MOV
DJNZ
DJNZ
DJNZ
CLR
CALL
B
B,#255d
B,$
B,$
B,$
LCD_reg_select
LCD_port_out
SWAP
DJNZ
DJNZ
DJNZ
CLR
CALL
B,$
B,$
B,$
LCD_reg_select
LCD_port_out
POP
RET
accumulator
;****************************************************************************
;* SUBROUTINE: LCD_putc
;* DESCRIPTION: Sending character to be displayed on LCD.
;****************************************************************************
LCD_putc:
accumulator
PUSH
MOV
DJNZ
SETB
CALL
B
B,#255d
B,$
LCD_reg_select
LCD_port_out
SWAP
DJNZ
SETB
B,$
LCD_reg_select
CALL
POP
RET
LCD_port_out
B
;****************************************************************************
;* SUBROUTINE: LCD_port_out
;* DESCRIPTION: Sending commands or characters on LCD display
;****************************************************************************
LCD_port_out:
memorized
port
PUSH
PUSH
MOV
ACC
B
B,LCD_port
ORL
ORL
ANL
B,#11110000b
A,#00001111b
A,B
MOV
LCD_port,A
SETB
LCD_enable
CLR
LCD_enable
POP
POP
RET
B
ACC
pin
END
; End of program
MOV
DIV
MOV
MOV
DIV
MOV
MOV
DIV
MOV
RET
B,#10d
AB
R3,B
B,#10d
AB
R2,B
B,#10d
AB
A,B
;
;
;
;
;
;
;
;
;
;
What is always the most difficult thing to do? You have bought the microcontroller, you have
learned everything about its circuits and registers, you have a great idea how to apply all your
knowledge in practice. But the most difficult thing to do is to start...
How to start working?
A microcontroller is a good-natured genie in the bottle and no extra knowledge is required to
use it.
In order to create a device controlled by the microcontroller, it is necessary to provide the
simplest PC, program for compiling and simple device to transfer the code from PC to the chip
itself.
Even though the whole process is quite logical, there are often some queries, not because it is
complicated, but for numerous variations. Lets take a look.
Writing program in assembly language
In order to write a program for the microcontroller, a specialized program in the Windows
environment may be used. It may, but it does not have to... When using such a software, there are
numerous tools which facilitate the operation (simulator tool comes first), which is an obvious
advantage. But there is also another ways to write a program. Basically, text is the only thing that
matters. Any program for text processing can be used for this purpose. The point is to write all
instructions in such an order they should be executed by the microcontroller, observe the rules of
assembly language and write instructions exactly as they are defined. In other words, you just
have to follow the program idea. Thats all!
;RESET
XRESET:
VECTOR
CSEG
JMP
AT
XRESET
CSEG
ORG
100H
ORL
ORL
WMCON,#PERIOD
WMCON,#WDTEN
0
; Reset vector
To enable the compiler to operate successfully, it is necessary that a document containing this
program has the extension, .asm in its name, for example: Program asm.
When a specialized program (mplab) is used, this extension will be automatically added. If any
other program for text processing (Notepad) is used then the document should be saved and
renamed. For example: Program.txt -> Program.asm. This procedure is not necessarily
performed. The document may be saved in original format while its text may be copied to the
programmer for further use.
Compiling a program
The microcontroller does not undrestand assembly language as such. That is why it is
necessary to compile the program into machine language. It is more than simple when a
specialized program (mplab) is used because a compiler is a part of the software. Just one click
on the appropriate icon solves the problem and a new document with .hex extension appears. It is
actually the same program, only compiled into machine language which the microcontroller
perfectly understands. Such documentation is commonly named hex code and seemingly
represents a meaningless sequence of numbers in hexadecimal number system.
:03000000020100FA1001000075813F
7590FFB29012010D80F97A1479D40
90110003278589EAF3698E8EB25B
A585FEA2569AD96E6D8FED9FAD
AF6DD00000001FF255AFED589EA
F3698E8EB25BA585FEA2569AD96
DAC59700D00000278E6D8FED9FA
DAF6DD00000001FF255AFED8FED
9FADAF6DD000F7590FFB29013278
E6D8FED9FADAF6DD00000001FF2
55AFED589EAF3698E8EB25BA585
FEA2569AD96DAC59D9FADAF6D
D00000001FF255AFED8FED9FADA
F6DD000F7590FFB29013278E6D82
78E6D8FED9FA589EAF3698E8EB2
5BA585FEA2569AD96DAF6DD000
00001FF2DAF6DD00000001FF255A
ADAF6DD00000001FF255AFED8FE
D9FA
In the event that other software for program writing in assembly language is used, a special
software for compiling the program must be installed and used as follows - set up the compiler,
open the document with .asm extension and compile. The result is the same- a new document
with extension .hex. The only problem now is that it is stored in your PC.
Programming a microcontroller
In order to transfer a hex code to the microcontroller, it is necessary to provide a cable for
serial communication and a special device, called programmer, with software. There are several
ways to do it.
A large number of programs and electronic circuits having this purpose can be found on the
Internet. Do as follows: open hex code document, set a few parameters and click the icon for
compiling. After a while, a sequence of zeros and ones will be programmed into the
microcontroller through the serial connection cable and programmer hardware. What's left is to
place the programmed chip into the taget device. In the event that it is necessary to make some
changes in the program, the previous procedure may be repeated an unlimited number of times.
The program is written and successfully compiled. All that's left is to dump the program to the
microcontroller. For this purpose it is necessary to have a software that takes the written and
compiled program and passes it to the microcontroller.
Start the program 8051 Flash_setup.exe...
The program has been installed and ready for use. The settings are easily performed so that there
is no need for additional explanations (the type of the microcontroller, frequency and clock
oscillator etc.).
Thats all! The microcontroller is programmed and everything is ready for operation. If you are
not satisfied, make some changes in the program and repeat the procedure. Until when? Until
you feel satisfied...
Development systems
A device which in the testing program phase can simulate any environment is called a
development system. Apart from the programmer, the power supply unit and the
microcontrollers socket, the development system contains elements for input pin activation and
output pin monitoring. The simplest version has every pin connected to one push button and one
LED as well. A high quality version has LED displays, LCD displays, temperature sensors and
all other elements which can be supplied with the target device. These peripherals can be
connected to the MCU via miniature jumpers. In this way, the whole program may be tested in
practice during its development stage, because the microcontroller doesn't know or care whether
its input is activated by a push button or a sensor built in a real device.
Sockets for placing microcontrollers in (14, 16, 20 and 40- pin packages)
Connector for external power supply (DC 12V)
USB programmer
The following text describes in short some circuits within this development system. It is rather
illustration of its features than complete manual. Besides, by learning about this device, one
understands that microcontrollers and its tools are intended to everybody, not only to the
privileged.
Sockets
All microcontrollers manufactured by Atmel appear in a few standard DIP packages. In order to
enable their programming using one device, corresponding pins (having the same name) on
sockets are connected in parallel. As a result, by being placed in the appropriate socket, each
microcontroller is automatically properly connected. Figure on the right shows a microcontroller
in 40-pin package and connection of one of its I/O pins (P1.5). As seen, the pin can be connected
to an external device (connector PORT1), LED (microswitch SW2), push button or resistor
through connectors. In the last two cases, polarity of voltage is selected using on-board jumpers.
Programmer
The purpose of the programmer is to transfer HEX code from PC to appropriate pins and provide
regular voltage levels during chip programming as well. For this development system, the
programmer is built in it and should be connected to PC via USB cable. When the process of
programming is completed, pins used for it are automatically available for other application.
There is a connector on the development board enabling commection to external power supply
source (AC/DC, 8-16V). Besides, voltage necessary for device operation can also be obtained
from PC via USB cable. Jumper J5 is used for power supply selection.
8MHz Oscillator
The EASY8051A development system has built-in oscillator used as a clock signal generator.
The frequency of this oscillator is stabilized by 8Hz quartz crystal. Besides, it is also possible to
select internal RC oscillator during chip programming,.
Each I/O port pin is connected to one LED which enables visual indication of its logic state. In
the event that the presence of directly polarized LEDs and serial resistors is not acceptable in
some applications, DIP switch SW2 enables them to be disconnected from the port.
Similar to LEDs, each I/O port pin is connected to one push button on the development board. It
enables simple activation of input pins. Jumper J6 is used for selecting voltage polarity (+ or -)
brought to pins by pressing appropriate push button.
Being often applied in the industry, four high-performance LED displays set in multiplex mode
belong to the development system. Display segments are connected to the port P0 via resistors.
Transistor drivers used for activating individual digits are connected to the first four port P1 pins.
It enables programs using 7-segment displays to be tested with minimum use of I/O ports.
Similar to LEDs, DIP switch SW2 enables transistor drivers to be disconnected from
microcontroller pins.
LCD displays
In order to enable programs using serial communication to be tested, the development system has
built in standard 9-pin SUB-D connector. The MAX232 is used as a voltage regulator.
Similar to other built-in circuits, electronics supporting serial communication can be enabled or
disabled by using jumpers J9 and J10.
Temperature measurement is one of the most common tasks of devices which operate in the
industry. For this reason, there is a circuit DS1820 on the EASY8051A development system
which measures temperature in the range of -55 to +125oC with accuracy greater than 0.50.
Results of measurement are transferred via serial communication to the pins P3.3 or P2.7.
Jumper J7 is used for selecting pins for data reception. In the event that no jumper is installed,
port pins are available for other applications.
A built-in 12-bit AD Converter MCP3204 has four input channels connected to on-board
connectors. Data are interchanged with the microcontroller via SPI serial communication system
using pins P1.5, P1.6, P1.7 and P3.5. If A/D converter is not in use, these pins can be used for
other applications (DIP switch SW1). In order to check operation, there is a potentiometer on the
development board used as a variable voltage source. It can be brought to the converters input
pins using one of four jumpers J12. As a special convenience, a reference voltage source
MCP1541 (4,096V) is built in. Jumper J11 is used to select whether converter will use this
voltage or 5V.
Digital to analog conversion (D/A) is another operation ofen performed by the microcontroller in
practice. For this reason, there is a special on-board chip which interchanges data with the
microcontroller via SPI communication system. It can also generate analog voltage in 12-bit
resolution on its output pin. When it is not in use, all microcontroller pins are available for other
applications using DIP switch SW1. Similar to A/D converter, jumper J11 is used for selecting
reference voltage.