Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

Pic 16f84a Manual

Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 62

INTRODUCTION TO MICROCONTROLLERS

The microcontroller is an exciting new device in the field of electronics


control. It is a complete computer control system on a single chip.
Microcontrollers include EPROM program memory, user RAM for storing
program data, timer circuits, an instruction set, special function registers, power
on reset, interrupts, low power consumption and a security bit for software
protection.

The microcontroller is used as a single chip control unit for example in a


washing machine, the inputs to the controller would be from a door catch, water
level switch, temperature sensor. The outputs would then be fed to a water inlet
valve, heater, motor and pump. The controller would monitor the inputs and
decide which outputs to switch on i.e. close the door – water inlet valve open –
monitor water level, close valve when water level reached. Check temperature,
turn on heater, switch off heater when the correct temperature is reached. Turn
the motor slowly clockwise for 5 seconds, anticlockwise for 5 seconds, repeat 20
times, etc. If you are not that maternal maybe you prefer discos to washing –
then you can build your own disco lights.

The microcontroller because of its versatility, ease of use and cost will
change the way electronic circuits are designed and will now enable projects to
be designed which previously were too complex. Additional components such as
versatile interface adapters (VIA), RAM, ROM, EPROM and address decoders
are no longer required.

One of the most difficult hurdles to overcome when using any new
technology is the first one – getting started! It was the aim of this guide is to
explain as simply as possible how to program and use the PIC microcontrollers.

PIC MICROCONTROLLERS

A microcontroller is a computer control system on a single chip. It has


many electronic circuits built into it, which can decode written instructions and
convert them to electrical signals. The microcontroller will then step through
these instructions and execute them one by one. As an example of this a
microcontroller could be instructed to measure the temperature of a room and
turn on a heater if it goes cold.

Microcontrollers are now changing electronic designs. Instead of hard


wiring a number of logic gates together to perform some function we now use
instructions to wire the gates electronically. The list of these instructions given to
the microcontroller is called a program.
A microcontroller is a single chip computer. Micro suggests that the device
is small, and controller suggests that the device can be used in control
applications. Another term used for microcontrollers is embedded controller,
since most of the microcontrollers are built into (or embedded in) the devices
they control.

A microprocessor differs from a microcontroller in many ways. The main


difference is that a microprocessor requires several other components for its
operation, such as program memory and data memory, I/O devices, and external
clock circuit. A microcontroller on the other hand has all the support chips
incorporated inside the same chip. All microcontrollers operate on a set of
instructions (or the user program) stored in their memory. A microcontroller
fetches the instructions from its program memory one by one, decodes these
instructions, and then carries out the required operations.

Microcontrollers have traditionally been programmed using the assembly


language of the target device. Although the assembly language is fast, it has
several disadvantages. An assembly program consists of mnemonics and it is
difficult to learn and maintain a program written using the assembly language.
Also, microcontrollers manufactured by different firms have different assembly
languages and the user is required to learn a new language every time a new
microcontroller is used. Microcontrollers can also be programmed using a high-
level language, such as BASIC, PASCAL, and C. High-level languages have the
advantage that it is much easier to learn a high-level language than the
assembler. Also, very large and complex programs can easily be developed
using a high-level language.

When you buy a PIC microcontroller, you get a useless lump of silicon
with amazing potential. It will do nothing without – but almost anything with – the
program that you write. Under your guidance, almost any number or combination
of normal logic chips can be squeezed into one PIC program and thus in turn,
into one PIC microcontroller. Figure shows the steps in developing a PIC
program.
Figure 1. The blank PIC microcontroller does nothing; 2. Write a program on a
computer; 3. Pretend to program the PIC microcontroller on a computer; 4. Test
the program on a computer; 5. Program a real PIC microcontroller; 6. Test the
PIC microcontroller in a real circuit.

In general, a single chip is all that is required to have a running


microcontroller system. In practical applications additional components may be
required to allow a microcomputer to interface to its environment. With the advent
of the PIC family of microcontrollers the development time of an electronic project
has reduced to several hours. Developing a PIC microcontroller-based project
simply takes no more than five or six steps.

1. Type the program into a PC


2. Assemble (or compile) the program
3. Optionally simulate the program on a PC
4. Load the program into PIC’s program memory
5. Design and construct the hardware
6. Test the project.
Basically, a microcontroller executes a user program which is loaded in its
program memory. Under the control of this program data is received from
external devices (inputs), manipulated and then sent to external devices
(outputs).

A microcontroller is a very powerful tool that allows a designer to create


sophisticated I/O data manipulation under program control. Microcontrollers are
classified by the number of bits they process. 8-bit microcontrollers are the most
popular ones and are used in most microcontroller based applications; 16- and
32-bit microcontrollers are much more powerful, but usually more expensive and
not required in many small- to medium-size general-purpose applications where
microcontrollers are generally used.

The simplest microcontroller architecture consists of a microprocessor,


memory, and I/O. The microprocessor consists of a central processing unit
(CPU) and the control unit (CU). The CPU is the brain of the microcontroller and
this is where all of the arithmetic and logic operations are performed. The CU
controls the internal operations of the microprocessor and sends out control
signals to other parts of the microcontroller to carry out the required instructions.

Memory is an important part of a microcontroller system. Depending upon


the type used we can classify memories into two groups: program memory and
data memory. Program memory stores the program written by the programmer
and this memory is usually non-volatile, i.e. data is not lost after the removal of
power. Data memory is where the temporary data used in a program are stored
and this memory is usually volatile, i.e. data is lost after the removal of power.

There are basically five types of memories as summarised below.

RAM
RAM means Random Access Memory. It is a general-purpose memory
which usually stores the user data used in a program. RAM is volatile, i.e. data is
lost after the removal of power. Most microcontrollers have some amount of
internal RAM. 256 bytes is a common amount, although some microcontrollers
have more, some less. In general it is possible to extend the memory by adding
external memory chips.

ROM
ROM is Read Only Memory. This type of memory usually holds program
or fixed user data. ROM memories are programmed at factory during the
manufacturing process and their contents cannot be changed by the user. ROM
memories are only useful if you have developed a program and wishto order
several thousand copies of it.
EEPROM
EEPROM is Electrically Erasable Programmable Read Only Memory,
which is a non-volatile memory. These memories can be erased and also be
programmed under program control. EEPROMs are used to save configuration
information, maximum and minimum values, identification data, etc.
Some microcontrollers have built-in EEPROM memories (e.g. PIC16F84
contains a 64-byte EEPROM memory where each byte can be programmed and
erased directly by software). EEPROM memories are usually very slow.

