Microcontroller Basics – A
Comprehensive Guide for
Beginners
By / / /
Sharing is Caring!
Do you think you can keep up with the innovations in
technology without using microcontrollers?
If your answer is a “BIG YES”, you are certainly going in the
wrong direction. Why?
Today, 17.6 billion devices around the world use
microcontrollers for consumer-targeted applications.
More importantly, this number is only going to increase
because of a rising trend in favor of microcontroller-based
IoT devices. Not Impressed? Let me put it in another
perspective.
A typical home in a developed country is likely to have 3
dozen microcontroller devices. Moreover, a mid-range
auto-mobile has about 30 microcontrollers.
Ranging from miniature devices (digital thermometers,
smartwatches, calculators, mobile phones, cameras) to
high-end consumer electronics (microwave ovens, washing
machines, televisions, refrigerators, vending machines), you
will almost always find a tiny microcontroller peeking at you
from the inside.
In 2019, the global microcontroller market size was valued at
$16.49 billion which is expected to hit $42.19 billion by
2027. Did that change your mind?
If no, my struggle will surely make you reconsider your
stance. Early on in my professional career, I tried to ignore
microcontrollers in about every aspect. Guess, what it got
me?
Three straight-off rejections during interviews for embedded
systems programmer. Another rejection for teaching
assistant position, where I was told “Your Electrical
Engineering is Weak!”. Well, you don’t want that? Or, do
you?
If you don’t want to end up like me, you need to start
learning about microcontrollers.
In this article, I will provide you with an ultimate Introduction
of Microcontroller Basics. This will help you get started with
microcontrollers right away.
Essentially, I will try to answer every question you may have
regarding the working of microcontrollers, such as:
What is a Microcontroller?
Components of Microcontroller
How Microcontroller Works?
Microcontroller Architecture
Microcontroller Peripherals
Difference between Microcontroller and Microprocessor
Microcontroller Applications
Disclaimer: I will be using exciting analogies and
interactive animations throughout the article, so you
won’t get bored. For those who think “Technology is
Boring Anyway”, try me and let me know of your
enjoyment score on a scale of 1-10.
Let’s get started then…
What is a Microcontroller
A “Microcontroller Unit” or “MCU” is an Integrated Circuit
(IC) that effectively controls electronic devices within a large
embedded system.
In simple terminology, a microcontroller takes input from a
user, processes the input signals, and then displays the
output as per the user demand.
A microcontroller is a combination of two words: “micro”
means small, and “controller” means an enhanced ability to
perform control functions.
This does not mean that you try to control your Spouse using
a microcontroller. Well, even if you do, don’t hold me
responsible for any repercussions.
Jokes apart, a microcontroller is a control device which
enables a friendly interaction between humans and
electronic devices.
You pour coffee ingredients in a coffee maker, and it helps
prepare a soothing coffee for you. With glucose meter, a
microcontroller helps analyse your blood glucose levels and
displays them on an LCD Display.
It helps thermostat in your Refrigerator to maintain a
freezing temperature. You can also set a timer on your
Washing Machines while doing your laundry. The
microcontroller also helps you capture, edit, and store
beautiful photos of your trips via Digital Cameras.
With microcontrollers, possibilities are endless. Most of the
time, you are using a microcontroller-driven device but you
are not fully aware of that. Now, how amazing is that!
Microcontroller Basics
Some of you may be thinking,” Why microcontrollers were
created when Personal Computers could have performed
such tasks with much better speed and accuracy?”
Your perspective is correct as far as the speed/accuracy
aspect is concerned. But look, here’s the thing…
You cannot deploy personal computers everywhere for
miniature tasks, simply because that would be too costly
and demand much greater space than a microcontroller
would, otherwise.
Your personal computer can run Word Editor, a Graphics
Design application, and a bunch of other resource-intensive
software, all at the same time.
But, why would you want to use such a powerful computer
only to detect your car and then open a simple garage door?
That would be a huge waste of computer resources, your
hard-earned money, and electrical power.
So, what’s the solution? Well, this is where Microcontrollers
say Hi to you!
Microcontrollers are highly application-oriented. You can
easily program a microcontroller to perform a dedicated task
for a specific application, that too at a reduced cost and
power requirements.
For a typical application, a personal computer would require
50 Watts. But a microcontroller can implement the same
task using merely 50 milliwatts. Does that ring any bells?
Moreover, a microcontroller can operate in extreme
conditions i.e., inside a hot car engine, in space satellites,
and chilly weather of Antarctica. Personal computers,
however, need to be ruggedized for such harsh
environments.
Microcontroller Components
Bus Bus
EEPROM/ DAC
Central Processing Unit (CPU)
FLASH
Arithmetic Logic Internal ADC
RAM Unit (ALU) Clock
Timers
External Crystal
Control Unit (CU) Registers
Oscillator (Clock) I/O Ports
Interrupt Controller EtherCAT
UART SPI I2C USB CAN
Schematic Diagram of Microcontroller Components (Copyrights: Embedded Robotics)
Until now, you must have understood the importance of
using a microcontroller within your next project. But we all
need to understand the technical aspects of anything we
intend to use, don’t we?
So, fasten your seatbelts now. I am going to dive into the
nitty-gritty details of the microcontroller.
Microcontroller Components
Until now, I hope that you have clearly understood ‘what is a
microcontroller’, and why do we even need microcontrollers
in the first place.
Now is the right time to tell you about the components which
combine to form a full-fledged microcontroller. And more
importantly, how microcontrollers process instructions given
by a human-user?
You cannot shout at the microcontrollers and say,” Fetch me
a glass of water”. Even your dog would not understand that
in true sense.
You need to talk to the microcontrollers in a language they
understand, THE BINARY LANGUAGE. Or more simply, the
language of ZEROs and ONEs.
In Binary language, one-bit can have two values (0 or 1). Two
bits can give you four values (0 to 3). Similarly, three bits can
take on eight values (0 to 7). Don’t you see a pattern
building up here?
Binary Decimal and Hexadecimal Representation for 1-4 Bits (Copyrights: Embedded
Robotics)
While binary instructions can help microcontrollers
understand the user-intentions, they still need some Data (in
binary form) to perform the desired operations.
The components of a microcontroller work in unison to
perform arithmetic (addition, subtraction, multiplication),
logical (OR, AND, XOR), shifting (left shift, right shift,
rotate), and move operations on Binary Data.
Let’s explore each of the individual microcontroller
components in great detail.
Memory
Once you have Instructions and Data, you need to store
them somewhere. Can you guess a place where you can
save them? Your cupboard maybe…
Don’t even think about that! Both the instructions and data
are in binary format, so you need a binary storage device.
In technical terms, such a device is called MEMORY.
The next question prevails, “How much data/instructions a
memory can store?”. Memory is divided into cells, and each
cell can store One Byte (8-bits). Moreover, the number of
Memory Address Lines depicts how much cells a memory
can have.
For example, a memory with one only address line can
address two cells (0,1) or store 2 bytes. Similarly, for two
address lines, there are 4 cells (0, 1, 2, 3) and storage of 4
bytes.
For three memory address lines, you can target 8 cells (0, 1,
2, 3, 4, 5, 6, 7) or store 8 bytes of data. If you are getting
along, you should be able to see another repetitive pattern.
Can you spot where have you seen such a pattern before?
Types of Memory
Three types of memories are commonly used in modern
microcontrollers. I am not going to discuss the old ones.
They are outdated anyway!
1. Random Access Memory (RAM)
2. Electrically Erasable Programmable Read-Only Memory
(EEPROM)
3. Flash Memory
Random Access Memory (RAM)
It is a volatile memory, which means it can only be accessed
when the system is powered-up. As the system power
shuts down, so do the contents inside the RAM.
It has a faster access time, but this is also expensive when
compared with the other ones. It is mainly used to store
temporary data, variables, and constants during the
execution of user instructions.
Due to the high cost and limited usage, the storage
capacity of RAM is less than EEPROM and Flash in most of
the modern-day microcontrollers.
Electrically Erasable Programmable Read-Only Memory
(EEPROM)
It is a non-volatile memory, which means that contents in
such a memory remain intact even when the power is
removed. You can program only one byte at a time in
EEPROM.
The main use of EEPROM in the microcontroller is to store
user instructions and data. The microcontroller then
accesses the instructions one-by-one and sequentially
executes them.
EEPROM needs to be programmed each time a user
changes the executable instructions. However, there is a
special circuitry needed for that.
Most of the manufacturers provide additional circuitry to
program EEPROM with the user instructions e.g., PICKIT3
Programmer for PIC Microcontrollers.
Flash Memory
Flash Memory is also non-volatile memory. Just like
EEPROM, it does not lose content when the power is
removed.
However, unlike EEPROM, it can only program a whole
sector or block of bytes. If you want to program a single
byte, you will have to program the whole memory sector.
Because of back and forth writing/erasing, flash memory
wears out more quickly than the EEPROM. That’s why Flash
memory is inexpensive as compared to EEPROM.
Some microcontroller manufacturers use either Flash or
EEPROM, while others use both to provide more flexibility to
the end-user.
Central Processing Unit (CPU)
CPU is a component of the microcontroller that fetches
instructions from the memory, decodes them, and then
executes them.
Whoa! Whoa! Stop! What is this Fetch, Decode, and
Execute? Are these the “Three Musketeers”?
Well, these are certainly not the musketeers. However, this is
what a CPU precisely does. I will explain the physical
interpretation of each term. But first, let me elaborate on the
major components which make up a CPU.
Control Unit (CU)
The main function of a control unit is to fetch and decode
the user instructions. The instructions are stored in
memory in the form of an ‘n-Bit’ stream. For an 8-bit
stream, 8 bits are stored in each cell of the memory.
For 16-bit instructions, two 8-bit streams are stored in the
consecutive cells of the memory.
8-Bit and 16-bit Instructions Stored in Memory (Copyrights: Embedded Robotics)
The first few bits depict the operation which is to be
performed i.e., addition, subtraction, multiplication, shifting,
rotation, and move, etc.
The remaining bits show the constants, or the memory
addresses for the data, or the memory store address.
Are you feeling overwhelmed? Yes? No? Please have some
faith in me.
I won’t leave you alone without providing a practical example
to easily understand all the concepts I have thrown at your
face.
I will use an instruction size of 8-bits. You need to
understand the concept, as it will remain the same for 16-bit
or even 32-bit instructions. Moreover, I will design my own
instruction set just for the sake of simplicity and obviously,
your understanding.
Here we go then!
Let’s suppose you want to design a microcontroller that can
perform four operations i.e., addition, subtraction, left shift,
and move.
Now you need a 2-bit opcode to define the four
instructions. Plus, each instruction needs two operands to
perform the desired operation.
Operands are the constants or the addresses of the
memory from where data is to be fetched. Each operand will
have a size of 3-bits in our case.
Now you can generalize the architecture of your 8-bit
instruction as:
Instruction: b7 b6 b5 b4 b3 b2 b1 b0
b2-b0: Source Operand
b5-b3: Destination Operand
b7-b6: Operation Code (or opcode)
Having defined the instruction architecture, you can define
custom instructions as:
00 – Add $a $b ($a = $a + $b): Add the value at memory
address ‘a’ and ‘b’. Store the result in memory address ‘a’
01 – Sub $a $b ($a = $a – $b): Subtract the value at
memory address ‘b’ from the value at memory address ‘a’.
Write the result in memory address ‘a’
10 – shl $a n ($a << n): Left-Shift the value at memory
address ‘a’ by n-bits. Write the result in memory address ‘a’
11 – mov $a $b ($a = $b): Copy the value located at
memory address ‘b’ to memory address ‘a’
Now I will explain some examples using the machine code
for our instructions set architecture. But, Wait…
Before I move forward, you have to promise me one thing.
You will not read the description of the machine codes
before you have tried hard enough to comprehend it
yourself. Promise? Ok, let’s dive in!
Question 1: What does the machine code ‘00011100’
means?
Answer 1: It means to add (remember the opcode ‘00’ for
add instruction) the numbers located at memory addresses
‘011’ and ‘100’. Later, the result should be stored in memory
address ‘011’
Easy-Peasy. Right? Let’s do another one…
Question 2: What does the machine code ‘01101001’
means?
Answer 2: It means to subtract (remember the opcode ‘01’
for sub instruction) the number located at memory
addresses ‘001’ from the number located at address ‘101’.
Later, the result should be stored in memory address ‘101’
I hope you are getting along! If not, you can throw in your
query in the comments section.
Time for the next one…
Question 3: What does the machine code ‘10111011’
means?
Answer 3: It means to left-shift (remember the opcode ‘10’
for shl instruction) the number located at memory addresses
‘111’ by 3 bits (‘011’). Later, the result should be stored in
memory address ‘111’
Now it’s your turn! Write the answer to the next question in
the comments:
Question 4: What does the machine code ‘11110111’ means?
Answer 4: I was not kidding. If you understand the concept,
please write the answer in the comments. Else, you can ask
me and I will personally reply to each and every one.
Whatever we have done in the last four examples is called
Decoding the Instructions.
Binary Instruction Decoding in a Microcontroller (Copyrights: Embedded Robotics)
Now, imagine the effort and amount of time you need to
decode 100,000 instructions like that? 5 hours? 10 hours?
Well, don’t get worried about that! You don’t need to do that,
as CPU has a dedicated Control Unit for this task.
But, Wait. If the Control unit can only fetch and decode the
instructions, who is going to perform the mathematical
operations? Is it again you who needs to get involved?
To get an answer, unlock the next sub-section. I am waiting
for you there…
Arithmetic Logic Unit (ALU)
The next component in the line of CPU operation is the
Arithmetic Logic Unit (ALU).
As the name implies, the basic task of an ALU is to perform
Arithmetic, Logic, Shifting, or other mathematical
operations as specified by the Instruction Set Architecture
of any microcontroller.
ALU precisely handles the “Instruction Execution”.
Control Unit fetches the instruction, decodes it, and then
sends appropriate commands to ALU about the desired
operation. ALU then executes the instruction, and stores the
result into memory.
So far, so good. I have discussed the CPU operation for a
single instruction. But what happens, when CPU has to deal
with a large number of instructions?
Instruction Pipelining
Instruction Pipelining is not a physical component in the
CPU. Rather, this is a concept to optimize the use of time
and the resources during Instruction Fetching, Decoding,
and Execution.
I have a question for you here. When the Control Unit is
fetching and decoding the instruction, what the ALU is doing
during that period? Also, when ALU is executing the
instruction, what the Control Unit is busy doing?
The answer to both of the questions is “NOTHING”. So, now
you have found the culprits who are using your time and
power but doing no useful work for almost half of the time.
What to do now? PIPELINE THEM! It means that the Control
Unit should fetch and start decoding the next instruction,
while ALU is busy executing the previous instruction.
By the time ALU executes the previous instruction, the
Control Unit should have decoded the next instruction. Now
control unit should pass this instruction over to ALU, and
fetch the next available instruction.
This cycle continues forever and reduces the instruction
execution time, a feature highly demanded by time-critical
applications.
Program Execution using Pipelined vs Non-Pipelined Architecture (Copyrights: Embedded
Robotics)
Stack
MCU Stack is a designated space in the memory used to
store the program status, as well as the return addresses
for Subroutine/Interrupt calls.
What is a Subroutine? It is a piece of code that is to be
executed by a program for a large number of times.
Rather than writing such code, again and again, it is written
for once and stored at a specific location in memory.
Whenever the program wants to use that code, it can go to
that specific location.
After executing the subroutine, the program jumps back to
the instruction which is sequentially next to the one that
called the subroutine.
What is an Interrupt? It is a diversion of the program from
normal execution flow due to external or internal
disturbances.
Each interrupt is satisfied using a specific Interrupt
Handler, which is again, a piece of code placed somewhere
into the memory.
Whenever an interrupt comes, the CPU disrupts the normal
program execution and starts executing the interrupt handler
to satisfy the interrupt requirements.
Once the interrupt handler terminates, CPU starts executing
the same instruction where it was interrupted.
For both the interrupt handler and the subroutine, the CPU
needs to go from the memory address of an instruction to
the memory address of the subroutine/interrupt handler.
But, how would a CPU know where to return once it has
entered the subroutine/interrupt handler? You need to store
the ‘Return Address’ somewhere in the memory. This is
where the mighty Stack comes in!
Stack works on a Last-In-First-Out (LIFO) scheme, which
means that the last pushed number will be the first one to
get popped out. Push means ‘Insert’. Pop means ‘Retrieve’.
Before starting the execution of any subroutine/interrupt
handler, CPU pushes the return address onto the stack.
Moreover, the last instruction in any subroutine/interrupt
handler pops the return address from the stack. This allows
the CPU to resume the normal program execution flow.
One critical point is that the CPU should push the return
address of the next instruction than the one, which is being
interrupted or calling the sub-routine. This will prevent an
infinite instruction execution loop.
You may be wondering “What is the need for a whole MCU
stack to store only the return address?”. Don’t Worry. You
will get the answer in the next sub-section.
Registers
Registers are temporary storage areas within a CPU. They
are used to store the information about the program flow,
program status, instruction results, and the hardware
configuration.
In most of the architectures, registers are merely 14-15 in
number. However, they are much faster to access than the
memory.
This is the single main reason why CPU prefers registers
over the memory for operations involving immediate data
access.
Microcontroller Registers with ARM Architecture (Copyrights: Embedded Robotics)
There are several types of registers which exist within a
CPU:
General Purpose Registers
These registers are used as source/destination operands
for arithmetic, logic, and shifting instructions
Stack Pointer
This register points to the section of the memory used for
the CPU hardware stack i.e., for subroutine/interrupt calls.
Stack Pointer always points to Top of the stack, which is also
the last pushed element onto the stack.
In a bottom-up stack (which increases in an upward
direction on element push), stack pointer gets incremented
first and then the element is pushed at the updated stack
pointer value.
For the pop operation, Top element is retrieved first and then
stack pointer gets decremented
Program Counter (PC)
This register stores the address of the next instruction,
which is to be executed by the CPU.
PC plays the most important rule during program execution
and guides the execution flow of the program.
During the normal program execution, PC gets incremented
to the address of the next instruction in a sequential manner.
For any subroutine/interrupt call, PC gets loaded with the
starting address of the subroutine/interrupt handler and
the return address for the next instruction is pushed onto the
stack.
While exiting out of the subroutine/interrupt handler, the last
instruction pops the return address from the stack into the
Program Counter. The CPU then starts executing the
instruction whose address gets loaded into PC.
Link Register (LR)
This register is not available in all of the microcontrollers.
However, its function is to store the return address of
subroutine/interrupt calls.
Remember! Earlier, CPU was saving the return address into a
stack. Now there is a register available for that.
But what happens when a subroutine is called within another
subroutine, or the same scenario occurs with an interrupt?
Now you also need to save your Link Register (LR) into the
stack, as LR will get updated with the new return address for
the nested subroutine/interrupt handler.
Once you get out of the nested subroutine, you need to pop
the value from stack into the LR. This will get you to the
starting point, the return address for the first sub-
routine/interrupt.
Special Function Registers
These registers are used for a specific configuration of the
hardware. More specifically, Status Flag Registers give
information about the hardware status.
For example, an interrupt status register sets a flag
whenever an interrupt occurs. This flag needs to be cleared
to be able to detect an interrupt from the same source again.
A zero-bit flag is set whenever a mathematical operation
result in a 0. This flag is used to compare the two operands
are equal or not.
The Carry-bit flag is set whenever the result of an operation
is larger than the allowed storage size.
For example, if you try to store a number greater than 255 in
an 8-bit storage area, the carry bit is set indicating that the
number is out-of-range.
Register Pushing onto Stack
Do you remember I promised you to answer one question in
this section? If no, I am repeating my question here:
“What is the need for a whole MCU stack to store only
the return address?”
After having learned about the registers, you are now well-
in-shape to understand this cheeky concept.
Stack does not only store the return address. It is also
needed to save Special Function Registers, Link Register,
and even general-purpose register at times.
Every sub-routine/interrupt handler tends to change the
Special Function Registers or flag status. Thus, it is
necessary to save the state of these registers into the stack
before entering the sub-routine/interrupt handler.
In the case of nested subroutines, Link Register gets
updated with the new value whenever a new sub-routine is
called. You need to store LR within the stack else you won’t
be able to return to the instruction which is called the first
instance of the sub-routine.
For the microcontroller architectures having no Link Register
(LR), the value of the Program Counter (PC) should be
stored in the stack whenever a subroutine or an interrupt
handler is invoked.
The general-purpose registers depict the status of a
program at any time. To preserve the status of the program
before any interrupt or subroutine, general-purpose registers
are pushed onto the stack and popped in reverse order
before the termination of interrupt handler or subroutine.
As Promised! Here is an interactive ANIMATION describing
the whole process:
Execution of a Program in Microcontroller with Nested Subroutines (Copyrights: Embedded
Robotics)
Clock
Before moving onto the clock signal, I want you to imagine a
scenario!
Let’s say you provided a bunch of instructions to CPU for
execution. You were happy and enthusiastic about that, but
then a strange thing happened!
CPU fetched instruction from memory and started executing
it. However, without executing the complete instruction, CPU
decided to fetch the next instruction. What will this
anomalous CPU behaviour leave you with?
A faulty or garbage result for the first instruction, which
tends to corrupt the whole program and ultimately the
complete embedded systems.
I am pretty sure; you wouldn’t want that! So, how you can
prevent this?
You need a Clock Signal which can synchronize each
activity of the CPU with a rising or falling edge.
Moreover, the frequency of the clock signal will specify the
execution period for each instruction. Higher the frequency,
lower the execution time.
And Boy oh Boy! Don’t we all want higher and higher
frequency…
I/O Ports
If you already know the data for your instruction, you can
feed that into the memory directly and you are good to go.
However, what will happen if you need to provide some
information about the environment during the program
execution?
Besides, what if you need to control some of the
environment variables or an external device?
The solution is simple. You need Input-Output ports in
microcontroller to read dynamic user-inputs, or to control
external devices.
For example, I/O Ports provide the user input data from
switches and keyboards to the CPU. Moreover, I/O Ports
output the desired information to the user by interfacing with
the LCD or LED display.
Each port in a microcontroller is programmable to be either
input/output. This provides a user with the flexibility to
program the I/O ports as per the application needs.
Bus
Now you have got all the components to execute your
instructions. All you need to do now is to connect all the
components using a Bus. This bus will establish a
communication link between different components.
There are three kinds of buses which are mostly used in
microcontrollers:
Instruction/Data Bus: This bus helps transfer
instructions/data back and forth into CPU and the memory
Address Bus: This bus specifies the address where the
desired instruction/data are located inside the memory
Control Bus: This bus specifies whether the
instructions/data are to be written or be fetched from the
memory
How Microcontroller Works
You are now aware of all the components which make up a
microcontroller, and their functions.
But how do all the components work in unison to execute
the instructions?
Or more simply, what happens when you have flashed your
code in the EEPROM and reset your microcontroller?
There are a series of steps that happen before even CPU
starts executing the first instruction of the user program.
Firstly, the microcontroller needs the know-how of the
address where the user instructions are stored within
EEPROM.
Luckily, there is a simple solution for that. On reset, the
microcontroller goes to a fixed memory location. This
memory location holds the actual address for the beginning
of the program code.
Compiler loads the Program Counter (PC) with the starting
address of the program code.
Control Unit (CU) fetches and decodes the instruction
pointed by the PC. ALU executes the instruction and stores
the result in the memory.
Meanwhile, PC gets updated with the address of the next-in-
line instruction. Control Unit then fetches the next
instruction, and the cycle goes on…
Repetitively, all the program instructions are fetched,
decoded, and executed as per the pipelined architecture.
Microcontroller Architecture
Most of the women believe that “All men are the same”. This
thinking, however, does not apply in the context of the
microcontrollers. Microcontrollers differ greatly based on
their architecture, which I am going to discuss further:
External Memory vs Embedded Memory
In the case of external memory microcontrollers, memory is
not interfaced within the microcontroller. Rather, the user
needs to connect an external memory to store
instructions/data.
For embedded memory microcontrollers, memory is
embedded inside the microcontroller.
If you are a beginner, embedded memory microcontrollers
are recommended since you will need a plug-and-play
approach to develop the desired application.
Instruction Set Architecture (ISA): RISC vs
CISC
RISC (Reduced Instruction Set Computer) has simplified
instructions, each of which takes one clock cycle to
execute. You need to write efficient software, as hardware in
RISC can only handle simple instructions.
CISC (Complex Instruction Set Architecture) has complex
instructions. Some of them may take one clock cycle, albeit
many will require multiple clock cycles. The hardware in
CISC is sophisticated enough to handle complex
instructions, so you won’t need to make any extra effort to
optimize your code.
Simply put, a CISC instruction may require multiple clock
cycles if executed on a RISC architecture. Besides, RISC
emphasizes software whereas CISC emphasizes
hardware.
Due to the execution of an instruction on each clock cycle,
RISC based microcontroller would also require more RAM as
compared to the CISC one.
Most of the modern-day microcontrollers employ RISC
Instruction Set Architecture. Besides, RISC has a successor
in RISC-V architecture, although it is not common in
commercial microcontrollers as of now.
Harvard vs Von. Neumann Architecture
In Harvard architecture, the microcontroller has separate
buses to access the instructions and data. Whereas, von
Neumann architecture has a common bus for both.
In simple terms, microcontrollers with Harvard architecture
can fetch data and instructions at the same time. However, in
von Neumann architecture, the microcontroller firstly fetches
instructions, and then the data.
This bottleneck in von Neumann architecture increases the
instruction execution time, and adversely affects the
overall system performance.
In Harvard architecture, memory address space is defined
for both the instructions and the data. So even if you have
some space available in the instruction region, you cannot
use that for the data and vice versa.
Difference between Harvard and Von Neumann Architecture (Copyrights: Embedded
Robotics)
Now, let’s evaluate the execution time of an ‘addition
operation’ for both the architectures.
In Harvard architecture, one clock cycle will be needed to
fetch both the instruction and data. The next clock cycle
would perform the addition operation. In the third clock
cycle, the data bus will store the result in memory whereas
the instruction bus will fetch the next instruction at the same
time.
In von Neumann architecture, two clock cycles will be used
to fetch the instruction and data. The third clock cycle will
see through the addition operation. The fourth clock cycle
will be used to store the data. Finally, the next instruction will
be fetched in the fifth clock cycle.
Now you can see for yourself, it took only three cycles in
Harvard architecture to execute an instruction and fetch
the next instruction. While von Neumann architecture took
five clock cycles for the same task.
Now imagine a scenario for tens of thousands of
instructions, and a cumulative delay caused by von
Neumann architecture.
That would be enough to convince you to adopt Harvard
Architecture, as most of the modern-day microcontroller
manufacturers already have.
Bit Configuration
As one shoe doesn’t fit all, so is the case with a
microcontroller for different applications. Microcontrollers
come in different bit configuration sizes i.e., 8-bit, 16-bit,
32-bit.
You may be wondering why so many configurations exist?
And why can’t we use a 32-bit microcontroller for all of the
applications? Let me explain this using a simple analogy.
Let’s say you are a team of 4 friends, and you all have
decided to visit Disney Land during summer vacations. You
have two choices for your ride: a car or an empty bus. Which
one would you pick?
I knew you would go for the bus. After all, you would be able
to sleep in the empty space. However, once you become
aware of the difference between the fare, you will certainly
prefer a car over an empty bus. I have excluded two kinds of
humans in my speculation: firstly BILLIONAIRES, and
secondly those with a fresh salary check!
The same concept applies to microcontrollers. If an 8-bit
microcontroller can fulfill the requirements of an
application, why would you want to use more costly and
more power-consuming 32-bit MCU? I mean, WHY?
And you won’t believe me, 90% of the applications can be
implemented with an 8-bit microcontroller. You will not need
16-bit or 32-bit MCU unless you intend to perform Digital
Signal Processing, Floating-Point Arithmetic, or other
resource-intensive tasks.
What is the physical, or technical interpretation of an n-bit
microcontroller?
An n-bit microcontroller simply means that the data bus is
‘n-bit’. This implies that we can store n-bits at a time in the
memory. Or, we can perform data manipulation up to a max
of n-bits during one clock cycle.
A 32-bit data manipulation will take 4 clock cycles on an 8-
bit microcontroller, whereas only 1 clock cycle on a 32-bit
microcontroller.
On the contrary, an 8-bit data manipulation will take one
clock cycle on either 8-bit/32-bit MCU. However, 32-bit
MCU will be more costly and consume more energy than the
8-bit counterpart.
Feeling confused? Let me elaborate with a practical
example…
Let’s suppose you need to add 100 and 150 on an 8-bit
microcontroller. How many clock cycles will be required?
Only one clock cycle, since 250 (100+150) is within the 8-
bit range (0…255).
However, if you want to add 200 and 250 using an 8-bit
MCU, you will require 2 clock cycles. The reason being 200
+ 250 = 450 is out-of-range for an 8-bit data (0-255) but
well within the range for 16-bit data (0-65535).
Now, tell me the number of clock cycles needed to add
‘60000’ and ‘10000’ in the comments…
Microcontroller Peripherals
Microcontrollers come with additional peripherals to develop
an interface with the external environment as well as to meet
the demands of the sophisticated applications.
These peripherals are add-on features for a microcontroller.
Some microcontrollers may have more of these features,
while others may have only two or three additional
peripherals.
It is you who is going to decide which features you need in a
microcontroller, considering the demands of the application
as well as the cost at which they are available.
Each peripheral of a microcontroller is sophisticated enough
to deserve a personal blog post. So, I am only going to
introduce each peripheral along with some of the possible
applications.
Timers/Counters:
As the name implies, this peripheral will induce the notion of
time within your system. A clock signal from an
external/internal crystal oscillator is used to ensure the
proper working of timers/counters.
Timers are used to introduce timer delays within your
program. For example, you can set a beep after every 1.5
seconds, or you can read the temperature sensor value after
every 5 minutes or so.
Counters are used to count external events. For example,
you may want to monitor how many times the user has
pressed a button in the last 5 seconds. You can also count
the number of bi-directional visitors passing through a
security gate within a window of 24 hours.
A most important feature of timers is the generation of Pulse
Width Modulation (PWM) signals. PWM signals are widely
used for motor control in robotic applications.
PWM is a square wave signal with a specified duty cycle and
frequency. The duty cycle means the ratio of signal ON-
Time to OFF-Time.
Duty Cycle = (ON Time/Off Time) * 100
Let’s suppose you have a PWM signal that is varying
between 0 and 5 volts. With a 20% Duty cycle, you will get 1
Volt. With 80% Duty Cycle, you will get 4 volts.
Pulse Width Modulation for different Duty Cycles (Copyrights: Embedded Robotics)
Thus, you can get different voltage at the output just by
varying the duty cycle of a PWM signal. Can you tell me how
much duty cycle you need to get 3 volts at the output? Over
to the comments section…
Communication Interfaces
Have you ever transferred any data from your mobile phone
to a desktop computer? Okay, so which communication
interface did you use?
Everybody knows it! USB or Universal Serial Bus. But do you
know that USB is not the only communication protocol?
Your desktop computer only has USB ports because it can
only interface with the USB hosts. However, the same is not
the case with a microcontroller.
The microcontroller needs to interface with all kinds of
devices, which have come to existence since the dark ages.
As the electronic devices are getting sophisticated with the
advent of technology, so are their communication interfaces.
The most important feature of a communication protocol is
its high speed and reliability during data transfer. Nobody
wants to lose their data. Right?
Many reliable and fast data communication protocols came
into existence. However, after recurring trials and testing,
there remain only a few which have won the trust of the
developers.
The most prominent of them are serial communication
protocols such as:
Universal Asynchronous Receiver Transmitter (UART)
Universal Synchronous Asynchronous Receiver
Transmitter (USART)
Serial Peripheral Interface (SPI)
Inter-Integrated Circuit (I2C)
Universal Serial Bus (USB)
Because of the never-ending demand for high speed and
reliable communication, we are inching towards Bus
Communication. There are two dominant protocols in this
domain:
Control Area Network (CAN) Bus
Ethernet for Control and Automation Technology
(EtherCAT)
Analog-to-Digital Converter (ADC)
All the sensors having either Serial or Bus Communication
Interface produce their output in a digital form. It means
that their output voltage is either at logic level ‘Low’ or logic
level ‘High’.
An output in such form is readily accepted by the
communication interfaces embedded within the
microcontroller.
However, there are some sensors whose output follows the
analog format. In other words, their output voltage varies
between the two levels.
Any such sensor could produce an output voltage of 1.3V, or
2.98V, or 4.78V. Such irregular output voltage is not
comprehended by the digital communication interfaces.
Ok. Fine. So, there must exist an analog communication
interface for analog data?
Believe me. That will be of no use because CPU also can’t
understand the analog voltage signals. What is the solution,
then?
An analog-to-digital converter is your best buddy for this
task. ADC takes analog inputs and converts them to digital
values. These digital values are then fed into CPU for further
processing.
If you have a 10-bit ADC, you will be able to convert analog
voltage (0-5 volts) to a digital value in the range of 0-1023.
A value of 0 volts will be equal to ‘0’, and a value of 5 volts
will be equal to ‘1023’ in the digital format. All the
intermediate values will have relative digital counterparts as
indicated by the formulae:
Digital Value = (Analog Voltage/5) * 1023
In a 16-bit ADC, you will be able to convert the analog
voltage into a digital range of 0-65535. So, you have more
precision and more control. In this case, formulae for digital
conversion will be:
Digital Value = (Analog Voltage/5) * 65535
Analog to Digital Converter (Image Source: DOEET)
Digital-to-Analog Converter (DAC)
Digital-to-Analog Converter (DAC) is a reciprocal of ADC.
DAC converts digital pulses into analog signals.
It finds applications for the devices which are controlled
using analog voltage.
As the microcontroller can only output digital values, you
need DAC to convert the digital values into analog voltage
signals.
For a 10-bit DAC, you can convert a digital value in the
range of 0-1023 to analog voltage signal from 0 – 5 volts.
The digital value of ‘0’ will correspond to 0 volts, and ‘1023’
will correspond to 5 volts as per the formulae:
Analog Voltage = (Digital Value/1023) * 5
For a 16-bit DAC, you can convert a high range of digital
values (0-65535) to an analog voltage in the range of 0-5
volts:
Analog Voltage = (Digital Value/65535) * 5
Digital to Analog Converter (Image Source: NUTAQ)
Interrupt Controllers
You may remember that we have already talked about
interrupt handlers in the context of MCU Stack. But what is
an interrupt controller?
You first need to be crystal clear about the interrupt handler.
Simply put, an Interrupt Handler is a piece of a program,
which is executed whenever an interrupt comes.
Interrupts caused by any external hardware are called
Hardware Interrupts. While interrupts happening internally
in the software are called Software Interrupts.
An example of a hardware interrupt is an interrupt due to
push button state change i.e., whenever a user presses a
push-button or releases it.
Software interrupt could be caused by an internal timer i.e.,
after each 1 sec, timer generates an interrupt.
There is also another type of interrupt called Exception.
Exceptions are the software interrupts caused by the
system-level programs rather than user-level programs.
Each peripheral in a microcontroller has its interrupt handler.
For example, Port A will have its interrupt handler. Timer0 will
have its interrupt handler. Timer1 will also have a unique
interrupt handler. I hope you are getting the point!
Whenever a software or hardware interrupt is caused by a
peripheral, the corresponding interrupt handler is executed.
You can write instructions in an interrupt handler, and your
instructions will execute whenever that same interrupt
handler is invoked.
Let’s say you want to toggle the output state of Port A after
each second. What will you do?
You will set a Timer0 to generate an interrupt after every
second. Then, you will go to the Timer0 Interrupt handler
and insert your application-specific instructions in that
handler i.e., toggle the state of Port A.
So far so good. But what role does Interrupt Controller play
in all this? Is Interrupt Controller just a fancy name for
‘Interrupt Handler’?
No, No! Wait, let me explain…
As there are a large number of interrupt handlers, they are
stored in NVIC (Nested Vectored Interrupt Controller). Now,
what the hell is this NVIC?
NVIC stores the starting address of each interrupt handler in
a vector-like format within the memory.
Whenever an interrupt occurs, THE “Interrupt Controller”
firstly detects the peripheral which has caused the interrupt.
In the second step, the interrupt controller fetches the
starting address of the corresponding interrupt handler from
the NVIC.
In the third step, the interrupt controller loads the Program
Counter (PC) with the address of the interrupt handler. CPU
then starts executing the interrupt handler, while the
Interrupt controller goes back to listen for more interrupts.
Nested Vector Interrupt Controller Mapping onto Interrupt Handlers (Copyrights:
Embedded Robotics)
Difference between Microcontroller and
Microprocessor
This is the topic that confuses almost 3/4th of the people,
who try to get their basics right about the microcontrollers.
Most of them get confused because they don’t understand
the microcontroller and its working principle. But you are not
like them!
You have now read almost 7000 words about the basics of
microcontroller, and understand microcontrollers from every
nook and angle. Understanding the difference between
microcontrollers and microprocessors is going to be a
piece of cake for you!
Do you remember all the components of a microcontroller
i.e., CPU, I/O Ports, Memory, Bus, and Clock? Also, do you
remember the additional peripherals that come embedded
into the microcontroller?
What if I remove all the components and peripherals from a
microcontroller except the CPU? What will you get then?
A Microprocessor!
How simple was that! I bet you did not have any problems
understanding that. People, however, make a mess of this
because they don’t comprehend microcontrollers in true
sense.
Simply put, a microprocessor is essentially a CPU with no
memory/peripherals attached. You need to interface the
memory as well as the other components/peripherals
externally.
With a microprocessor, you need to get some homework
done before you can even get the simplest of the
applications up and running.
On the contrary, a microcontroller is a ready-to-use unit. It
has all the memories, components, and peripherals
embedded inside a single chip. You only need to burn
EEPROM with the instructions and you are good to go!
But why do microprocessors even exist?
Although microcontrollers come with an embedded
memory inside, the memory is only enough to implement
low-profile applications.
What if you want to execute resource-intensive applications
such as Graphics, 3D Modelling, Android/IOS App
development? A more extreme case would be to run all such
applications at a single time.
Can a microcontroller perform such an intensive task?
Maybe, yes. However, due to the limited memory and CPU
computational power, it will take ages.
But we don’t want that? So, what is the solution?
Again. A Microprocessor!
A microprocessor essentially comes with high
computational power. Besides, you can interface large
memories with the microprocessor, making it an ideal
candidate for resource-intensive applications.
Another selling point of the microprocessor is its ability to
execute a myriad of resource-intensive applications at the
same time. This is the main reason why your desktop/laptop
computers come with a processor rather than a
microcontroller.
Microcontroller Applications
By now, you should have a fair idea of the applications which
can be implemented with the help of a microcontroller.
I have also mentioned many such applications within the
entire article. However, to give you an extra boost, I am
sharing some more:
Baby Monitors
Fire Detection
Internet of Things
Home Automation
Light Sensing
LED Control
Low-Cost Wearables
Medical Equipment
Sub-Marines
Ships
Aerospace System
and many more…
This list will never end, even If I continued to write for the
next three days.
I am calling it a day here. However, it’s time for you to take
some action!
Assignment: Think of 20 devices that you can develop with
the microcontrollers. Once you have done that, share them
with me via email. In return, I will share them on the social
media pages so that others can also benefit from your
knowledge. Awaiting your answers!
And, please. Don’t forget to share this amazing article with
your friends, colleagues, and even your stubborn Boss. You
may get a promotion for doing that!
Sharing is Caring!