You are on page 1of 90

1.

1 INTRODUCTION
Novices in electronics usually think that the microcontroller is the same as the
microprocessor. That's not true. They differ from each other in many ways. The first
and most important difference in favour of the microcontroller is its functionality. In
order for the microprocessor to be used, other components, first of all memory, must
be added to it. Even though it is considered a powerful computing machine, it is not
capable of establishing direct communication with the peripherals. Instead, specialized
circuits must be used for this purpose. This is how it was in the beginning and remains
the same today.

On the other hand, the microcontroller is designed to be all of that in one. No other
specialized peripheral components are needed for its operation as all necessary
circuits, which otherwise belong to peripherals, have been already built into it. It saves
both time and space required when designing a device.

ALL THE MICROCONTROLLER IS CAPABLE OF


Microcontrollers are very popular nowadays. Just pay attention to the example below
and you will understand the reasons for their great success. It won't take up much of
your time, just a couple of minutes.

Around ten years ago, the process of designing an electronic device controlling an
elevator in a multistory building was extremely difficult, even for a team of experts.
Have you ever thought of what requirements an ordinary elevator has to meet? How to
deal with situation when two or more people call the same elevator at the same time?
Which call has the priority? How to handle the security questions? Loss of electricity?
Operation failure? Misuse? After solving these basic questions, a tough process of
designing an appropriate electronics using a large number of special-purpose chips
comes next. Depending on the device complexity, such process can take weeks, even
months. Then it's time to make a printed circuit board and assemble device. A huge
device! It is another long-lasting and trying work. Finally, when your device is finished
and tested many times, the crucial moment comes. The moment when you take a deep
breath and switch the power supply on. The party is over at this point as electronic
devices almost never start to operate immediately. Get ready for many sleepless
nights, corrections, improvements... and don't forget, we are still talking about running
an ordinary elevator.
When your device finally works perfectly and everybody is satisfied and you get paid
for the work you have done, other constructing companies will become interested in
your work. Of course, if you are lucky, another day will bring you a locking offer from a
new investor. A new building has four stories more. You know what it is all about? You
think you can control destiny? You are going to make a universal device which can be
used in buildings of 4 to 40 stories, a masterpiece of electronics? Even if you manage
to make such an electronic jewel, your investor will wait in front of your door asking for
a camera in the elevator. Or for relaxing music in case of elevator failure. Or for a twodoor elevator. Anyway, Murphy's law is inexorable and you will certainly not be able to
make advantage of all the effort you have made. Unfortunately, everything said so far
is true. This is what 'handling electronics' really means. No, no, wait, let us correct
ourselves, this is how it was until the first microcontrollers were designed - small,
powerful and cheap devices. Since the moment their programming stopped being a
science, everything went in another direction...
Electronics capable of controlling a small submarine, a crane or an elevator are now
built into one single chip. Microcontrollers offer a wide range of applications, but only a
few of them are normally used. It's up to you to decide what you want from the
microcontroller and dump a program accordingly containing appropriate instructions
into it. Prior to turning the device on, its operation should be tested by simulation. If
everything works fine, build the microcontroller into your device. If you ever need to
change, improve or upgrade the program, just do it. Until when? Until you feel
satisfied. That's all.

Did you know that all people can be classified into one out of 10 groups- those who are
familiar with binary number system and those who are not familiar with it. You don't
understand? Then you still belong to the latter group. If you want to change your status
read the following text which briefly describes some of the basic concepts used further
in this book (just to be sure we are on the same page).

1.2 NUMBERS, NUMBERS, NUMBERS...


Mathematics is such a good science! Everything is so logical... The whole universe can
be described with ten digits only. But, does it really have to be like that? Do we need
exactly ten digits? Of course not, it is only a matter of habit. Remember the lessons
from school. For example, what does the number 764 mean: four units, six tens and
seven hundreds. It's as simple as that! Could it be described in a more complicated
way? Of course: 4 + 60 + 700. Even more complicated? Definitely: 4*1 + 6*10 + 7*100.
Could this number look more scientific? The answer is yes again: 4*100 + 6*101 +
7*102. What does it actually mean? Why do we use exactly these numbers: 100,
101 and 102 ? Why is it always about the number 10? The answer is because we use
ten different digits (0, 1, 2, ... 8, 9). In other words, we use the base-10 number system,
i.e. decimal numeric system.

BINARY NUMERIC SYSTEM


What would happen if only two digits were used- 0 and 1? Or if we didn't not know how
to determine whether something is 3 or 5 times greater than something else? Or if we
were restricted when comparing two sizes, i.e. if we could only state that something
exists (1) or doesn't exist (0)? The answer is 'nothing special', we would keep on using
numbers in the same way as we do now, but they would look a bit different. For
example: 11011010. How many pages of a book does the number 11011010 include?
In order to learn that, you just have to follow the same logic as in the previous
example, but in reverse order. As you can see here, it's all based on only two digits- 0
and 1, i.e. on the base-2 numeric system (binary numeric system).

It is clearly the same number represented in two different numeric systems. The only
difference between these two formats is the number of digits they consist of. One digit
(2) is used for writing number 2 in decimal system, whereas two digits (1 and 0) are
used for its writing in binary system. Do you now agree that there are 10 groups of
people? Welcome to the world of binary arithmetic! Do you have any idea where it is
used?
Except in strictly controlled laboratory conditions, even the most complex electronic
circuits cannot accurately determine the difference between two sizes (two voltage
values, for example) if they are too small (lower than several volts). The reason for it
lies in the noise and something known as a real working environment (unpredictable
changes of power supply voltage, temperature change, tolerance to values of built-in
components etc.). Imagine a computer which operates upon decimal numbers by
interpreting them as follows: 0=0V, 1=5V, 2=10V, 3=15V, 4=20V...9=45V.
Did anybody say batteries?
A far simpler solution is the binary logic where 0 indicates that there is no voltage and
1 indicates that there is a voltage. It is easier to write 0 or 1 instead of full sentences
there is no voltage or there is a voltage, respectively. It is about a logic zero (0) and a
logic one (1) which electronics perfectly copes with, and easily performs all those
endlessly complex mathematical operations. Obviously, the electronics we are talking
about applied mathematics in which all the numbers are represented by two digits only
and where it is only important to know whether there is a voltage or not. Of course, we
are talking about digital electronics.

HEXADECIMAL NUMERIC SYSTEM


At the very beginning of the computer development there were many problems when
working with binary numbers. For this reason, a new numeric system, using 16

different symbols was established and called a hexadecimal numeric system. It is


comprised of ten digits we are used to (0, 1, 2, 3,... 9) and six letters of alphabet A, B,
C, D, E and F. You probably wonder whats the purpose of this seemingly bizarre
combination? Just look how perfectly it fits the story about binary numbers and you will
understand.

The largest number that can be represented by 4 binary digits is the number 1111. It
corresponds to the number 15 in a decimal system, whereas it is represented by letter
F in hexadecimal system. It is the largest 1-digit number in the hexadecimal system.
Do you see how skillfully it is used? The largest number written with eight binary digits
is at the same time the largest 2-digit hexadecimal number. Remember that computers
use 8-digit binary numbers. Coincidence?

BCD CODE
A BCD code is a binary code for decimal numbers only (Binary-Coded Decimal). It
consists of 4-digit binary numbers representing the first ten digits (0, 1, 2, 3 ... 8, 9).
Even though four bits can give 16 possible combinations in total, the BCD code makes
advantage of the first ten only.

NUMBER SYSTEM CONVERSION


The binary numeric system is the most commonly used, the decimal system is the
most understandable, while the hexadecimal system is somewhere in the middle.
Therefore, it is very important to learn how to convert numbers from one numeric
system to another, i.e. how to turn a sequence of zeros and ones into understandable
values.

BINARY TO DECIMAL NUMBER CONVERSION


Same digits in a binary number have different values depending on their position in
that number. Each position may contain either 1 or 0 and its value can be easily
determined by counting its position from the right. To perform a binary to decimal
number conversion it is necessary to multiply digits (0 or 1) with their position value (20,
21, 22, 23 etc.) and add all the results. The magic of binary to decimal number
conversion works... Look at the example below:

In order for decimal numbers from 0 to 3 to be represented, you need only two binary
digits. For larger numbers, extra binary digits must be used. Thus, in order for the
decimal numbers from 0 to 7 to be represented, three binary digits are required, for
numbers from 0 to 15, four digits etc. Simply put, the largest binary number consisting
of n digits is obtained when the base 2 is raised by n and the respective result is
subtracted by 1. For example, if n=4:
24 - 1 = 16 - 1 = 15
Accordingly, 4 binary digits enable you to represent decimal numbers from 0 to 15,
which amounts to 16 different values in total.

HEXADECIMAL TO DECIMAL NUMBER CONVERSION


To perform a hexadecimal to decimal number conversion, each hexadecimal digit
should be multiplied with 16 raised by its position value and after that, the obtained
results should be added. For example:

HEXADECIMAL TO BINARY NUMBER CONVERSION


It is not necessary to perform any calculations to convert hexadecimal numbers to
binary. Hexadecimal digits are simply replaced by appropriate binary digits. Since the
maximum value of a hexadecimal digit is equivalent to decimal number 15, it is
necessary to use four binary digits to represent one hexadecimal digit. For example:

A comparative table on the left shows the values of numbers 0-255 represented in
three different number systems. This is probably the easiest way to understand the
common logic applied to all numeric systems.

MARKING NUMBERS
The hexadecimal numeric system is, along with binary and decimal numeric systems,
considered the most important for us. It is easy to convert any hexadecimal number to
binary. It is also easy to remember it. However, such conversions may confuse us. For
example, what does the sentence It is necessary to count up 110 products on the
assembly line actually mean? Depending on whether it is about binary, decimal or
hexadecimal system, the result could be 6, 110 or 272 products, respectively. To avoid
such and similar situations, different prefixes and suffixes are directly added to the
numbers. Prefixes $ and 0x mark hexadecimal numbers. For example, hexadecimal
number 10AF looks either as $10AF or 0x10AF. Similarly, binary numbers usually get
the prefix %. If a number has neither suffix nor prefix it is considered decimal.
Unfortunately, this way of marking numbers is not standardized, yet depends on
specific application.

BIT
In theory, a bit is the basic unit of information... Lets forget this for a moment and take
a look at what it is in practice. The answer is- nothing special- a bit is just a binary digit.

Similar to the decimal numeric system where the same digits of a number do not have
the same value (for example, digits in decimal number 444), the significance of bits
depends on their positions in the binary number. Unlike the decimal numeric system,
binary digits are not referred to as units, tens etc, but zero bit (rightmost bit), first bit
(second from the right) etc. Since the binary system uses only two different digits (0
and 1), the value of one bit can be either 0 or 1.
Dont be confused if you come across a bit having value 4, 16 or 64. It means that its
value is represented in the decimal system. We are simply so much accustomed to the
usage of decimal numbers that such expressions are very common. It would be correct
to say for example, the value of the sixth bit of any binary number is equivalent to
decimal number 64. But we are human and old habits die hard... Besides, how would
it sound number one-one-zero-one-zero...?

BYTE
A byte consists of eight bits grouped together. If a bit is a digit, then bytes represent
numbers. All mathematical operations can be performed upon them, like upon common
decimal numbers. Similar to digits of any number, byte digits do not have the same
significance either. The largest value has the leftmost bit called the most significant bit
(MSB). The rightmost bit has the least value and is therefore called the least significant
bit (LSB). Since eight zeros and ones of one byte can be combined in 256 different
ways, the largest decimal number which can be represented by one byte is 255 (one
combination represents a zero).
A nibble is referred to as half a byte. Depending on which half of the register we are
talking about (left or right), there are high and low nibbles, respectively.

Have you ever wondered what electronics within digital integrated circuits,
microcontrollers or processors look like? What do circuits performing complicated
mathematical operations and making decisions look like? Do you know that their
seemingly complicated schematics comprise only a few different components called
logic circuits or logic gates?

1.3 MUST KNOW DETAILS


The operation of logic circuits is based on principles established by a British
mathematician George Boole in the middle of the 19th century, even before the first
bulb was invented. Originally, the main idea was to express logical forms through
algebraic functions. It soon had lead to a real product which, much later, evaluated in

what today is known as AND, OR and NOT logic circuits. The principle of their
operation is known as Boolean algebra.

LOGIC CIRCUITS
Some of the program instructions give the same results as logic gates. The principle of
their operation will be discussed below.

AND Gate

The logic gate AND has two or more inputs and one output. Let us presume that the gate used in this example has only two inputs. A logic
one (1) will appear on its output only if both inputs (A AND B) are driven high (1). Table on the right shows mutual dependence between the
AND gates inputs and output.

The principle of operation is the same even when the gate has more than two inputs: a logic one (1) will appear on its output only when all
inputs are driven high (1). Any other combination of input voltages will result in a logic zero (0) on its output. When used in the program, the
logic AND is performed by a program instruction to be discussed later. Just remember that logic AND in the program refers to the
corresponding bits of two registers.

OR GATE

Similarly, OR gates also have two or more inputs and one output. If the gate has only two inputs the following applies. A logic one (1) will
appear on its output if either input (A OR B) is driven high (1). If the OR gate has more than two inputs then the following applies. A logic one
(1) appears on its output if at least one input is driven high (1). If all inputs are at logic zero (0), the output will be at logic zero (0) as well.