EPROM
EPROM is erasable Programmable Read Only Memory. This is similar to
ROM, but the EPROM can be programmed using a suitable programming device.
EPROM memories have a small clear glass window on top of the chip where the
data can be erased under UV light. Many development versions of
microcontrollers are manufactured with EPROM memories where the user
program can be stored. These memories are erased and re-programmed until
the user is satisfied with the program. Some versions of EPROMs, known as
OTP (One Time Programmable), can be programmed using a suitable
programmer device but these memories cannot be erased. OTP memories cost
much less than the EPROMs. OTP is useful after a project has been developed
completely and it is required to make many copies of the program memory.

Flash EEPROM
This is another version of EEPROM-type memory. This memory has
become popular in microcontroller applications and is used to store the user
program. Flash EEPROM is non-volatile and is usually very fast. The data is
erased and then re-programmed using a programming device. The entire
contents of the memory should be erased and then re-programmed.

MICROCONTROLLER FEATURES

Microcontrollers from different manufacturers have different architectures


and different capabilities. Some may suit a particular application while others
may be totally unsuitable for the same application. The hardware features of
microcontrollers in general are described in this section.

Supply voltage

Most microcontrollers operate with the standard logic voltage of _5V.


Some microcontrollers can operate at as low as _2.7 V and some will tolerate _6
V without any problems. You should check the manufacturers’ data sheets about
the allowed limits of the power supply voltage.
A voltage regulator circuit is usually used to obtain the required power
supply voltage when the device is to be operated from a mains adaptor or
batteries. For example, a 5 V regulator is required if the microcontroller is to be
operated from a 5 V supply using a 9 V battery.

The clock

All microcontrollers require a clock (or an oscillator) to operate. The clock


is usually provided by connecting external timing devices to the microcontroller.
Most microcontrollers will generate clock signals when a crystal and two small
capacitors are connected. Some will operate with resonators or external resistor–
capacitor pair. Some microcontrollers have built-in timing circuits and they do not
require any external timing components. If your application is not time-sensitive
you should use external or internal (if available) resistor–capacitor timing
components for simplicity and low cost.

An instruction is executed by fetching it from the memory and then


decoding it. This usually takes several clock cycles and is known as the
instruction cycle. In PIC microcontrollers an instruction cycle takes four-clock
periods. Thus, the microcontroller is actually operated at a clock rate which
is a quarter of the actual oscillator frequency.

Timers

Timers are important parts of any microcontroller. A timer is basically a


counter which is driven either from an external clock pulse or from the internal
oscillator of the microcontroller. A timer can be 8-bits or 16-bits wide. Data can
be loaded into a timer under program control and the timer can be stopped or
started by program control. Most timers can be configured to generate an
interrupt when they reach a certain count (usually when they overflow). The
interrupt can be used by the user program to carry out accurate-timing-related
operations inside the microcontroller.
Reset input

A reset input is used to reset a microcontroller. Resetting puts the


microcontroller into a known state such that the program execution starts from
address 0 of the program memory. An external reset action is usually achieved
by connecting a push-button switch to the reset input such that the
microcontroller can be reset when the switch is pressed.

Interrupts

Interrupts are very important concepts in microcontrollers. An interrupt


causes the microcontroller to respond to external and internal (e.g. a timer)
events very quickly. When an interrupt occurs the microcontroller leaves its
normal flow of program execution and jumps to a special part of the program,
known as the Interrupt Service Routine (ISR). The program code inside the ISR
is executed and upon return from the ISR the program resumes its normal flow of
execution.
The ISR starts from a fixed address of the program memory. This address
is also known as the interrupt vector address. For example, in a PIC16F84
microcontroller the ISR starting address is 4 in the program memory. Some
microcontrollers with multi-interrupt features have just one interrupt vector
address, while some others have unique interrupt vector addresses, one for each
interrupt source. Interrupts can be nested such that a new interrupt can suspend
the execution of another interrupt. Another important feature of a microcontroller
with multi-interrupt capability is that different interrupt sources can be given
different levels of priority.

Power-on reset

Some microcontrollers (e.g. PIC) have built-in power-on reset circuits


which keep the microcontroller in reset state until all the internal circuitry has
been initialised. This feature is very useful as it starts the microcontroller from a
known state on power-up. An external reset can also be provided where the
microcontroller can be reset when an external button is pressed.

Low power operation

Low power operation is especially important in portable applications where


the microcontroller based equipment is operated from batteries. Some
microcontrollers (e.g. PIC) can operate with less than 2 mA with 5 V supply, and
around 15_A at 3 V supply. Some other microcontrollers, especially
microprocessor-based systems where there could be several chips may
consume several hundred milliamperes or even more.
Current sink/source capability

This is important if the microcontroller is to be connected to an external


device which may draw large current for its operation. PIC microcontrollers can
source and sink 25 mA of current from each output port pin. This current is
usually sufficient to drive LEDs, small lamps, buzzers, small relays, etc. The
current capability can be increased by connecting external transistor switching
circuits or relays to the output port pins.

MICROCONTROLLER ARCHITECTURES

Usually two types of architectures are used in microcontrollers (see


Figure): Von Neumann architecture and Harvard architecture. Von Neumann
architecture is used by a large percentage of microcontrollers and here all
memory space is on the same bus and instruction and data use the same bus. In
the Harvard architecture (used by the PIC microcontrollers), code and data are
on separate busses and this allows the code and data to be fetched
simultaneously, resulting in an improved performance.

Von Neumann and Harvard architectures

RISC and CISC

RISC (Reduced Instruction Set Computer) and CISC (Complex Instruction


Computer) refer to the instruction set of a microcontroller. In an 8-bit RISC
microcontroller, data is 8-bits wide but the instruction words are more than 8-bits
wide (usually 12, 14, or 16-bits) and the instructions occupy one word in the
program memory. Thus, the instructions are fetched and executed in one cycle,
resulting in an improved performance. PIC microcontrollers are RISC-based
devices and they have no more than 35 instructions.
In a CISC microcontroller both data and instructions are 8-bits wide. CISC
microcontrollers usually have over 200 instructions. Data and code are on the
same bus and cannot be fetched simultaneously.

MICROCONTROLLER OF CHOICE
PIC16F84: This has been one of the most popular PIC microcontrollers for a very
long time. This is an 18-pin device and it offers 1024 _ 14 flash program memory,
36 bytes of data RAM, 64 bytes of non-volatile EEPROM data memory, 13 I/O
pins, a timer, a watchdog, and internal and external interrupt sources. The timer
is 8-bits wide but can be programmed to generate internal interrupts for timing
purposes. PIC16F84 can be operated from a crystal or a resonator for accurate
timing. A resistor-capacitor can also be used as a timing device for applications
where accurate timing is not required.
Inside a PIC16f84a microcontroller

