Professional Documents
Culture Documents
project applications. In this project we have used the ultrasonic waves to measure the
distance in between two points. The basic principal is based on the speed of ultrasonic
waves in open air. Sensor’s are mount on the stepper motor bas platform. When circuit is
on then motor moves in one direction and search the object . If the object is located then
sensor provide a feedback and at the same time circuit count the step move by the stepper
motor. By counting the step of stepper motor we show the direction of the object We
have used a microcontroller AT89S51 to transmit and receive ultrasonic waves through
40 KHz ultrasonic receiver and transmitters. By measuring the time required to travel the
unknown distance by ultrasonic waves in air we can find out the distance between two
points. The distance measured is displayed on a LCD display. The transmission &
techniques to process these waves. We have used a very complex structure of amplifier
and filters for this purpose. The speed of ultrasonic waves is dependent on temperature.
So before using ultrasonic waves for any measurement we need to calibrate the speed of
These applications include measurement of distance, speed, flow etc. Ultrasonic also find
16x2 LCD
Display
Comparator Microcontroller
Driver Circuit
(sensitivity selector ) AT89S51
40 KHz Ultrasonic
Amplifier Circuit
Transmitter
2nd stage
40 KHz
Ultrasonic Receiver
In this project we combine two project. One is ultra sonic distance
when we press the start switch then stepper motor is rotate. Stepper motor is
connected to the port P1. Pin no 1,2,3,4. Here we use bi-polar stepper motor
moves to 1.8 degree, there is lot of stepper motor available in the market,
In this project we connect the stepper motor to the pin no 1,2,3,4 of the
controller. In the stepper motor there is four coil. To provide a voltage from
the controller we connect two transistor circuit. Output from the controller is
firstly connected to the base of the PNP transistor via current limiting
active low output to the base of the PNP transistor and output of the PNP
transistor is connected to the base of the NPN transistor. Emitter of the NPN
transistor connected to the ground pin and collector of the NPN transistor is
connected to the one coil of the stepper motor. Here we use four coil stepper
motor , so we use four series circuit of transistor to to the four coil of the
Here in this project we use 40 khtz transmitter . This 40 k htz frequency is
The inverter is used for the drive of the ultrasonic sensor. The two inverters
The phase with the voltage to apply to the positive terminal and the negative
terminal of the sensor has been 180 degrees shifted. Because it is cutting the
direct current with the capacitor, about twice of voltage of the inverter
The ultrasonic signal which was received with the reception sensor is
with two stages. It is 100 times at the first stage (40dB) and 10 times (20dB)
Generally, the positive and the negative power supply are used for the
operational amplifier. The circuit this time works with the single power
amplifiers, the half of the power supply voltage is applied as the bias voltage
current signal. When using the operational amplifier with the negative
feedback, the voltage of the positive input terminal and the voltage of the
voltage, the side of the positive and the side of the negative of the alternating
current signal can be equally amplified. When not using this bias voltage,
the distortion causes the alternating current signal. When the alternating
current signal is amplified, this way is used when working the operational
amplifier for the 2 power supply with the single power supply.
The detection is done to detect the received ultrasonic signal. It is the half-
wave rectification circuit which used the Shottky barrier diodes. The DC
capacitor behind the diode. the Shottky barrier diodes are used because the
This circuit is the circuit which detects the ultrasonic which returned from
the object. The output of the detection circuit is detected using the
comparator. At the circuit this time, the operational amplifier of the single
amplifies and outputs the difference between the positive input and the
negative input.
feedback, at a little input voltage, the output becomes the saturation state.
factors. So, when the positive input becomes higher a little than the negative
input, the difference is tens of thousands of times amplified and the output
becomes the same as the power supply almost.(It is the saturation state)
Oppositely, when the positive input becomes lower a little than the negative
input, the difference is tens of thousands of times amplified and the output
different about the comparator and the operational amplifier, the comparator
At the circuit this time, it connects the output of the detection circuit with
the negative input of the signal detector and it makes the voltage of the
object and returns after sending out the ultrasonic. It is using the SR (the set
The set condition is the time which begins to let out the ultrasonic with the
The reset condition is the time which detected the signal with the signal
That is, the time that the output of SR-FF (D) is in the ON condition
becomes the time which returns after letting out the ultrasonic
The time that the sound wave goes and returns in the 40-cm distance
When the ambient temperature is 20°C, the propagation speed of the sound wave is 343.5
m/second.
In the time to be propagated by 80 cm (the going and returning), it is as follows.
TS = 0.8/343.5
= 0.00233
= 2.33 milliseconds
The time that the sound wave goes and returns in the 10-m distance
In the time to be propagated by 20 m (the going and returning), it is as follows.
TL = 20/343.5
= 0.05822
= 58.2 milliseconds
.
MICROCONTROLLER AT89C51
Pin Description
VCC
Supply voltage.
GND
Ground.
Port 0
Port 0 is an 8-bit open drain bidirectional I/O port. As an output port each pin can sink
eight TTL inputs. When 1s are written to port 0 pins, the pins can be used as high
impedance inputs. Port 0 may also be configured to be the multiplexed low order
address/data bus during accesses to external program and data memory. In this mode P0
has internal pull-ups. Port 0 also receives the code bytes during Flash programming, and
outputs the code bytes during program verification.
External pull-ups are required during program verification.
Port 1
Port 1 is an 8-bit bidirectional I/O port with internal pull-ups. The Port 1 output buffers
can sink/source four TTL inputs. When 1s are written to Port 1 pins they are pulled high
by the internal pull-ups and can be used as inputs. As inputs, Port 1 pins that are
externally being pulled low will source current (IIL) because of the internal pull-ups. Port
1 also receives the low-order address bytes during Flash programming and verification.
Port 2
Port 2 is an 8-bit bidirectional I/O port with internal pull-ups. The Port 2 output buffers
can sink/source four TTL inputs. When 1s are written to Port 2 pins they are pulled high
by the internal pull-ups and can be used as inputs. As inputs, Port 2 pins that are
externally being pulled low will source current (IIL) because of the internal pull-ups. Port
2 emits the high-order address byte during fetches from external program memory and
during accesses to external data memory that uses 16-bit addresses (MOVX @ DPTR). In
this application it uses strong internal pull-ups when emitting 1s. During accesses to
external data memory that uses 8-bit addresses (MOVX @ RI); Port 2 emits the contents
of the P2 Special Function Register. Port 2 also receives the high-order address bits and
some control signals during Flash programming and verification.
Port 3
Port 3 is an 8-bit bidirectional I/O port with internal pull-ups. The Port 3 output buffers
can sink/source four TTL inputs. When 1s are written to Port 3 pins they are pulled high
by the internal pull-ups and can be used as inputs. As inputs, Port 3 pins that are
externally being pulled low will source current (IIL) because of the pull-ups. Port 3 also
serves the functions of various special features of the AT89C51 as listed below:
Port 3 also receives some control signals for Flash programming and verification.
RST
Reset input. A high on this pin for two machine cycles while the oscillator is running
resets the device.
ALE/PROG
Address Latch Enable output pulse for latching the low byte of the address during
accesses to external memory. This pin is also the program pulse input (PROG) during
Flash programming. In normal operation ALE is emitted at a constant rate of 1/6 the
oscillator frequency, and may be used for external timing or clocking purposes. Note,
however, that one ALE pulse is skipped during each access to external Data Memory. If
desired, ALE operation can be disabled by setting bit 0 of SFR location 8EH. With the bit
set, ALE is active only during a MOVX or MOVC instruction. Otherwise, the pin is
weakly pulled high. Setting the ALE-disable bit has no effect if the microcontroller is in
external execution mode.
PSEN
Program Store Enable is the read strobe to external program memory.
When the AT89C51 is executing code from external program memory, PSEN is activated
twice each machine cycle, except that two PSEN activations are skipped during each
access to external data memory.
EA/VPP
External Access Enable. EA must be strapped to GND in order to enable the device to
fetch code from external program memory locations starting at 0000H up to FFFFH.
Note, however, that if lock bit 1 is programmed, EA will be internally latched on reset.
EA should be strapped to VCC for internal program executions. This pin also receives the
12-volt programming enable voltage (VPP) during Flash programming, for parts that
require 12-volt VPP.
XTAL1
Input to the inverting oscillator amplifier and input to the internal clock operating circuit.
XTAL2
Output from the inverting oscillator amplifier.
Oscillator Characteristics
XTAL1 and XTAL2 are the input and output, respectively, of an inverting amplifier
which can be configured for use as an on-chip oscillator, as shown in Figure 1. Either a
quartz crystal or ceramic resonator may be used. To drive the device from an external
clock source, XTAL2 should be left unconnected while XTAL1 is driven as shown in
Figure 2.There are no requirements on the duty cycle of the external clock signal, since
the input to the internal clocking circuitry is through a divide-by-two flip-flop, but
minimum and maximum voltage high and low time specifications must be observed.
Idle Mode
In idle mode, the CPU puts itself to sleep while all the on chip peripherals remain active.
The mode is invoked by software. The content of the on-chip RAM and all the special
functions registers remain unchanged during this mode. The idle mode can be terminated
by any enabled
Interrupt or by hardware reset. It should be noted that when idle is terminated by a hard
Hardware reset, the device normally resumes program execution, from where it left off,
up to two machine cycles before the internal reset algorithm takes control. On-chip
hardware inhibits access to internal RAM in this event, but access to the port pins is not
inhibited. To eliminate the possibility of an unexpected write to a port pin when Idle is
terminated by reset, the instruction following the one that invokes Idle should not be one
that writes to a port pin or to external memory.
Status of External Pins during Idle and Power down Modes
Mode Program Memory ALE PSEN PORT0 PORT1 PORT2 PORT3
Idle Internal 1 Data
Idle External 1 Float Data Address Data
Power down Internal 0 Data
Power down External 0 Float Data
Programming Algorithm:
Before programming the AT89C51, the address, data and control signals should be set up
according to the Flash programming mode table and Figures 3 and 4. To program the
AT89C51, take the following steps.
1. Input the desired memory location on the address lines.
2. Input the appropriate data byte on the data lines.
3. Activate the correct combination of control signals.
4. Raise EA/VPP to 12V for the high-voltage programming mode.
5. Pulse ALE/PROG once to program a byte in the Flash array or the lock bits. The byte-
write cycle is self-timed and typically takes no more than 1.5 ms. Repeat steps 1 through
5, changing the address and data for the entire array or until the end of the object file is
reached.
Data Polling:
The AT89C51 features Data Polling to indicate the end of a write cycle. During a write
cycle, an attempted read of the last byte written will result in the complement of the
written datum on PO.7. Once the write cycle has been completed, true data are valid on
all outputs, and the next cycle may begin. Data Polling may begin any time after a write
cycle has been initiated.
Ready/Busy:
The progress of byte programming can also be monitored by the RDY/BSY output
signal. P3.4 is pulled low after ALE goes high during programming to indicate BUSY.
P3.4 is pulled high again when programming is done to indicate READY.
Program Verify:
If lock bits LB1 and LB2 have not been programmed, the programmed code data can be
read back via the address and data lines for verification. The lock bits cannot be verified
directly. Verification of the lock bits is achieved by observing that their features are
enabled.
Chip Erase:
The entire Flash array is erased electrically by using the proper combination of control
signals and by holding ALE/PROG low for 10 ms. The code array is written with all
“1”s. The chip erase operation must be executed before the code memory can be re-
programmed.
Programming Interface
Every code byte in the Flash array can be written and the entire array can be erased by
using the appropriate combination of control signals. The write operation cycle is self
timed and once initiated, will automatically time itself to completion. All major
programming vendors offer worldwide support for the Atmel microcontroller series.
Please contact your local programming vendor for the appropriate software revision.
Both timers are the 89c51 share the one register TMOD. 4 LSB bit for the timer 0 and 4
MSB for the timer 1.
In each case lower 2 bits set the mode of the timer
Upper two bits set the operations.
GATE: Gating control when set. Timer/counter is enabled only while the INTX
pin is high and the TRx control pin is set. When cleared, the timer is enabled whenever
the TRx control bit is set
C/T: Timer or counter selected cleared for timer operation (input from internal
system clock)
M1 Mode bit 1
M0 Mode bit 0
If the bit is 0, the corresponding interrupt has a lower priority and if the bit is 1 the
corresponding interrupt has a higher priority
IP.7 NOT IMPLEMENTED, RESERVED FOR FUTURE USE.
IP.6 NOT IMPLEMENTED, RESERVED FOR FUTURE USE
PT2 IP.5 DEFINE THE TIMER 2 INTERRUPT PRIORITY LELVEL
PS IP.4 DEFINES THE SERIAL PORT INTERRUPT PRIORITY LEVEL
PT1 IP.3 DEFINES THE TIMER 1 INTERRUPT PRIORITY LEVEL
PX1 IP.2 DEFINES EXTERNAL INTERRUPT 1 PRIORITY LEVEL
PT0 IP.1 DEFINES THE TIMER 0 INTERRUPT PRIORITY LEVEL
PX0 IP.0 DEFINES THE EXTERNAL INTERRUPT 0 PRIORITY LEVEL
Counter 1 On/off
TF0 TCON.5 Timer 0 overflows flag. Set by hardware when the timer/counter 0
Overflows. Cleared by hardware as processor
TR0 TCON.4 Timer 0 run control bit. Set/cleared by software to turn timer
Counter 0 on/off.
IE1 TCON.3 External interrupt 1 edge flag
ITI TCON.2 Interrupt 1 type control bit
IE0 TCON.1 External interrupt 0 edge
IT0 TCON.0 Interrupt 0 type control bit.
MCS-51 FAMILY INSTRUCTION SET
ACALL addr11
Function: Absolute call
Description: ACALL unconditionally calls a subroutine located at the indicated address.
The instruction increments the PC twice to obtain the address of the following
instruction, then pushes the 16-bit result onto the stack (low-order byte first) and
increments the stack pointer twice. The destination address is obtained by successively
concatenating the five high-order bits of the incremented PC, op code bits 7-5, and the
second byte of the instruction. The subroutine called must therefore start within the same
2K block of program memory as the first byte of the instruction following ACALL. No
flags are affected. Example: Initially SP equals 07H. The label”SUBRTN” is at program
memory location 0345H. After executing the instruction ACALL SUBRTN at location
0123H, SP will contain 09H, internal RAM location 08H and 09H will contain 25H and
01H, respectively, and the PC will contain 0345H.
Operation: ACALL
(PC) ¬ (PC) + 2
(SP) ¬ (SP) + 1
((SP)) ¬ (PC7-0)
(SP) ¬ (SP) + 1
((SP)) ¬ (PC15-8)
(PC10-0) ¬ Page address
Bytes: 2
Cycles: 2
Encoding: a10 a9 a8 1 0 0 0 1 a7 a6 a5 a4 a3 a2 a1 a0
ADD A, <src-byte>
Function: Add
Description: ADD adds the byte variable indicated to the accumulator, leaving the result
in the accumulator. The carry and auxiliary carry flags are set, respectively, if there is a
Carry out of bit 7 or bit 3, and cleared otherwise. When adding unsigned integers, the
carry flag indicates an overflow occurred. OV is set if there is a carry out of bit 6 but not
out of bit 7, or a carry out of bit 7 but not out of bit 6; otherwise OV is cleared. When
adding signed integers, OV indicates a negative number produced as the sum of two
positive operands, or a positive sum from two negative operands. Four source operand
addressing modes are allowed: register, direct, register indirect, or immediate.
Example: The accumulator holds 0C3H (11000011B) and register 0 holds 0AAH
(10101010B). The instruction ADD A, R0 will leave 6DH (01101101B) in the
accumulator with the AC flag cleared and both the carry flag and OV set to 1.
ADD A,Rn
Operation: ADD
(A) ¬ (A) + (Rn)
Bytes: 1
Cycles: 1
ADD A, direct
Operation: ADD
(A) ¬ (A) + (direct)
Bytes: 2
Cycles: 1
Encoding: 0 0 1 0 1 r r r
Encoding: 0 0 1 0 0 1 0 1 direct address
ADD A, @Ri
Operation: ADD
(A) ¬ (A) + ((Ri))
Bytes: 1
Cycles: 1
ADD A, #data
Operation: ADD
(A) ¬ (A) + #data
Bytes: 2
Cycles: 1
Encoding: 0 0 1 0 0 1 1 i
Encoding: 0 0 1 0 0 1 0 0 immediate data
ADDC A, Rn
Operation: ADDC
(A) ¬ (A) + (C) + (Rn)
Bytes: 1
Cycles: 1
ADDC A, direct
Operation: ADDC
(A) ¬ (A) + (C) + (direct)
Bytes: 2
Cycles: 1
Encoding: 0 0 1 1 1 r r r
Encoding: 0 0 1 1 0 1 0 1 direct address
ADDC A, @Ri
Operation: ADDC
(A) ¬ (A) + (C) + ((Ri))
Bytes: 1
Cycles: 1
ADDC A, #data
Operation: ADDC
(A) ¬ (A) + (C) + #data
Bytes: 2
Cycles: 1
Encoding: 0 0 1 1 0 1 1 i
Encoding: 0 0 1 1 0 1 0 0 immediate data
AJMP addr11
Function: Absolute jump
Description: AJMP transfers program execution to the indicated address, which is formed
at runtime by concatenating the high-order five bits of the PC (after incrementing the PC
twice), op code bits 7-5, and the second byte of the instruction. The destination must
therefore be within the same 2K block of program memory as the first byte of the
instruction following AJMP.
Example: The label”JMPADR” is at program memory location 0123H. The instruction
AJMP JMPADR is at location 0345H and will load the PC with 0123H.
Operation: AJM P
(PC) ¬ (PC) + 2
(PC10-0) ¬ Page address
Bytes: 2
Cycles: 2
Encoding: a10 a9 a8 0 0 0 0 1 a7 a6 a5 a4 a3 a2 a1 a0
ANL A, Rn
Operation: ANL
(A) ¬ (A) Ù (Rn)
Bytes: 1
Cycles: 1
Encoding: 0 1 0 1 1 r r r
ANL A, direct
Operation: ANL
(A) ¬ (A) Ù (direct)
Bytes: 2
Cycles: 1
ANL A, @Ri
Operation: ANL
(A) ¬ (A) Ù ((Ri))
Bytes: 1
Cycles: 1
ANL A, #data
Operation: ANL
(A) ¬ (A) Ù #data
Bytes: 2
Cycles: 1
ANL direct, A
Operation: ANL
(direct) ¬ (direct) Ù (A)
Bytes: 2
Cycles: 1
Encoding: 0 1 0 1 0 1 0 1 direct address
Encoding: 0 1 0 1 0 1 1 i
Encoding: 0 1 0 1 0 1 0 0 immediate data
Encoding: 0 1 0 1 0 1 0 1 direct address
ANL C, <src-bit>
Function: Logical AND for bit variables
Description: If the Boolean value of the source bit is logic 0 then clear the carry flag;
otherwise leave the carry flag in its current state. A slash (”/” preceding the operand in
the assembly language indicates that the logical complement of the addressed bit is used
as the source value, but the source bit itself is not affected. No other flags are affected.
Only direct bit addressing is allowed for the source operand.
Example: Set the carry flag if and only if, P1.0 = 1, ACC.7 = 1 and OV = 0:
MOV C, P1.0; Load carry with input pin state
ANL C, ACC.7; AND carry with accumulator bit 7
ANL C, /OV; AND with inverse of overflow flag
ANL C, bit
Operation: ANL
(C) ¬ (C) Ù (bit)
Bytes: 2
Cycles: 2
ANL C, /bit
Operation: ANL
(C) ¬ (C) Ù Ø (bit)
Bytes: 2
Cycles: 2
Encoding: 1 0 0 0 0 0 1 0 bit address
Encoding: 1 0 1 1 0 0 0 0 bit address
CLR A
Function: Clear accumulator
Description: The accumulator is cleared (all bits set to zero). No flags are affected.
Example: The accumulator contains 5CH (01011100B). The instruction
CLR A
will leave the accumulator set to 00H (00000000B).
Operation: CLR
(A) ¬ 0
Bytes: 1
Cycles: 1
Encoding: 1 1 1 0 0 1 0 0
CLR bit
Function: Clear bit
Description: The indicated bit is cleared (reset to zero). No other flags are affected. CLR
can operate on the carry flag or any directly addressable bit. Example: Port 1 has
previously been written with 5DH (01011101B). The instruction
CLR P1.2
will leave the port set to 59H (01011001B).
CLR C
Operation: CLR
(C) ¬ 0
Bytes: 1
Cycles: 1
CLR bit
Operation: CLR
(bit) ¬ 0
Bytes: 2
Cycles: 1
Encoding: 1 1 0 0 0 0 1 1
Encoding: 1 1 0 0 0 0 1 0 bit address
CPL A
Function: Complement accumulator
Description: Each bit of the accumulator is logically complemented (one’s complement).
Bits which previously contained a one are changed to zero and vice versa. No flags are
affected.
Example: The accumulator contains 5CH (01011100B). The instruction
CPL A
will leave the accumulator set to 0A3H (10100011 B).
Operation: CPL
(A) ¬ Ø (A)
Bytes: 1
Cycles: 1
Encoding: 1 1 1 1 0 1 0 0
CPL bit
Function: Complement bit
Description: The bit variable specified is complemented. A bit which had been a one is
changed to zero and vice versa. No other flags are affected. CPL can operate on the carry
or any directly addressable bit.
Note:
When this instruction is used to modify an output pin, the value used as the original data
will be read from the output data latch, not the input pin.
Example: Port 1 has previously been written with 5DH (01011101B). The instruction
sequence
CPL P1.1
CPL P1.2
will leave the port set to 5BH (01011011B).
CPL C
Operation: CPL
(C) ¬ Ø (C)
Bytes: 1
Cycles: 1
CPL bit
Operation: CPL
(bit) ¬ Ø (bit)
Bytes: 2
Cycles: 1
Encoding: 1 0 1 1 0 0 1 1
Encoding: 1 0 1 1 0 0 1 0 bit address
DA A
Function: Decimal adjust accumulator for addition
Description: DA A adjusts the eight-bit value in the accumulator resulting from the
earlier addition of two variables (each in packed BCD format), producing two four-bit
digits. Any ADD or ADDC instruction may have been used to perform the addition.
If accumulator bits 3-0 are greater than nine (xxxx1010-xxxx1111), or if the AC flag
is one, six is added to the accumulator producing the proper BCD digit in the low order
nibble. This internal addition would set the carry flag if a carry-out of the low order
four-bit field propagated through all high-order bits, but it would not clear the carry flag
otherwise.
If the carry flag is now set, or if the four high-order bits now exceed nine (1010xxxx-
1111xxxx), these high-order bits are incremented by six, producing the proper BCD digit
in the high-order nibble. Again, this would set the carry flag if there was a carryout of the
high-order bits, but wouldn’t clear the carry. The carry flag thus indicates if the sum of
the original two BCD variables is greater than 100, allowing multiple precision decimal
additions. OV is not affected.
All of this occurs during the one instruction cycle. Essentially; this instruction performs
the decimal conversion by adding 00H, 06H, 60H, or 66H to the accumulator, depending
on initial accumulator and PSW conditions.
Note:
DA A cannot simply convert a hexadecimal number in the accumulator to BCD notation,
nor does DA A apply to decimal subtraction.
Example: The accumulator holds the value 56H (01010110B) representing the packed
BCD digits of the decimal number 56. Register 3 contains the value 67H (01100111B)
representing the packed BCD digits of the decimal number 67. The carry flag is set.
The instruction sequence
ADDC A, R3
DA A
will first perform a standard two’s-complement binary addition, resulting in the value
0BEH (10111110B) in the accumulator. The carry and auxiliary carry flags will be
cleared.
The decimal adjust instruction will then alter the accumulator to the value 24H
(00100100B), indicating the packed BCD digits of the decimal number 24, the low order
two digits of the decimal sum of 56, 67, and the carry-in. The carry flag will be set by the
decimal adjust instruction, indicating that a decimal overflow occurred.
The true sum 56, 67, and 1 is 124.
DEC byte
Function: Decrement
Description: The variable indicated is decremented by 1. An original value of 00H wills
underflow to 0FFH. No flags are affected. Four operand addressing modes are allowed:
accumulator, register, direct, or register-indirect.
Note:
When this instruction is used to modify an output port, the value used as the original
port data will be read from the output data latch, not the input pins.
Example: Register 0 contains 7FH (01111111B). Internal RAM locations 7EH and 7FH
contain 00H and 40H, respectively. The instruction sequence
DEC @R0
DEC R0
DEC @R0
will leave register 0 set to 7EH and internal RAM locations 7EH and 7FH set to 0FFH
and 3FH.
DEC A
Operation: DEC
(A) ¬ (A) – 1
Bytes: 1
Cycles: 1
DEC Rn
Operation: DEC
(Rn) ¬ (Rn) – 1
Bytes: 1
Cycles: 1
Encoding: 0 0 0 1 0 1 0 0
Encoding: 0 0 0 1 1 r r r
DEC direct
Operation: DEC
(direct) ¬ (direct) – 1
Bytes: 2
Cycles: 1
DEC @Ri
Operation: DEC
((Ri)) ¬ ((Ri)) – 1
Bytes: 1
Cycles: 1
Encoding: 0 0 0 1 0 1 0 1 direct address
Encoding: 0 0 0 1 0 1 1 i
DIV AB
Function: Divide
Description: DIV AB divides the unsigned eight-bit integer in the accumulator by the
unsigned eight-bit integer in register B. The accumulator receives the integer part of the
quotient; register B receives the integer remainder. The carry and OV flags will be
cleared.
Exception: If B had originally contained 00H, the values returned in the accumulator and
B register will be undefined and the overflow flag will be set. The carry flag is cleared in
any case.
Example: The accumulator contains 251 (0FBH or 11111011B) and B contains 18 (12H
or
00010010B). The instruction
DIV AB
will leave 13 in the accumulator (0DH or 00001101 B) and the value 17 (11H or
00010001B) in B, since 251 = (13x18) + 17. Carry and OV will both be cleared.
Operation: DIV
(A15-8)
(B7-0)
Bytes: 1
Cycles: 4
Encoding: 1 0 0 0 0 1 0 0
¬ (A) / (B)
INC <byte>
Function: Increment
Description: INC increments the indicated variable by 1. An original value of 0FFH will
overflow to 00H. No flags are affected. Three addressing modes are allowed: register,
direct, or register-indirect.
Note:
When this instruction is used to modify an output port, the value used as the original
port data will be read from the output data latch, not the input pins.
Example: Register 0 contains 7EH (01111110B). Internal RAM locations 7EH and 7FH
contain 0FFH and 40H, respectively. The instruction sequence
INC @R0
INC R0
INC @R0
will leave register 0 set to 7FH and internal RAM locations 7EH and 7FH holding
(respectively) 00H and 41H.
INC A
Operation: INC
(A) ¬ (A) + 1
Bytes: 1
Cycles: 1
INC Rn
Operation: INC
(Rn) ¬ (Rn) + 1
Bytes: 1
Cycles: 1
Encoding: 0 0 0 0 0 1 0 0
Encoding: 0 0 0 0 1 r r r
INC direct
Operation: INC
(direct) ¬ (direct) + 1
Bytes: 2
Cycles: 1
INC @Ri
Operation: INC
((Ri)) ¬ ((Ri)) + 1
Bytes: 1
Cycles: 1
Encoding: 0 0 0 0 0 1 0 1 direct address
Encoding: 0 0 0 0 0 1 1 i
INC DPTR
Function: Increment data pointer
Description: Increment the 16-bit data pointer by 1. A 16-bit increment (modulo 216) is
performed; an overflow of the low-order byte of the data pointer (DPL) from 0FFH to
00H will increment the high-order byte (DPH). No flags are affected. This is the only 16-
bit register which can be incremented.
Example: Registers DPH and DPL contain 12H and 0FEH, respectively. The instruction
sequence
INC DPTR
INC DPTR
INC DPTR
will change DPH and DPL to 13H and 01H.
Operation: INC
(DPTR) ¬ (DPTR) + 1
Bytes: 1
Cycles: 2
Encoding: 1 0 1 0 0 0 1 1
JB bit, rel
Function: Jump if bit is set
Description: If the indicated bit is a one, jump to the address indicated; otherwise proceed
with the next instruction. The branch destination is computed by adding the signed
relative-displacement in the third instruction byte to the PC, after incrementing the PC to
the first byte of the next instruction. The bit tested is not modified. No flags are affected.
Example: The data present at input port 1 is 11001010B. The accumulator holds 56
(01010110B). The instruction sequence
JB P1.2, LABEL1
JB ACC.2, LABEL2
will cause program execution to branch to the instruction at label LABEL2.
Operation: JB
(PC) ¬ (PC) + 3
if (bit) = 1
then (PC) ¬ (PC) + rel
Bytes: 3
Cycles: 2
Encoding: 0 0 1 0 0 0 0 0 bit address rel. address
JC rel
Function: Jump if carry is set
Description: If the carry flag is set, branch to the address indicated; otherwise proceed
with the next instruction. The branch destination is computed by adding the signed
relative displacement in the second instruction byte to the PC, after incrementing the PC
twice. No flags are affected.
Example: The carry flag is cleared. The instruction sequence
JC LABEL1
CPL C
JC LABEL2
will set the carry and cause program execution to continue at the instruction identified by
the label LABEL2.
Operation: JC
(PC) ¬ (PC) + 2
if (C) = 1
then (PC) ¬ (PC) + rel
Bytes: 2
Cycles: 2
Encoding: 0 1 0 0 0 0 0 0 rel. address
JMP @A + DPTR
Function: Jump indirect
Description: Add the eight-bit unsigned contents of the accumulator with the sixteen-bit
data pointer, and load the resulting sum to the program counter. This will be the address
for subsequent instruction fetches. Sixteen-bit addition is performed (modulo 216): a
carry-out from the low-order eight bits propagates through the higher-order bits. Neither
the accumulator nor the data pointer is altered. No flags are affected.
Example: An even number from 0 to 6 is in the accumulator. The following sequence of
instructions will branch to one of four AJMP instructions in a jump table starting at
JMP_TBL:
MOV DPTR, #JMP_TBL
JMP @A + DPTR
JMP_TBL: AJMP LABEL0
AJMP LABEL1
AJMP LABEL2
AJMP LABEL3
If the accumulator equals 04H when starting this sequence, execution will jump to label
LABEL2. Remember that AJMP is a two-byte instruction, so the jump instructions start
at every other address.
Operation: JMP
(PC) ¬ (A) + (DPTR)
Bytes: 1
Cycles: 2
Encoding: 0 1 1 1 0 0 1 1
JNC rel
Function: Jump if carry is not set
Description: If the carry flag is a zero, branch to the address indicated; otherwise proceed
with the next instruction. The branch destination is computed by adding the signed
relative-displacement in the second instruction byte to the PC, after incrementing the PC
twice to point to the next instruction. The carry flag is not modified.
Example: The carry flag is set. The instruction sequence
JNC LABEL1
CPL C
JNC LABEL2
will clear the carry and cause program execution to continue at the instruction identified
by the label LABEL2.
Operation: JNC
(PC) ¬ (PC) + 2
if (C) = 0
then (PC) ¬ (PC) + rel
Bytes: 2
Cycles: 2
Encoding: 0 1 0 1 0 0 0 0 rel. address
JNZ rel
Function: Jump if accumulator is not zero
Description: If any bit of the accumulator is a one, branch to the indicated address;
otherwise proceed with the next instruction. The branch destination is computed by
adding the signed relative-displacement in the second instruction byte to the PC, after
incrementing the PC twice. The accumulator is not modified. No flags are affected.
Example: The accumulator originally holds 00H. The instruction sequence
JNZ LABEL1
INC A
JNZ LABEL2
will set the accumulator to 01H and continue at label LABEL2.
Operation: JNZ
(PC) ¬ (PC) + 2
if (A) ¹ 0
then (PC) ¬ (PC) + rel.
Bytes: 2
Cycles: 2
Encoding: 0 1 1 1 0 0 0 0 rel. address
JZ rel
Function: Jump if accumulator is zero
Description: If all bits of the accumulator are zero, branch to the address indicated;
otherwise proceed with the next instruction. The branch destination is computed by
adding the signed relative-displacement in the second instruction byte to the PC, after
incrementing the PC twice. The accumulator is not modified. No flags are affected.
Example: The accumulator originally contains 01H. The instruction sequence
JZ LABEL1
DEC A
JZ LABEL2
will change the accumulator to 00H and cause program execution to continue at the
instruction identified by the label LABEL2.
Operation: JZ
(PC) ¬ (PC) + 2
if (A) = 0
then (PC) ¬ (PC) + rel
Bytes: 2
Cycles: 2
Encoding: 0 1 1 0 0 0 0 0 rel. address
LCALL addr16
Function: Long call
Description: LCALL calls a subroutine located at the indicated address. The instruction
adds three to the program counter to generate the address of the next instruction and then
pushes the 16-bit result onto the stack (low byte first), incrementing the stack pointer by
two. The high-order and low-order bytes of the PC are then loaded, respectively, with the
second and third bytes of the LCALL instruction. Program execution continues with the
instruction at this address. The subroutine may therefore begin anywhere in the full 64
Kbytes program memory address space. No flags are affected.
Example: Initially the stack pointer equals 07H. The label”SUBRTN” is assigned to
program memory location 1234H. After executing the instruction
LCALL SUBRTN
at location 0123H, the stack pointer will contain 09H, internal RAM locations 08H and
09H will contain 26H and 01H, and the PC will contain 1234H.
Operation: LCALL
(PC) ¬ (PC) + 3
(SP) ¬ (SP) + 1
((SP)) ¬ (PC7-0)
(SP) ¬ (SP) + 1
((SP)) ¬ (PC15-8)
(PC) ¬ addr15-0
Bytes: 3
Cycles: 2
Encoding: 0 0 0 1 0 0 1 0 addr15. . addr8 addr7. . addr0
LJMP addr16
Function: Long jump
Description: LJMP causes an unconditional branch to the indicated address, by loading
the high order and low-order bytes of the PC (respectively) with the second and third
instruction bytes. The destination may therefore be anywhere in the full 64K program
memory address space. No flags are affected.
Example: The label”JMPADR” is assigned to the instruction at program memory location
1234H. The instruction
LJMP JMPADR
at location 0123H will load the program counter with 1234H.
Operation: LJMP
(PC) ¬ addr15-0
Bytes: 3
Cycles: 2
Encoding: 0 0 0 0 0 0 1 0 addr15 . . . addr8 addr7 . . . addr0
MOV A, Rn
Operation: MOV
(A) ¬ (Rn)
Bytes: 1
Cycles: 1
MOV A, direct *)
Operation: MOV
(A) ¬ (direct)
Bytes: 2
Cycles: 1
*) MOV A, ACC is not a valid instruction.
Encoding: 1 1 1 0 1 r r r
Encoding: 1 1 1 0 0 1 0 1 direct address
MOV A,@Ri
Operation: MOV
(A) ¬ ((Ri))
Bytes: 1
Cycles: 1
MOV A, #data
Operation: MOV
(A) ¬ #data
Bytes: 2
Cycles: 1
MOV Rn, A
Operation: MOV
(Rn) ¬ (A)
Bytes: 1
Cycles: 1
MOV direct, A
Operation: MOV
(direct) ¬ (A)
Bytes: 2
Cycles: 1
MOV direct, Rn
Operation: MOV
(direct) ¬ (Rn)
Bytes: 2
Cycles: 2
MOV direct, direct
Operation: MOV
(direct) ¬ (direct)
Bytes: 3
Cycles: 2
Encoding: 0 1 1 1 1 r r r immediate data
Encoding: 1 1 1 1 0 1 0 1 direct address
Encoding: 1 0 0 0 1 r r r direct address
Encoding: 1 0 0 0 0 1 0 1 dir.addr. (src) dir.addr. (dest)
MOV direct, @ Ri
Operation: MOV
(direct) ¬ ((Ri))
Bytes: 2
Cycles: 2
MOV @ Ri, A
Operation: MOV
((Ri)) ¬ (A)
Bytes: 1
Cycles: 1
MOV C, bit
Operation: MOV
(C) ¬ (bit)
Bytes: 2
Cycles: 1
MOV bit, C
Operation: MOV
(bit) ¬ (C)
Bytes: 2
Cycles: 2
Encoding: 1 0 1 0 0 0 1 0 bit address
Encoding: 1 0 0 1 0 0 1 0 bit address
MOVC A, @A + <base-reg>
Function: Move code byte
Description: The MOVC instructions load the accumulator with a code byte, or constant
from program memory. The address of the byte fetched is the sum of the original
unsigned eight-bit accumulator contents and the contents of a sixteen-bit base register,
which may be either the data pointer or the PC. In the latter case, the PC is incremented
to the address of the following instruction before being added to the accumulator;
otherwise the base register is not altered. Sixteen-bit addition is performed so a carry-out
from the low-order eight bits may propagate through higher-order bits. No flags are
affected.
Example: A value between 0 and 3 is in the accumulator. The following instructions will
translate the value in the accumulator to one of four values defined by the DB (define
byte) directive.
REL_PC: INC A
MOVC A, @A + PC
RET
DB 66H
DB 77H
DB 88H
DB 99H
If the subroutine is called with the accumulator equal to 01H, it will return with 77H in
the accumulator. The INC A before the MOVC instruction is needed to”get around” the
RET instruction above the table. If several bytes of code separated the MOVC from the
table, the corresponding number would be added to the accumulator instead.
MOVC A, @A + DPTR
Operation: MOVC
(A) ¬ ((A) + (DPTR))
Bytes: 1
Cycles: 2
Encoding: 1 0 0 1 0 0 1 1
MOVC A, @A + PC
Operation: MOVC
(PC) ¬ (PC) + 1
(A) ¬ ((A) + (PC))
Bytes: 1
Cycles: 2
Encoding: 1 0 0 0 0 0 1 1
MOVX A,@Ri
Operation: MOVX
(A) ¬ ((Ri))
Bytes: 1
Cycles: 2
MOVX A,@DPTR
Operation: MOVX
(A) ¬ ((DPTR))
Bytes: 1
Cycles: 2
MOVX @Ri, A
Operation: MOVX
((Ri)) ¬ (A)
Bytes: 1
Cycles: 2
MOVX @DPTR, A
Operation: MOVX
((DPTR)) ¬ (A)
Bytes: 1
Cycles: 2
Encoding: 1 1 1 0 0 0 1 i
Encoding: 1 1 1 0 0 0 0 0
Encoding: 1 1 1 1 0 0 1 i
Encoding: 1 1 1 1 0 0 0 0
MUL AB
Function: Multiply
Description: MUL AB multiplies the unsigned eight-bit integers in the accumulator and
register B. The low-order byte of the sixteen-bit product is left in the accumulator, and
the high-order byte in B. If the product is greater than 255 (0FFH) the overflow flag is
set; otherwise it is cleared. The carry flag is always cleared. Example: Originally the
accumulator holds the value 80 (50H). Register B holds the value 160 (0A0H). The
instruction
MUL AB
will give the product 12,800 (3200H), so B is changed to 32H (00110010B) and the
accumulator is cleared. The overflow flag is set, carry is cleared.
Operation: MUL
(A7-0)
(B15-8)
Bytes: 1
Cycles: 4
Encoding: 1 0 1 0 0 1 0 0
¬ (A) x (B)
NOP
Function: No operation
Description: Execution continues at the following instruction. Other than the PC, no
registers or flags are affected.
Example: It is desired to produce a low-going output pulse on bit 7 of port 2 lasting
exactly 5 cycles. A simple SETB/CLR sequence would generate a one-cycle pulse, so
four additional cycles must be inserted. This may be done (assuming no interrupts are
enabled) with the instruction sequence
CLR P2.7
NOP
NOP
NOP
NOP
SETB P2.7
Operation: NOP
Bytes: 1
Cycles: 1
Encoding: 0 0 0 0 0 0 0 0
ORL A, Rn
Operation: ORL
(A) ¬ (A) Ú (Rn)
Bytes: 1
Cycles: 1
Encoding: 0 1 0 0 1 r r r
ORL A, direct
Operation: ORL
(A) ¬ (A) Ú (direct)
Bytes: 2
Cycles: 1
ORL A,@Ri
Operation: ORL
(A) ¬ (A) Ú ((Ri))
Bytes: 1
Cycles: 1
ORL A, data
Operation: ORL
(A) ¬ (A) Ú #data
Bytes: 2
Cycles: 1
ORL direct, A
Operation: ORL
(direct) ¬ (direct) Ú (A)
Bytes: 2
Cycles: 1
Encoding: 0 1 0 0 0 1 0 1 direct address
Encoding: 0 1 0 0 0 1 1 i
Encoding: 0 1 0 0 0 1 0 0 immediate data
Encoding: 0 1 0 0 0 0 1 0 direct address
ORL direct, #data
Operation: ORL
(direct) ¬ (direct) Ú #data
Bytes: 3
Cycles: 2
Encoding: 0 1 0 0 0 0 1 1 direct address immediate data
ORL C, <src-bit>
Function: Logical OR for bit variables
Description: Set the carry flag if the Boolean value is logic 1; leave the carry in its
current state otherwise. A slash (”/”) preceding the operand in the assembly language
indicates that the logical complement of the addressed bit is used as the source value, but
the source bit itself is not affected. No other flags are affected.
Example: Set the carry flag if and only if, P1.0 = 1, ACC.7 = 1 or OV = 0:
MOV C, P1.0; Load carry with input pin P1.0
ORL C, ACC.7; OR carry with the accumulator bit 7
ORL C, /OV; OR carry with the inverse of OV
ORL C, bit
Operation: ORL
(C) ¬ (C) Ú (bit)
Bytes: 2
Cycles: 2
ORL C, /bit
Operation: ORL
(C) ¬ (C) Ú Ø (bit)
Bytes: 2
Cycles: 2
Encoding: 0 1 1 1 0 0 1 0 bit address
Encoding: 1 0 1 0 0 0 0 0 bit address
POP direct
Function: Pop from stack
Description: The contents of the internal RAM location addressed by the stack pointer are
read, and the stack pointer is decremented by one. The value read is the transfer to the
directly addressed byte indicated. No flags are affected.
Example: The stack pointer originally contains the value 32H, and internal RAM
locations 30H
through 32H contain the values 20H, 23H, and 01H, respectively. The instruction
sequence
POP DPH
POP DPL
will leave the stack pointer equal to the value 30H and the data pointer set to 0123H.
At this point the instruction
POP SP
will leave the stack pointer set to 20H. Note that in this special case the stack pointer
was decremented to 2FH before being loaded with the value popped (20H).
Operation: POP
(direct) ¬ ((SP))
(SP) ¬ (SP) – 1
Bytes: 2
Cycles: 2
Encoding: 1 1 0 1 0 0 0 0 direct address
PUSH direct
Function: Push onto stack
Description: The stack pointer is incremented by one. The contents of the indicated
variable is then copied into the internal RAM location addressed by the stack pointer.
Otherwise no flags are affected.
Example: On entering an interrupt routine the stack pointer contains 09H. The data
pointer holds the value 0123H. The instruction sequence
PUSH DPL
PUSH DPH
will leave the stack pointer set to 0BH and store 23H and 01H in internal RAM locations
0AH and 0BH, respectively.
Operation: PUSH
(SP) ¬ (SP) + 1
((SP)) ¬ (direct)
Bytes: 2
Cycles: 2
Encoding: 1 1 0 0 0 0 0 0 direct address
RET
Function: Return from subroutine
Description: RET pops the high and low-order bytes of the PC successively from the
stack, decrementing the stack pointer by two. Program execution continues at the
resulting address, generally the instruction immediately following an ACALL or LCALL.
No flags are affected.
Example: The stack pointer originally contains the value 0BH. Internal RAM locations
0AH and 0BH contain the values 23H and 01H, respectively. The instruction RET will
leave the stack pointer equal to the value 09H. Program execution will continue at
location 0123H.
Operation: RET
(PC15-8) ¬ ((SP))
(SP) ¬ (SP) – 1
(PC7-0) ¬ ((SP))
(SP) ¬ (SP) – 1
Bytes: 1
Cycles: 2
Encoding: 0 0 1 0 0 0 1 0
RETI
Function: Return from interrupt
Description: RETI pops the high and low-order bytes of the PC successively from the
stack, and restores the interrupt logic to accept additional interrupts at the same priority
level as the one just processed. The stack pointer is left decremented by two. No other
registers are affected; the PSW is not automatically restored to its pre-interrupt status.
Program execution continues at the resulting address, which is generally the instruction
immediately after the point at which the interrupt request was detected. If a lower or
same-level interrupt is pending when the RETI instruction is executed, that one
instruction will be executed before the pending interrupt is processed.
Example: The stack pointer originally contains the value 0BH. An interrupt was detected
during the instruction ending at location 0122H. Internal RAM locations 0AH and 0BH
contain the values 23H and 01H, respectively. The instruction
RETI
will leave the stack pointer equal to 09H and return program execution to location
0123H.
Operation: RETI
(PC15-8) ¬ ((SP))
(SP) ¬ (SP) – 1
(PC7-0) ¬ ((SP))
(SP) ¬ (SP) – 1
Bytes: 1
Cycles: 2
Encoding: 0 0 1 1 0 0 1 0
RL A
Function: Rotate accumulator left
Description: The eight bits in the accumulator are rotated one bit to the left. Bit 7 is
rotated into the bit 0 position. No flags are affected.
Example: The accumulator holds the value 0C5H (11000101B). The instruction RL A
leaves the accumulator holding the value 8BH (10001011B) with the carry unaffected.
Operation: RL
(An + 1) ¬ (An) n = 0-6
(A0) ¬ (A7)
Bytes: 1
Cycles: 1
Encoding: 0 0 1 0 0 0 1 1
RLC A
Function: Rotate accumulator left through carry flag
Description: The eight bits in the accumulator and the carry flag are together rotated one
bit to the left. Bit 7 moves into the carry flag; the original state of the carry flag moves
into the bit 0 position. No other flags are affected.
Example: The accumulator holds the value 0C5H (11000101B), and the carry is zero.
The instruction
RLC A
leaves the accumulator holding the value 8AH (10001010B) with the carry set.
Operation: RLC
(An + 1) ¬ (An) n = 0-6
(A0) ¬ (C)
(C) ¬ (A7)
Bytes: 1
Cycles: 1
Encoding: 0 0 1 1 0 0 1 1
RR A
Function: Rotate accumulator right
Description: The eight bits in the accumulator are rotated one bit to the right. Bit 0 is
rotated into the bit 7 positions. No flags are affected.
Example: The accumulator holds the value 0C5H (11000101B). The instruction
RR A
leaves the accumulator holding the value 0E2H (11100010B) with the carry unaffected.
Operation: RR
(An) ¬ (An + 1) n = 0-6
(A7) ¬ (A0)
Bytes: 1
Cycles: 1
Encoding: 0 0 0 0 0 0 1 1
RRC A
Function: Rotate accumulator right through carry flag
Description: The eight bits in the accumulator and the carry flag are together rotated one
bit to the right. Bit 0 moves into the carry flag; the original value of the carry flag moves
into the bit 7 position. No other flags are affected.
Example: The accumulator holds the value 0C5H (11000101B), the carry is zero. The
instruction
RRC A
leaves the accumulator holding the value 62H (01100010B) with the carry set.
Operation: RRC
(An) ¬ (An + 1) n=0-6
(A7) ¬ (C)
(C) ¬ (A0)
Bytes: 1
Cycles: 1
Encoding: 0 0 0 1 0 0 1 1
SETB <bit>
Function: Set bit
Description: SETB sets the indicated bit to one. SETB can operate on the carry flag or
any directly addressable bit. No other flags are affected.
Example: The carry flag is cleared. Output port 1 has been written with the value 34H
(00110100B). The instructions
SETB C
SETB P1.0
will leave the carry flag set to 1 and change the data output on port 1 to 35H
(00110101B).
SETB C
Operation: SETB
(C) ¬ 1
Bytes: 1
Cycles: 1
SETB bit
Operation: SETB
(bit) ¬ 1
Bytes: 2
Cycles: 1
Encoding: 1 1 0 1 0 0 1 1
Encoding: 1 1 0 1 0 0 1 0 bit address
SJMP rel
Function: Short jump
Description: Program control branches unconditionally to the address indicated. The
branch destination is computed by adding the signed displacement in the second
instruction byte to the PC, after incrementing the PC twice. Therefore, the range of
destinations allowed is from 128 bytes preceding this instruction to 127 bytes following
it.
Example: The label ”RELADR” is assigned to an instruction at program memory location
0123H. The instruction
SJMP RELADR
will assemble into location 0100H. After the instruction is executed, the PC will contain
the value 0123H.
Note:
Under the above conditions the instruction following SJMP will be at 102H. Therefore,
the displacement byte of the instruction will be the relative offset (0123H-0102H) = 21H.
In other words, an SJMP with a displacement of 0FEH would be a one-instruction infinite
loop.
Operation: SJMP
(PC) ¬ (PC) + 2
(PC) ¬ (PC) + rel
Bytes: 2
Cycles: 2
Encoding: 1 0 0 0 0 0 0 0 rel. address
SUBB A, <src-byte>
Function: Subtract with borrow
Description: SUBB subtracts the indicated variable and the carry flag together from the
accumulator, leaving the result in the accumulator. SUBB sets the carry (borrow) flag if a
borrow is needed for bit 7, and clears C otherwise. (If C was set before executing a
SUBB instruction, this indicates that a borrow was needed for the previous step in a
multiple precision subtraction, so the carry is subtracted from the accumulator along with
the source operand). AC is set if a borrow is needed for bit 3, and cleared otherwise. OV
is set if a borrow is needed into bit 6 but not into bit 7, or into bit 7 but not bit 6. When
subtracting signed integers OV indicates a negative number produced when a negative
value is subtracted from a positive value or a positive result when a positive number is
subtracted from a negative number. The source operand allows four addressing modes:
register, direct, register indirect, or immediate.
Example: The accumulator holds 0C9H (11001001B), register 2 holds 54H (01010100B),
and the carry flag is set. The instruction
SUBB A, R2
will leave the value 74H (01110100B) in the accumulator, with the carry flag and AC
cleared but OV set. Notice that 0C9H minus 54H is 75H. The difference between this and
the above result is due to the (borrow) flag being set before the operation. If the state of
the carry is not known before starting a single or multiple-precision subtraction, it should
be explicitly cleared by a CLR C instruction.
SUBB A, Rn
Operation: SUBB
(A) ¬ (A) – (C) – (Rn)
Bytes: 1
Cycles: 1
SUBB A, direct
Operation: SUBB
(A) ¬ (A) – (C) – (direct)
Bytes: 2
Cycles: 1
SUBB A, @ Ri
Operation: SUBB
(A) ¬ (A) – (C) – ((Ri))
Bytes: 1
Cycles: 1
SUBB A, #data
Operation: SUBB
(A) ¬ (A) – (C) – #data
Bytes: 2
Cycles: 1
Encoding: 1 0 0 1 0 1 0 1 direct address
Encoding: 1 0 0 1 0 1 1 i
Encoding: 1 0 0 1 0 1 0 0 immediate data
SWAP A
Function: Swap nibbles within the accumulator
Description: SWAP A interchanges the low and high-order nibbles (four-bit fields) of the
accumulator (bits 3-0 and bits 7-4). The operation can also be thought of as a four bit
rotate instruction. No flags are affected.
Example: The accumulator holds the value 0C5H (11000101B). The instruction
SWAP A
leaves the accumulator holding the value 5CH (01011100B).
Operation: SWAP
(A3-0) (A7-4), (A7-4) ¬ (A3-0)
Bytes: 1
Cycles: 1
Encoding: 1 1 0 0 0 1 0 0
XCH A, <byte>
Function: Exchange accumulator with byte variable
Description: XCH loads the accumulator with the contents of the indicated variable, at
the same time writing the original accumulator contents to the indicated variable. The
source/destination operand can use register, direct, or register-indirect addressing.
Example: R0 contains the address 20H. The accumulator holds the value 3FH
(00111111B).
Internal RAM location 20H holds the value 75H (01110101B). The instruction
XCH A, @R0
will leave RAM location 20H holding the value 3FH (00111111 B) and 75H
(01110101B) in the accumulator.
XCH A, Rn
Operation: XCH
(A) (Rn)
Bytes: 1
Cycles: 1
XCH A, direct
Operation: XCH
(A) (direct)
Bytes: 2
Cycles: 1
Encoding: 1 1 0 0 1 r r r
Encoding: 1 1 0 0 0 1 0 1 direct address
XCH A, @ Ri
Operation: XCH
(A) ((Ri))
Bytes: 1
Cycles: 1
Encoding: 1 1 0 0 0 1 1 i
XCHD A,@Ri
Function: Exchange digit
Description: XCHD exchanges the low-order nibble of the accumulator (bits 3-0,
generally representing a hexadecimal or BCD digit); with that of the internal RAM
location indirectly addressed by the specified register. The high-order nibbles (bits 7-4)
of each register are not affected. No flags are affected.
Example: R0 contains the address 20H. The accumulator holds the value 36H
(00110110B). Internal RAM location 20H holds the value 75H (01110101B). The
instruction
XCHD A, @ R0
will leave RAM location 20H holding the value 76H (01110110B) and 35H (00110101B)
in the accumulator.
Operation: XCHD
(A3-0) ((Ri) 3-0)
Bytes: 1
Cycles: 1
Encoding: 1 1 0 1 0 1 1 i
XRL A, Rn
Operation: XRL2
(A) ¬ (A) ^ (Rn)
Bytes: 1
Cycles: 1
Encoding: 0 1 1 0 1 r r r
XRL A, direct
Operation: XRL
(A) ¬ (A) ^ (direct)
Bytes: 2
Cycles: 1
XRL A, @ Ri
Operation: XRL
(A) ¬ (A) ^ ((Ri))
Bytes: 1
Cycles: 1
XRL A, #data
Operation: XRL
(A) ¬ (A) #data
Bytes: 2
Cycles: 1
XRL direct, A
Operation: XRL
(direct) ¬ (direct) ^ (A)
Bytes: 2
Cycles: 1
Encoding: 0 1 1 0 0 1 0 1 direct address
Encoding: 0 1 1 0 0 1 1 i
Encoding: 0 1 1 0 0 1 0 0 immediate data
Encoding: 0 1 1 0 0 0 1 0 direct address
XRL direct, #data
Operation: XRL
(direct) ¬ (direct) ^ #data
Bytes: 3
Cycles: 2
Encoding: 0 1 1 0 0 0 1 1 direct address immediate data
Logic Operations
Mnemonic Description Byte Cycle
ANL A, Rn AND register to accumulator 1 1
ANL A, direct AND direct byte to accumulator 2 1
ANL A,@Ri AND indirect RAM to accumulator 1 1
ANL A, #data AND immediate data to accumulator 2 1
ANL direct, A AND accumulator to direct byte 2 1
ANL direct, #data AND immediate data to direct byte 3 2
ORL A, Rn OR register to accumulator 1 1
ORL A, direct OR direct byte to accumulator 2 1
ORL A,@Ri OR indirect RAM to accumulator 1 1
ORL A, #data OR immediate data to accumulator 2 1
ORL direct, A OR accumulator to direct byte 2 1
ORL direct, #data OR immediate data to direct byte 3 2
XRL A, Rn Exclusive OR register to accumulator 1 1
XRL A direct Exclusive OR direct byte to accumulator 2 1
XRL A,@Ri Exclusive OR indirect RAM to accumulator 1 1
XRL A, #data Exclusive OR immediate data to accumulator 2 1
XRL direct, A Exclusive OR accumulator to direct byte 2 1
XRL direct, #data Exclusive OR immediate data to direct byte 3 2
CLR A Clear accumulator 1 1
CPL A Complement accumulator 1 1
RL A Rotate accumulator left 1 1
RLC A Rotate accumulator left through carry 1 1
RR A Rotate accumulator right 1 1
RRC A Rotate accumulator right through carry 1 1
SWAP A Swap nibbles within the accumulator 1 1
Data Transfer
*) MOV A, ACC is not a valid instruction
Mnemonic Description Byte Cycle
MOV A, Rn Move register to accumulator 1 1
MOV A, direct *) Move direct byte to accumulator 2 1
MOV A,@Ri Move indirect RAM to accumulator 1 1
MOV A, #data Move immediate data to accumulator 2 1
MOV Rn, A Move accumulator to register 1 1
MOV Rn, direct Move direct byte to register 2 2
MOV Rn, #data Move immediate data to register 2 1
MOV direct, A Move accumulator to direct byte 2 1
MOV direct, Rn Move register to direct byte 2 2
MOV direct, direct Move direct byte to direct byte 3 2
MOV direct,@Ri Move indirect RAM to direct byte 2 2
MOV direct, #data Move immediate data to direct byte 3 2
MOV @Ri, A Move accumulator to indirect RAM 1 1
MOV @Ri, direct Move direct byte to indirect RAM 2 2
MOV @Ri, #data Move immediate data to indirect RAM 2 1
MOV DPTR, #data16 Load data pointer with a 16-bit constant 3 2
MOVC A,@A + DPTR Move code byte relative to DPTR to accumulator 1 2
MOVC A,@A + PC Move code byte relative to PC to accumulator 1 2
MOVX A,@Ri Move external RAM (8-bit addr.) to A 1 2
MOVX A,@DPTR Move external RAM (16-bit addr.) to A 1 2
MOVX @Ri, A Move A to external RAM (8-bit addr.) 1 2
MOVX @DPTR, A Move A to external RAM (16-bit addr.) 1 2
PUSH direct Push direct byte onto stack 2 2
POP direct Pop direct byte from stack 2 2
XCH A, Rn Exchange register with accumulator 1 1
XCH A, direct Exchange direct byte with accumulator 2 1
XCH A,@Ri Exchange indirect RAM with accumulator 1 1
XCHD A,@Ri Exchange low-order nibble indir. RAM with A 1 1
Frequently, an 8051 program must interact with the outside world using input and output
devices that communicate directly with a human being. One of the most common devices
attached to an 8051 is an LCD display. Some of the most common LCDs connected to
the 8051 are 16x2 and 20x2 displays. This means 16 characters per line by 2 lines and 20
characters per line by 2 lines, respectively.
44780 BACKGROUND
The 44780 standard requires 3 control lines as well as either 4 or 8 I/O lines for
the data bus. The user may select whether the LCD is to operate with a 4-bit data
bus or an 8-bit data bus. If a 4-bit data bus is used, the LCD will require a total of
7 data lines (3 control lines plus the 4 lines for the data bus). If an 8-bit data bus
is used, the LCD will require a total of 11 data lines (3 control lines plus the 8
lines for the data bus).
The three control lines are referred to as EN, RS, and RW.
The EN line is called "Enable." This control line is used to tell the LCD that you
are sending it data. To send data to the LCD, your program should first set this
line high (1) and then set the other two control lines and/or put data on the data
bus. When the other lines are completely ready, bring EN low (0) again. The 1-0
transition tells the 44780 to take the data currently found on the other control
lines and on the data bus and to treat it as a command.
The RS line is the "Register Select" line. When RS is low (0), the data is to be
treated as a command or special instruction (such as clear screen, position
cursor, etc.). When RS is high (1), the data being sent is text data which should
be displayed on the screen. For example, to display the letter "T" on the screen
you would set RS high.
The RW line is the "Read/Write" control line. When RW is low (0), the information
on the data bus is being written to the LCD. When RW is high (1), the program is
effectively querying (or reading) the LCD. Only one instruction ("Get LCD status")
is a read command. All others are write commands--so RW will almost always be
low.
Finally, the data bus consists of 4 or 8 lines (depending on the mode of operation
selected by the user). In the case of an 8-bit data bus, the lines are referred to as
DB0, DB1, DB2, DB3, DB4, DB5, DB6, and DB7.
Let's draw a sample psuedo-schematic of how the LCD will be connected to the
8051.
As you can see, we've established a 1-to-1 relation between a pin on the 8051
and a line on the 44780 LCD. Thus as we write our assembly program to access
the LCD, we are going to equate constants to the 8051 ports so that we can refer
to the lines by their 44780 name as opposed to P0.1, P0.2, etc. Let's go ahead
and write our initial equates:
As we mentioned above, the EN line is used to tell the LCD that you are ready for
it to execute an instruction that you've prepared on the data bus and on the other
control lines. Note that the EN line must be raised/lowered before/after each
instruction sent to the LCD regardless of whether that instruction is read or write,
text or instruction. In short, you must always manipulate EN when communicating
with the LCD. EN is the LCD's way of knowing that you are talking to it. If you
don't raise/lower EN, the LCD doesn't know you're talking to it on the other lines.
Thus, before we interact in any way with the LCD we will always bring the EN line
high with the following instruction:
SETB EN
And once we've finished setting up our instruction with the other control lines and data
bus lines, we'll always bring this line back low:
CLR EN
Programming Tip: The LCD interprets and executes our command at the instant
the EN line is brought low. If you never bring EN low, your instruction will never
be executed. Additionally, when you bring EN low and the LCD executes your
instruction, it requires a certain amount of time to execute the command. The time
it requires to execute an instruction depends on the instruction and the speed of
the crystal which is attached to the 44780's oscillator input.
While it is possible to write code that waits for a specific amount of time to allow
the LCD to execute instructions, this method of "waiting" is not very flexible. If the
crystal frequency is changed, the software will need to be modified. Additionally,
if the LCD itself is changed for another LCD which, although 44780 compatible,
requires more time to perform its operations, the program will not work until it is
properly modified.
A more robust method of programming is to use the "Get LCD Status" command
to determine whether the LCD is still busy executing the last instruction received.
The "Get LCD Status" command will return to us two tidbits of information; the
information that is useful to us right now is found in DB7. In summary, when we
issue the "Get LCD Status" command the LCD will immediately raise DB7 if it's
still busy executing a command or lower DB7 to indicate that the LCD is no
longer occupied. Thus our program can query the LCD until DB7 goes low,
indicating the LCD is no longer busy. At that point we are free to continue and
send the next command.
Since we will use this code every time we send an instruction to the LCD, it is
useful to make it a subroutine. Let's write the code:
WAIT_LCD:
SETB EN ;Start LCD command
CLR RS ;It's a command
SETB RW ;It's a read command
MOV DATA,#0FFh ;Set all pins to FF initially
MOV A,DATA ;Read the return value
JB ACC.7,WAIT_LCD ;If bit 7 high, LCD still busy
CLR EN ;Finish the command
CLR RW ;Turn off RW for future commands
RET
Thus, our standard practice will be to send an instruction to the LCD and then call our
WAIT_LCD routine to wait until the instruction is completely executed by the LCD.
This will assure that our program gives the LCD the time it needs to execute instructions
and also makes our program compatible with any LCD, regardless of how fast or slow it
is.
Programming Tip: The above routine does the job of waiting for the LCD, but
were it to be used in a real application a very definite improvement would need to
be made: as written, if the LCD never becomes "not busy" the program will
effectively "hang," waiting for DB7 to go low. If this never happens, the program
will freeze. Of course, this should never happen and won't happen when the
hardware is working properly. But in a real application it would be wise to put
some kind of time limit on the delay--for example, a maximum of 256 attempts to
wait for the busy signal to go low. This would guarantee that even if the LCD
hardware fails, the program would not lock up.
Before you may really use the LCD, you must initialize and configure it. This is
accomplished by sending a number of initialization instructions to the LCD.
The first instruction we send must tell the LCD whether we'll be communicating
with it with an 8-bit or 4-bit data bus. We also select a 5x8 dot character font.
These two options are selected by sending the command 38h to the LCD as a
command. As you will recall from the last section, we mentioned that the RS line
must be low if we are sending a command to the LCD. Thus, to send this 38h
command to the LCD we must execute the following 8051 instructions:
SETB EN
CLR RS
MOV DATA,#38h
CLR EN
LCALL WAIT_LCD
Programming Tip: The LCD command 38h is really the sum of a number of
option bits. The instruction itself is the instruction 20h ("Function set"). However,
to this we add the values 10h to indicate an 8-bit data bus plus 08h to indicate that
the display is a two-line display.
We've now sent the first byte of the initialization sequence. The second byte of the
initialization sequence is the instruction 0Eh. Thus we must repeat the initialization code
from above, but now with the instruction. Thus the next code segment is:
SETB EN
CLR RS
MOV DATA,#0Eh
CLR EN
LCALL WAIT_LCD
Programming Tip: The command 0Eh is really the instruction 08h plus 04h to
turn the LCD on. To that an additional 02h is added in order to turn the cursor on.
The last byte we need to send is used to configure additional operational parameters of
the LCD. We must send the value 06h.
SETB EN
CLR RS
MOV DATA,#06h
CLR EN
LCALL WAIT_LCD
Programming Tip: The command 06h is really the instruction 04h plus 02h to
configure the LCD such that every time we send it a character, the cursor position
automatically moves to the right.
So, in all, our initialization code is as follows:
INIT_LCD:
SETB EN
CLR RS
MOV DATA,#38h
CLR EN
LCALL WAIT_LCD
SETB EN
CLR RS
MOV DATA,#0Eh
CLR EN
LCALL WAIT_LCD
SETB EN
CLR RS
MOV DATA,#06h
CLR EN
LCALL WAIT_LCD
RET
Having executed this code the LCD will be fully initialized and ready for us to send
display data to it.
When the LCD is first initialized, the screen should automatically be cleared by
the 44780 controller. However, it's always a good idea to do things yourself so
that you can be completely sure that the display is the way you want it. Thus, it's
not a bad idea to clear the screen as the very first opreation after the LCD has
been initialiezd.
CLEAR_LCD:
SETB EN
CLR RS
MOV DATA,#01h
CLR EN
LCALL WAIT_LCD
RET
How that we've written a "Clear Screen" routine, we may clear the LCD at any time by
simply executing an LCALL CLEAR_LCD.
Programming Tip: Executing the "Clear Screen" instruction on the LCD also
positions the cursor in the upper left-hand corner as we would expect.
WRITING TEXT TO THE LCD
Now we get to the real meat of what we're trying to do: All this effort is really so
we can display text on the LCD. Really, we're pretty much done.
Once again, writing text to the LCD is something we'll almost certainly want to do
over and over--so let's make it a subroutine.
WRITE_TEXT:
SETB EN
SETB RS
MOV DATA,A
CLR EN
LCALL WAIT_LCD
RET
The WRITE_TEXT routine that we just wrote will send the character in the accumulator
to the LCD which will, in turn, display it. Thus to display text on the LCD all we need to
do is load the accumulator with the byte to display and make a call to this routine. Pretty
easy, huh?
LCALL INIT_LCD
LCALL CLEAR_LCD
MOV A,#'H'
LCALL WRITE_TEXT
MOV A,#'E'
LCALL WRITE_TEXT
MOV A,#'L'
LCALL WRITE_TEXT
MOV A,#'L'
LCALL WRITE_TEXT
MOV A,#'O'
LCALL WRITE_TEXT
MOV A,#' '
LCALL WRITE_TEXT
MOV A,#'W'
LCALL WRITE_TEXT
MOV A,#'O'
LCALL WRITE_TEXT
MOV A,#'R'
LCALL WRITE_TEXT
MOV A,#'L'
LCALL WRITE_TEXT
MOV A,#'D'
LCALL WRITE_TEXT
The above "Hello World" program should, when executed, initialize the LCD, clear the
LCD screen, and display "Hello World" in the upper left-hand corner of the display.
CURSOR POSITIONING
The above "Hello World" program is simplistic in the sense that it prints its text in
the upper left-hand corner of the screen. However, what if we wanted to display
the word "Hello" in the upper left-hand corner but wanted to display the word
"World" on the second line at the tenth character? This sounds simple--and
actually, it is simple. However, it requires a little more understanding of the
design of the LCD.
Thus, the first character in the upper left-hand corner is at address 00h. The
following character position (character #2 on the first line) is address 01h, etc.
This continues until we reach the 16th character of the first line which is at
address 0Fh.
However, the first character of line 2, as shown in the memory map, is at address
40h. This means if we write a character to the last position of the first line and
then write a second character, the second character will not appear on the
second line. That is because the second character will effectively be written to
address 10h--but the second line begins at address 40h.
Thus we need to send a command to the LCD that tells it to position the cursor
on the second line. The "Set Cursor Position" instruction is 80h. To this we must
add the address of the location where we wish to position the cursor. In our
example, we said we wanted to display "World" on the second line on the tenth
character position.
Referring again to the memory map, we see that the tenth character position of
the second line is address 4Ah. Thus, before writing the word "World" to the
LCD, we must send a "Set Cursor Position" instruction--the value of this
command will be 80h (the instruction code to position the cursor) plus the
address 4Ah. 80h + 4Ah = C4h. Thus sending the command C4h to the LCD will
position the cursor on the second line at the tenth character position:
SETB EN
CLR RS
MOV DATA,#0C4h
CLR EN
LCALL WAIT_LCD
The above code will position the cursor on line 2, character 10. To display "Hello" in the
upper left-hand corner with the word "World" on the second line at character position 10
just requires us to insert the above code into our existing "Hello World" program. This
results in the following:
LCALL INIT_LCD
LCALL CLEAR_LCD
MOV A,#'H'
LCALL WRITE_TEXT
MOV A,#'E'
LCALL WRITE_TEXT
MOV A,#'L'
LCALL WRITE_TEXT
MOV A,#'L'
LCALL WRITE_TEXT
MOV A,#'O'
LCALL WRITE_TEXT
SETB EN
CLR RS
MOV DATA,#0C4h
CLR EN
LCALL WAIT_LCD
MOV A,#'W'
LCALL WRITE_TEXT
MOV A,#'O'
LCALL WRITE_TEXT
MOV A,#'R'
LCALL WRITE_TEXT
MOV A,#'L'
LCALL WRITE_TEXT
MOV A,#'D'
LCALL WRITE_TEXT
1. Vss GROUND
6 E ENABLE
7 DB0
8 DB1
9. DB2
10. DB3
11. DB4
12. DB5
13. DB6
14. DB7
2. RETURN HOME
Start
D
Is No
Any
Key?
Is Key = Yes
Measure A
key?
Start
D
Is No
Any
Key?
Is Key = Yes
Measure A
key?
Is Key = Yes
find speed B
key?
No
A
Is Wait No
Timer
Over?
Yes
Enable Receiver
No
Is a Valid
return pulse
Yes
D
B
No
Is Wait
Timer
Over?
Yes
Enable Receiver
No
Is a Valid
return pulse
Yes
D
Updated 8/17/98
Working With Stepper Motors Online Tutorial #1
This page is divided into several sections. Choose a section to jump to from the list, or scroll
down to view the entire document.
INTRODUCTION
I am by no means an expert on stepper motors. I have not completed my education, so I do not
know all of the mathematics or mechanics that go into the design and operation of stepper
motors. What I do know is what I have learned from my experience with these electro-mechanical
wonders. This document willout line sources that carry stepper motors and how to control them
manually (with discrete logic), with a microcontroller, and with computer control.
Surplus stores
These places buy surplus from others and sell it to the public, often at great
prices. The average price for a small to medium stepper motor is usually around
$5.00.
Stepper motors, however, behave differently than standard DC motors. First of all, they cannot
run freely by themselves. Stepper motors do as their name suggests -- they "step" a little bit at a
time.Stepper motors also differ from DC motors in their torque-speed relationship. DC motors
generally are not very good at producing high torque at low speeds, without the aid of a gearing
mechanism. Stepper motors, on the other hand, work in the opposite manner. They produce the
highest torque at lowspeeds. Stepper motors also have another characteristic, holding torque,
which is not present in DC motors. Holding torque allows a stepper motor to hold its position
firmly when not turning. This can be useful for applications where the motor may be starting and
stopping, while the force acting against the motor remains present. This eliminates the need for a
mechanical brake mechanism. Steppers don't simply respond to a clock signal, they have several
windings which need to be energized in the correct sequence before the motor's shaft will rotate.
Reversing the order of the sequence will cause the motor to rotate the other way. If the control
signals are not sent in the correct order, the motor will not turn properly. It may simply buzz and
not move, or it may actually turn, but in a rough or jerky manner. A circuit which is responsible for
converting step and direction signals into winding energization patterns is called a translator.
Most stepper motor control systems include adriver in addition to the translator, to handle the
current drawn by the motor's windings.
A basic example of the "translator +
driver" type of configuration. Notice
the separate voltages for logic and for
the stepper motor. Usually the motor
will require a different voltage than
the logic portion of the system.
Typically logic voltage is +5 Vdc and
the stepper motor voltage can range
from +5 Vdc up to about +48 Vdc.
The driver is also an "open collector"
driver, wherein it takes its outputs to
Figure 1.1 - A typical translator / driver connection GND to activate the motor's windings.
Most semiconductor circuits are more
capable of sinking(providing a GND
or negative voltage) than sourcing
(outputting a positive voltage).
Voltage
Stepper motors usually have a voltage rating. This is either printed directly on the
unit, or is specified in the motor's datasheet. Exceeding the rated voltage is
sometimes necessary to obtain the desired torque from a given motor, but doing
so may produce excessive heat and/or shorten the life of the motor.
Resistance
Resistance-per-winding is another characteristic of a stepper motor. This
resistance will determine current draw of the motor, as well as affect the motor's
torque curve and maximum operating speed.
Figure 2.1 - A typical unipolar stepper motor driver circuit. Note the 4 back EMF protection
diodes.
Figure 5.1 - Bipolar stepper motor coil setup (left) and drive pattern (right).
Another characteristic of H-bridge circuits is that they have electrical "brakes" that
can be applied to slow or even stop the motor from spinning freely when not
moving under control by the driver circuit. This is accomplished by essentially
shorting the coil(s) of the motor together, causing any voltage produced in the
coils by during rotation to "fold back" on itself and make the shaft difficult to turn.
The faster the shaft is made to turn, the more the electrical "brakes" tighten.
Figure 6.1 - A typical H-Bridge circuit. The 4 diodes clamp inductive kickback.
Figure 8.1 illustrates the simplest solution to generating a one-phase drive sequence. For
unipolar stepper motors, the circuit in Figure 2.1, or for bipolar stepper motors, the circuit in
Figure 6.1 can be connected to the 4 outputs of this circuit to provide a complete translator +
driver solution. This circuit is limited in that it cannot reverse the direction of the motor. This circuit
would be most useful in applications where the motor does not need to change directions.
Figure 9.1 is an translator for two-phase operation. I have seen this circuit many places, but I
believe it originated from The Robot Builders' Bonanza book, by Gordon McComb. I have used
this circuit in the past and seem to recall that it had a problem. This may not be the case but I
think when you reverse direction and continue stepping, the motor will advance 1 more step in the
previous direction it was going before responding. As always, prototype this circuit to be sure it
will work for your application before you build anything with it.
Figure 9.1 - A simple, bidirectional, two-phase drive stepper motor translator circuit.
There are several standard stepper motor translation circuits which use discrete logic ICs. Below
you will find yet another one of these. The circuit in Figure 10.1 has not been tested but
theoretically should work without problems.
Figure 10.1 - Another example of a two-phase drive translator circuit, this time using a multiplexer.
Words of caution:
When making connections to either a PC parallel port, or I/O pins of a microcontroller, be sure to
isolate the motor well. High voltage spikes of several hundered volts are possible as back EMF
from stepper motor coils. Always use clamping diodes to short these spikes back to the motor's
power bus. The use of optical isolation devices (optoisolators) will add yet another layer or
protection between the delicate control logic and the high-voltage potentials which may be
present in the power output stage. Whenever possible, use separate power supplies for the motor
and the translator / microcontroller. This further reduces the chance of destructive voltages
reaching the controller, and reduces or eliminates power supply noise that may be introduced by
the motor.
If you're using a computer that has a parallel port as part of its onboard I/O, you may want to
consider purchasing a parallel port card to use instead. I've seen them for as little as $9.99 at
Fry's Electronics and other computer stores. Not only does this reduce the risk of permanently
damaging or destroying your motherboard (it happened to a friend of mine!), but it will also allow
you to experiment without the need for swapping cables or flipping a switchbox when you want to
use your parallel printer, since your experiments won't be sharing its port. It is much cheaper to
throw out a $10.00 parallel port card than it is to replace your motherboard!
Unless otherwise indicated, all material on this site is the original work of Jason Johnson.
Copyright © 1998 Jason Johnson
Return to eio's Home Page or view Articles/Reviews, Order Information, Events, Hot
Deals, Forums, Discussion Groups, Weekly Specials, Monthly Specials, Specials,
Inventory, Resources, 99 Cent Page or E-Mail us
CIRCUIT WORKING OF STEPPER MOTOR CONTROL.
In this project when we interface the data from the computer then firstly we interface the
circuit with the optocoupler. In optocoupler circuit we use ic 817 optocoupler. Here we
use four optocoupler with this circuit. Output of the optpcoupler is negative. So to
convert this negative output to the positive we use one inverter ic. In this project we use
ic 4049 as a inverter. Pin no 3,5,7,9,11 is the input pin and pin no 2,4,6,10, 12 is the
output pin. . from the output pin we interface the transistor circuit. Here we use NPN
transistor. Emitter of the NPN transistor is connected to the negative voltage. Collector of
the NPN transistor is connected to the coil of the stepper motor . Here we use total four
transistor’s . collector of the transistor is connected to the each coil of the stepper motor.
$include (reg51xa.INC)
LCD_DATA equ P0
org 0000h
ljmp main
org 0003h
reti
org 000bh
reti
org 0013h
reti
org 001bh
reti
org 0023h
reti
main:
mov psw,#00h
mov sp,#070h
mov tmod,#01h
mov tcon,#00h
mov scon,#00h
mov ie,#08h
mov ip,#08h
mov p0,#00h
mov p1,#0ffh
mov p2,#0ffh
mov p3,#0ffh
mov delayr0,#00h
mov delayr1,#00h
mov PULSL,#00h
mov PULSH,#00h
clr lcd_rs
clr lcd_rw
clr lcd_en
clr flag0
lcall DELAY41
lcall DELAY41
lcall INIT_LCD
lcall CLR_LCD
mov dptr,#MSG0
lcall LINE_1
mov dptr,#MSG1
lcall LINE_2
lcall DELAY41
lcall DELAY41
BEG1:
lcall DELAY41
jb key1,BEG1
lcall DELAY41
jb key1,BEG1
BEG:
MOV TH0,#0
MOV TL0,#0
mov r1,#12
djnz r1,$
clr p3.0
mov r1,#5
djnz r1,
setb tr0
clr p3.2
mov r2,#20
djnz r2,$
setb p3.2
lp2:
jb p3.1,lp1
clr tr0
mov dptr,#MSG2
lcall LINE_2
lcall DELAY41
lcall DELAY41
mov r0,TL0
mov r1,TH0
mov r2,#58
mov r3,#0
call UDIV16
clr c
mov a,r0
add a,#18d
mov r0,a
mov a,r1
addc a,#0d
mov r1,a
mov PULSH,r1
mov PULSL,r0
call disp1
lcall DELAY41
lcall DELAY41
clr output
mov p1,#0ffh
jmp beg1
lp1:
mov a,th0
cjne a,#17h,lp2
mov dptr,#MSG3
lcall LINE_2
setb output
nxt_up: jb flag0,nxt_dn
mov a,des_contr
inc a
cjne a,#200d,nxt_step
setb flag0
sjmp nxt_step
mov a,des_contr
dec a
cjne a,#0d,nxt_step
clr flag0
sjmp nxt_step
nxt_step:
mov des_contr,a
anl a,#03h
cjne a,#3d,nxt_step1
mov p1,#3d
nxt_step1:
cjne a,#2d,nxt_step2
mov p1,#6d
nxt_step2:
cjne a,#1d,nxt_step3
mov p1,#12d
nxt_step3:
cjne a,#0d,nxt_step4
mov p1,#9d
nxt_step4:
lcall DELAY41
lcall DELAY41
jmp beg
mov r6,#0
mov B,#16
div_loop:
mov a,r7
rlc a
mov r4,a
mov a,r5
rlc a
mov r5,a
djnz B,div_loop
mov a,r5
mov r1,a
mov a,r4
mov r0,a
mov a,r7
mov r3,a
mov a,r6
mov r2,a
ret
Hex2BCD:
MOV R3,#00D
MOV R4,#00D
MOV R5,#00D
MOV R6,#00D
MOV R7,#00D
MOV B,#10D
MOV A,R2
DIV AB
MOV R3,B
MOV B,#10
DIV AB
MOV R4,B
MOV R5,A
CJNE R1,#0H,HIGH_BYTE
SJMP ENDD
HIGH_BYTE:
MOV A,#6
ADD A,R3
MOV B,#10
DIV AB
MOV R3,B
ADD A,#5
ADD A,R4
MOV B,#10
DIV AB
MOV R4,B
ADD A,#2
ADD A,R5
MOV B,#10
DIV AB
MOV R5,B
CJNE R6,#00D,ADD_IT
SJMP CONTINUE
CONTINUE:
MOV R6,A
DJNZ R1,HIGH_BYTE
MOV B, #10D
MOV A,R6
DIV AB
MOV R6,B
MOV R7,A
ENDD: ret
DISP1:
mov r1,PULSH
mov r2,PULSL
LCALL HEX2BCD
MOV dp1,r3
MOV dp2,r4
MOV dp3,r5
mov LCD_DATA,#0cch
lcall COMMAND_BYTE
ADD a,#30h
mov LCD_DATA,a
lcall DATA_BYTE
mov LCD_DATA,#0cdh
lcall COMMAND_BYTE
mov a,dp2
ADD a,#30h
mov LCD_DATA,a
lcall DATA_BYTE
mov LCD_DATA,#0ceh
lcall COMMAND_BYTE
mov LCD_DATA,a
lcall DATA_BYTE
mov a,des_contr
mov b,#18d
mul ab
mov r1,b
mov r2,a
LCALL HEX2BCD
MOV dp4,r3
MOV dp5,r4
MOV dp6,r5
MOV dp7,r6
mov LCD_DATA,#0c3h
lcall COMMAND_BYTE
mov a,dp7
ADD a,#30h
mov LCD_DATA,a
lcall DATA_BYTE
mov LCD_DATA,#0c4h
lcall COMMAND_BYTE
mov a,dp6
ADD a,#30h
mov LCD_DATA,a
lcall DATA_BYTE
mov LCD_DATA,#0c5h
lcall COMMAND_BYTE
mov a,dp5
ADD a,#30h
mov LCD_DATA,a
lcall DATA_BYTE
mov LCD_DATA,#0c6h
lcall COMMAND_BYTE
mov LCD_DATA,#'.'
lcall DATA_BYTE
mov LCD_DATA,#0c7h
lcall COMMAND_BYTE
mov a,dp4
ADD a,#30h
mov LCD_DATA,a
lcall DATA_BYTE
ret
LINE_1:
mov LCD_DATA,#080h
lcall COMMAND_BYTE
lcall DELAY1
lcall WRITE_MSG
ret
LINE_2:
mov LCD_DATA,#0c0h
lcall COMMAND_BYTE
lcall DELAY1
lcall WRITE_MSG
ret
INIT_LCD:
mov LCD_DATA,#00h
lcall COMMAND_BYTE
lcall DELAY1
mov LCD_DATA,#00h
lcall COMMAND_BYTE
lcall DELAY1
mov LCD_DATA,#038h
lcall COMMAND_BYTE
lcall DELAY1
mov LCD_DATA,#038h
lcall COMMAND_BYTE
lcall DELAY1
mov LCD_DATA,#038h
lcall COMMAND_BYTE
lcall DELAY1
mov LCD_DATA,#038h
lcall COMMAND_BYTE
lcall DELAY1
mov LCD_DATA,#008h
lcall COMMAND_BYTE
lcall DELAY1
mov LCD_DATA,#00ch
lcall COMMAND_BYTE
lcall DELAY1
mov LCD_DATA,#006h
lcall COMMAND_BYTE
lcall DELAY1
ret
CLR_LCD:
mov LCD_DATA,#001h
lcall COMMAND_BYTE
lcall DELAY1
ret
WRITE_MSG:
mov a,#00h
movc a,@a+dptr
cjne a,#'$',WRITE_CONT
ret
WRITE_CONT:
mov LCD_DATA,a
lcall DATA_BYTE
inc dptr
ljmp WRITE_MSG
COMMAND_BYTE:
clr lcd_rs
lcall DELAY
ljmp CMD10
DATA_BYTE:
setb lcd_rs
lcall DELAY
CMD10:
clr lcd_rw
lcall DELAY
setb lcd_en
lcall DELAY
clr lcd_en
lcall DELAY41
ret
DELAY:
mov delayr0,#10d
DEL:
djnz delayr0,DEL
ret
DELAY1:
mov delayr0,#0d
mov delayr1,#20d
DELAY10:
djnz delayr0,DELAY10
djnz delayr1,DELAY10
ret
DELAY41:
mov delayr0,#0d
mov delayr1,#15d
DLP410:
djnz delayr0,DLP410
djnz delayr1,DLP410
ret
END