In the program, the peration is performed in the same manner as the logic AND operation.

NOT GATE
The logic gate NOT has only one input and only one output. It operates in an extremely
simple way. When a logic zero (0) appears on its input, a logic one (1) appears on its
output and vice versa. It means that this gate inverts the signal and is therefore often
called inverter.

The logic NOT operation in the program is performed upon one byte. The result is a
byte with inverted bits. If byte bits are considered a number, the inverted value is
actually a complement thereof. The complement of a number is a value which added to
that number makes it reach the largest 8-digit binary number. In other words, the sum
of an 8-digit number and its complement is always 255.

EXCLUSIVE OR GATE

The EXCLUSIVE OR (XOR) gate is a bit complicated compared to other gates. It is a sort of combination of all of them. A logic one (1)
appears on its output only when its inputs have different logic states.

In the program, the appropriate instruction is commonly used to compare two bytes. Subtraction has the same purpose (if the result is 0,
bytes are equal), but the advantage of the EXCLUSIVE OR logic operation is that it never gives negative results.

REGISTER
In short, a register or a memory cell is an electronic circuit which can memorize the
state of one byte.

SFR REGISTERS
In addition to registers which do not have any special and predefined function, every
microcontroller also has a number of special-function registers (SFRs) the function of
which is predefined by the manufacturer. Their bits are connected (literally) to the
integrated circuits within the microcontroller such as timers, A/D converter, oscillators
etc. It means that they are directly in command of the operation of these circuits, i.e.
the microcontroller. Imagine eight switches controlling the operation of a small circuit
within the microcontroller - Special Function Registers do exactly that.

In other words, the state of register bits is changed from within the program, registers run small integrated circuits within the microcontroller,
these circuits are via microcontroller pins connected to peripherals which are used for... Well, its up to you to decide for what.

INPUT / OUTPUT PORTS


In order for the microcontroller to be useful, it has to be connected to additional
electronics, i.e. peripherals. Each microcontroller has one or more registers connected
to the microcontroller I/O pins. Such connections make I/O ports. Why input/output?
Because you can change a pin function as you wish. For example, suppose you want
your device to turn on/off three signal LEDs and simultaneously monitor the logic state
of five sensors or push buttons. Some of the ports need to be configured so as to have
three outputs (connected to LEDs) and five inputs (connected to sensors). It can be
easily done from within the software, which means that a pin function can be changed
during the operation.

One of the important features of input/output (I/O) pins is a maximum current they can
handle. For most microcontrollers, current supplied from one pin is sufficient to activate
a LED or some other low-consumption device (10-20 mA).
Another important pin feature is a pull-up resistor it may be provided with. The pull-up
resistor connects the appropriate pin to the positive power supply voltage. It can also
be used when the pin is configured as an input connected to a switch or a push button.
Later versions of microcontrollers have pull-up resistors configurable by software.
Each I/O port is usually under control of one SFR, which means that each bit of that
register determines the state of the corresponding microcontroller pin. For example, by
writing a logic one (1) to some of the register bits, the appropriate microcontroller pin is
automatically configured as an input. The voltage supplied to that pin is visible on its
port as 0 or 1. Otherwise, by writing a logic zero to the SFR, the appropriate port pin is
configured as an output. Voltage provided on such an output pin (0V or 5V) reflects the
state of the appropriate register bit (logic 0 or 1, respectively).

MEMORY UNIT
Memory module is a part of the microcontroller used for data storage. The easiest way
to explain it is by comparing it with a filing cabinet with many drawers. Suppose, the
drawers are clearly marked so that their contents can be easily available by reading
labels on the front of the drawers. In the same way, each memory address
corresponds to one memory location. The contents of any location can be accessed
and read by its address. Memory can either be written to or read from.

There are several types of memory within the microcontroller:

READ ONLY MEMORY (ROM)


Read Only Memory (ROM) is used to permanently save the program to be executed by
the microcontroller. The size of a program to be written depends on the size of this
memory. Todays microcontrollers commonly use 16-bit addressing, which means that
they are able to address up to 64 Kb of memory, i.e. 65535 locations. If you are a
novice, your program will hardly exceed several hundred instructions. There are
several types of ROM.

Masked ROM (MROM)


Masked ROM is a special type of ROM the content of which is determined by the
manufacturer. The term masked comes from the manufacturing process, where parts
of the chip are masked off before the process of photolithography. In case of a largescale production, the price is very low. Forget it...

One Time Programmable ROM (OTP ROM)

One time programmable ROM enables you to download a program into it, but, as its
name states, one time only. If an error is detected after the process of loading a
program, the only thing you can do is to load the program to another chip.

UV ERASABLE PROGRAMMABLE ROM (UV EPROM)

Both the manufacturing process and characteristics of UV EPROM memory are fully identical to OTP ROM. However, the package of the
microcontroller with this memory has a recognizable window on its top side. It enables data to be erased under strong ultraviolet light. After
a few minutes of such sunbathing it is possible to load a new program into it. The installation of this window is complicated, which normally
affects the price. In our opinion, unfortunately negative...

Flash Memory
Flash memory, known as the successor to the UV EPROM, was made in the 80s in the
laboratories of INTEL. Since such memory can be rewritten practically an unlimited
number of times, microcontrollers with Flash ROM are ideal for learning,
experimentation and small-scale production. Due to its great popularity, most
microcontrollers are today manufactured in flash technology. So, if you are going to
buy a microcontroller, the type to look for is definitely Flash!

RANDOM ACCESS MEMORY (RAM)


Once the power supply is off the contents of RAM is cleared. It is therefore used for
temporary storing data and intermediate results created and used during the operation
of the microcontroller. For example, if the program performs an addition, it is necessary
to have a register which stands for what in everyday life is called the sum. For this
reason, one of the registers of RAM is called the sum and used for storing results of
addition.

ELECTRICALLY ERASABLE PROGRAMMABLE ROM (EEPROM)


The contents of EEPROM may be changed during operation (similar to RAM), but
remains permanently saved even after the loss of power (similar to ROM). Accordingly,
EEPROM is often used to store values, created during operation, which must be
permanently saved. For example, if you design an electronic lock or an alarm, it would
be great to enable the user to create and enter the password, but its useless if lost
every time the power supply goes off. The ideal solution is a microcontroller with an
embedded EEPROM.

INTERRUPT
Most programs use interrupts in their regular execution. The purpose of the
microcontroller is mainly to respond to changes in its surrounding. In other words,
when an action takes place, the microcontroller does something... For example, when
you push a button on a television remote control, the microcontroller will register it and
respond by changing a channel, turn the volume up or down etc. As such, the
microcontroller would spend most of its time endlessly checking a few buttons for
hours or days, which is not practical at all.
This is why the microcontroller has learnt a trick during its evolution. Instead of
constant checking each pin or bit, the microcontroller delegates the wait issue to a
specialist which will respond only when something attention worthy happens.
A signal which informs the central processor unit about such action is called an
INTERRUPT.

BUS
A bus consists of 8, 16 or more wires. There are two types of buses: the address bus
and the data bus. The address bus consists of as many lines as necessary for memory
addressing. It is used to tranfer an address from the CPU to the memory. The data bus
is as wide as data, in this case it is 8 bits or wires wide. It is used to connect all the
circuits within the microcontroller.

CENTRAL PROCESSOR UNIT (CPU)


As its name suggests, the CPU is a unit which monitors and controls all processes
within the microcontroller. It consists of several subunits, of which the most important
are:

Instruction Decoder decodes program instructions and runs other


circuits on the basis of that;
Arithmetical Logical Unit (ALU) performs all mathematical and logical
operations upon data. The instruction set which is different for each
microcontroller family shows the abilities of this circuit; and
Accumulator is an SFR closely related to the operation of the ALU. It is a
kind of working desk used for storing all data upon which some operation
is to be performed (addition, shift/move etc.). It also stores results to be
used in further processing. One of the SFRs, called a Status Register
(PSW), is closely related to the accumulator. It shows, at any given time,
the status of a number stored in the accumulator (number is larger or
less than zero etc.). The accumulator is also called the working register
and is referred to as W register or just W therefore.

SERIAL COMMUNICATION
A parallel connection between the microcontroller and peripherals established via
input/output ports is an ideal solution when the distance between them is up to several
meters. Otherwise, when it is necessary to establish communication on longer
distances the parallel connection is out of the question. Serial communication is used
instead.
Today, most microcontrollers have several different modules for serial communication
built into them as a standard equipment. Which of these modules will be used depends
on many factors of which the most important are:

How many devices the microcontroller has to exchange data with?


How fast does the data exchange have to be?
What is the distance between devices?
Is it necessary to send and receive data simultaneously?

One of the most important things about the serial communication is the Protocol which
should be strictly observed. It is a set of rules which enables devices to correctly
interpret data they exchange. Fortunately, the microcontroller itself takes care of this,
so that the work of the programmer/user boils down to simple writing (data to be sent)
and reading (received data).

DATA RATE
The term data rate is used to denote the number of bits transferred per second [bps].
Note that it refers to bits, not bytes. According to the protocol, each byte is transferred
along with several control bits. It means that one byte in serial data stream may consist
of 11 bits. For example, if the data rate is 300 bps then maximum 37 and minimum 27
bytes may be transferred per second.
The most commonly used serial communication modules are:

I2C (INTER INTEGRATED CIRCUIT)


An inter-integrated circuit is a module for serial data exchange between
microcontrollers and specialized integrated circuits of a new generation. It is used
when the distance between these devices is short (receiver and transmitter are usually
on the same printed board). The connection is established via two conductors. One is
used for data transfer, while the other is used for synchronization (clock signal). As can
be seen in figure below, one device is always a master device. It performs addressing
of one slave device before communication starts and controls the process of data
transfer. In this way one microcontroller can communicate with 112 different devices
using I2C. Data rate is usually 100 Kb/sec (standard mode) or 10 Kb/sec (slow data
rate mode). Devices with a data rate of 3.4 Mb/sec have recently appeared. The
distance between devices which communicate over an I2C bus is limited to several
meters.

SPI (SERIAL PERIPHERAL INTERFACE BUS)


A serial peripheral interface (SPI) bus is a module for serial communication which uses
three or four conductors. One conductor is used to receive data, one to send data, one
for synchronization and one alternatively for selecting a device to communicate with. It
is a full duplexconnection, which means that data can be sent and received
simultaneously.
The maximum data rate is higher than that in the I2C communication module.

UART (UNIVERSAL ASYNCHRONOUS


RECEIVER/TRANSMITTER)
As its name suggests, the USART communication is asynchronous, which means that
no special line for clock signal transfer is used. In some applications, such as radio
connection or infrared waves remote control, this feature is crucial. Since only one
communication line is used, both receiver and transmitter operate at the same
predefined rate in order to maintain necessary synchronization. This is a very simple
way of transferring data as it basically comes down to the conversion of 8-bit data from
parallel to serial format. Data rate is not high, up to 1 Mbit/sec.

OSCILLATOR

Even pulses generated by the oscillator enable a harmonic and synchronous operation of all circuits within the microcontroller. The oscillator
is usually configured so as to use a quartz crystal or ceramic resonator for frequency stabilization, but it can also operate as a stand-alone
circuit (like RC oscillator). It is important to say that instructions are not executed at the rate imposed by the oscillator itself, but several
times slower. It happens because each instruction is executed in several steps. In some microcontrollers, the same number of cycles is
required to execute all instructions, while in others, the number of cycles is different for different instructions. Accordingly, if the
microcontroller uses quartz crystal with a frequency of 20 Mhz, the execution time of an instruction is not 50nS, but 200, 400 or 800 nS,
depending on the microcontroller type.

POWER SUPPLY CIRCUIT


There are two things worth attention when speaking of the microcontroller power
supply circuit:

Brown out is a potentially dangerous condition which occurs at the


moment the microcontroller is turned off or when the power supply
voltage drops to its minimum value due to noise. As the microcontroller
consists of several circuits with different operating voltage levels, such
condition can cause its out-of-control performance. In order to prevent it,
the microcontroller usually has a built-in reset circuit which causes the
reset condition to occur as soon as the microcontroller goes into a brown
out state of emergency.
Reset pin is usually referred to as MCLR (Master Clear Reset). It is used
for causing an external reset of the microcontroller by applying a logic
zero (0) or a logic one (1) to it, which depends on the type of the
microcontroller. In case the brown out circuit is not built into the
microcontroller, a simple external circuit for brown out reset can be
connected to the MCLR pin.

TIMERS/COUNTERS
The microcontroller oscillator uses quartz crystal for its operation. Even though it is not
the best solution, there are still many reasons to use it. The frequency of such
oscillator is precisely defined and very stable, so that pulses it generates are always
the same width, which makes them ideal for time measurement. Such oscillators are
also used in quartz watches. If it is necessary to measure time between two events, it
is sufficient to count up pulses generated by this oscillator. This is exactly what the
timer does.

Most programs use these miniature electronic stopwatches. Their heart make 8- or
16- bit SFRs, the contents of which is automatically incremented by each coming
pulse. Once a register is fully loaded, an interrupt may be generated.
If the timer uses an internal quartz oscillator for its operation, then it can be used to
measure time between two events (if the value stored in the timer register is T1 at the
moment the measurement starts, and T2 at the moment it terminates, then the time
elapsed is equal to the result of subtraction T2-T1). If registers use pulses supplied
from an external source then such timer is turned into a counter.
This is just a simple explanation of the operation of timer/counter. As you already know,
it is more complicated in practice.