Program memory (Flash)

The program memory is where program resides. In early microprocessors


and microcontrollers the program memory was EPROM which meant that it had
to be erased using UV light before it could be re-programmed. Most PIC
microcontrollers nowadays are based on the flash technology where the memory
chip can be erased or re-programmed using a programmer device. Most PIC
microcontrollers can also be programmed without removing them from their
circuits. This process (called in-circuit serial programming, or ISP) speeds up the
development cycle and lowers the development costs. Although the program
memory is mainly used to store a program, there is no reason why it cannot be
used to store constant data used in programs.

Data memory (RAM)

The data memory is used to store all of your program variables. This is a
RAM which means that all the data is lost when power is removed. The width of
the data memory is 8-bits wide and this is why the PIC microcontrollers are called
8-bit microcontrollers.
The data memory in a PIC microcontroller consists of banks where some
models may have only 2 banks, some models 4 banks, and so on. A required
bank of the data memory can be selected under program control.

Register file map and special function registers

Register File Map (RFM) is a layout of all the registers available in a


microcontroller and this is extremely useful when programming the device,
especially when using an assembler language.
The RFM is divided into two parts: the Special Function Registers (SFR), and the
General Purpose Registers (GPR). For example, on a PIC16F84 microcontroller
there are 68 GPR registers and these are used to store temporary data.

SFR is a collection of registers used by the microcontroller to control the


internal operations of the device. Depending upon the complexity of the devices
the number of registers in the SFR varies. It is important that the programmer
understands the functions of the SFR registers fully since they are used both in
assembly language and in high-level languages.
Some of the important SFR registers that you may need to configure while
programming using a high-level language are:

● OPTION register
● I/O registers
● Timer registers
● INTCON register
● STATUS register
OPTION register

This register is used to setup various internal features of the


microcontroller and is named as OPTION_REG. This is a readable and writable
register which contains various control bits to configure the on-chip timer and the
watchdog timer. This register is at address 81 (hexadecimal) of the
microcontroller and its bit definitions are given. The OPTION REG register is also
used to control the external interrupt pin RB0. This pin can be setup to generate
an interrupt, for example, when it changes from logic 0 to logic 1. The
microcontroller then suspends the main program execution and jumps to the
interrupt service routine (ISR) to service the interrupt. Upon return from the
interrupt, normal processing resumes.
I/O registers

These registers are used for the I/O control. Every I/O port in the PIC
microcontroller has two registers:

PORT DATA AND PORT DIRECTION REGISTER

Port data register has the same name as the port it controls. For example,
PIC16F84 microcontroller has two port data registers PORTA and PORTB. A
PIC16F877 microcontroller has 5 port data registers PORTA, PORTB, PORTC,
PORTD, and PORTE. An 8-bit data can be sent to any port, or an 8-bit data can
be read from the ports. It is also possible to read or write to individual port pins.
For example, any bit of a given port can be set or cleared, or data can be read
from one or more port pins at the same time.

Timer registers

Depending on the model used, some PIC microcontrollers have only one
timer, and some may have up to 3 timers. In this section we shall look at the
PIC16F84 microcontroller which has only one timer. The extension to several
timers is similar and we shall see in the projects section how to use more than
one timer.

The timer in the PIC16F84 microcontroller is an 8-bit register (called


TMR0) which can be used as a timer or a counter. When used as a counter, the
register increments each time a clock pulse is applied to pin T0CK1 of the
microcontroller. When used as a timer, the register increments at a rate
determined by the system clock frequency and a prescaler selected by register
OPTION_REG.

Prescaler rates vary from 1:2 to 1:256. For example, when using a 4 MHz clock,
the basic instruction cycle is 1_s (the clock is internally divided by four). If we
select a prescaler rate of 1:16, the counter will be incremented at every 16_s.

INTCON register

This is the interrupt control register. This register is at address 0 and 8B


(hexadecimal) of the microcontroller RAM. For example, to enable interrupts so
that external interrupts from pin INT (RB0) can be accepted on a PIC16F84, the
following bit pattern should be loaded into register INTCON:

1XX1XXXX

Similarly, to enable timer interrupts, bit 5 of INTCON must be set to 1.


STATUS REGISTER

The STATUS register contains the arithmetic status of the ALU, the
RESET status and the bank select bit for data memory. As with any register, the
STATUS register can be the destination for any instruction. If the STATUS
register is the destination for an instruction that affects the Z, DC or C bits, then
the write to these three bits is disabled.

These bits are set or cleared according to device logic. Furthermore, the
TO and PD bits are not writable. Therefore, the result of an instruction with the
STATUS register as destination may be different than intended. For example,
CLRF STATUS will clear the upper-three bits and set the Z bit. This leaves the
STATUS register as 000u u1uu (where u = unchanged).
Oscillator circuits

An Oscillator circuit is used to provide a microcontroller with a clock. A


clock is needed so that the microcontroller can execute a program.

PIC microcontrollers have built-in oscillator circuits and this oscillator can be
operated in one of five modes.
● LP – Low-power crystal
● XT – Crystal/resonator
● HS – High-speed crystal/resonator
● RC resistor – capacitor
● No external components (only on some PIC microcontrollers).
In LP, XT, or HS modes, an external oscillator can be connected to the OSC1
input as shown in Figure. This can be a crystal-based oscillator, or simple logic
gates can be used to design an oscillator circuit.

Crystal operation

As shown in Figure in this mode of operation an external crystal and two


capacitors are connected to the OSC1 and OSC2 inputs of the microcontroller.
For example, with a crystal frequency of 4 MHz, two 22 pF capacitors can be
used.

Resonator operation

Resonators are available from 4 to about 8 MHz. They are not as accurate
as crystal-based oscillators.
Resonators are usually 3-pin devices and the two pins at either sides are
connected to OSC1 and OSC2 inputs of the microcontroller. The middle pin is
connected to the ground. Figure shows how a resonator can be used in a PIC
microcontroller circuit.
RC oscillator

For applications where the timing accuracy is not important we can


connect an external resistor and a capacitor to the OSC1 input of the
microcontroller as in Figure. The oscillator frequency depends upon the values of
the resistor and capacitor the supply voltage, and to the temperature. For most
applications, using a 5 K resistor with a 20 pF capacitor gives about 4 MHz and
this may be acceptable in non-time critical applications.

Reset circuit

Reset is used to put the microcontroller into a known state. Normally when
a PIC microcontroller is reset execution starts from address 0 of the program
memory. This is where the first executable user program resides. The reset
action also initialises various SFR registers inside the microcontroller.

PIC microcontrollers can be reset when one of the following conditions occur:
● Reset during power on (POR – Power On Reset)
● Reset by lowering MCLR input to logic 0
● Reset when the watchdog overflows.
As shown in Figure, a PIC microcontroller is normally reset when power is
applied to the chip and when the MCLR input is tied to the supply voltage through
a 4.7 K resistor.

I/O interface

A PIC microcontroller port can source and sink 25 mA of current. When


sourcing current, the current is flowing out of the port pin, and when sinking
current, the current is flowing into the pin. When the pin is sourcing current, one
pin of the load is connected to the microcontroller port and the other pin to the
ground (see Figure). The load is then energised when the port output is at logic
1. When the pin is sinking current, one pin of the load is connected to the supply
voltage and the other pin to the output of the port. The load is then energised
when the port output is at logic 0.

LED interface

LEDs come in many different sizes, shapes, and colours. The brightness
of an LED depends on the current through the device. Some small LEDs operate
with only a few milliamperes of current, while standard size LEDs consume about
10 mA of current for normal brightness. Some very bright LEDs consume 15–20
mA of current. The voltage drop across an LED is about 2V, but the voltage at
the output of a microcontroller port is about 5 V when the port is at logic 1 level.
As a result of this it is not possible to connect an LED directly to a microcontroller
output port.
Button input

One of the most common type of input is a button (a push-button switch)


input where the user can change the state of an input pin by pressing a button.
Basically, button input can be in two different ways: active low and active high.
As shown in Figure in active low implementation, the microcontroller input pin is
connected to the supply voltage using a resistor (this is also called a pull-up
resistor) and the button is connected between the port pin and ground. Normally
the microcontroller input is pulled to logic 1 by the resistor. When the button is
pressed the input is forced to ground potential which is logic 0. The change of
state in the input pin can be determined by a program.
PIC MICROCONTROLLER PROJECT DEVELOPMENT

Required hardware tools

A PIC microcontroller is an integrated circuit and as such it is useless


unless it is programmed and used properly in an electronic circuit to carry out a
certain task. The following hardware tools are normally required before a
microcontroller-based project can be developed:

● A desktop or a laptop PC
● PIC microcontroller programmer device
● A solderless breadboard or a similar circuit development board
● PIC microcontroller chip(s) and support components
● Power supply

The complete circuit diagram of our PIC16F84-based basic system,


together with the power supply, is shown in Figure. What is required now is to
write our program and load it into the program memory of the microcontroller.

Required software tools

All microcontrollers require a program (or software) for their operation.


This program is developed and tested by the programmer (or the user). The
following software tools are normally required in a PIC microcontroller-based
project development cycle:

● A text editor
● MPASMWIN.EXE compiler
● PIC programmer device software
Numerical Systems

Introduction

It was always difficult for people to accept the fact that some things differ
from them or their way of thinking. That is probably one of the reasons why
numerical systems which differ from a decimal are still hard to understand. Still,
whether we want it or not, reality is different. Decimal numerical system that
people use in everyday life is so far behind the binary system used by millions of
computers around the world.

Each numerical system are based on some basis. With a decimal numerical
system, that basis is 10, with binary 2, and with a hexadecimal system 16. The
value of each decimal is determined by its position in relation to the whole
number represented in the given numerical system. The sum of values of each
decimal gives the value of the whole number. Binary and hexadecimal numerical
systems are especially interesting for the subject of this book. Beside these, we
will also discuss a decimal system, in order to compare it with the other two.
Even though a decimal numerical system is a subject we are well acquainted
with, we will discuss it here because of its relatedness to other numerical
systems.

Decimal numerical system

Decimal numerical system is defined by its basis 10 and decimal space


that is counted from right to left, and consists of numbers 0,1, 2, 3, 4, 5, 6, 7, 8, 9.
That means that the end right digit of the total sum is multiplied by 1, next one by
10, next by 100, etc.

Example:

Operations of addition, subtraction, division, and multiplication in a decimal


numerical system are used in a way that is already known to us, so we won't
discuss it further.
Binary numerical system

Binary numerical system differs in many aspects from the decimal system
we are used to in our everyday lives. Its numerical basis is 2, and each number
can have only two values, '1' or '0'. Binary numerical system is used in computers
and microcontrollers because it is far more suitable for processing than a decimal
system. Usually, binary number consists of binary digits 8, 16 or 32, and it is not
important in view of the contents of our book to discuss why. It will be enough for
now to adopt this information.

Example:

10011011 binary number with 8 digits

In order to understand the logic of binary numbers, we will consider an


example. Let's say that we have a small chest with four drawers, and that we
need to tell someone to bring something from one of the drawers to us. Nothing
is more simple, we will say left side, bottom (drawer), and the desired drawer is
clearly defined. However, if we had to do this without the use of instructions like
left, right, beneath, above, etc., then we would have a problem. There are many
solution to this problem, but we should look for one that is most beneficent and
practical! Lets designate rows with A, and types with B. If A=1, it refers to the
upper row of drawers, and for A=0, bottom row. Similarly with columns, B=1
represents the left column, and B=0, the right (next picture). Now it is already
easier to explain from which drawer we need something. We simply need to state
one of the four combinations: 00, 01, 10 or 11. This characteristic naming of each
drawer individually is nothing but binary numerical representation, or conversion
of common numbers from a decimal into binary form. In other words, references
like "first, second, third and fourth" are exchanged with "00,01, 10 and 11".

What remains is for us to get acquainted with logic that is used with binary
numerical system, or how to get a numerical value from a series of zeros and
ones in a way we can understand, of course. This procedure is called conversion
from a binary to a decimal number.
Example:

As you can see, converting a binary number into a decimal number is


done by calculating the expression on the left side. Depending on the position in
a binary number, digits carry different values which are multiplied by themselves,
and by adding them we get a decimal number we can understand. Let's further
suppose that there are few marbles in each of the drawers: 2 in the first one, 4 in
the second drawer, 7 in the third and 3 in the fourth drawer. Let's also say to the
one who's opening the drawers to use binary representation in answer. Under
these conditions, question would be as follows: "How many marbles are there in
01?", and the answer would be: "There are 100 marbles in 01." It should be
noted that both question and the answer are very clear even though we did not
use the standard terms. It should further be noted that for decimal numbers from
0 to 3 it is enough to have two binary digits, and that for all values above that we
must add new binary digits. So, for numbers from 0 to 7 it is enough to have
three digits, for numbers from 0 to 15, four, etc. Simply said, the biggest number
that can be represented by a binary digit is the one obtained when basis 2 is
graded onto a number of binary digits in a binary number and thus obtained
number is decremented by one.