HOW DOES THE TIMER OPERATE?


This is how the timer operates in practice: pulses generated by the quartz oscillator are
directly, or via a prescaler, brought to the circuit which increments the number stored in
the timer register. By embedding a quartz crystal with a frequency of 4MHz the
following applies: if one instruction (one machine cycle) lasts for four quartz oscillator
periods then by embedding a quartz crystal with a frequency of 4MHz this number will
be incremented a million times per second (each microsecond).

It is easy to measure short time intervals, up to 256 microseconds, in the way


described above because it is the largest number that one register can store. This
restriction may be easily made up by using a slower oscillator, registers with more bits,
prescaler or interrupts. The first two solutions have some drawbacks so that it is more
advisable to use prescalers or interrupts.

USING A PRESCALER IN TIMER OPERATION


A prescaler is an electronic device used to reduce frequency by a predefined division
rate. In order to generate one pulse on its output, it is necessary to bring 1, 2, 4 or
more pulses on its input. Most microcontrollers have one or more bulit-in prescalers
and their division rate may be changed from within the program. The prescaler is used
when it is necessary to measure longer periods of time.

USING INTERRUPT IN TIMER OPERATION


If the timer register consists of 8 bits, the largest number it can store is 255. For 16-bit
registers it is the number 65.535. If such number is exceeded, the timer will be
automatically reset and counting will start from zero again. This condition is called
an overflow. If enabled from within the program, the overflow can cause an interrupt,
which gives completely new possibilities. For example, the state of registers used for
counting seconds, minutes or days can be changed in an interrupt routine. The whole

process (except for the interrupt routine) is automatically performed behind the scenes,
which enables the main circuits of the microcontroller to operate normally.

Figure above illustrates the use of an interrupt in timer operation. Delays of arbitrary
duration, having almost no influence on the main program execution, can be easily
obtained by assigning a prescaler to the timer.

COUNTERS
If the timer is supplied with pulses from the microcontroller input pin, then it turns into a
counter. It is clear that the same electronic circuit is able to operate in two different
modes. The only difference is that in this case pulses to be counted come via the
microcontroller input pin and their duration (width) is usually undefined. This is why
they cannot be used for time measurement, but can be used for other purposes such
as counting products on an assembly line, number of axis rotation, passengers etc.
(depending on sensor in use).

WATCHDOG TIMER
A watchdog timer is a timer connected to a stand-alone RC oscillator within the
microcontroller.
If the watchdog timer is enabled, every time it counts up to the maximum value, the
microcontroller reset occurs and the program execution starts from the first instruction.
The point is to prevent this from happening by using a specific command.
Anyway, the whole idea is based on the fact that every program is executed in several
longer or shorter loops. If instructions for the watchdog timer reset are set at the
appropriate program locations, in addition to commands being regularly executed, then
the operation of the watchdog timer will not affect the program execution. If for any
reason, usually due to manufacturing noise, the program counter gets stuck at some
memory location from which there is no return, the watchdog timer will not be cleared,

so the registers value being constantly incremented will reach the maximum et
voila! Reset occurs and the program will be executed from the beginning.

A/D CONVERTER

External signals are usually fundamentally different from those the microcontroller recognizes (0V and 5V only) and therefore have to be
converted into recognizable values. An analog to digital converter is an electronic circuit which converts continuous signals to discrete digital
numbers. In other words, this circuit converts an analogue value into a binary number and forwards it to the CPU for further processing. This
module is thus used for input pin voltage (analogue value) measurement.

The result of measurement is a number (digital value) used and processed later in the
program.

INTERNAL ARCHITECTURE
All upgraded microcontrollers implement one of the two basic design models
called Harvard and von-Neumann architecture.
They represent two different ways of exchanging data between the CPU and memory.

VON-NEUMANN ARCHITECTURE

Microcontrollers using the von-Neumann architecture have only one memory block and one 8-bit data bus. As all data is exchanged through
these 8 lines, the bus is overloaded and communication is slow and inefficient. The CPU can either read an instruction or read/write data
from/to the memory. Both processes cannot be performed at the same time since instructions and data use the same bus. For example, if a
program line reads that a RAM memory register called SUM should be incremented by one (instruction: incf SUM), the microcontroller will
do the following:

1. Read the part of the program instruction specifying WHAT should be done
(in this case the incf instruction for increment is to be performed).
2. Read the other part of the same instruction specifying upon WHICH data i
should be performed (in this case it is the SUM register).

3. After being incremented, the contents of this register should be written to


the register from which it was read (the address of the SUM register).
The same data bus is used for all these intermediate operations when data is
exchanged between the CPU and memory.

HARVARD ARCHITECTURE

Microcontrollers which implement the Harvard architecture have two different data buses. One is 8 bits wide and connects the CPU to RAM.
The other consists of 12, 14 or 16 lines and connects the CPU to ROM. Accordingly, the CPU can read an instruction and access data
memory at the same time. Since all RAM memory registers are 8 bits wide, all data being exchanged is of the same width. During the writing
process, only 8-bit data is included. In other words, all you can change from within the program and all you can deal with is 8 bits wide. All
the programs written for these microcontrollers will be stored in the microcontroller internal ROM after being compiled to machine code.
However, ROM memory locations are not 8, but 12, 14 or 16 bits wide. The rest of bits 4, 6 or 8, respectively, represents the instruction
alone specifying for the CPU what to do with the 8-bit data.

The advantages of this architecture are as follows:

All data in the program is one byte (8 bits) wide. As the data bus used for
program reading has 12, 14 or 16 lines, both instruction and data can be
read simultaneously using these spare bits. For this reason, all
instructions are single-cycle instructions, except the jump instruction
which is two-cycle.
Owing to the fact that the program (ROM) and temporary data (RAM) use
separate buses, the CPU can execute two instructions at the same time.
In other words, while RAM read or write is in progress (the end of one
instruction), the next program instruction is read via the other bus.
With microcontrollers with the von-Neumann architecture, one never
knows how much memory is to be occupied by the program. Basically,
most program instructions occupy two memory locations (one contains
information on WHAT should be done, while the other contains
information upon WHICH data it should be done). However, it is not a
hard and fast rule, but the most common case. In the Harvard
architecture the program bus is wider than one byte, which allows each

program word to consist of instruction and data, i.e. one memory location
- one program instruction.

INSTRUCTION SET

All instructions recognizable by the microcontroller are colectivelly called the Instruction Set. When you write a program in assembly
language, you actually specify instructions in such order as they should be executed. The main restriction here is the number of available
instructions. The manufacturers usually employ one of the two opposite solutions and design microcontrollers which implement the smallest
or the largest possible number of instructions. In other words - they choose between RISC and CISC instruction sets, respectively.

RISC (REDUCED INSTRUCTION SET COMPUTER)


In this case, the microcontroller recognizes and executes basic operations only
(addition, subtraction, copying etc.). Other, more complicated operations are performed
by combining them. For example, multiplication in the program must be performed as a
successive addition. Its the same as if you try to explain to someone, using only a few
different words, how to reach the airport in a big city. However, its not as black as its
painted. As a matter of fact, it is not so difficult to explain where the airport is if you use
the right words such as left, right, kilometers etc.

CISC (COMPLEX INSTRUCTION SET COMPUTER)


CISC is the opposite to RISC. Microcontrollers designed to recognize more than 200
different instructions can do a lot of things at high speed. However, one needs to
understand how to take all that such a rich instruction set offers, which is not easy at
all...

HOW TO MAKE THE RIGHT CHOICE?


OK, you are a beginner and you have made a decision to go on an adventure of
working with microcontrollers. Congratulations on your choice. But, it is not as easy to
choose the right microcontroller as it may seem. The problem is not a limited range of
devices, but the opposite.

Before you start designing a microcontroller-based device, think of the following: how
many inputs/outputs does your project require? Should it perform some other
operations than to simply turn relays on/off? Does it need some specialized modules
such as serial communication, A/D converter etc.? When you create a clear picture of
what you need, the selection range is considerably reduced and its time to think of the
price. Are you going to make several such devices? Several hundred? A million?
Anyway, you get the point.
If you think of all these things for the very first time then everything seems a bit
complicated. Make it simple and go step by step. First of all, select the manufacturer,
i.e. the microcontroller family you can easily get. Study one particular model. Learn as
much as you need, dont go into details. Solve a specific problem and something
incredible will happen- you will be able to handle any model belonging to that
microcontroller family.
Remember learning to ride a bicycle. After several bruises you got when you started,
you were able to keep the balance and then easily ride any other bicycle. And of
course, you will never forget programming just as you will never forget riding bicycles!

1.4 PIC MICROCONTROLLERS


The original name of the PIC microcontroller is PICmicro (Peripheral Interface
Controller), but it is better known as a PIC. Its ancestor, called the PIC1650, was
designed in 1975 by General Instruments. It was intended for totally different purposes.
About ten years later, this circuit evolved into a real PIC microcontroller by adding
EEPROM memory.
If you want to learn more about it, just keep on reading.
The main purpose of this book is to provide the user with necessary information he/she
needs to know in order to be able to use microcontrollers in practice. In order to avoid
tedious explanations and endless stories about the useful features of different
microcontrollers, this book deals with the operation of one particular model belonging
to the high middle class. It is the PIC16F887 microcontroller - powerful enough to be
worth attention and simple enough to be easily learned by everybody. So, even though
the following chapters describe this microcontroller in detail, they actually refer to the
whole PIC family.
All PIC microcontrollers implement the Harvard architecture, which means that their
program memory is connected to the CPU via more than 8 lines. Depending on the
bus width, there are 12-, 14- and 16-bit microcontrollers. Table below shows the main
features of these three categories of PIC microcontrollers.
Family

ROM
[Kbytes]

RAM
[bytes]

Pins

Clock
Freq.
[MHz]

A/D
Inputs

Resolution
of A/D
Converter

Comparators

8/16
bit
Timers

Serial
Comm.

PWM
Outputs

Others

Base-Line 8 - bit architecture, 12-bit Instruction Word Length


PIC10FXXX

0.375 -

16 - 24

6-8

4-8

0-2

0-1

1x8

0.75
PIC12FXXX

0.75 - 1.5

25 - 38

4-8

0-3

0-1

1x8

EEPROM

PIC16FXXX

0.75 - 3

25 - 134

14 44

20

0-3

0-2

1x8

EEPROM

PIC16HVXXX

1.5

25

18 20

20

1x8

Vdd =
15V

Mid-Range 8 - bit architecture, 14-bit Instruction World Length


PIC12FXXX

1.75 - 3.5

64 - 128

20

0-4

10

1-2x
81x
16

0-1

EEPROM

PIC12HVXXX

1.75

64

20

0-4

10

1-2x
81x
16

0-1

PIC16FXXX

1.75 - 14

64 - 368

14 64

20

0 - 13

8 or 10

0-2

1-2x
81x
16

USART
I2C SPI

0-3

PIC16HVXXX

1.75 - 3.5

64 - 128

14 20

20

0 - 12

10

2x81
x 16

USART
I2C SPI

0-3

0-2x
82-3
x 16

USB2.0
CAN2.0
USART
I2C SPI

0-5

USB2.0
USART
Ethernet
I2C SPI

2-5

USART
I2C SPI

High-End 8 - bit architecture, 16-bit Instruction Word Length

4 - 128

256 3936

18 80

32 48

PIC18FXXJXX

8 - 128

1024 3936

28 100

40 48

10 - 16

10

0-2x
82-3
x 16

PIC18FXXKXX

8 - 64

768 3936

28 44

64

10 - 13

10

1x83
x 16

PIC18FXXX

4 - 16

10 or 12

All PIC microcontrollers use Harvard architecture, which means that their program
memory is connected to the CPU over more than 8 lines. Depending on the bus width,
there are 12-, 14- and 16-bit microcontrollers. Table above shows the main features of
these three categories.
As can be seen in the table on the previous page, if we disregard 16-bit monstersPIC 24FXXX and PIC 24HXXX for a moment- all PIC microcontrollers have 8-bit
Harvard architecture and belong to one out of three large groups. Accordingly,
depending on the size of the program word there are the first, second and third
microcontroller category, i.e. 12-, 14- or 16-bit microcontrollers. Having similar 8-bit
core, all of them use the same instruction set and the basic hardware skeleton
connected to more or less peripheral units.
PIC microcontrollers with 14-bit program words are most likely the best choice for
beginners. Here is why...

INSTRUCTION SET
The instruction set for the 16F8XX includes 35 instructions in total. The reason for such
a small number of instructions lies in the RISC architecture. Instructions are well
optimized from the operating speed aspect, simplicity in architecture and code
compactness. The drawback to the RISC architecture is that the user is expected to
cope with these instructions. Of course, this is relevant only if you use assembly

language for programming. This book deals with programming in a high-level


programming language called Basic, which means that most work has been already
done by somebody else. You just have to use relatively simple instructions.

INSTRUCTION EXECUTION TIME


All instructions for PIC microcontrollers are single-cycle instructions. The only
exception are conditional branch instructions (if condition is met) and instructions
performed upon the program counter. In both cases, two cycles are required for
instruction execution, while the second cycle is executed as an NOP (No Operation).
Single-cycle instructions consist of four clock cycles. It means that if a 4MHz oscillator
is used, it will take 1S for an instruction to be executed. The instruction execution time
for jump instructions is 2S.
Instruction set of 14-bit program words PIC microcontrollers:
INSTRUCTION