Example:

This means that it is possible to represent decimal numbers from 0 to 15 with 4


binary digits, including numbers '0' and '15', or 16 different values.
Operations which exist in decimal numerical system also exist in a binary system.
Basic rules that apply to binary addition are:
Addition is done so that digits in the same numerical positions are added,
similar to the decimal numerical system. If both digits being added are zero, their
sum remains zero, and if they are '0' and '1', result is '1'. The sum of two ones
gives two, in binary representation it will be a zero, but with transferring '1' to a
higher position that is added to digits from that position.

Example:

We can check whether result is correct by transferring these number to decimal


numerical system and by performing addition in it. With a transfer we get a value
10 as the first number, value 9 as the second, and value 19 as the sum. Thus we
have proven that operation was done correctly. Trouble comes when sum is
greater than what can be represented by a binary number with a given number of
binary digits. Different solutions can be applied then, one of which is expanding
the number of binary digits in the sum as in the previous example.

Subtraction, like addition is done on the same principle. The result of subtraction
between two zeros, or two ones remains a zero. When subtracting one from
zero, we have to borrow one from binary digit which has a higher value in the
binary number.

Example:

By checking the result as we did with addition, when we translate these


binary numbers we get decimal numbers 10 and 9. Their difference corresponds
to number 1 which is what we get in subtraction.

Hexadecimal numerical system

Hexadecimal numerical system has a number 16 as its basis. Since the


basis of a numerical system is 16, there are 16 different digits that can be found
in a hexadecimal number. Those digits are "0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D,
E, F". Letters A, B, C, D, E and F are nothing but values 10, 11, 12, 13, 14 and
15. They are introduced as a replacement to make writing easier. As with a
binary system, here too, we can determine with same formula what is the biggest
decimal number we can represent with a specific number of hexadecimal digits.
Example: With two hexadecimal digits

Usually, hexadecimal number is written with a prefix "$" or "0x" ,or


suffix"h" , to emphasize the numerical system. Thus, number A37E would be
written more correctly as $A37E, 0xA37E, or A37Eh. In order to translate a
hexadecimal number into a binary numerical system it is not necessary to
perform any calculation but simple exchange of hexadecimal digits with binary
digits. Since the maximum value of a hexadecimal number is 15, that means that
it is enough to use 4 binary digits for one hexadecimal digit.

Example:

By checking, that is transferring both numbers into decimal numerical


system, we get a number 228 which proves the accuracy of our action.

In order to get a decimal equivalent of a hexadecimal number, we need to


multiply each digit of a number with number 16 which is gradated by the position
of that digit in hexadecimal number.

Example:

Addition is, like in two preceding examples, performed in a similar manner.

Example:

We need to add corresponding number digits. If their sum is equal 16,


write 0 and transfer one to the next higher place. If their sum is greater than 16,
write value above and transfer 1 to the next higher digit.Eg. if sum is 19
(19=16+3) write 3 and transfer 1 to the next higher place. By checking, we get
14891 as the first number, and second is 43457. Their sum is 58348, which is a
number $E3EC when it is transferred into a decimal numerical system.
Subtraction is an identical process to those in previous two numerical systems. If
the number we are subtracting is smaller, we borrow from the next place of
higher value.

Example:

By checking this result, we get values 11590 for the first number and 5970
for the second, where their difference is 5620, which corresponds to a number
$15F4 after a transfer into a decimal numerical system.
Digital Logic, Arithmetic, and Conversions

This lesson is about the fundamental arithmetic and logical operations of


digital machines. It serves as a background for developing processing routines
which involve decisions, data filtering and processing, and number crunching.
This discusses the logical and arithmetic operations in general, that is, without
reference to any individual processor.

There are so many different hardware versions of microcontrollers that it is


not feasible to develop an actual routine for each device. On the other hand,
once the logic is understood, the actual coding is a simple process of finding a
way of implementing it in a specific instruction set. It also includes material
related to data type conversions since these operations are closely related to the
other material in this lesson.

Microcontroller Logic and Arithmetic

All microcontrollers contain instructions to perform arithmetic and logic


transformations on binary or decimal operands. These instructions can be
classified into three groups:

1. Logical instructions. Sometimes these are called Boolean operators. The


group includes instructions with mnemonics such as AND, NOT, OR, and XOR.
They perform the logical functions that correspond to their names.

2. Arithmetic instructions. Typically this group of instructions performs integer


addition and subtraction. Occasionally, the instruction set includes multiplication
and division. The operands can be signed or unsigned binary and binary coded
decimal numbers.

3. Auxiliary and bit manipulation instructions. This group includes instructions to


shift and rotate bits, to compare operands, to test, set, and reset individual binary
digits, and to perform various auxiliary operations.

CPU Flags

All microcontrollers are equipped with a special register that reflects the
current processing status. This register, sometimes called the status register or
the flags register, contains individual bits, usually called flags, that are
meaningful during the execution of logic and arithmetic operations.

The most common flags are:

1. The zero flag. This flag is set if a previous operation produces a value of zero.
2. The carry/overflow flag. This flag is set if there has been a carry or a borrow-
out of the high-order bit of the operand.
3. The half-carry or digit-carry flag. This flag is set if there has been a carry or a
borrow-out of the low-order nibble of the operand.

Not all instructions affect all the flags. For example, loading a zero
constant into a register may be said to produce a zero value; however, such an
instruction may or may not affect the zero flag, according to the implementation
on each particular device. More powerful and sophisticated microcontrollers
sometimes implement other flags, such as flags to indicate a negative operand,
an arithmetic overflow, or an interrupt.

Word Size

The word-size of a computer or a digital device refers to the number of bits


used in storing data and in moving data in and out of the various machine units.
In other words, a machine’s word-size is the native data unit for a particular
architecture. In this manner we speak of the Pentium having a 32-bit word size or
the PIC16x84 having an 8-bit word-size for data operations and 14-bit program
words.

In the context of digital arithmetic and logic the data word-size determines
the processing capabilities of each device. For example, a machine with an 8-bit
word-size can perform unsigned addition of operands whose sum does not
exceed the decimal value 255, since 255 is the largest unsigned integer that can
be stored in eight bits. However, a machine with 16-bit words can perform
unsigned additions up to a sum of 65,535 since it is the largest number that can
be stored in 16 bits.

Therefore, the coding of numerical routines is determined by the word size


of the machine or device. A device with 8-bit word-size requires multi-byte
arithmetic to perform addition that exceeds a sum of 255, while a machine with a
16-bit word can do direct addition up to the sum 65,535. Considering that most
popular microcontrollers have 8-bit word-sizes, we assume this limit in the
arithmetic and logic algorithms and routines developed in this lesson.

Logical Instructions

The logical instructions include the Boolean operators, AND, OR, NOT,
and XOR, as well as instructions to shift and rotate individual bits.

The logical instructions operate on a bit-by-bit basis; therefore, in the AND, OR,
NOT, and XOR there is no interaction between bits. The action performed by the
logical instructions is as follows:

1. AND, OR, and XOR logically combine each bit in the source operand with the
corresponding bit in the destination operand. The result does not affect the
neighbouring bits.
2. The NOT operator inverts all bits in the destination operand.

These actions explain the term bitwise operation sometimes used to describe the
instructions.

Logical AND

The AND instruction performs a bitwise logical AND of two operands. This
determines that a bit in the result is set if and only if the corresponding bits are
set in both operands. A frequent use of the AND operation is to clear one or more
bits without affecting the remaining ones. This action is possible because ANDing
with a 0 bit always clears the result bit and ANDing with a 1 bit preserves the
original value of the first operand.

For example, if we have the binary coded decimal number 34 packed into a
single byte, we can isolate the four low-order bits as follows:

The second operand, in this case 0FH, is called a mask. The AND operation
preserves the 1-bits in the mask and clears the bits that are 0. Consequently, the
mask 00000001B clears the seven high-order bits and preserves the original
value of the low-order bit.

Logical OR

The OR operation performs the bitwise logical inclusive OR of two


operands. After a logical OR, a bit in the result is set if one or both of the
corresponding bits in the operands were set. A frequent use for the OR is to
selectively set one or more bits. The action takes place because ORing with a 1-
bit always sets the result bit, while ORing with a 0-bit preserves the original value
in the first operand.
For example, to set the high-order bit (bit number 7) we can OR with a 1 bit, as
follows:

The OR operation sets the bits that are 1 in the mask and preserves the bits that
are masked 0.

Logical XOR

The XOR operator performs the bitwise logical exclusive OR of the two
operands. Therefore, a bit in the result is set if the corresponding bits in the
operands have opposite values. For this reason, XORing a value with itself
always generates a zero result since all bits necessarily have the same value. On
the other hand, XORing with a 1-bit inverts the value of the other operand, since
0 XOR 1 is 1 and 1 XOR 1 is 0.

This toggling action of XORing with a 1 bit generates identical bitwise


results as the NOT operation, Digital Logic, Arithmetic, and Conversions 57 but
by selecting the XOR mask, the programmer can control which bits of the
operand are inverted and which are preserved. In this manner it is possible to
invert the four high-order bits of an operand by XORing with a mask that has
these bits set. If the four low-order bits of the mask are clear, then the original
values of the bits in the other operand are preserved in the result.

For example:

In the previous example, the XOR operation inverts the bits that are 1 in the
mask and preserves the bits that are masked 0. Consequently, the XOR mask
11110000B inverts the four high-order bits.
Logical NOT

In contrast with the other logical operators which require two operands,
the NOT instruction acts on a single value. Its action is consistent with a Boolean
NOT function, which converts all 1-bits to 0 and all 0-bits to 1. Arithmetically, the
result is the one’s complement of the original value. This instruction can be useful
in obtaining the two’s complement representation by performing the logical NOT
and then adding one to the results.

Microcontroller Arithmetic

Microcontrollers are not designed for intensive numeric processing;


therefore, they are not equipped with many arithmetic operators usually found in
microprocessors. A typical mid-range microcontroller has instructions to add and
subtract integers and perhaps to increment and decrement. Hardware
multiplication is rarely available and even more so is division. Likewise, there is
usually no hardware support for decimal and floating-point arithmetic. For this
reason the microcontroller programmer is often challenged to provide most
arithmetic and data processing operations in software.

In this discussion we assume a mid-range microcontroller, such as the


PIC 16f8x. These devices contain primitives for adding and subtracting integers,
shifting and rotating bits, incrementing and decrementing machine registers,
some support for decimal operations and conversions, as well as the basic logic
primitives AND, OR, XOR, and NOT. Multiplication and division operators, as
well as floating-point operators, are not available in the mid-range devices.

Unsigned and Two’s Complement Arithmetic

We have discussed the various representations for signed and unsigned


binary and decimal numbers. Arithmetic operations of unsigned operands are the
simplest. In this case we assume that the encoding always represents a positive
number and that all bits relate to the number’s magnitude.

Unsigned arithmetic can be binary or decimal. In a machine with 8-bit


words binary arithmetic on unsigned numbers use the entire range of the format.
This is true even when the primitive operations are valid in two’s complement
form; in fact, it is one of the great advantages of two’s complement
representation. Table 4.1 shows a 4-bit binary in several numeric formats.
Note, in the previous example, that if the encoding were in two’s complement
form, the addition of the positive values 6 plus 7 would produce a result that
overflows the capacity of the representation. In 4-bit two’s complement
representation there is no way of encoding the value 13.

The question that arises is: in a device that performs two’s complement
addition, must we always assume that the operands are in two’s complement
form? The answer is: no. Signed addition of two’s complement operands and the
unsigned addition of integer operands can be performed with identical processing
and by the same electronic circuitry. It is the software that must take into account
the encoding of the operands in order to interpret the results. For example, in the
4-binary digit device previously considered, the two’s complement addition of the
values 6 and 7 produce an overflow, which can be detected by observing the
change in the high-order bit (the sign bit) of the result. Therefore, in this case, the
result of the addition operation is invalid. However, if the same decimal values
represent unsigned operands, then the addition of 7 plus 6 produce the valid
result 13. In either case the binary values of the operands, as well as the result,
are the same.

Microcontrollers usually support the fundamental operations of addition


and subtraction on signed and unsigned integer operands with a single primitive
operation. The addition and subtraction operators in low- and mid-range devices
allow two operands. The more powerful microcontrollers support addition and
subtraction of three operands, which is useful in implementing multi-digit
routines. In either case, the software determines if the result is signed or
unsigned by interpreting the changes in the high-order bit of the operands and by
evaluating the status flags if these are available.

Operations on Decimal Numbers

Although microcontrollers are binary devices, the instruction set often


includes operations for performing arithmetic on binary coded decimal numbers.
In packed format two BCD digits are contained in each byte. The low-order BCD
digit takes up bits 0 to 3 and the high-order BCD digit takes up bits 4 to 7.
Unpacked BCD digits are stored one digit per byte; in this case the high-order
nibble is unused.