DESCRIPTION

O P E R ATI O N

FLAG

CLK

Data Transfer Instructions


MOVLW k

Move constant to W

k -> w

MOVWF f

Move W to f

W -> f

MOVF f,d

Move f to d

f -> d

CLRW

Clear W

0 -> W

CLRF f

Clear f

0 -> f

SWAPF f,d

Swap nibbles in f

f(7:4),(3:0) -> f(3:0),(7:4)

1, 2

1, 2

Arithmetic-logic Instructions
ADDLW k

Add W and constant

W+k -> W

C, DC, Z

ADDWF f,d

Add W and f

W+f -> d

C, DC ,Z

SUBLW k

Subtract W from constant

k-W -> W

C, DC, Z

SUBWF f,d

Subtract W from f

f-W -> d

C, DC, Z

ANDLW k

Logical AND with W with constant

W AND k -> W

ANDWF f,d

Logical AND with W with f

W AND f -> d

IORLW k

Logical OR with W with constant

W OR k -> W

IORWF f,d

Logical OR with W with f

W OR f -> d

1, 2

XORWF f,d

Logical exclusive OR with W with constant

W XOR k -> W

1, 2

XORLW k

Logical exclusive OR with W with f

W XOR f -> d

INCF f,d

Increment f by 1

f+1 -> f

1, 2

DECF f,d

Decrement f by 1

f-1 -> f

1, 2

RLF f,d

Rotate left f through CARRY bit

1, 2

RRF f,d

Rotate right f through CARRY bit

1, 2

COMF f,d

Complement f

1, 2

f -> d

1, 2

1, 2

1, 2

Bit-oriented Instructions
BCF f,b

Clear bit b in f

0 -> f(b)

1, 2

BSF f,b

Clear bit b in f

1 -> f(b)

1, 2

Program Control Instructions


BTFSC f,b

Test bit b of f. Skip the following instruction if


clear.

Skip if f(b) = 0

1 (2)

BTFSS f,b

Test bit b of f. Skip the following instruction if set.

Skip if f(b) = 1

1 (2)

DECFSZ f,d

Decrement f. Skip the following instruction if clear.

f-1 -> d skip if Z = 1

1 (2)

1, 2, 3

INCFSZ f,d

Increment f. Skip the following instruction if set.

f+1 -> d skip if Z = 0

1 (2)

1, 2, 3

GOTO k

Go to address

k -> PC

CALL k

Call subroutine

PC -> TOS, k -> PC

RETURN

Return from subroutine

TOS -> PC

RETLW k

Return with constant in W

k -> W, TOS -> PC

RETFIE

Return from interrupt

TOS -> PC, 1 -> GIE

Other instructions
NOP

No operation

TOS -> PC, 1 -> GIE

CLRWDT

Clear watchdog timer

0 -> WDT, 1 -> TO, 1 -> PD

TO, PD

SLEEP

Go into sleep mode

0 -> WDT, 1 -> TO, 0 -> PD

TO, PD

*1 When an I/O register is modified, the value used will be that value present on the
pins themselves.
*2 If the instruction is executed upon the TMR register and if d=1, the prescaler will be
cleared.
*3 If the PC is modified or test result is a logic one (1), the instruction requires two
cycles. The second cycle is executed as an NOP.

The architecture of 8-bit PIC microcontrollers. Which of these modules are to be built
into the microcontroller depends on the type there

Chapter 2: Programming Microcontrollers


You certainly know that it is not enough to simply connect the microcontroller to other
components and turn the power supply on to make it work, dont you? There is more to
be done. Microcontrollers need to be programmed to be capable of performing
anything useful. This chapter deals with programming in Basic and we are going to
describe only the essential things you have to know to write a program. It might seem
complicated, especially if you have no experience in this field. Dont give up, take a
deep breath and start...

2.1 PROGRAMMING LANGUAGES


2.2 THE BASICS OF BASIC PROGRAMMING LANGUAGE
2.3 COMPILER MIKROBASIC PRO FOR PIC

2.1 PROGRAMMING LANGUAGES

The microcontroller executes the program loaded in its Flash memory. It is a so called executable code which consists of a seemingly
bizarre sequence of zeros and ones. Depending on the microcontrollers architecture, this binary code is organized in 12-, 14- or 16-bit wide
words. Every word is considered by the CPU as an instruction to be executed during the operation of the microcontroller. As it is much
easier for us to deal with hexadecimal numeric system, the executable code is usually represented as a sequence of hexadecimal numbers
called a Hex code which, long time ago, used to be written by the programmer. All instructions that the microcontroller can recognize and
execute are collectively known as the Instruction set. For PIC microcontrollers with 14-bit wide program words, the instruction set includes
35 different instructions.

As the writing of executable code was endlessly tiring, the first high-level programming language called assembly language was created. It
made the process of programming a bit more complicated, but on the other hand the process of writing program stopped being a nightmare.

Assembly instructions consist of meaningful abbreviations which are compiled into executable code by means of a special program installed
on a PC called assembler. It compiles instruction by instruction without optimization. The main advantages of assembly language are its
simplicity and the fact that each program instruction matches only one memory location. In other words, assembly language enables a
complete control of all processes being under way within the microcontroller, which still makes it popular nowadays.

On the other hand, programs are always executed at high speeds and in most cases it
is not necessary to know in detail what is going on within the microcontroller. Despite
all good attributes of the assembly language, programmers have always needed a
programming language similar to the language they use in everyday speech. Finally,
high-level programming languages, including Basic, have been created. The main
advantage of these languages is a simplicity of program writing. Several assembly
instructions are now replaced by one statement in Basic. The programmer is not
required to be familiar with the instruction set of the microcontroller in use any more. It
is no longer possible to know how each statement is executed, but it doesnt matter
anyway. In case it does, the problem is solved by adding a sequence written in
assembly language to the program.

Similar to assembly language, a specialized program installed on the PC is in charge


of compiling program into machine code. Unlike assembler, compilers for high-level
programming languages create an executable code which is not always the shortest
possible.

Figure above gives a rough illustration of what is going on during the process of
compiling a program written in Basic into a hex code.
Here is an example of a simple program written in Basic:

ADVANTAGES OF HIGH-LEVEL PROGRAMMING LANGUAGES


If you have any experience in writing programs for PIC microcontrollers in assembly
language, then you are probably familiar with the other side of the medal of RISC
architecture - the lack of instructions. For example, there is no appropriate instruction
for multiplying two numbers. Of course, there is a way to solve this issue owing to
mathematics which enables you to perform complex operations by breaking them into
a number of simple ones. Accordingly, multiplication can be easily substituted by

successive addition (a x b = a + a + a + ... + a). And here we are, just at the beginning
of a very long story... Still there is no reason to be worried about as far as you use one
of the high-level programming languages, such as Basic, as the compiler will
automatically find a solution to these and similar issues. Simply write a*b.

2.2 THE BASICS OF BASIC PROGRAMMING LANGUAGE


Similar to the use of any language which is not limited to books and magazines only,
the Basic programming language is not closely related to any special type of computer,
processor or operating system. It is a general-purpose language. This fact can make
some problems as the Basic language slightly varies depending on its application (like
different dialects of one language). So, we are not going to provide you with a detailed
description of all the attributes of Basic in this book. Instead, we are going to describe
a concrete application of the Basic programming language, i.e. Basic used by the
mikroBasic PRO for PIC compiler.

The Basic programming language is a simple and easy to understand programming


language. To use it correctly, it is sufficient to know just a few basic elements that every
program consists of. These are:

Identifiers
Comments
Operators
Expressions
Instructions
Constants
Variables
Symbols
Directives
Labels
Procedures and functions
Modules

Here is an example of how you should not write a program. No comments are included, labels names are meaningless, code sections are
not grouped This program is going to work properly, but its purpose and way of execution will be only known to the programmer who has
written it (at least for a day or two).

Figure below illustrates the structure of a simple program written in Basic, pointing out
the parts it consists of. This is an example of how you should write a program.
Differences are more than obvious...

PROGRAM STRUCTURE
Similar to other programming languages, Basic provides a set of strictly defined rules
to be observed when writing programs. For a program to be written in Basic, it is
necessary to install a software which provides the appropriate work environment and
understands these rules on your PC... When you write a letter, you need a word
processing program, dont you? In this case, you need the mikroBasic PRO for
PICcompiler.
Unlike most programs you have already got used to dealing with, the process of writing
programs in the compiler doesnt start by selecting the File>New option,

but Project>New. Why is that? Well, you write a program in a document with the .mbas
extension (mikroBasic). You diligently write, write, write... When you compile it into a
HEX code, a new document with the .hex extension will be created. At the same time
the compiler will automatically create several documents in addition to it. The purpose
of these documents is not important at this point. Of course, there must be something
to connect them all. You get it - we are talking about a project. The program you write
is just a part of it.

Just to be sure that we are on the same page... From now on the word module refers
to a document with the .mbas extension. The text it contains is referred to as
a program. Every project written in the mikroBasic PRO for PIC compiler has the
.mbppi extension (microBasicProject for PIC) and consists of at least one
module (Main Module).
Every project in mikroBasic PRO for PIC requires a single main module. It is identified
by the keyword program and instructs the compiler from where to start the process of
compiling. When you successfully create an empty project in Project Wizard, the main
module will be automatically displayed in the Code Editor window:

program MyProject ' The main module is called MyProject


here
main: ' Main procedure
... '*
... '* Write program code here
... '*
end.
Nothing may precede the program keyword, except comments. As mentioned above,
the project may also include other modules which, unlike the main one, start with
the module keyword.

module MyModule ' Auxiliary module is called MyModule


... '*
... '* Implements
... '*
end.
To make the compiler familiar with all modules which belong to one project, it is
necessary to specify them in the main module using theinclude keyword followed by a
quoted module name. The extension of these files should not be included. Only one
module per includeclause is allowed. The number of include clauses is not limited, but
they all must be specified immediately after the program (main module) name. Heres
an example:

program MyProgram ' Start of program (main module named


MyProgram)
' Other modules included are:
include "utils" ' Module "utils"
include "strings" ' Module "strings"
include "MyUnit" ' Module "MyUnit"
...

ORGANIZATION OF THE MAIN MODULE


Basically, the main module can be divided in two sections: declarations and program
body. What is a declaration in programming? A declaration is a process of defining the
properties of identifiers to be used in the program. Like most other programming
languages, Basic also requires all identifiers to be declared prior to being used in the
program. Otherwise, the compiler may not be able to interpret them correctly. This is
how a declaration of a variable called distance looks like:

dim distance as float ' Declare variable distance


As can be seen, it is a floating point variable, i.e. a number with optional decimal
places. Two other variables are declared and namedspeed and time. Now, they can be
used in the program as follows:
This is an example of how to write the main module correctly:

ORGANIZATION OF OTHER MODULES


Other modules start with the module keyword. Every module consists of three
sections: include, interface and implementation. Only the implementation section is
obligatory. It starts with the implements keyword. Follow the example below:

IDENTIFIERS
Identifiers are arbitrary names assigned to the basic language objects such as
constants, variables, functions, procedures etc. Somebody just came to an idea to use
the word identifier instead of name. As simple as that. Here are a few rules to be
observed when using identifiers:

Identifiers may contain all the letters of alphabet (both upper and lower
case), digits (0-9) and the underscore character ( _ ).
The first character of an identifier must not be a digit.