Microcontroller designers usually adopt the packed BCD format for


representing decimal operands. One advantage of packed BCDs is that the two
decimal digits encoded in a single byte can be represented as hexadecimal
digits. For example, the values H24 and H99 represent the packed BCD digits 24
and 99 respectively. Note that each hex digit is preceded by the letter H to
indicate radix 16. In actual microcontroller programming other ways are often
used for representing numbers in hexadecimal notation.

The addition and subtraction of decimal numbers represented in packed


BCD can be performed with binary primitive operations, complemented with
some additional adjustments. In some cases the addition of two BCD numbers in
packed format may produce a valid result, for example:

In the previous examples the results are valid because the sum of each digit
does not exceed the range of the BCD format. However, the following additions
do not produce valid BCD results:

In the case of the first operation the valid BCD result would be: 33 + 27 = 60, in
the second one 31 + 59 = 90, and in the third one 56 + 27 = 83. A simple
adjustment corrects the error, as follows:
In all three cases adding 6 to the previous sum produces the expected
result. The logic for deciding when the value 6 must be added is simple: if the
sum of the low-order digit is greater than 9 or if the sum produced a carry out of
the low-order nibble, then add 6 to the sum to perform the decimal adjustment.
Some high-end microcontrollers contain a primitive instruction that executes the
decimal adjustment automatically, that is, without having to test the sum.
However, this instruction is not available in low- and mid-range devices.

Also note that the largest number that can be encoded in packed BCD
format is the decimal 99. When adding two BCD digits the high-order digit of the
sum cannot be greater than 9. If so, then the capacity of the format has been
exceeded and the result cannot be adjusted by the simple addition of 6. Here
again, a multi-byte processing routine can be developed in order to
accommodate the result of BCD addition when the sum exceeds a single byte.

Many microcontrollers are equipped with a flag that indicates overflow


from binary digit number 3. This flag, sometimes called the digit carry or the half
carry flag, can be used to detect that a calculation has overflowed the storage
capacity of four binary digits. The availability of this flag simplifies the logic
necessary for adjusting binary addition of decimal operands since the value 6
must be added when the digit in the low-order nibble is larger than 9, or when
there has been a carry to the next digit. The following flowchart shows this
processing.

Bit Manipulations and Auxiliary Operations

In addition to basic logic and arithmetic, microcontrollers contain primitive


operators to manipulate individual bits, to compare operands, to make decision
based on the state of individual bits and flags, and to convert data to other
formats. As always, presence or absence of some of these operations, as well as
their degree of power and sophistication, varies with the individual
microcontroller. In the following subsections we describe the most commonly
available primitives.
Bit Shift and Rotate

The fundamental operators to shift and rotate are useful in developing


BCD and binary arithmetic routines. One interesting use of bit shifting is in
implementing binary multiplication and division routines.
Shift operations consist of transposing to the left or right all the bits in the
operand. In microcontrollers the operand is usually a processor register. For
example, after a right shift operation all the bits in the value 01110101B (75H)
are moved one position to the right, resulting in the value 00111010B (3AH).
Note that on a right shift the right-most bit disappears and a zero comes into the
high-order bit. By the same token, in a left shift the high-order bit disappears and
a zero comes into the low-order bit. The figure shows the action of a left-shift
operation.

The rotate operation differs from the shift in that in the rotate the low-order
bit is either a copy of the high-order bit or of the carry flag. In the first case the
operation is a pure rotate, in the second case the rotate is referred to as rotate-
through-carry. Figure shows the action of a left-rotate-through-carry flag.

Figure Rotate-through-carry Left Operation

Note that in the figure contents of the carry flag are first copied to the low-
order bit of the destination operand, then the individual bits of the source (in gray
in the illustration) are shifted left and moved to the destination. Finally the high-
order bit of the source is copied to the carry flag.

There are several possible variations of the rotate operation. The Intel
microprocessors distinguish between arithmetic and logic rotates. In the
arithmetic rotation the high-order bit is preserved in order to maintain the sign of
the operand. The rotate shown in the figure is the one most common in
microcontroller hardware.

Clearing the carry flag before the rotate takes place makes the operation
identical to a shift.

Comparison Operations

An interesting property of subtraction is its use in finding the relative size


of two operands. This interesting action of subtraction is based on the following
logic:

1. If the result of a subtraction is zero, then both operands were of the same size.
2. If the result of a subtraction is a positive number, then the subtrahend was
smaller than the minuend.
3. If the result of a subtraction is a negative number, the subtrahend was larger
than the minuend.

In a binary/digital device the result of a subtraction operation can be


determined by observing the flags. If the zero flag is set, then the operands were
the same (case 1, above). If the carry flag is set, then the subtrahend was larger
than the minuend (case 3, above). If neither the carry nor the zero flag is set,
then resulting subtrahend was smaller than the minuend (case 2, above). Since
all microcontrollers offer some mechanism for re-directing execution according to
the state of the flags, a program can use subtraction to make these decisions.

The one objection to the use of subtraction in comparing the size of two
operands is that the process will change one of them. To use subtraction in
comparison operations the programmer has to find some way of preserving the
minuend. Alternatively, some devices contain a comparison operator that sets
the flags as if a subtraction had taken place but without changing the operands.
High-end microcontrollers are equipped with dedicated comparison operators,
but the middle- and low-range devices usually are not.
Other Support Operations

Mid- and high-range microcontrollers contain other auxiliary bitwise,


arithmetic, and logic operators that can be useful to the programmer. These
include instructions to:

1. Increment and decrement operands


2. Clear registers or storage locations
3. Swap nibbles
4. Clear and set individual bits
5. Test individual bits

Usually instructions to increment and decrement and to test individual bits


are also capable of redirecting execution according to the result. For example, a
special decrement can be followed by a jump if decrementing sets the zero flag.
Or a bit test instruction can include a jump that is taken if the tested bit is set or
reset.
Instruction Set

Introduction

We have already mentioned that microcontroller is not like any other


integrated circuit. When they come out of production most integrated circuits are
ready to be built into a device which is not the case with microcontrollers. In order
to "make" microcontroller perform a task, we have to tell it exactly what to do, or
in other words we must write the program microcontroller will execute. We will
describe in this chapter instructions which make up the assembler, or lower-level
program language for PIC microcontrollers.

Instruction Set in PIC16Fxx Microcontroller Family

Complete set which includes 35 instructions is given in the following table.


A reason for such a small number of instructions lies primarily in the fact that we
are talking about a RISC microcontroller whose instructions are well optimized
considering the speed of work, architectural simplicity and code compactness.
The only drawback is that programmer is expected to master "uncomfortable"
technique of using a reduced set of 35 instructions.

Data transfer

Transfer of data in a microcontroller is done between work (W) register


and an 'f' register that represents any location in internal RAM (regardless
whether those are special or general purpose registers).

First three instructions (look at the following table) provide for a constant being
written in W register (MOVLW is short for MOVe Literal to W), and for data to be
copied from W register onto RAM and data from RAM to be copied onto W
register (or on the same RAM location, at which point only the status of Z flag
changes). Instruction CLRF writes constant 0 in 'f ' register, and CLRW writes
constant 0 in register W. SWAPF instruction exchanges places of the 4-bit
nibbles field inside a register.

Arithmetic and logic

Of all arithmetic operations, PIC like most microcontrollers supports only


subtraction and addition. Flags C, DC and Z are set depending on a result of
addition or subtraction, but with one exception: since subtraction is performed
like addition of a negative value, C flag is inverse following a subtraction. In other
words, it is set if operation is possible, and reset if larger number was subtracted
from a smaller one.
Logic unit of PIC has capability of performing operations AND, OR, EX-
OR, complementing (COMF) and rotation (RLF and RRF).
Instructions which rotate the register contents move bits inside a register through
flag C by one space to the left (toward bit 7), or to the right (toward bit 0). Bit
which "comes out" of a register is written in flag C, and value of C flag is written
in a bit on the "opposite side" of the register.

Bit operations

Instructions BCF and BSF do setting or cleaning of one bit anywhere in


the memory. Even though this seems like a simple operation, it is executed so
that CPU first reads the whole byte, changes one bit in it and then writes in the
entire byte at the same place.

Directing a program flow

Instructions GOTO, CALL and RETURN are executed the same way as
on all other microcontrollers, only stack is independent of internal RAM and
limited to eight levels. 'RETLW k' instruction is identical with RETURN instruction,
except that before coming back from a subprogram a constant defined by
instruction operand is written in W register. This instruction enables us to design
easily the Look-up tables (lists). Mostly we use them by determining data position
on our table adding it to the address at which the table begins, and then we read
data from that location (which is usually found in program memory). Table can be
formed as a subprogram which consists of a series of 'RETLW k' instructions,
where 'k' constants are members of the table.

We write the position of a member of our table in W register, and using CALL
instruction we call a subprogram which creates the table. First subprogram line
ADDWF PCL, f adds the position of a W register member to the starting address
of our table, found in PCL register, and so we get the real data address in
program memory. When returning from a subprogram we will have in W register
the contents of an addressed table member. In a previous example, constant 'k2'
will be in W register following a return from a subprogram.

RETFIE (RETurn From Interrupt - Interrupt Enable) is a return from interrupt


routine and differs from a RETURN only in that it automatically sets GIE (Global
Interrupt Enable) bit. Upon an interrupt, this bit is automatically cleared. As
interrupt begins, only the value of program counter is put at the top of a stack. No
automatic storing of register values and status is provided.

Conditional jumps are synthesized into two instructions: BTFSC and BTFSS.
Depending on a bit status in 'f' register that is being tested, instructions skip or
don't skip over the next program instruction.
*1 If I/O port is source operand, status on microcontroller pins is read
*2 If this instruction is executed on TMR register and if d=1, prescaler assigned to
that timer will automatically be cleared
*3 If PC was modified, or test result =1, instruction was executed in two cycles.
Instruction Execution Period

All instructions are executed in one cycle except for conditional branch
instructions if condition was true, or if the contents of program counter was
changed by some instruction. In that case, execution requires two instruction
cycles, and the second cycle is executed as NOP (No Operation). Four oscillator
clocks make up one instruction cycle. If we are using an oscillator with 4MHz
frequency, the normal time for executing an instruction is 1 µs, and in case of
conditional branching, execution period is 2 µs.

Word list

f any memory location in a microcontroller


W work register
b bit position in 'f' register
d destination bit
label group of eight characters which marks the beginning of a part of the
program
TOS top of stack
[] option
<> bit position inside register
Instruction List

The lists contains all instructions presented separately with examples for their
use. Syntax, description and its effects on status bits are given for each
instruction.

 A.1 MOVLW
 A.2 MOVWF
 A.3 MOVF
 A.4 CLRW
 A.5 CLRF
 A.6 SWAPF
 A.7 ADDLW
 A.8 ADDWF
 A.9 SUBLW
 A.10 SUBWF
 A.11 ANDLW
 A.12 ANDWF
 A.13 IORLW
 A.14 IORWF
 A.15 XORLW
 A.16 XORWF
 A.17 INCF
 A.18 DECF
 A.19 RLF
 A.20 RRF
 A.21 COMF
 A.22 BCF
 A.23 BSF
 A.24 BTFSC
 A.25 BTFSS
 A.26 INCFSZ
 A.27 DECFSZ
 A.28 GOTO
 A.29 CALL
 A.30 RETURN
 A.31 RETLW
 A.32 RETFIE
 A.33 NOP
 A.34 CLRWDT
 A.35 SLEEP
A.1 MOVLW Write constant in W register

A.2 MOVWF Copy W to f


A.3 MOVF Copy f to d

A.4 CLRW Write 0 in W


A.5 Write 0 in f

A.6 SWAPF Copy the nibbles from f to d crosswise


A.7 ADDLW Add W to a constant

A.8 ADDWF Add W to f


A.9 SUBLW Subtract W from a constant

A.10 SUBWF Subtract W from f


A.11 ANDLW Logic AND W with constant

A.12 ANDWF Logic AND W with f


A.13 IORLW Logic OR W with constant

A.14 IORWF Logic OR W with f


A.15 XORLW Logic exclusive OR W with constant

A.16 XORWF Logic exclusive OR W with f


A.17 INCF Increment f
A.18 DECF Decrement f
A.19 RLF Rotate f to the left through CARRY
A.20 RRF Rotate f to the right through CARRY
A.21 COMF Complement f

A.22 BCF Reset bit b in f


A.23 BSF Set bit b in f

A.24 BTFSC Test bit b in f, skip if it = 0


A.25 BTFSS Test bit b in f, skip if =1

A.26 INCFSZ Increment f, skip if=0


A.27 DECFSZ Decrement f, skip if = 0

A.28 GOTO Jump to address


A.29 CALL Call a program

A.30 RETURN Return from a subprogram


A.31 RETLW Return from a subprogram with constant in W

A.32 RETFIE Return from interrupt routine

A.33 NOP No operation


A.34 CLRWDT Initialize watchdog timer

A.35 SLEEP Stand by mode

You might also like