No identifier may contain special characters such as ! [{ # $ % & etc.


Basic is not case-sensitive, which means that FIRST, first and First will be
considered identical.
The ^ (caret) symbol is used to denote an exponentiation operator, the *
(asterisk) symbol is used to denote multiplication, while other symbols
have their usual meanings.
Keywords being already used by the compiler must not be used as
identifiers The mikroBasic keywords are listed in the following table:
Abstract
And
Array
As
At
Asm
Assembler
Automated
Bdata
Begin
Bit
Case
Cdecl
Class
Code
Compact
Const
Constructor
Contains
Data
Default
Deprecated
Destructor
Dispid
Dispinterface
Div
Do
Downto
Dynamic
Else

End
Except
Export
Exports
External
Far
File
Finalization
Finally
For
Forward
Function
Goto
Idata
If
Ilevel
Implementation
In
Index
Inherited
Initialization
Inline
Interface
Io
Is
Label
Large
Library
Message
Mod
Name
Near
Nil
Not
Object
Of
On

Or
Org
Out
Overload
Override
Package
Packed
Pascal
Pdata
Platform
Private
Procedure
Program
Property
Protected
Public
Published
Raise
Read
Readonly
Record
Register
Reintroduce
Repeat
Requires
Resourcestring
Rx
Safecall
Sbit
Set
Sfr
Shl
Shr
Small
Stdcall
Stored
String

Stringresource
Then
Threadvar
To
Try
Type
Unit
Until
Uses
Var
Virtual
Volatile
While
With
Write
Writeonly
Xdata
Xor

A list of identifiers which must not be used in the program.

COMMENTS
Comments are parts of the program used to provide more information about the
program and make it clear to the user. In Basic, any text following a single quotation
mark (') is considered a comment. Comments are not compiled into executable code.
The compiler is capable of recognizing special characters used to mark where
comments start and completely ignores the following text during compilation. Even
though comments cannot affect the program execution, they are as important as any
other part of the program because almost every program needs to be improved,
modified, upgraded or simplified at some point. Without comments, it is almost
impossible to understand even the simplest programs.

LABELS

Labels provide the easiest way of controlling the program flow. They are used to mark
particular lines in the program where jump instruction and appropriate subroutine are
to be executed. All labels must be terminated by : so that the compiler can easily
recognize them.

CONSTANTS
A constant is a number or a character the value of which cannot be changed during the
program execution. Unlike variables, constants are stored in ROM memory of the
microcontroller in order to save as much memory space of RAM as possible. The
compiler recognizes constants by their names and prefix const. Every constant is
declared under unique name which must be a valid identifier. Constants are available
in decimal, hexadecimal and binary formats. The compiler distinguishes between them
according to their prefixes. If a constant has no prefix, it is considered decimal by
default.
F O R M AT

PREFIX

Decimal

EXAMPLE
const MAX = 100

Hexadecimal

0x or $

const MAX = 0xFF

Binary

Floating point

const MAX = %11011101

Constants are declared in the declaration part of the program or routine. The syntax of
constants is:

const constant_name [as type] = value


Constant names are usually written in capitals. The type of a constant is automatically
recognized by its size. In the following example, the constant MINIMUM is considered
a signed integer and will be stored within two bytes of Flash memory (16 bits):

const MINIMUM = -1000 ' Declare constant MINIMUM


Type of constant is optionally specified. In the absence of type, the compiler assumes
the smallest type that can accommodate the constant value.

const MAX as longint = 10000


const MIN = 1000 ' Compiler will assume word type
const SWITCH = "n" ' Compiler will assume char type
In the following example, a constant named T_MAX is declared so as to have a
fractional value 32.60. Now, the program can compare the measured temperature to
that constant with a meaningful name instead to number 32.60.

const T_MAX = 32.60 ' Declare temperature T_MAX


const T_MAX = 3.260E1 ' Another way of declaring constant
T_MAX
A string constant consists of a sequence of characters. They are enclosed within
double quotation marks. A blank space may also be included in the string constant as a
character. String constants are used to represent non-numeric quantities such as
names, addresses, messages etc.

const Message_1 = "Press the START button" ' Message 1 for


LCD
const Message_2 = "Press the RIGHT button" ' Message 2 for
LCD
const Message_3 = "Press the LEFT button" ' Message 3 for
LCD
In this example, sending the Message_1 constant to an LCD will cause the
message press the START button to be displayed.

VARIABLES
A variable is a named object able to contain a data which can be modified during
program execution. Every variable is declared under a unique name which must be a
valid identifier. For example, to add two numbers (number1 + number2) in the program,
it is necessary to have a variable to represent what we in everyday life call the sum. In
this case number1, number and sum are variables. The syntax of one single variable
declaration is as follows:

dim variable_name as type


Variables in Basic are typed, which means that it is necessary to specify the type of
data a variable is to receive. Variables are stored in RAM and the memory space
occupied (in bytes) depends on their type. In addition to single declarations, variables

of the same type can be declared as a list. Here, identifier_list is a comma-delimited


list of valid identifiers, whereas type can be any data type.

dim i, j, k as byte 'Define variables i, j, k


dim counter, temp as word 'Define variables counter and
temp

SYMBOLS
Symbols in Basic allow you to create simple macros without parameters. It means that
any code line may be replaced with one single identifier. Symbols, when used properly,
can increase code legibility and reusability.
Symbols are declared at the beginning of the module, right after the module name and
optional include directive. The scope of a symbol is always limited to the module in
which it has been declared.

symbol symbol_name = code


Here, symbol_name must be a valid identifier to be used throughout the code. The
code specifier can be any code line (literals, assignments, function calls, etc).

symbol MAXALLOWED = 216


' Symbol MAXALLOWED for
numeric value
symbol OUT = PORTA
' Symbol OUT for SFR
symbol MYDELAY = Delay_ms(762) ' Symbol MYDELAY for
procedure call
dim cnt as byte
' Variable cnt
main:
if cnt > MAXALLOWED then
' Program checks whether cnt
> 216
cnt = 0
' If yes,
OUT.1 = 0
' the following three commands
MYDELAY
' are to be executed
end if
...
' If not, program continues
here
No RAM memory space is used for storing symbols being used in the program. The
compiler will simply replace all symbols with appropriate code lines assigned to them
when declared.

BASIC LANGUAGE DATA TYPES


There are several data types that can be used in the Basic programming language.
Table below shows the range of values these data may have when used in their basic
form.

D ATA T Y P E

DESCRIPTION

SIZE (NUMBER OF BITS)

R A N G E O F V AL U E S

bit

One bit

0 or 1

sbit

One bit

0 or 1

byte, char

Character

0 ... 255

short

Signed short integer

-127 ... 128

word

Unsigned integer

16

0 ... 65535

integer

Signed integer

16

-32768 ... 32767

longword

32-bit word

32

0 ... 4294967295

longint

32-bit signed word

32

-2147483648 ... 2147483647

float

Floating point

32

1.17549435082*10-38 ... 6.80564774407*1038

AUTOMATIC DATA TYPE CONVERSION


The compiler automatically performs implicit conversion in the following situations:

if a statement requires an expression of particular type, but expression of


different type is used;
if an operator requires an operand of particular type, but operand of
different type is used;
if a function requires a formal parameter of particular type, but is assigned
an object of different type; and
if a function result does not match the declared function return data type.

PROMOTION
When operands are of different types, implicit conversion promotes a less complex to a
more complex type as follows:

bit byte
short, byte/char integer, word, longint, longword
integer, word longint, longword
short, byte/char, integer, word, longint, longword float

DATA CLIPPING
In assignment statements and statements requiring an expression of particular type,
the correct value will be stored in destination only if the result of expression doesnt
exceed the destination range. Otherwise, if expression evaluates to a more complex
type than expected, the excess data will simply be clipped, i.e. higher bytes will be lost.

dim
dim
...
j =
i =

i as byte ' Variable i occupies one byte of RAM


j as word ' Variable j occupies two bytes of RAM
$FF0F
j ' i becomes $0F, higher byte $FF is lost

EXPLICIT DATA TYPE CONVERSION

Explicit conversion may be executed upon any expression at any point by writing
desired type keyword (byte, word, short, integer, longint, float...) before the
expression to be converted. The expression must be enclosed in parentheses. Explicit
conversion cannot be performed upon the operand to the left of the assignment
operator.

a = word(b) ' Explicit conversion of expression b


word(b) = a ' Compiler will report an error
A special case of explicit conversion is a conversion between signed and unsigned
data types as it does not affect the binary representation of data.

dim a as byte
dim b as short
'...
b = -1
a = byte(b) ' a is 255, not -1
' Data doesnt change its binary representation %11111111
' it is just interpreted differently by the compiler

OPERATORS
An operator is a symbol used to denote particular arithmetic, logic or some other
operation. Every operation is performed upon one or more operands (variables or
constants) in an expression. Besides, every operator features priority execution and
associativity. If an expression contains more than one operand, the order of their
execution is determined by the level of their priority. There are four priority categories
in Basic. Operators belonging to the same category have equal priority. If two or more
operators have the same priority level, the operations are performed from left to right.
Parenthesis can be used to define the priority of the operation within an expression.
Each category is assigned either left-to-right or rightto- left associativity rule. Refer to
the table below.
PRIORITY

O P E R ATO R S

A S S O C I ATI V I T Y

High

@ not + -

from right to left

* / div mod and << >>

from left to right

+ - or xor

from left to right

= <> < > <= >=

from left to right

Low

ARITHMETIC OPERATORS
Arithmetic operators are used to perform arithmetic operations. These operations are
performed upon numeric operands and always return numerical results. Binary
operations are performed upon two operands, whereas unary operations are
performed upon one operand. All arithmetic operators associate from left to right.
O P E R ATO R

O P E R ATI O N

Addition

Subtraction

Multiplication

Division - floating point

div

Division - round down

mod

Reminder

DIVISION BY ZERO
If a zero (0) is used explicitly as the second operand in the division operation (x div 0),
the compiler will report an error and will not generate a code. In case of implicit division
where the second operand is an object the value of which is 0 (x div y, where y=0), the
result will be undefined.

RELATIONAL OPERATORS
Relational operators are used to compare two variables and determine the validity of
their relationship. In mikroBasic, all relational operators return 255 if the expression
is true, or zero (0) if it is false. The same applies in expressions such as if the
expression is true then...
O P E R ATO R

MEANING

EXAMPLE

TRUTH CONDITION

>

is greater than

b>a

if b is greater than a

>=

is greater than or equal to

a >= 5

If a is greater than or equal to 5

<

is less than

a<b

if a Is less than b

<=

is less than or equal to

a <= b

if a Is less than or equal to b

is equal to

a=6

if a Is equal to 6

<>

is not equal to

a <> b

if a Is not equal to b

LOGIC BITWISE OPERATORS


Logic bitwise operators are performed upon bits of an operand. They associate from
left to right. The only exception is the bitwise complement operator not which
associates from right to left. Bitwise operators are listed in the table on the right:
The bitwise operators and, or and xor perform logic operations upon appropriate pairs
of bits of operands. The not operator complements each bit of one single operand.
OPERAND

MEANING

EXAMPLE

RESULT

<<

Shift left

A = B << 2

B = 11110011

A = 11001100

>>

Shift right

A = B >> 3

B = 11110011

A = 00011110

and

Bitwise AND

C = A and B

A=11100011
B=11001100

C = 11000000

or

Bitwise OR

C = A or B

A=11100011
B=11001100

C = 11101111

not

Bitwise NOT

A = not B

B = 11001100

A = 00110011

xor

Bitwise EXOR

C = A xor B

A = 11100011
B = 11001100

C = 00101111

The bitwise operators and, or and xor perform logic operations upon appropriate pairs
of bits of operands. The not operator complements each bit of one single operand.

$1234 and $5678 ' result is $1230 because:


' $1234 : 0001 0010 0011 0100
' $5678 : 0101 0110 0111 1000
' ---------------------------' and : 0001 0010 0011 0000 ... that is, $1230
$1234 or $5678 ' equals $567C
$1234 xor $5678 ' equals $444C
not $1234 ' equals $EDCB

BITWISE SHIFT OPERATORS


There are two shift operators in mikroBasic. These are the << operator which moves
bits to the left and the >> operator which moves bits to the right. Both operators have
two operands each. The left operand is an object to move, whereas the right operand
is a number of positions to move the object by. Both operands must be of integral type.
The right operand must be a positive value.
By shifting an operand left (<<), the leftmost bits are discarded, whereas new bits on
the right are assigned zeroes. Shifting unsigned operand to the left by n positions is
equivalent to multiplying it with 2n. The same applies to signed operands if all
discarded bits are equal to the sign bit.

dim num as word ' declare variable num as word


num = 1 ' asign it decimal value 1 (00000000 00000001 bin.)
num << 5 ' equals 32 (00000000 00100000 bin.)
By shifting operand right (>>), the rightmost bits are discarded, whereas new bits on
the left are assigned zeroes (in case of unsigned operand) or the sign bit (in case of
signed operand). Shifting operand to the right by n positions is equivalent to dividing it
by 2n.

dim num as integer ' declare variable num as signed integer


num = 0xFF56 ' asign it hex value FF56 (11111111 01010110
bin.)
num >> 4 ' equals 0xFFF5 (11111111 11110101 bin.)

CONDITIONAL STATEMENTS
Conditions are common ingredients of a program. They enable one or a number of
statements to be executed depending on the validity of an expression. In other
words If the condition is met (...), do (...). Otherwise, do (...). A conditional statement
can be followed either by a single statement or by a block of statements to execute.

CONDITIONAL STATEMENT IF
The syntax of a simple form of the if statement is:

if expression then
operations
end if
If the result of expression is true (not 0), operations are performed, then the program
proceeds with execution. If the result of expression is false (0), operations are not
performed and the program immediately proceeds with execution.
The if operator can also be used in combination with else operators:

if expression then
operations1
else
other operations2
end if
If the result of expression is true (not 0), operations1 are performed, otherwise
operations2 are performed. The program proceeds with execution after these
operations are performed.

NESTED IF STATEMENTS
Nested if statement need additional attention. A nested if-statement is a statement
used inside the other if-statement. As a rule, they are parsed starting from the most
nested ifstatement, whereas each else statement is bound to the nearest available if
on its left:

SELECT CASE STATEMENT


The select case statement is a conditional statement with multiple branching. It
consists of a selector expression (condition) and a list of possible values of that
expression. The syntax of the select case statement is:
The selector specifier is an expression which should evaluate as integral value.

Specifiers value_1...value_n represent selectors possible values and can be literals,


constants or constant expressions. Specifiers statements_1 ...statements_n can be
any statements.
The case else clause is optional.
First, the selector expression is evaluated. It is then compared to all available values. If
the match is found, the statements following the match evaluate and the select case
statement terminates. If there are multiple matches, statements following the first
match will be executed. If none of the values matches the selector, then
default_statements in the case else clause (if there is one) are executed.
Here is an example of the select case statement:

select case decimal_digit ' Decimal-digit value is being


checked
case 0
mask = %01111110 ' Display "0"
case 1
mask = %00110000 ' Display "1"
case 2
mask = %01101101
case 3
mask = %01111001
case 4
mask = %00110011
case 5
mask = %01011011
case 6
mask = %01011111
case 7
mask = %01110000
case 8
mask = %01111111
case 9
mask = %01111011
end select

This program routine converts decimal digits into appropriate binary combination on
the port in order to display them on an LED display.

PROGRAM LOOPS
Some instructions (operations) have to be executed more than once in the program. A
set of commands being repeated makes a program loop. How many times it will be
executed, i.e. how long the program will stay within a loop, depends on the conditions
to leave the loop.

WHILE LOOP
The while loop is implemented when the number of iterations is not specified. It is
necessary to check the iteration condition before a loop execution. Simply put, the
while loop is executed while all necessary conditions for its execution are met... The
syntax of the while loop looks as follows:

while expression
statements
wend
The statements specifier represents a group of statements which are executed
repeatedly as long as the value of the expression specifier which represents an
expression is true. In other words, the program remains in the loop until expression
becomes false. The value of expression is checked before the next iteration is
executed. Accordingly, if it is false before entering the loop, no iterations executes, i.e.
statements will never be executed. The program will proceed with execution from the
end of the while loop (from instructions following the wend instruction).

A special type of the program loop is an endless loop. It is created if the condition to
exit loop remains unchanged within the loop.
In this case, the execution is simple as the result in brackets is always true (1 will
allways be different from 0), which means that the program remains in the loop.

while 1 ' true can be written instead of 1


...
' Expressions will be unceasingly executed (endless
loop)
...
wend

FOR LOOP
The for loop is implemented when the number of iterations is specified. The syntax of
the for loop looks as follows:

for counter = initial_value to final_value [step


step_value]
statements
next counter
Here, with each iteration of the loop, the counter variable is incremented by
step_value. The step_value parameter is an optional integer value, considered 1 if
omitted. Before the first iteration, the counter (counter) is set to its initial value
(initial_value) and will be incremented until it reaches or exceeds the final value
(final_value). Statements will be executed with each iteration. Iinitial_value and
final_value should be expressions compatible with the counter, whereas the
statements specifier can be any statement that doesnt change the counter value. Note
that the step_value parameter may be negative, thus enabling a countdown.

for k=1 to 5 ' Increase variable k five times (from 1 to 5)


and
operation ' keep on executing "operation" every time
...
next k
A set of instructions (operation) will be executed five times. After that, it will be
determined that the k<5 is false (after 5 iterations k=5) and the program will exit the for
loop.

DO LOOP

The do loop is implemented when the number of iterations is not specified. The loop is
executed repeatedly until the expression evaluates to true. The syntax of the do loop
is:

do
statements
loop until expression
In this case, the statements specifier represents a group of statements which are
executed as long as the expression (expression) is true. The loop conditions are
checked at the end of the loop, so the loop is executed at least once regardless of
whether the condition is true or false. In the following example, the program remains in
the do loop until variable a reaches 1E06 (a million iterations).

a = 0 ' Set initial value


do
a = a+1 ' Operation in progress
loop until a <= 1E06 ' Check condition

WRITING CODE IN ASSEMBLY LANGUAGE

Sometimes a program in Basic requires parts of the code to be written in assembly language. In this way some parts of the program can be
executed in a precisely defined way for exact period of time. For example, when it is necessary to provide very short pulses (a few
microseconds) to appear periodically on a microcontroller pin, the best solution is to write an assembly code for pulse duration control. The
asm command is used to introduce one or more assembly instructions to the program written in Basic:

asm
Assembly language instructions
...
end asm
Assembly instructions may use objects (constants, variables, routines etc.) that must
be previously declared in the Basic language. It goes without saying that these objects
are declared according to the rules of the Basic language. Refer to the example below:

ARRAYS
An array is a finite and arranged list of variables of the same type called elements. This
type is called the base type. Each element is assigned a unique index so that different
elements may have the same value. An array is declared by specifying the type of its
elements (called array type), its name and the number of its elements enclosed within
brackets:

dim array_name as component_type [number_of_components]


Elements of an array are identified by their position. Indices go from 0 (the first element
of an array) to N-1 (N is the number of elements contained in an array). The compiler
must know how many memory locations to allocate when an array is declared and
because of that the array size cant be variable.
E L E M E N T S O F AR R AY

CONTENTS OF ELEMENT

shelf[0]

shelf[1]

23

shelf[2]

34

shelf[3]

shelf[4]

shelf[5]

12

shelf[6]

...

...

...

...

shelf [99]

23

To illustrate it, an array can be thought of as a shorter or longer list of variables of the
same type where each of these is assigned an ordinal number always starting from
zero. Such an array is called a vector. Table on the right shows an array named shelf
which consists of 100 elements.
In this case, the contents of a variable (element) represents a number of products the
shelf contains. Elements are accessed by indexing, i.e. by specifying their indices
enclosed in square brackets:

dim shelf as byte [100] ' Declare the array "shelf" with
100 elements
shelf [4] = 12
' 12 items are placed on shelf
[4]
temp = shelf [1]
' Variable shelf [1] is copied to
' variable temp
In constant arrays, elements can be assigned their contents during array declaration.
In the following example, an constant array named CALENDAR is declared and each
element is assigned specific number of days:

const CALENDAR as byte [12]=


(31,28,31,30,31,30,31,31,30,31,30,31)
The number of assigned values must not exceed the specified array length, but can be
less. In this case, the trailing excess elements will be assigned zeroes.

GOTO STATEMENT
The goto statement enables you to make an absolute jump to another point in the
program. Be careful when using this statement since its execution causes an
unconditional jump ignoring any type of nesting limitations. The destination point is
identified by a label, which is used as an argument for the goto statement. A label
consists of a valid identifier followed by a colon (:).The syntax of the goto statement is:

goto: label_name
This statement executes a jump to the label_name specifier which represents a label.
The goto statement can precede or follow the label. Hence it is not possible to jump
into or out of a procedure or function. The goto statement can be used to break out
from any level of nested structures. It is not advisable to jump into a loop or other
structured statement as it may give unexpected results.

GOSUB STATEMENT
A subroutine is a portion of code within a larger program executed upon demand. It
performs a specific task and is relatively independent from the rest of code. The
interpreter will jump to the subroutine, execute it, and return to the main program.
Keywords gosub and return are used in the Basic language to denote start and end of
subroutine.

gosub label_name
...
...

...
label_name:
...
return
Subroutines are considered by many to be hard to maintain, difficult to read and digest,
just like the goto statement. Use them just if you dont have any better solution.

ACCESSING INDIVIDUAL BITS


Compiler mikroBasic PRO for PIC, installed on your PC, includes a list of supported
PIC microcontrollers with all registers, their accurate addresses and bit names. The
compiler allows you to access individual bits of these registers by their names, without
specifying their positions (the compiler already knows them). There are a number of
ways to access and modify one individual bit within a register. Lets access the GIE bit
(Global Interrupt Enable bit) for example. Its the seventh bit of the INTCON register.
One way to access this bit by its name is to write the following:

INTCON.GIE = 0 ' Clear Global Interrupt Enable Bit (GIE)


Instead of a bit name, a variable, constant, function call or an expression enclosed
within parentheses may be used to denote the position of bit in a register. In addition,
for individual bit access there are predefined global constants B0, B1, , B7, or 0, 1,
7, where 7 is considered the most significant bit.

INTCON.B0 = 0 ' Clear bit 0 of the INTCON register


ADCON0.5 = 1 ' Set bit 5 of the ADCON0 register
i = 5
STATUS.(i+1) = 1 ' Set bit 6 of the STATUS register
Finally, a desired bit may be accessed by using its alias name. In this case its the
GIE_bit:

GIE_bit = 1 ' Set Global Interrupt Enable Bit (GIE)

SBIT TYPE
The mikroBasic PRO for PIC compiler has the sbit data type. This is the shortest data
type referring to one single bit. If type sbit is assigned to a variable, the appropriate bit
of some register will be changed by changing that variable without specyfing the
register name and location. The sbit variable will behave like a pointer. In order to
declare the sbit variable, it is sufficient to write:

dim Bit_name as sbit at Register_name.Bit_position

program MyProgram ' Main module


...
dim Output1 as sbit at PORTB.0 ' Variable Output1 is of
sbit type
...
Output1 = 1 ' Pin PORTB.0 is set (5V)

BIT TYPE
The mikroBasic PRO for PIC compiler provides the bit data type that may be used for
variable declarations.

dim bf as bit
Unlike variables of sbit type, only the bit name is declared here, whereas the compiler
stores bit-variable into some of the free registers of RAM. As can be seen, it is not
necessary to specify a bit of some specific register. The exact location of the variable
of bit type is unknown to the user.
Bit and sbit types are implemented with the following limitations:

Cannot be used for argument lists and as function return values


Cannot be used as a member of structures
Cannot be used as array elements
Cannot be initialized
Cannot be pointed to
Their addresses cannot be red, therefore the unary operator @ cannot be
used with variable of this type

dim ptr as ^bit ' invalid


dim arr as array[5] of bit ' invalid

PROCEDURES AND FUNCTIONS


Functions and procedures, collectively referred to as routines, are subprograms
(selfcontained statement blocks) which perform a certain task based on a number of
input parameters. Functions return a value after execution, while procedures dont.

PROCEDURES
A procedure is a named block of code, i.e. a subroutine with some additional features.
For example, it can accept parameters. Procedures are declared as follows:

sub procedure procedure_name(parameter_list)


[ local declarations ]
procedure body
end sub

The procedure_name specifier represents a procedure name and can


be any valid identifier.
The parameter_list specifier within parentheses represents a list of
formal parameters declared similar to variables. In mikroBasic PRO for
PIC, parameters are passed to a procedure by value. To pass parameters
by address, it is necessary to add the byref keyword at the beginning of
the parameter declaration.
Local declarations are optional declarations of variables and constants
which refer to the given procedure only.
Procedure body is a sequence of statements to be executed upon
calling the procedure.
Procedures are called by their name followed by actual parameters placed in the same
order as their matching formal parameters. Upon a procedure call, all formal
parameters are created as local objects initialized by values of actual arguments.

'Add two numbers


sub procedure add (dim byref sum as word, dim x, y as byte)
sum = x + y ' add numbers x and y and store result into sum
variable
end sub ' end of subprocedure
Now, we can call the add procedure to calculate full weight of a cargo for example:
add (gross_weight, net_weight, tare_weight)

FUNCTIONS
Functions must be properly declared in order to be correctly interpreted during the
process of compiling.

sub function function_name(parameter_list) as return_type


[ local declarations ]
function body
end sub
Every declaration contains the following elements:

Function name is an identifier by which it will be possible to call a function


(function_name in the example).

Type of result (returned value) is data type of the returned data


(return_type in the example).
Declaration of parameters: each parameter consists of a variable,
constant, pointer or array preceded by its data type specifier similar to
any regular variable declaration (parameter_list in the example). They are
used to pass information to the function when it is called.
Local declarations are optional declarations of variables and constants
which refer only to the given function.
Function body is a sequence of statements to be executed upon calling
the function.
Here is an example of how to define and use the power function:

'function which calculates xn based on input parameters x


and n (n > 0)
sub function power(dim x, n as byte) as longint ' x and n
are bytes, result is longint
dim i as byte ' i is a byte
result = 1 ' result = 1 if n = 0
if n > 0 then
for i = 1 to n
result = result*x
next i
end if
end sub
Now, we can call the power function to calculate 312 for example:

tmp = power(3, 12) ' Calculate 312

FUNCTION AND PROCEDURE LIBRARIES


Declarations of all functions and procedures being used in Basic are usually stored in
special module files called libraries. Prior to using any of them in the program, it is
necessary to specify the appropriate module by means of the include clause at the
beginning of the program. Its just a general rule. But if you write a program in compiler
mikroBasic PRO for PIC it is sufficient to check desired library on the list and the
appropriate module will be automatically included in the project. This compiler already
has a number of such libraries. If the compiler encounters an unknown function or
procedure during program execution, first it will look for its declaration in the previously
checked libraries.

BUILT-IN ROUTINES IN MIKROBASIC PRO FOR PIC


In addition to function and procedure libraries, the mikroBasic PRO for PIC compiler
provides a set of useful built-in functions:

Lo
Hi
Higher
Highest
Inc
Dec
Chr
Ord
SetBit
ClearBit
TestBit
Delay_us
Delay_ms
Vdelay_Advanded_ms
Vdelay_ms
Delay_Cyc
Clock_KHz
Clock_MHz
Reset
ClrWdt
DisableContextSaving
SetFuncCall
SetOrg
GetDateTime
GetVersion

The Delay_us and Delay_ms routines are generated in the place of call.
The Vdelay_ms, Delay_Cyc and Get_Fosc_kHz are actual Basic routines. Their
sources can be found in the Delays.mbas file located in the uses folder of the compiler.

PREPROCESSOR
A preprocessor is an integral part of every compiler. Its function is to recognize and
execute preprocessor instructions. What are preprocessor instructions? These are
special instructions which do not belong to the Basic language, but are integrated into
the compiler. Prior to compiling, the compiler activates the preprocessor which goes
through the program in search for these instructions. If any found, the preprocessor will
simply replace them by another text which, depending on the type of command, can be
a file (command include) or just a short sequence of characters (command define).
Then, the process of compiling may start. The preprocessor instructions can be

anywhere in the source program and refer only to the part of the program following
their appearance up to the end of the program.

PREPROCESSOR DIRECTIVE INCLUDE


Many programs often repeat the same set of commands for several times. In order to
speed up the process of writing a program, these commands and declarations are
usually grouped in particular modules that can easily be included in the program using
the include directive. To be more precise, the include directive imports text from
another document, no matter whether it is a set of commands, comments etc., into the
program.

CONDITIONAL COMPILATION
Conditional compilation directives are typically used to make source programs easy to
modify and compile for different microcontrollers. mikroBasic PRO for PIC supports
conditional compilation. All conditional compilation directives must be completed within
the module in which they have started.

DIRECTIVES #IF, #ELIF, #ELSE, AND #ENDIF


Conditional directives #if, #elif, #else and #endif are executed similar to the common
Basic conditional statements. If an expression you write after #if has a non-zero value,
then program lines following the #if directive will be treated as a valid program code
and compiled into a hex code. The syntax thereof is:

#if constant_expression_1
is not zero,
<section_1>
compiled
[#elif constant_expression_2
is not zero,
<section_2>]
compiled
...
[#elif constant_expression_n
is not zero,
<section_n>]
compiled
[#else
sections are compiled
<final_section>]
compiled
#endif

'If constant_expression_1
'section_1 will be
'If constant_expression_2
'section_2 will be
'If constant_expression_n
'section_n will be
'If none of previous
'final_section will be
'End of #if directive

Each #if directive in a source file must be matched by a closing #endif


directive. Any number of #elif directives can appear between #if and
#endif directives, but only one #else directive is allowed. The #else
directive, if present, must be the last directive before #endif.
Section can be any program code that may be recognized by the
compiler or preprocessor. The preprocessor selects a single section by
evaluating constant_expression following each #if or #elif directive until it
finds a true (non-zero) constant_expression.
If all constant-expressions evaluate to false or no #elif directives appear,
the preprocessor selects the final_section following the #else clause. If
the #else clause is omitted and all instances of constant_expression in
the #if block evaluate to false, no section will be selected for further
processing.
Finally, the result is that only one code section, even the empty one, will be compiled.

POINTERS
As you know, every object in the program (variable, procedure, subroutine, etc.) is
assigned one specific memory address. When declaring a variable in the program, the
compiler automatically assigns it a free RAM location. During programming, these
addresses are kept hidden from programmers. In other words - addresses are
secretly used... The possibility to access different objects by their names (identifiers)
instead of addresses is one of the main advantages of the high-level programming
languages. As a matter of fact it is much easier to deal with words (names) than with

numbers. Besides, the compiler takes care of associating objects and their adresses.
Addressing objects by specifying their names is called direct addressing.
However, sometimes you have to deal with memory location addresses. Then, pointers
are used - variables holding memory address of an object. In this case it is possible to
access objects using pointers only. This way of addressing is therefore called indirect
addressing.
Prior to using a pointer, it is necessary to declare its data type. Simply, add a caret
prefix (^) before the type.

dim pointer_p as ^word ' pointer_p points to data of word


type
If it is required to store a variable at some specific RAM memory location, then
the absolute directive should be used in the program as follows:

dim variable_a as word absolute 12 ' variable_a will occupy


1 word
' (16 bits) at address
12
Now, if you want to access data at the pointers memory location, you need to add a
caret after the pointer's name. For example, lets declare the above mentioned pointer
pointer_p which points to a word (in this case, it is previously defined variable_a stored
at address 12 in RAM). The pointed variable_a will be assigned value 26:

dim pointer_p as ^word 'Pointer_p points to data of word


type
...
...
pointer_p = 12
'Pointer_p points to memory adress
12
...
pointer_p^ = 26
'Variable a at memory address 12 has
value 26
'Similar to the absolute directive that is used for
variables, the org
'directive specifies the starting address of a routine in
ROM. It is
'appended to the routine declaration. For example:
sub procedure proc(dim par as word) org 0x200 ' Procedure
will start at

...
0x200
end sub

' the address

In this case, the pointer_p pointer is assigned value 12 (pointer_p =12), which means
that the memory address 12 is specified hereby.

If you want to change the value of a pointed variable, it is sufficient to change the
pointer's value and add a caret symbol (^) as a suffix to it. Refer to figure on the right,
variable variable_a at address 12 is assigned value 26 by means of the pointer_p
pointer.
Pointers can point to data stored in any available memory space and can reside in any
available memory space except in program memory space (ROM).

@ OPERATOR
The @ operator returns the address of an object, i.e. creates a pointer upon its
operand. The following rules apply here:

If X is a variable, @X returns the address of X.

If F is a routine (function or procedure), @F creates a pointer to F.


dim temp as word
ptr_b as ^byte
ptr_arr as ^byte[10]
arr as byte[10]
main:
ptr_b = @arr
' @ operator will return ^byte
temp = @arr
' @ operator will return ^byte
ptr_arr = @arr ' @ operator will return ^byte[10]
end.
If variable X is of array type, the @ operator will return pointer to it's first basic element,
except when the left side of the statement in which X is used is an array pointer. In this
case, the @ operator will return pointer to array, not to it's first basic element.

Program structure in mikroBasic PRO for PIC:

1. Every program normally starts with a comment which provides information


on the purpose of the program, date of program writing, programmer,
version, changes made relative to the previous version etc. These
comments (header) are not compulsory, but its a good habit to write them
and have them in the program.
2. Every program code starts with a program directive followed by the
program name.
3. If the program, apart from the main module, contains other modules as
well, their names must be specified using the include directive (one include
directive per each module). Accordingly, if the compiler, while compiling the
main module, comes to an undeclared object (function, variable etc.), it wil
first try to find its declaration within declared modules. If no appropriate
declaration is found, the compiler will report an error.
4. The include directive (if there is any) is followed by a code portion
intended to declare variables, constants, procedures, subprograms,
functions and other objects to be used later in the program. These
declarations are used to reserve RAM registers for data storing as well as
to instruct the compiler how to execute some function or procedure. For
example, a data of byte type occupies only one register, while a data
of float type occupies four registers.
5. The main program starts with the main: directive (always followed by a
colon). It is also called a program body.
6. Every program is terminated with the end. directive (always followed by a
period).

2.3 COMPILER MIKROBASIC PRO FOR PIC

Everything you have read so far about programming in Basic is just a theory. It is
useful to know, of course, but dont forget that this programming language is not much
in connection with something concrete and tangible. You will experience many
problems with accurate names of registers, their addresses, names of particular
control bits and many others when you start writing your first program in Basic. The
point is that you need more than theory to make the microcontroller do something
useful.
Having in mind a saying Prevention is better than cure, we have to remind you of all
the things you must have settled before you start writing a program for the
microcontroller. First of all, you need a program installed on your PC which
understands the programming language you are going to use and which provides
appropriate working environment for it. There is no such a compiler sutable for only
one type of microcontrollers nor for all microcontrollers. Its about software used for
programming similar microcontrollers of one manufacturer. We have previously
introduced mikroBasic language which has been especially designed for programming
PIC microcontrollers. Now, when you know enough about it, its time to present the
software you are going to use for developing and editing your projects. This software is
called the mikroBasic PRO for PIC compiler. Its IDE (Integrated Development
Environment) includes all the tools you need to develop your projects (editor, compiler
debugger etc.)
As its name implies, the mikroBasic PRO for PIC compiler is intended for writing
programs for PIC microcontrollers in the Basic language. It contains information about
architecture of PIC microcontrollers (registers, their accurate addresses, memory
modules, operation of its modules, instruction set, pinout etc.). Moreover, it includes
specific tools for PIC microcontroller programming. So, the first thing you have to do
when you start up the compiler is to select the chip and operating frequency from the
list. This is not the end. This is the beginnig. You can finally start writing your program
in Basic.
The process of creating and executing a project can be divided in several parts:

1. Creation of the project (project name, project settings, file dependancies);


2. Editing of the program;
3. Compilation of the program and correction of errors;
4. Debugging (execute your program step by step to make sure that it
performs the operations you expect);
5. Microcontroller programming (load the .hex file genertaed by the compiler
into the microcontroller by using thePICflash programmer).

INSTALLING MIKROBASIC PRO FOR PIC


The installation of mikroBasic PRO for PIC is similar to the installation of any other
Windows program and the whole procedure is carried out through Wizard:

You just have to follow the instructions and click on Next, OK, Next, Next... The same
old story except for the last option 'Do you want to install PICFLASH v7.11
programmer?'. Does it make you question what to do? As you know, the compiler
translates a program written in Basic into a hex code. The next step is to load that code
into the microcontroller. Thats why you need the PICFLASH programmer. Install it!

After completing the PICFLASH installation, you will be asked for the installation of
another similar program. It is a software for programming a special family of PIC
microcontrollers which operate in low consumption mode (3.3 V). Skip it...
The last step - driver installation!

A driver is a program which enables the operating system to communicate with a


peripheral device. In our case, this device is the hardware programmer of your
development system. You definitely need it. Click Yes.

A type of driver to be installed depends on the operating system in use. In this case,
the PC runs a 32-bit operating system Windows XP. Select the Win 2000, XP, 2003 32bit folder containing the appropriate driver and start up its installation.
Now you are safe, just keep on clicking Next, OK, Next, Next...

IDE OF MIKROBASIC PRO FOR PIC


This is what appears on your screen when you start up mikroBasic PRO for PIC for the
very first time:

Unfortunately, a detailed description of all the options available in this IDE would take
up too much time, so we are not going into it. We are going to describe only the most
important features of the mikroBasic PRO for PIC compiler, instead. Of course, you
can always get more information by pressing the Help button [F1]. A detailed
explanation on how to create a new project and write a program is given in several
practical examples in Chapter 4 of this book.

PROJECT MANAGER

A program written in the mikroBasic PRO for PIC compiler is not a separate document, but a part of a project that also includes hex code,
assembly code, and other files. Some of them are created during the compilers operation, while some are imported from other programs.
However, the Project Manager window enables you to handle all of the project files. Just right click on any folder and select the option you
need for your project.

LIBRARY MANAGER

Libraries contain a large number of ready-to-use functions and provide a lot of facilities when writing programs for PIC MCUs. The compiler
must know all dependencies of your mikroBasic source file in order to compile it properly. You should open the Library Manager window and
check libraries you want to use in your program. When a library is checked, it is automatically added to the project and linked during the
compiling process. Thus, you dont have to include them manually into your source code files using the #include directive. For example, if
your program uses an LCD then there is no need to write new functions because by selecting the Lcd Library you will be able to use readyto-use LCD functions in your program. If this library is not selected in the Library Manager, every time you try to use any of its functions, the
compiler will report an error. A description of each library is available by right clicking on its name and selecting the Help option.

CODE EXPLORER

The Code Explorer window enables you to easily locate objects (functions, constants, procedures etc.) within long programs. For example, if
you look for a function used in the program, just double click its name in this window, and the cursor will be automatically positioned at the
appropriate line in the program.

PROJECT SETTINGS

When compiling a project, the compiler generates files to be loaded into the microcontroller. These files will be different depending on the
type of the microcontroller and the purpose of the compilation. Thus, in order to enable the compiler to operate properly, it is necessary to
set some project parameters in the Project Settings window:
Device: Selection of the microcontroller to be used enables the compiler to retrieve the associated definition file. The definition file of a
microcontroller contain specific information on its SFR registers, their memory addresses and some variables specific to that microcontroller.
It is all mandatory for creating a compatible .hex file.
Oscillator: This option is used to specify the operating speed of the microcontroller. Of course this value depends on the oscillator in use. It
is retrieved by the compiler for compiling routines which require time information (function Delay_ms( ) for example). Later, this information

will also be used by the programmer. The operating speed is set so as to enable the microcontrollers internal oscillator to operate at
selected frequency.

Build/Debugger Type: The whole compiling process is called building and includes
parsing, compiling, linking and generation of .hex files. The build type enables you to
set up the building mode. Depending on your choice of mode, the generated file to be
loaded into the microcontroller will be different.
Build type - release: The program to be loaded into the microcontroller will not
contain any complementary information to be debugged later. After completing the
compiling process, the compiler has no more influence on the program execution.
Build type - ICD debug: Some information is added to the .hex file in order to allow
you to perform hardware debugging. When the compiling process is completed and the
microcontroller is programmed, the compiler remains connected to the microcontroller
and still can affect its operation. A tool called mikroICD (In Circuit Debugger) enables
the program to be executed step by step and provides an access to the current content
of all registers of the microcontroller.
For the purpose of debugging, a software simulator can be used in both build type
modes. It enables you to simulate your program by reproducing the microcontroller
behaviour. The simulator doesnt use real devices for its operation, so that some
operations cannot be reproduced (interrupt, for example). However, it is faster to
debug a program by using simulator and it doesnt require any taget device.
Note that any of these settings can be modified at any time while editing the program.
Dont forget to re-build and re-program your device after modifying any of those
settings.

EDITING AND COMPILING PROGRAMS


CODE EDITOR
Code Editor is a central part of the compiler window used for writing and editing
programs. A large number of options used for setting its functions and layout can be
found in the Tools/Options menu [F12]. When you write a program, dont forget
comments. Comments are very important for the program debugging and upgrading.
Moreover, even if the compiler doesnt have formatting restriction, you should always
follow the same editing rules (like in the examples provided in this book). As there is no
line length limitation, dont hesitate to use blank spaces in order to make your code
more readable.

When you write a program, compile it regularly in order to correct syntax errors as you
come along. You can also compile your program every time the redaction of a new
function is completed and test its behaviour by using debug mode. In this way, it is
much easier to fix compilation errors. Otherwise, you will be compelled to modify the
entire program.

COMPILING AND FIXING ERRORS


To compile your code, you just have to click on the Build option in the Project menu. In
fact, the entire project is compiled and, in case the compilation is sucessful, the output
files are generated (asm, .hex etc.). A compilation is successful if no error was found.
The compilation generates many messages which are displayed in the Messages
window. These messages consist of information, warnings and errors. Each error
found is associated with its program line and description. As an error in your code can
generate many other errors, you should always try to fix the first error on the list and
then recompile your program. In other words, it is advisable to fix errors one by one.

In the previous example, the program reports a syntax error in the 80th line. The
compilation enables you to correct your program by fixing all mikroBasic errors. When
all the errors are fixed, your program is ready to be dumped into the microcontroller.
However, your job is not finished yet because you still dont know whether your
program behaves as expected or not.

DEBUGGING YOUR PROGRAM


As we could see before, there are two debug modes: a software debugger which
simulates actions of the microcontroller (default mode) and a hardware debugger
(mikroICD) which directly reads the content of the microcontroller memory. Whatever
mode you choose, the debugging procedure is the same. In case you choose ICD
debug make sure you load your program into the microcontroller. Debugging is a very
important step as it allows you to test your program after a sucessful compilation, or to
fix bugs discovered in a running program.
To start the debugger, click on the Start debugger option from the Run menu. The code
editor will automatically be slightly modified and a window called Watch Values will
appear. The principle of debugging is based on running a program step by step and
following the evolution of the content of registers and variable values. In this way, you
will be able to verify the computation and to see if something unexpected has occured.
By running the program step by step, you will be able to easily locate where problems
occur. As debugging can lead to program modification, you should always re-compile
the program after each correction and restart the debugger in order to verify what you
have changed.

SOFTWARE SIMULATOR
If you wish to be a programmer and devote yourself to programming microcontrollers,
then you have to get used to the fact that programs almost NEVER work on the first try
or start using a simulator. The simulator is an integral part of the compiler used to
simulate the operation of the microcontroller.

Prior to starting up the simulator, select its operating mode in the Project Settings window (Build type - release), compile the program and
click the Run /Start Debugger option.
The compiler will be automatically set to simulation mode. As such, it monitors the state of all register bits and enables you to execute the
program step by step while monitoring the operation of the microcontroller on the screen.
A few icons, used only for the operation of this simulator, will appear in the toolbar when the compiler is set to this mode.

These icons have the following meanings:

Step Into: Execute the current program line, then halts. If the executed
program line calls a subroutine, the debugger steps into the subroutine
and halts after executing the first instruction within it.
Step Over: Execute the current program line, then halts. If the executed
program line calls a subroutine, the debugger will not step into it. The
whole subroutine will be executed and the debugger halts at the first
instruction following the call. It seems that one program line is skipped
even though the whole subroutine is executed. As a result, the state of
registers is changed. This command is commonly used when it is
necessary to speed up the execution of long program loops.
Run To Cursor: Execute all the program lines until the cursor position is
reached.
Step out: Execute all remaining program lines within the subroutine. The
debugger halts immediately after exiting the subroutine.
Breakpoints make the process of debugging programs more efficient by enabling you
to stop the program execution at some specific line. This is very useful as you will be
able to check only critical parts of the program, not lose your time by testing the whole
program line by line. To add or remove a breakpoint you just have to click on the left
side of your code editor on the appropriate line or press [F5]. A small window called
Breakpoints indicates you where the breakpoints are located. Note that the lines
marked by breakpoints are highlighted in red.

The line being currently executed is highlighted in blue. You can read the content of
registers and variables you have selected in Watch Values at any time. If you want to
jump directly to breakpoints, use the Run/Pause Debugger command.

WATCH VALUES WINDOW

The software and harware debuggers have the same function to monitor the state of registers during program execution. The difference is
that the software debugger simulates the execution of the program on a PC, while the ICD debugger uses the microcontroller. Any change
of a pin logic state is reflected on the appropriate register (port). As the Watch Values window enables you to monitor the state of all
registers, it is easy to check whether a pin is set or cleared. The latest modifications appears in red in this window. This enables you to
easily locate modifications in the list file when debugging. Select View/Windows and click the Watch Values option to activate this window.
You can make a list of registers/variables the state of which you want to monitor.

STOPWATCH

If you want to find out how long it takes for the microcontroller to execute a part of the program, select the Run/View Stopwatch option. A
window, as shown in figure on the right, will appear. Do you know how the stopwatch works? Well, its as simple as that. The times (time
when the program has been started, time of the last step execution etc.) are automatically measured for each action of the debugger (step
into, step over, run/pause etc.) and displayed in the Stopwatch window.

IN-CIRCUIT DEBUGGER

Another way to check a program execution is by using mikroICD debugger (in-circuit


debugger). The mikroICD is an integral part of the PICflash programmer. It is used for
testing and debugging programs. The process of testing and debugging is performed
by monitoring the state of all registers within the microcontroller which operates in real
time. In order to enable debugging, it is necessary to select options Build Type-ICD
Debug and Debugger-mikroICD before the program is loaded into the microcontroller.
As soon as the mikroICD debugger starts up, a window, as shown in figure below,
appears. The mikroICD debugger communicates with the PIC through its pins used for
programming. Therefore, these pins cannot be used as I/O pins while the process of
debugging is in progress. During the mikroICD debugger operation, programmer and
PC have to be connected using a USB cable.

mikroICD debugger options:

Start Debugger [F9]


Run/Pause Debugger [F6]
Stop Debugger [Ctrl+F2]
Step Into [F7]
Step Over [F8]
Step Out [Ctrl+F8]
Toggle Breakpoint [F5]
Show/Hide Breakpoints [Shift+F4]
Clear Breakpoints [Ctrl+Shift+F4]

Each of these commands is activated via keyboard shortcuts or by clicking appropriate icon within the
Watch Values window.

The mikroICD debugger also offers options such as running a program step by step
(single stepping), pausing the program execution to examine the state of currently
active registers using breakpoints, tracking values of some variables etc. The following
example illustrates a step-by-step program execution using the Step Over command.

Step 1:

In this example the 31st program line is highlighted in blue, which means that it will be executed next. The current state of all registers within
the microontroller can be viewed in the mikroICD Watch Values window.

Step 2:

After the Step Over command [F8] is executed, the microcontroller will execute the 31st program line. The first next line (32nd) to be
executed is highlighted in blue. The state of registers being changed during the execution of this instruction may be viewed now in the
Watch Values window.

LOADING PROGRAM INTO THE MICROCONTROLLER


If you have fixed all errors in your code and you think the program is ready for use,
then you should load it into the microcontroller. Use the PICflash programmer for this
purpose. PICflash is a tool designed to program all types of PIC microcontrollers. It is
composed of two parts:

The hardware part buffers a hexadecimal file (the program to be loaded)


and programs the microcontroller using specific voltage levels. During the
process of programming, a new program is written into the

microcontrollers flash memory. The previous program will be


automatically erased from the flash memory.
The software part is in charge of sending program (.hex file) to the
hardware part of the programmer over a USB cable. It is activated by
clicking mE_Programmer from the Tools menu or by pressing [F11]. As a
result, you can modify some programming settings and also control the
operation of the programmers hardware (Load, Write, Verify...).

Note that you can re-program your microcontroller as many times as you wish.

COMPILERS TOOLS
This compiler provides special tools which considerably simplify the process of
program writing. All these tools are available from the Tools menu. Here is a brief
description for all of them.

USART TERMINAL

The USART terminal is a replacement for the standard Windows Hyper Terminal. It can be used for checking the operation of the
microcontroller which uses USART communication. Such microcontrollers are built into the target device and connected to the PCs RS-232
connector over a serial cable. The USART terminal window contains options for setting serial communication and displaying sent/received
data.

EEPROM EDITOR

By selecting the EEPROM Editor option from the Tools menu, a window, as shown in figure below, will appear. Here you can see how the
EEPROM memory of the microcontroller looks like. If you want to change its contents after loading the program into the microcontroller this
is the right way to do it. If a new content is a data of specific type (char, int or double), then you should select it, enter the value in the Edit
Value field and click Edit. Then click the Save button to save it as a document with the .hex extension. If the Use EEPROM in Project option
is active, the data will be automatically loaded into the microcontroller during the programming process.

ASCII CHART
If you need numerical representation of any ASCII character, just select the ASCII chart
option from the Tools menu and the table, as shown in figure below, will appear.

You probably know that every key of your keyboard is associated with one code
(ASCII). Numbers have strange equivalents. For this reason, the program instruction
for displaying number 7 on an LCD will not display it, but the equivalent of the BEL
instruction. If you send the same number as a character, you will get the expected
result - number 7. Accordingly, if you want to display a number without previously
converting it into appropriate character, then it is necessary to add number 48 to each
digit the number to be displayed consists of.

SEVEN SEGMENT EDITOR


A seven segment editor enables you to easily find out which number is necessary to be
set on an output port in order to display a desired symbol. Of course, it goes without
saying that port pins must be properly connected to display segments. You just have to
place the cursor on any display segment and click it. The number that you should enter
into the program will be shown immediately. Thats all.

LCD CUSTOM CHARACTER


In addition to the standard characters, the LCD display can also display characters
created by the programmer. By selecting the LCD custom character tool you will spare
yourself from tedious work of writing functions for sending appropriate code to a
display. Just create a symbol by clicking small squares in the LCD custom character
window, select position and row and click the GENERATE button. The appropriate
code appears in another window. No more clicks are needed. Copy to Clipboard Paste...

GRAPHIC LCD BITMAP GENERATOR


This is another necessary tool in case the microcontroller you are writing program for
uses graphic LCD display (GLCD). This tool enables you to display any bitmap easily.
In order to take advantage of it, select Tools/Glcd Bitmap Editor and appropriate
window appears. Select the type of display to be used and load a bitmap. The bitmap
must be monochromatic and in specified resolution (128 x 64 pixels in this case).
Further procedure is the same as in the example above. Copy to Clipboard...

Every code generated using tools for controlling LCD and GLCD displays contains
functions of the Lcd library. If you use them in the program, dont forget to check the

box next to this library in the Library Manager window so as to enable the compiler to
recognize these functions correctly.

LIBRARIES

One of the most useful features of the mikroBasic PRO for PIC compiler is the Library Manager and surely deserves our attention.
If you need a function or a procedure to perform certain task while writing a program, you just have to find it in one of the libraries included
into the compiler and use it. A library is actually a file called header. It contains a group of variables and functions written in mikroBasic.
Each library has a specific purpose. For example, if you need a procedure to generate an audio signal on some pin, open the Sound library
in the Library Manager window and double click the appropriate procedure Sound_Play. A detailed description of this procedure appears on
the screen. Copy it to your program and set appropriate parameters. If this library is checked, its functions will be retrieved during the
process of compiling and it will not be necessary to use the include directive.
The mikroBasic PRO for PIC includes miscellaneous and hardware specific libraries.

MISCELLANEOUS LIBRARIES
Miscellaneous libraries contain some of the general-purpose functions:
LIBRARY

DESCRIPTION

Button Library

Function eliminates the influence of contact button flickering

Conversions Library

Library routines for numerals to strings and BCD/decimal conversions

C Type Library

Library functions for testing and mapping characters

String Library

Library which automatizes string related tasks

Time Library

Time library routines usage for time calculations in UNIX time format

Trigon Library

Library functions for floating point math handling

HARDWARE SPECIFIC LIBRARIES


Hardware specific libraries include functions used to control the operation of hardware
modules:

LIBRARY

DESCRIPTION

ADC Library

Used for A/D converter operation

CAN Library

Used for operation with CAN module

CANSPI Library

Used for operation with external CAN module (MCP2515 or MCP2510)

Compact Flash Library

Used for operation with Compact Flash memory cards

EEPROM Library

Used for operation with built-in EEPROM memory

Ethernet PIC18FxxJ60 Library

Used for operation with built-in Ethernet module

Flash Memory Library

Used for operation with built-in Flash memory

Graphic Lcd Library

Used for operation with graphic LCD module with 128x64 resolution

IC Library

Used for operation with built-in serial communication module I2C

Keypad Library

Used for operation with keyboard (4x4 push buttons)

Lcd Library

Used for operation with LCD display (2x16 characters)

Manchester Code Library

Used for communication using Manchester code

Multi Media Card library

Used for operation with multimedia MMC flash cards

OneWire Library

Used for operation with circuits using One Wire serial communication

Port Expander Library

Used for operation with port expander MCP23S17

PS/2 Library

Used for operation with standard keyboard PS/2

PWM Library

Used for operation with built-in PWM module

RS-485 Library

Used for operation with modules using RS485 serial communication

Software IC Library

Used for I2C software simulation

Software SPI Library

Used for SPI software simulation

Software UART Library

Used for UART software simulation

Sound Library

Used for audio signal generation

SPI Library

Used for operation with built-in SPI module

SPI Ethernet Library

Used for SPI communication with ETHERNET module (ENC28J60)

SPI Graphic Lcd Library

Used for 4-bit SPI communication with graphic LCD display

SPI Lcd Library

Used for 4-bit SPI communication with LCD display (2x16 characters)

SPI Lcd8 Library

Used for 8-bit SPI communication with LCD display

SPI T6963C Graphic Lcd Library

Used for SPI communication with graphic LCD display

UART Library

Used for operation with built-in UART module

USB HID Library

Used for operation with built-in USB module

You might also like