Lite
Lite
LITE/JA1/08
LITE/J21/08
LITE/DN1/08
Basics of Embedded
1.1 INTRODUCTION
1.2. RESISTOR
1.2.1 Introduction
1.2.2 Types of Resistors
1.3 CAPACITOR
1.3.1 Introduction
1.3.2 Types of capacitors
1.4 DIODES
1.4.1 Introduction
1.4.2 Types of Diodes
1.5. TRANSISTOR
1.5.1 Introduction
1.5.2 Commercial Type of Transistors
1.6. INTEGRATED CIRCUITS
1.6.1 Introduction
1.6.2 Types of IC’s
1.7 RELAY
1.7.1 Introduction
1.7.2 Application
1.7.3 Operation
1.8 RF-TRANSCEIVER
1.8.1 RF-TRANSMITTER
1.8.2 RF Receiver
FUNDAMENTAL CONCEPT OF C LEVEL 2
2.1 INTRODUCTION
2.2 C KEYWORDS
2.3 DATA TYPE
2.4 VARIABLE
2.4.1 Extern
.4.2 Static
2.4.3 Auto
2.4.4 Register
2.5 Constant
2.6 Operators
2.6.1 Arithmetic:
2.6.2 Assignment
2.6.3 Logical/Relational
2.6.4 Bitwise
2.7 Statements
2.7.1. If Statement
2.7.2. IF Else Statement
2.8 MULTI WAY STATEMENTS
2.8.1. Switch
2.9 Loop Control Structure
6.3 Shifts
6.3.1 Relation of Shifts and Division and Multiplication
6.3.2 Arithmetic Shifts
6.4 Rotates
6.4.1 Synthesizing Multiplication Using Shifts and Additions
6.5 data transfer
6.5.1 data transfer instructions- Internal
6.5.2 data transfer instructions-External
6.6 Ram
6.6.1 EXTERNAL CODE MEMORY
6.6.2 EXTERNAL RAM DATA MEMORY
6.6.3 INTERNAL MEMORY
6.7 Port register SFR
6.8 PSW, Program Status Word
6.9 Stack Pointer
6.10 Data Pointer
6.11 accumulator
6.12 Program Counter
6.13 SFR register for the Internal Timer
6.14 Power Control register
6.15 serial register port
6.16 Interrupts registers
6.17 ROM
6.18 Hybrid Memory
6.19 Summary
CHAPTER -1
BASIC ELECTRONICS
You can able to know different types of electronic components and its
functions.
You can able to handle the circuit components effectively.
1.1 INTRODUCTION
Passive components are those that do not have gain or directionality. In the Electric
industry they are called Electrical elements or electrical components.
Active components are those that have gain or directionality, in contrast to passive
components, which have neither.
1.2. RESISTOR
1.2.1 Introduction
Resistance value is designated in units called the "Ohm." A 1000 Ohm resistor is typically
shown as 1K-Ohm (kilo Ohm) and 1000 K-Ohms is written as 1M-Ohm (megohm).
There are two classes of resistors: Fixed resistors and variable resistors. They are
also classified according to the material from which they are made. The typical resistor is
made of either carbon film or metal film. There are other types as well, but these are the most
common.
a) Fixed Resistors
A fixed resistor is one in which the value of its resistance cannot change.
ROUGH SIZE
Rating power Thickness Length
From the top of the photograph (W) (mm) (mm)
1/8 2 3
1/8W
1/4W 1/4 2 6
1/2W
1/2 3 9
This is the most general purpose, cheap resistor. Usually the tolerance of the
resistance value is ±5%. Power ratings of 1/8W, 1/4W and 1/2W are frequently used.
Carbon film resistors have a disadvantage; they tend to be electrically noisy. Metal film
resistors are recommended for use in analog circuits
.
This resistor is called a Single-In-Line (SIL) resistor network. It is made with many
resistors of the same value, all in one package. One side of each resistor is connected with
one side of all the other resistors inside.
b) Variable Resistors
There are two general ways in which variable resistors are used. One is the variable
resistor which value is easily changed, like the volume adjustment of Radio. The other is
semi-fixed resistor that is not meant to be adjusted by anyone but a technician. It is used to
adjust the operating condition of the circuit by the technician. Semi-fixed resistors are used to
compensate for the inaccuracies of the resistors, and to fine-tune a circuit. The rotation angle
of the variable resistor is usually about 300 degrees. Some variable resistors must be turned
many times to use the whole range of resistance they offer. This allows for very precise
adjustments of their value. These are called "Potentiometers" or "Trimmer Potentiometers."
The variable resistor typically used for volume controls can be seen on the far right. Its
value is very easy to adjust. The four resistors at the center of the photograph are the semi-
fixed type. These ones are mounted on the printed circuit board.
1.3 CAPACITOR
1.3.1 Introduction
The capacitor's function is to store electricity, or electrical energy. The capacitor also
functions as a filter, passing alternating current (AC) and blocking direct current (DC).
This symbol is used to indicate a capacitor in a circuit diagram.
The capacitor is constructed with two electrode plates facing each other, but separated
by an insulator. When DC voltage is applied to the capacitor an electric charge is stored on
each electrode. While the capacitor is charging up current flows. The current will stop
flowing when the capacitor has fully charged. The value of a capacitor (the capacitance) is
designated in units called the Farad (F).
a) Electrolytic Capacitors
Aluminum is used for the electrodes by using a thin oxidization membrane. Large
values of capacitance can obtained in comparison with the size of the capacitor, because the
dielectric used is very thin. The most important characteristic of electrolytic capacitors is that
they have polarity. They have a positive and a negative electrode [Polarized]. This means that
it is very important in which way round they are connected. If the capacitor is subject to
voltage exceeding its working voltage, or if it has connected with incorrect polarity, it may
burst. It is extremely dangerous, because it can quite literally explode. Make absolutely no
mistakes. Generally, in the circuit diagram, the positive side is indicated by a "+" (plus)
symbol. Electrolytic capacitors range in value from about 1µF to thousands of µF. These
types of capacitors are use as a ripple filter in a power supply circuit, or as a filter to bypass
low frequency signals, etc. Because this type of capacitor is comparatively similar to the
nature of a coil in construction, it is not possible to use for high-frequency circuits.
b) Ceramic Capacitors
c) Variable Capacitors
One of the component's lead is connected to the adjustment screw of the capacitor.
This means that the value of the capacitor can be affected by the capacitance of the
screwdriver in your hand. It is better to use a special screwdriver to adjust these components.
1.4 DIODES
1.4.1 Introduction
In electronics, a diode is a two-terminal device (except that harmonic diodes may also
have one or two ancillary terminals for a heater). Diodes have two active electrodes between
which the signal of interest may flow, and most of them are used for their unidirectional
current property. The varicap diode is used as an electrically adjustable capacitor.
The directionality of current flow which most diodes exhibit is sometimes generically
called the rectifying property. The most common function of a diode is to allow an electric
current to pass in one direction (called the forward biased condition) and to block it in the
opposite direction (the reverse biased condition). Thus the diode can be thought of as an
electronic version of a check valve. Real diodes do not display such a perfect on-off
directionality but have a more complex non-linear electrical characteristic, which depends on
the particular type of diode technology. Diodes also have many other functions in which they
are not designed to operate in this on-off manner.
This symbol is used to indicate a diode in a circuit diagram. The meaning of the
symbol is (Anode) (Cathode).Current flows from the anode side to the cathode side.
Light emitting diodes must be chosen according to how they will be used, because
there are various kinds. The diodes are available in several colors. The most common colors
are red and green, but there are even blue ones. The device on the far right in the photograph
combines a red LED and green LED in one package. The component lead in the middle is
common to both LEDs. As for the remaining two leads, one side is for the green, the other for
the red LED. When both are turned on simultaneously, it becomes orange.
When an LED is new out of the package, the polarity of the device can be determined
by looking at the leads. The longer lead is the Anode side, and the short one is the Cathode
side. The polarity of an LED can also be determined using a resistance meter, or even a 1.5 V
battery.
When using a test meter to determine polarity, set the meter to a low resistance
measurement range. Connect the probes of the meter to the LED. If the polarity is correct, the
LED will glow. If the LED does not glow, switch the meter probes to the opposite leads on
the LED.
1.5. TRANSISTOR
1.5.1 Introduction
a) SL100
Bipolar transistors are composed of three segments called "Collector," "Base," and
"Emitter," and there is a thin insulating layer between Base and Emitter. If a voltage of the
correct polarity is applied to the Base and Emitter terminals, the insulating layer becomes so
thin that it behaves as a conductor. If this voltage polarity is reversed, the insulating layer
becomes wide. By changing the thickness of this insulating layer, the BJT behaves as a
voltage-controlled valve or switch. Whenever the Base-Emitter voltage is causing the
insulator layer to become thinner, there occurs a leakage current in the base terminal. This
tiny current is proportional to any larger current passing through the entire transistor.
Although the BJT is controlled by the voltage between Base and Emitter, designers usually
ignore the base-emitter voltage, and the BJT is treated as a current-controlled valve or switch.
All transistors are made of a "doped" semiconductor, typically silicon. Pure silicon
contains few movable charges, so it behaves as an insulator. In the silicon crystal impurities
are deliberately introduced during manufacturing process. Each impurity atom will produce a
movable charged particle in the silicon, which changes the silicon into a conductor. Doped
silicon is very different than metal conductors. The charges within metals behave like a dense
liquid, while the charges in doped silicon behave as a highly compressible gas. Doped
semiconductor is a special kind of conductor where an applied voltage can easily "compress"
or sweep the charges away. By sweeping the charges away, the semiconductor is changed
from a conductor to an insulator. Semiconductors are like electric switches, but with no
moving parts.
1.6.1 Introduction
An integrated circuit contains transistors, capacitors, resistors and other parts packed
with high density on one chip. Although the function is similar to a circuit made with
separate components.The internal structure of the components are different in an integrated
circuit. The transistors, resistors, and capacitors are formed very small, and in high density on
a foundation of silicon. They are formed by a variation of printing technology. There are
different kind of ICs, including special use ICs.
There are lot of IC packages. They are DIP (Dual In - line Package), SOP (Smart
Outline Package) etc. The most commonly used package is DIP. The following figure shows
the typical value of IC, Pin diagram, Operating voltage and Operating temperature and
Operating Current.
Specifications
Name Function Vcc Pin Assign(Top View)
On the right is a 7805. The output voltage is +5V, and maximum output current is 500mA to
1A. (It depends on the heat sink used)
The maximum input voltage is also +35V.
ADC 0809
1.7 RELAY
1.7.1 Introduction
A relay is an electrical switch that opens and closes under the control of another electrical
circuit. In the original form, the switch is operated by an electromagnet to open or close one
or many sets of contacts. It was invented by Joseph Henry in 1835. Because a relay is able to
control an output circuit of higher power than the input circuit, it can be considered to be, in a
broad sense, a form of an electrical amplifier.
• DPDT - Double Pole Double Throw. These have two rows of change-over terminals.
Equivalent to two SPDT switches or relays actuated by a single coil. Such a relay has
eight terminals, including the coil.
1.7.2 Application
The above figure shows the relay controlling method using NPN transistor. Here we
are applying 12V supply at one end of the relay coil. Other end of the relay coil is connected
with transistor collector. When input of the transistor base is low, the collector output is high.
During that period the relay will be in OFF condition. If transistor base is high, the collector
output is low. The relay is energized and then the relay will be in ON condition.
The relay controlling method using PNP transistor is shown in above figure. The free
wheeling diode is connected across the relay coil. It is used to protect the circuit from return
voltage in relay coil.
The above figure shows the relay driver using ULN 2003. The input pins from 1 to 7
are connected with microcontroller. Output pins are connected with relay coil. If input is high
the output will be low. Therefore the relay is energized. If input pins are low the output will
be high.
1.8 RF-TRANSCEIVER
1.8.1 RF-TRANSMITTER
Introduction
TWS-434 and RWS-434 are extremely small, and are excellent for applications
requiring short-range RF remote controls. The transmitter module is only 1/3 the size of a
standard postage stamp, and can easily be placed inside a small plastic enclosure.
Types of Transmitter
a) TWS-434
b) TWS-434A
The TWS-434 transmitter accepts both linear and digital inputs can operate from 1.5
to 12 Volts-DC, and makes building a miniature hand-held RF transmitter very easy. The
TWS-434 is approximately the size of a standard postage stamp.
The sample transmitter circuit is shown in above. We can choose any one from 00 to
FF as the address line. The TE pin must be low while transmitting the RF signal. HT 12E has
4 bit data line.
1.8.2 RF Receiver
Rws-434
The receiver also operates at 433.92MHz, and has a sensitivity of 3uV. The RWS-
434 receiver operates from 4.5 to 5.5 volts-DC, and has both linear and digital outputs.
RWS-434 Receiver
Note: For maximum range, the recommended antenna should be approximately 35cm long.
To convert from centimeters to inches -- multiply by 0.3937. For 35cm, the length in inches
will be approximately 35cm x 0.3937 = 13.7795 inches long. We tested these modules using
a 14", solid, 24 gauge hobby type wire, and reached a range of over 400 foot.
Description
Here we are using HT12 D decoder. It has 8 bit address line and 4 bit data line. The
data line is connected with the microcontroller. The VT (Valid Transmission) will be set
when transmitting the RF signal. The 8 bit address line must be same as the address line on
the encoder.
Summary
The electronic elements can be classified into active and passive elements.
A fixed resistor is one in which the value of its resistance cannot change.
A variable resistor is one in which the value of its resistance can change.
HT12E and HT12D have 8 bit address line and 4 bit data line.
The TE pin on the encoder should be low when transmitting the signal.
Technical Questions
CHAPTER 2
FUNDAMENTAL CONCEPT OF C
We have to briefly discuss about the Basic Essential Concepts in C Language such
as some important concepts of this language.
There are Data Types, Variables, Operators, Statements, Arrays, Strings, Pointers
and Linked List.
You have to work with some Sample Examples of the above events.
We have to work with all the events in separate example.
2.1 INTRODUCTION
C Programming/Why learns C?
C is the most commonly used programming language for writing operating systems.
UNIX was the first operating system written in C. Later Microsoft Windows, Mac OS X, and
GNU/Linux were all written in C. Operating systems run directly on top of the hardware --
there is no lower layer to mediate their requests with the except of the C compiler, which is
assembly language.
Not only is C the language of operating systems, it is the precursor and inspiration for
almost all of the most popular high-level languages available today. In fact, Perl, PHP,
Python, and Ruby are all written in C!
By way of analogy, let's say that you were going to be learning Spanish, Italian,
French, or English. Do you think knowing Latin would be helpful? In the same way, knowing
C will enable you to understand and appreciate an entire family of programming languages
built upon the traditions of C. Knowledge of C enables freedom.
2.2 C KEYWORDS
The definition of a variable will assign storage for the variable and define the type of
data that will be held in the location.
{
int Count;
Count = 5;
}
{
float Miles;
Miles = 5.6;
}
{
double Atoms;
Atoms = 2500000;
}
{
char Letter;
Letter = 'x';
}
2.4 VARIABLES
The scope of the variable (where it can be used), is determined by where it is defined.
If it is defined outside any block or list of parameters, then it has file scope. This means it
may be accessed anywhere in the current source code file. This is normally called a global
variable and is normally defined at the top of the source code. All other types of variables are
local variables. If a variable is defined in a block (encapsulated with {and}), then its scope
begins when the variable is defined and ends when it hits the terminating}. This is called
block scope. If the variable is defined in a function prototype, then the variable may only be
accessed in that function. This is called function prototype scope.
Access to variables outside of their file scope can be made by using linkage. Linkage
is done by placing the keyword extern prior to a variable declaration. This allows a variable
that is defined in another source code file to be accessed.
Variables defined within a function scope have automatic storage duration. The life of
the variable is determined by the life of the function. Space is allocated at the beginning of
the function and terminated at the end of the function. Static storage duration can be obtained
by placing the keyword static in front of the variable declaration. This causes the variable's
space to be allocated when the program starts up and is kept during the life of the program.
The value of the variable is preserved during subsequent calls to the function that defines it.
Variables with file scope are automatically static variables.
2.4.1 Extern
Indicates that the variable is defined outside of the current file. This brings the
variables scope into the current scope. No variable is actually created by this.
2.4.2 Static
2.4.3 Auto
2.4.4 Register
Requests that the variable be accessed as quickly as possible. This request is not
guaranteed. Normally, the variable's value is kept within a CPU register for maximum speed.
2.5 CONSTANT
The const keyword is used to create a read only variable. Once initialized, the value
of the variable cannot be changed but can be used just like any other variable.
Const syntax
main()
{ const float pi = 3.14;
}
The const keyword is used as a qualifier to the following data types - int float char double
struct.
2.6 OPERATORS
Operators are used with operands to build expressions. For example the following
is an expression containing two operands and one operator.
4+5
The order (precedence) that operators are evaluated can be seen here.
2.6.1 Arithmetic:
+
-
/
*
% Modulo
-- Decrement (post and pre)
++ Increment (post and pre)
2.6.2 Assignment
These all perform an arithmetic operation on the lvalue and assign the result to the
lvalue. So what does this mean in English? Here is an example:
Counter = counter + 1;
Can be reduced to
Counter += 1;
Here is the full set.
=
*= Multiply
/= Divide.
%= Modulus.
+= add.
-= Subtract.
<<= left shift.
>>= Right shift.
&= Bitwise AND.
^= bitwise exclusive OR (XOR).
|= bitwise inclusive OR.
2.6.3 Logical/Relational
== Equal to
!= Not equal to
>
<
>=
<=
&& Logical AND
|| Logical OR
! Logical NOT
2.6.4 Bitwise
& AND (Binary operator)
| Inclusive OR
^ Exclusive OR
<< Shift left. C ++ use of <<
>> shift right. C ++ use of >>
~ one's complement
Sizeof () size of objects and data types.
Strlen may also be of interest.
& Address of (Unary operator)
2.7 STATEMENTS
Control Structures
There are two types of Control Structure statements used in the C Language.
Conditional Statements
• Decision Control Structures
• Loop Control Structures
Unconditional Statements
Control Statements
Decision Control Structure is used to execute the set of conditions. If the condition will
be true the first statement is executed otherwise the else block statement will be executed.
There are two styles of Control Statements are used in this Decision Structure.
Single Way Statement
Multi Way Statement
2.7.1. If Statement
Or
If (expression) statement1;
Else statement2;
If (loop<3) counter++;
If(x==y)
X++;
Else
Y++;
If (z>x)
{
z=5;
x=3;
}
Else
{
z=3;
x=5;
}
2.8.1. Switch
Syntax:
Switch (variable)
{
Case const:
Statements...;
Default:
Statements...;
}
Examples
Switch (Betty)
{
Case 1:
Printf ("Betty=1\n");
Case 2:
Printf ("Betty=2\n");
Break;
Case 3:
Printf ("Betty=3\n");
Break;
Default:
Printf ("Not sure.\n");
Examples
While (counter<5)
{
Printf ("counter=%I”, counter);
Counter++;
}
Syntax:
For (expression1; expression2; expression3) statement...
Expression1 is evaluated before the first iteration. After each iteration, expression 3 is
evaluated. Both expression1 and expression3 may be omitted. If expression2 is omitted, it is
assumed to be 1. Statement is executed repeatedly until the value of expression2 is 0. The test
on expression2 occurs before each execution of statement.
Examples
For (loop=0; loop<1000; loop++)
Printf ("%i\n", loop);
Prints numbers 0 through 999.
For(x=3, y=5; x<100+y; x++, y--)
{
Printf ("%i\n", x);
Some function ();
}
Prints numbers 3 through 53. Some function is called 51 times.
Syntax
Examples
do {
betty++;
printf ("%i", betty);
} while (betty<100);
2.10.1. Goto
The goto statement transfers program execution to some label within the program.
Syntax
Goto label;
....
Label:
Examples
goto skip_point;
printf ("This part was skipped.\n");
skip_point:
printf ("Hi there! \n");
Only the text "Hi there!" is printed.
2.10.2. Continue
The continue statement can only appear in a loop body. It causes the rest of the
statement body in the loop to be skipped.
Syntax
Continue;
Examples:
For (loop=0; loop<100; loop++)
{
if (loop==50)
Continue;
Printf ("%i\n", loop);
}
The numbers 0 through 99 are printed except for 50.
Joe=0;
While (Joe<1000)
{
For (zip=0; zip<100; zip++)
{
If (Joe==500)
Continue;
Printf ("%i\n", joe);
}
Joe++;
}
Each number from 0 to 999 is printed 100 times except for the number 500 which is not
printed at all.
2.10.3. Break
The break statement can only appear in a switch body or a loop body. It causes the
execution of the current enclosing switch or loop body to terminate.
Syntax
Break;
Examples
Switch (Henry)
{
Case 1: print ("Hi! \n");
Break;
Case 2: break;
}
If Henry is equal to 2, nothing happens.
For (loop=0; loop<50; loop++)
{
If (loops==10)
Break;
Printf ("%i\n", loop);
}
Only numbers 0 through 9 are printed.
2.10.4. Return
The return statement causes the current function to terminate. It can return a value to
the calling function. A return statement can not appear in a function whose return type is
void. If the value returned has a type different from that of the function's return type, then the
value is converted. Using the return statement without an expression creates an undefined
result. Reaching at the end of the function is the same as returning without an expression.
Syntax
Return expression;
Examples
2.11.1 Calloc
Declaration:
Void *calloc (size_t nitems, size_t size);
Allocates the requested memory and returns a pointer to it. The requested size is
nitems each size bytes long (total memory requested is nitems*size). The space is initialized
to all zero bits. On success a pointer to the requested space is returned. On failure a null
pointer is returned.
2.11.2. Free
Declaration
2.11.3. Malloc
Declaration
2.11.4 .Realloc
Declaration
Attempts to resize the memory block pointed to by ptr that was previously allocated
with a call to malloc or calloc. The contents pointed to by ptr are unchanged. If the value of
size is greater than the previous size of the block, then the additional bytes have an
indeterminate value. If the value of size is less than the previous size of the block, then the
difference of bytes at the end of the block are freed. If ptr is null, then it behaves like malloc.
If ptr points to a memory block that was not allocated with calloc or malloc, or is a space that
has been deallocated, then the result is undefined. If the new space cannot be allocated, then
the contents pointed to by ptr are unchanged. If size is zero, then the memory block is
completely freed. On success a pointer to the memory block is returned (which may be in a
different location as before). On failure or if size is zero, a null pointer is returned.
2.12 STRING
2.12.1. Strlen ()
Declaration
Size_t strlen (const char *STR);
Computes the length of the string STR up to but not including the terminating null
character.
Returns the number of characters in the string.
2.12.2 Strncpy ()
Declaration
Char *strcpy (char *str1, const char *str2);
Copies the string pointed to by str2 to str1. Copies up to and including the null
character of str2. If str1 and str2 overlap the behavior is undefined.
Returns the argument str1.
2.12.3 Strcmp ()
Declaration
Int strcmp (const char *str1, const char *str2);
Compares the string pointed to by str1 to the string pointed to by str2.
Returns zero if str1 and str2 are equal. Returns less than zero or greater than zero if
str1 is less than or greater than str2 respectively.
2.12.4 Strcat ()
Declaration
Char *strncat (char *str1, const char *str2, size_t n);
Appends the string pointed to by str2 to the end of the string pointed to by str1 up to n
characters long. The terminating null character of str1 is overwritten. Copying stops once n
characters are copied or the terminating null character of str2 is copied. A terminating null
character is always appended to str1. If overlapping occurs, the result is undefined.
The argument str1 is returned.
2.13 ARRAYS
C provides no facility for automatic bounds checking for array usage. Though
logically the last subscript in an array of 10 elements would be 9, subscripts 10, 11, and so
forth could accidentally be specified, with undefined results.
Int a[n];
A [3] = 10;
This behavior can be imitated with the help of the C standard library. The malloc
function provides a simple method for allocating memory. It takes one parameter: the amount
of memory to allocate in bytes. Upon successful allocation, malloc returns a generic (void *)
pointer value, pointing to the beginning of the allocated space. The pointer value returned is
converted to an appropriate type implicitly by assignment. If the allocation could not be
completed, malloc returns a null pointer. The following segment is therefore similar in
function to the above desired declaration:
The result is a "pointer to int" variable (a) that points to the first of n contiguous int
objects; due to array↔pointer equivalence this can be used in place of an actual array name,
as shown in the last line. The advantage in using this dynamic allocation is that the amount of
memory that is allocated to it can be limited to what is actually needed at run time, and this
can be changed as needed (using the standard library function realloc).
Free (a);
a = NULL;
Standard C also supports variable-length arrays with block scope. Such arrays
variables are allocated based on the value of an integer value at runtime upon entry to a
block, and are deallocated at the end of the block.
(Where ROWS and COLUMNS are constants); this defines a two-dimensional array.
Reading the subscripts from left to right, array2d is an array of length ROWS, each element of
which is an array of COLUMNS nits.
2.14 FUNCTION
t = i, i = j, j = t;
Printf ("exchange: i = %d j = %d\n", i, j);
}
The following output is produced
Main : i = 1 j = 2
Exchange: i = 2 j = 1
Main : i = 1 j = 2
C programming this is the key difference between passing by reference and passing
by value. If we pass the variables normally, they will be passed by value: a copy of the
variable's assigned content will be passed to the function as a constant. This means that it can
not be changed.
However, if we pass the variables by reference, then only a reference to the memory
where the variable is stored is passed to the function. Using this reference, the function is able
to modify the contents of the variable.
A recursive function is one which calls itself. This is another complicated idea which
you are unlikely to meet frequently. We shall provide some examples to illustrate recursive
functions.
2.15 POINTER
#include <stdio.h>
int arr[10] = { 3,6,1,2,3,8,4,1,7,2};
Void bubble (int a [], int N);
Int main (void)
{
Int i;
Put char ('\n');
For (i = 0; i < 10; i++)
{
Printf ("%d ", arr[i]);
}
Bubble (arr, 10);
Put char ('\n');
Strings are arrays of characters. This is not necessarily true in other languages. In
BASIC, Pascal, FORTRAN and various other languages, a string has its own data type. But
in C it does not. In C a string is an array of characters terminated with a binary zero character
(written as '\0'). To start off our discussion we will write some code which, while preferred
for illustrative purposes, you would probably never write in an actual program. Consider, for
example:
#include <stdio.h>
We stated that given an array of integers we could point an integer pointer at that array using:
Int *ptr;
Ptr = &my array [0]; /* point our pointer at the first
Integer in our array */
A structure which contains a data element and a pointer to the next node is created by,
Struct list {
Int value;
Struct list *next;
};
This defines a new data structure called list (actually the definition of a node), which
contains two members. The first is an integer called value. The second is called next, which is
a pointer to another list structure (or node). Suppose that we declare two structures to be of
the same type as list, e.g.
The advantage of a single linked list is that it is simple to create, and add/remove
'nodes'. However, its main disadvantage is that it can take a while to add/remove nodes due to
a pointer only able to go one way.
E very linked list needs to have one node that has no value, but just points to the start
of the list we call this the 'Head Node'. The end of the list must always point to NULL this is
good programming behavior and ensures that the program using the list in that method will
be more stable.
The doubly linked list has one major advantage; it is possible to move a pointer that
reads the list back and forth which saves on time a great deal. However, there is more pointer
bookkeeping involved Instead of changing two pointers in a single linked list, you now have
to change four. The speed in how data is found/added/removed however is still a large step.
A visual example of a doubly linked list. Notice there're two nulls, one head, and each node
has two pointers. There's usually a second head pointer called the rear (tail) pointer which
keeps up the other end of the list.
A visual example of adding a node to a doubly linked list. Notice how four pointers
need to be changed. A common mistake in adding an element is changing the pointers in the
wrong order, you want to have the pointers of the node you are adding pointing to its
neighbors first, and then you want its neighbors to point to it.
There are two types of circular linked list, single and double. Like its name, the end of
the list points at the beginning so there is no need for null. The advantage about this is that
there is no real end of the list, and you don't have to reset pointers much. However, you have
to keep track of the beginning and end of the list or problems are going to arise in the
program.
Summary:
Technical Question:
1. Write a program for calculating Armstrong Number
2. To write the program for to tests whether a number is prime or not.
3. Performs XOR encryption
Exercise:
1. Reverses a series of numbers by using pointer version
2. Finds the largest and smallest elements in an array
3. Sorts an array of integers using Quick sort algorithm
4. Write a program Recursive Function
CHAPTER 3
ADVANCED C
To recap: strings are arrays of chars. String literals are words surrounded by double quotation
marks.
Remember that special sauce mentioned above? Well, it turns out that C-style strings
are always terminated with a null character, literally a '\0' character (with the value of 0), so
to declare a string of 49 letters, you need to account for it by adding an extra character, so
you would want to say:
This would declare a string with a length of 50 characters. Do not forget that arrays
begin at zero, not 1 for the index number. In addition, we've accounted for the extra with
a null character, literally a '\0' character. It's important to remember that there will be
an extra character on the end on a string, just like there is always a period
at the end of a sentence. Since this string terminator is unprintable, it is not counted as a
letter, but it still takes up a space. Technically, in a fifty char array you could only hold 49
letters and one null character at the end to terminate the string.
can also be used as a string. If you have read the tutorial on pointers, you can do something
such as:
which allows you to access array just as if it were an array? Keep in mind that to use delete
you must put [] between delete and array to tell it to free all 256 bytes of memory allocated.
For example:
delete [] array.
There are several approaches to handling this problem, but probably the simplest and
safest is to use the fgets function, which is declared in stdio.h.
There are a few new things here. First of all, let's clear up the questions about that
funky FILE* pointer. The reason this exists is because fgets is supposed to be able to read
from any file on disk, not just from the user's keyboard (or other "standard input" device). For
the time being, whenever we call fgets, we'll just pass in a variable called stdin, defined in
stdio.h, which refers to "standard input". This effectively tells the program to read from the
keyboard. The other two arguments to fgets, str and size, are simply the place to store the data
read from the input and the size of the char*, str. Finally, fgets returns str whenever it
successfully read from the input.
For an example
#include <stdio.h>
int main ()
{
/* A nice long string */
char string [256];
Getchar ();
}
Remember that you are actually passing the address of the array when you pass string
because arrays do not require an address operator (&) to be used to pass their addresses, so
the values in the array string are modified.
The one thing to watch out for ,when using fgets is that it will include the new line
character ('\n') when it reads input unless there isn't room in the string to store it. This means
that you may need to manually remove the input. One way to do this would be to search the
string for a new line and then replace it with the null terminator. What would this look like?
See if you can figure out a way to do it before looking below:
Here, we just loop through the input until we come to a new line, and when we do, we
replace it with the null terminator. Notice that if the input is less than 256 characters long, the
user must have hit enter, which would have included the new line character in the string! (By
the way, aside from this example, there are other approaches to solving this problem that use
functions from String.h.)
String.h is a header file that contains many functions for manipulating strings. One of
these is the string comparison function.
strcmp will accept two strings. It will return an integer. This integer will either be:
Strcmp performs a case sensitive comparison; if the strings are the same except for a
difference in case, then they're countered as being different. Strcmp also passes the address of
the character array to the function to allow it to be accessed.
strcat is short for "string concatenate"; concatenate is a fancy word that means to add
to the end, or append. It adds the second string to the first string. It returns a pointer to the
concatenated string. Beware this function; it assumes that dest is large enough to hold the
entire contents of src as well as its own contents.
strcpy is short for string copy, which means it copies the entire contents of src into
dest. The contents of dest after strcpy will be exactly the same as src such that strcmp (dest,
src) will return 0.
strlen will return the length of a string, minus the treating character ('\0'). The size_t is
nothing to worry about. Just treat it as an integer that cannot be negative, When fgets actually
reads input from the user, it will read up to size - 1 characters and then place the null
terminator after the last character it read. fgets will read input until it either has no more room
to store the data or until the user hits enter. Notice that fgets may fill up the entire space
allocated for str, but it will never return a non-null terminated string to you.
number of characters that fit into the buffer; there are string functions that take an additional
argument to indicate the length of the destination buffer. For instance, the strcpy function has
an analogous strncpy function
which will only copy Len bytes from src to dest (Len should be less than the size of
dest or the write could still go beyond the bounds of the array)? Unfortunately, strncpy can
lead to one niggling issue: it doesn't guarantee that dest will have a null terminator attached to
it (this might happen if the string src is longer than dest). You can avoid this problem by
using strlen to get the length of src and make sure it will fit in dest. Of course, if you were
going to do that, then you probably don't need strncpy in the first place, right? Wrong. Now it
forces you to pay attention to this issue, which is a big part of the battle
When accessing files through C, the first necessity is to have a way to access the files.
For C File I/O you need to use a FILE pointer, which will let the program keep track of the
file being accessed. (You can think of it as the memory address of the file or the location of
file).
For Example:
FILE *fp;
To open a file you need to use the fopen function, which returns a FILE pointer. Once you've
opened a file, you can use the FILE pointer to let the compiler perform input and output
functions on the file.
In the filename, if you use a string literal as the argument, you need to remember to
use double backslashes rather than a single backslash as you otherwise risk an escape
character such as \t. Using double backslashes \\ escapes the \ key, so the string works as it is
expected. Your users, of course, do not need to do this! It's just the way quoted strings are
handled in C and++.
The modes are as follows:
Note that it's possible for fopen to fail even if your program is perfectly correct: you might try
to open a file specified by the user, and that file might not exist (or it might be write-
protected). In those cases, fopen will return 0, the NULL pointer.
FILE *fp;
fp=fopen ("c:\\test.txt", "r");
This code will open test.txt for reading in text mode. To open a file in a binary mode
you must add a b to the end of the mode string; for example, "rb" (for the reading and writing
modes, you can add the b either after the plus sign - "r+b" - or before - "rb+")
fclose (fp);
To work with text input and output, you use fprintf and fscanf, both of which are
similar to their friend’s printf and scanf except that you must pass the FILE pointer as first
argument. For example:
FILE *fp;
fp=fopen ("c:\\test.txt", "w");
fprintf (fp, "Testing...\n");
It is also possible to read (or write) a single character at a time--this can be useful if
you wish to perform character-by-character input (for instance, if you need to keep track of
every piece of punctuation in a file it would make more sense to read in a single character
than to read in a string at a time.) The fgetc function, which takes a file pointer, and returns
an int, will let you read a single character from a file:
Notice that fgetc returns an int. What this actually means is that when it reads a
normal character in the file, it will return a value suitable for storing in an unsigned char
(basically, a number in the range 0 to 255). On the other hand, when you're at the very end of
the file, you can't get a character value--in this case, fgetc will return "EOF", which is a
constant that indicates that you've reached the end of the file. To see a full example using
fgetc in practice, take a look at the example here.
The fputc function allows you to write a character at a time--you might find this
useful if you wanted to copy a file character by character. It looks like this:
Note that the first argument should be in the range of an unsigned char so that it is a
valid character. The second argument is the file to write to. On success, fputc will return the
value c, and on failure, it will return EOF.
size_t fread (void *ptr, size_t size_of_elements, size_t number_of_elements, FILE *a file);
Both of these functions deal with blocks of memories - usually arrays. Because they
accept pointers, you can also use these functions with other data structures; you can even
write struts to a file or a read struct into memory.
Let's look at one function to see how the notation works.fread takes four arguments.
Don't by confused by the declaration of a void *ptr; void means that it is a pointer that can be
used for any type variable. The first argument is the name of the array or the address of the
structure you want to write to the file. The second argument is the size of each element of the
array; it is in bytes. For example, if you have an array of characters, you would want to read it
in one byte chunks, so size_of_elements is one. You can use the sizeof operator to get the
size of the various data types; for example, if you have a variable int x; you can get the size
of x with sizeof(x); This usage works even for struts or arrays. E.g., if you have a variable of
a struct type with the name abstract, you can use sizeof (abstract) to find out how much
memory it is taking up.
e.g.
sizeof (int);
The third argument is simply how many elements you want to read or write; for
example, if you pass a 100 element array, you want to read no more than 100 elements, so
you pass in 100.
The final argument is simply the file pointer we've been using. When fread is used,
after being passed an array, fread will read from the file until it has filled the array, and it will
return the number of elements actually read. If the file, for example, is only 30 bytes, but you
try to read 100 bytes, it will return that it read 30 bytes. To check to ensure the end of file was
reached, use the feof function, which accepts a FILE pointer and returns true if the end of the
file has been reached. fwrite is similar in usage, except instead of reading into the memory
you write from memory into a file.
For example,
FILE *fp;
fp=fopen ("c:\\test.bin", "web");
char x [10] ="ABCDEFGHIJ";
fwrite(x, sizeof(x [0]), sizeof(x)/sizeof(x [0]), fp);
A C program is executed by calling its main () function. The function is called with
one argument that indicates how many words are in the command and another argument that
is an array containing the command words.
In order to access the command words, the main () function must have a prototype
similar to the following.
The names argc and argv are usually used for the parameters, but a programmer could
use different names.
The command words can be accessed as arg [0] through argv [argc - 1]. The program
name is the first word on the command line,
#include <stdio.h>
main (int argc, char *argv [])
{
if (argc == 2)
printf ("The argument supplied is %s\n", argv [1]);
else if (argc > 2)
printf ("Too many arguments supplied.\n");
else
printf ("One argument expected.\n");
}
We'll need to use some macros (which work much like functions, and you can treat
them as such) from the stdarg.h header file to extract the values stored in the variable
argument list--va_start, which initializes the list, va_arg, which returns the next argument in
the list, and va_end, which cleans up the variable argument list.
va_list a_list;
va_start is a macro which accepts two arguments, a va_list and the name of the
variable that directly precedes the ellipsis ("..."). So in the function a function, to initialize
a_list with va_start, you would write va_start (a_list, x);
Va_arg takes a va_list and a variable type, and returns the next argument in the list in the
form of whatever variable type it is told. It then moves down the list to the next argument.
For example, va_arg (a_list, double) will return the next argument, assuming it exists, in the
form of a double. The next time it is called, it will return the argument following the last
returned number, if one exists. Note that you need to know the type of each argument--that's
part of why printf requires a format string! Once you're done, use va_end to clean up the list:
va_end (a_list); It isn't necessarily a good idea to use a variable argument list at all times; the
potential exists for assuming a value is of one type, while it is in fact another, such as a null
pointer being assumed to be an integer. Consequently, variable argument lists should be used
sparingly.
The binary tree is a fundamental data structure used in computer science. The binary
tree is a useful data structure for rapidly storing sorted data and rapidly retrieving stored data.
A binary tree is composed of parent nodes, or leaves, each of which stores data and also links
to up to two other child nodes (leaves) which can be visualized spatially as below the first
node with one placed to the left and with one placed to the right. It is the relationship between
the leaves linked to and the linking leaf, also known as the parent node, which makes the
binary tree such an efficient data structure. It is the leaf on the left which has a lesser key
value (i.e., the value used to search for a leaf in the tree), and it is the leaf on the right which
has an equal or greater key value. As a result, the leaves on the farthest left of the tree have
the lowest values, whereas the leaves on the right of the tree have the greatest values. More
importantly, as each leaf connects to two other leaves, it is the beginning of a new, smaller,
binary tree. Due to this nature, it is possible to easily access and insert data in a binary tree
using search and insert functions recursively called on successive leaves.
10
/ \
6 14
/\ / \
5 8 11 18
The node storing the 10, represented here merely as 10, is the root node, linking to the
left and right child nodes, with the left node storing a lower value than the parent node, and
the node on the right storing a greater value than the parent node. Notice that if one removed
the root node and the right child nodes, that the node storing the value 6 would be the
equivalent a new, smaller, binary tree.
The structure of a binary tree makes the insertion and search functions simple to
implement using recursion. In fact, the two insertions and search functions are also both very
similar. To insert data into a binary tree involves a function searching for an unused node in
the proper position in the tree in which to insert the key value. The insert function is generally
a recursive function that continues moving down the levels of a binary tree until there is an
unused leaf in a position which follows the rules of placing nodes. The rules are that a lower
value should be to the left of the node, and a greater or equal value should be to the right.
Following the rules, an insert function should check each node to see if it is empty, if so, it
would insert the data to be stored along with the key value (in most implementations, an
empty node will simply be a NULL pointer from a parent node, so the function would also
have to create the node). If the node is filled already, the insert function should check to see if
the key value to be inserted is less than the key value of the current node, and if so, the insert
function should be recursively called on the left child node, or if the key value to be inserted
is greater than or equal to the key value of the current node the insert function should be
recursively called on the right child node. The search function works along a similar fashion.
It should check to see if the key value of the current node is the value to be searched. If not, it
should check to see if the value to be searched for is less than the value of the node, in which
case it should be recursively called on the left child node, or if it is greater than the value of
the node, it should be recursively called on the right child node. Of course, it is also necessary
to check to ensure that the left or right child node actually exists before calling the function
on the node.
Because binary trees have log (base 2) n layers, the average search time for a binary
tree is log (base 2) n. To fill an entire binary tree, sorted, takes roughly log (base 2) n * n.
Lets take a look at the necessary code for a simple implementation of a binary tree. First, it is
necessary to have a struct, or class, defined as a node.
struct node
{
int key value;
struct node *left;
struct node *right;
};
The struct has the ability to store the key value and contains the two child nodes
which define the node as part of a tree. In fact, the node itself is very similar to the node in a
linked list. A basic knowledge of the code for a linked list will be very helpful in
understanding the techniques of binary trees. Essentially, pointers are necessary to allow the
arbitrary creation of new nodes in the tree.
There are several important operations on binary trees, including inserting elements,
searching for elements, removing elements, and deleting the tree. We'll look at three of those
four operations in this tutorial, leaving removing elements for later.
We'll also need to keep track of the root node of the binary tree, which will give us
access to the rest of the data:
It is necessary to initialize root to 0 for the other functions to be able to recognize that the tree
does not yet exist. The destroy tree shown below which will actually free all of the nodes of
in the tree stored under the node leaf: tree.
The function destroy tree goes to the bottom of each part of the tree, that is, searching
while there is a non-null node, deletes that leaf, and then it works its way back up. The
function deletes the leftmost node, then the right child node from the leftmost node's parent
node, then it deletes the parent node, then works its way back to deleting the other child node
of the parent of the node it just deleted, and it continues this deletion working its way up to
the node of the tree upon which delete tree was originally called. In the example tree above,
the order of deletion of nodes would be 5 8 6 11 18 14 10. Note that it is necessary to delete
all the child nodes to avoid wasting memory.
Libraries for use by C programs really consist of two parts: header files that define
types and macros and declare variables and functions; and the actual library or archive that
contains the definitions of the variables and functions.
In order to use the facilities in the GNU C library, you should be sure that your
program source files include the appropriate header files. This is so that the compiler has
declarations of these facilities available and can correctly process references to them. Once
your program has been compiled, the linker resolves these references to the actual definitions
provided in the archive file.
Header files are included into a program source file by the `#include' preprocessor
directive. The C language supports two forms of this directive; the first,
#include "header"
Is typically used to include a header file header that you write yourself; this would
contain definitions and declarations describing the interfaces between the different parts of
your particular application. By contrast,
#include <file.h>
File.h is typically used to include a header file `file.h' that contains definitions and
declarations for a standard library. This file would normally be installed in a standard place
by your system administrator. You should use this second form for the C library header files.
Contains the assert macro, used to assist with detecting logical errors and other
<assert.h>
types of bug in debugging versions of a program.
<complex.h> A set of functions for manipulating complex numbers. (New with C99)
<inttypes.h> For precise conversion between integer types. (New with C99)
<iso646.h> For programming in ISO 646 variant character sets. (New with NA1)
For set locale () and related constants. This is used to choose an appropriate
<locale.h>
locale.
<setjmp.h> Declares the macros set Jmp and long Jmp, which are used for non-local exits
Provides the core input and output capabilities of the C language. This file
<stdio.h>
includes the venerable printf function.
For manipulating wide streams and several kinds of strings using wide
<wchar.h>
characters - key to supporting a range of languages. (New with NA1)
Taking the address of a library function works even if it is also defined as a macro.
This is because, in this context, the name of the function isn't followed by the left parenthesis
that is syntactically necessary to recognize a macro call.
You might occasionally want to avoid using the macro definition of a function--
perhaps to make your program easier to debug. There are two ways you can do this:
• You can avoid a macro definition in a specific use by enclosing the name of the
function in parentheses. This works because the name of the function doesn't appear
in a syntactic context where it is recognizable as a macro call.
• You can suppress any macro definition for a whole source file by using the `#undef'
preprocessor directive, unless otherwise stated explicitly in the description of that
facility.
For example, suppose the header file `stdlib.h' declares a function named abs with
#include <stdlib.h>
int f (int *i) {return (abs (++*i)) ;}
The reference to abs might refer to either a macro or a function. On the other hand, in
each of the following examples the reference is to a function and not a macro.
#include <stdlib.h>
int g (int *i) {return ((abs) (++*i)) ;}
#undef abs
int h (int *i) {return (abs (++*i)) ;}
Since macro definitions that double for a function behave in exactly the same way as
the actual function version, there is usually no need for any of these methods. In fact,
removing macro definitions usually just makes your program slower.
short a=2000;
int b;
b=a;
class A {};
class B { public: B (A a) {} };
A a;
B b=a;
Here, an implicit conversion happened between objects of class A and class B, because
B has a constructor that takes an object of class A as parameter. Therefore, implicit
conversions from A to B are allowed.
Explicit conversion occurs when you are converting the value of the larger data type
to the value of the smaller data type.
Syntax
cast-expression:
unary expression
(type-name) cast-expression
type-name:
specified-qualifier-list abstract-decelerator
Type conversions depend on the specified operator and the type of the operand or
operators. Type conversions are performed in the following cases:
C has a concept of 'Storage classes' which are used to define the scope (visibility) and
life time of variables and/or functions.
static is the default storage class for global variables. The two variables below (count and
road) both have a static storage class.
main()
{
printf("%d\n", Count);
printf("%d\n", Road);
}
'Static' can also be defined within a function. If this is done, the variable is initialized
at compilation time and retains its value between calls. Because it is initialed at compilation
time, the initialization value must be a constant. This is serious stuff - tread with care.
void Func(void)
{
static Count=1;
}
Here is an example
There is one very important use for 'static'. Consider this bit of code.
char *Func(void);
main()
{
char *Text1;
Text1 = Func();
}
char *Func(void)
{
char Text2[10]="martin";
return(Text2);
}
'Func' returns a pointer to the memory location where 'Text2' starts BUT Text2 has a
storage class of auto and will disappear when we exit the function and could be overwritten
by something else. The answer is to specify:
The storage assigned to 'Text2' will remain reserved for the duration if the program.
Source 1 Source 2
-------- --------
Write () main ()
{ {
printf ("count is %d\n", count); write ();
} }
Count in 'source 1' will have a value of 5. If source 1 changes the value of count - source 2
will see the new value. Here are some example source files
Summary
We learnt about the Advanced C Programming Techniques.
We are familiar in concepts like C style Arguments, File I/O, and Type Casting and
command line arguments.
We saw about the Variable Argument List and Macro Substitutions like how we can
store the Variables and Constants in C like Memory Management
Exercise
1. Write a Program for Reading the Command Line
2. Write a Program for Average Calculation Using Variable Argument List
CHAPTER 4
The system is dedicated to specific tasks; design engineers can optimize it, reducing the
size and cost of the product.
Embedded systems are often mass-produced, benefiting from economies of scale.
4.1.1 Characteristics
1) Embedded systems are designed to do some specific task, rather than be a general-
purpose computer for multiple tasks. Some also have real-time performance constraints that
must be met, for reason such as safety and usability; others may have low or no performance
requirements, allowing the system hardware to be simplified to reduce costs.
3) The software written for embedded systems is often called firmware, and is stored
in read-only memory or Flash memory chips rather than a disk drive. It often runs with
limited computer hardware resources: small or no keyboard, screen, and little memory.
Embedded systems frequently control hardware, and must be able to respond to them in
real time. Failure to do so could cause inaccuracy in measurements, or even damage hardware
such as motors. This is made even more difficult by the lack of resources available.
Almost all embedded systems need to be able to prioritize some tasks over others, and to
be able to put off/skip low priority tasks in favor of high priority tasks like hardware control.
4.1.3 Reliability
Embedded systems will work without the need of rebooting or resetting. Hence, the
hardware and software should be reliable. The system should be able to reset itself without
human intervention at the time of any hardware failure. In addition, embedded systems must
operate reliably under extreme environmental conditions.
If embedded system is designed for a very special purpose like in a nuclear plant,
space satellites cost may not be an issue. However, when it is used for the mass market, as in
CD players, toys or mobile devices cost is an important consideration. SIC are developed to
reduce the hardware components and cost.
Most Embedded systems do not have secondary storage such as hard disk. The
memory chips available on the embedded system are only ROM for storing program and
RAM for data. The developer may determine the program size and data size considering the
functionality, based on which memory requirements are important.
In real time applications, certain tasks must be performed within a specified time.
Hence, analyzing the tasks to meet the performance constraints is of considerable importance.
The performance requirement also involves code optimization to maximum possible extent.
The embedded system design and development process is divided into four phases.
1. creating the architecture of the system
2. implementing the architecture
3. testing the system
4. maintaining the system
The embedded system design involves choosing the right processor, memory, devices
and bus.
4.1.10. Applications
Embedded systems are used in many diverse fields.Embedded systems play crucial
role in design and manufacture of devices and systems. Depending on their areas of usage,
the embedded systems fall into different categories.
Plant control: Robots, plant monitors, industrial process systems, airplane control
systems, missile guidance systems etc.
Having decided to use an 8051 processor as the basis of your embedded system,
the next key decision that needs to be made is the choice of programming language.
In order to identify a suitable language for embedded systems, we might begin by making the
following observations:
Of course, not all of the issues involved in language selection are purely technical:
• No software company remains in business for very long if it generates new code,
from scratch, for every project. The language used must support the creation of
flexible libraries, making it easy to re-use (well-tested) code components in a
range of projects. It must also be possible to adapt complete code systems to work
with a new or updated processor with minimal difficulty.
• Staff members change and existing personnel have limited memory spans. At the
same time, systems evolve and processors are updated. As concern over the ‘Year
2000’ problem in recent years has illustrated, many embedded systems have a
long lifespan. During this time, their code will often have to be maintained.
• The language chosen should be in common use. This will ensure that you can
continue to recruit experienced developers who have knowledge of the language.
It will also mean that your existing developers will have access to sources of
information Even this short list immediately raises the paradox of programming
language selection.
• From one point of view, only machine code is safe, since every other language
involves a translator, and any code you create is only as safe as the code written
by the manufacturers of the translator.
• On the other hand, real code needs to be maintained and re-used in new projects,
possibly on different hardware: few people would argue that machine code is easy
to understand, debug or to port. Inevitably, therefore, we need to make
compromises; there is no perfect solution.
• All we can really say is that we require a language that is efficient, high-level,
gives low-level access to hardware, and is well defined. In addition, – of course –
the language must be available for the platforms we wish to use. Against all of
these points, C scores well.
Mobile devices like mobile phones; PDAs, smart phones etc are a special category of
embedded systems. Since the mobile devices have resource limitations like embedded
systems such as memory constraints, small size, lack of good user interfaces such as full-
fledged keyboard and display they are classified as embedded systems
Building a desktop PC from an 8051 would not be a practical proposition, but it is an excellent
device for building many embedded systems. One important factor is that the 8051 requires a
minimum number of external components in order to operate. For example, figure shows the
circuit diagram for a complete 8051- based application.
The different nature of the embedded and desktop markets is emphasized by the fact
that some of the more recent 8051 devices – far from being more powerful and having more
features than the 1980 original – actually have fewer features. The original 8051 had 32 I/O
pins and could – if necessary – be connected to up to 128 Kbytes of External memory. By
contrast, the more recent ‘Small 8051’ devices typically have only some 15 I/O pins, and do
not support external memory. These devices are finding their way into applications that
would have involved a small number of discrete components (transistors, diodes, resistors,
capacitors) a few years ago, but which may now be Implemented more cheaply using
microcontrollers ‘8051’
1. Arithmetic instructions.
2. Logic instructions.
3. Data transfer instructions.
4. Boolean variable manipulation instruction.
5. Program and machine control instruction
No. of No. of
Addressing
MNEMONICS OPERATIONAL bytes cycles
mode
DESCRIPTION occupied used
INC A Add 1 to acc Register 1 1
INC RR Add 1 to register Rr Register 1 1
INC ADD Add 1 to the content of add Direct 2 1
Add 1 to the content of the
INC @RP indirect 1 1
address in Rp
INC DPTR Add 1 to DPTR Register 1 2
DEC A Subtract 1 from acc Register 1 1
DEC RR Subtract 1 from Rr Register 1 1
DEC ADD Subtract 1 from content of add Direct 2 1
Subtract 1 from the content of
DEC @RP indirect 1 1
address
Add the immediate num with acc
ADD A, #NUM immediate 2 1
and stores result in acc
Add the data in Rx with acc and
ADD A, RX Register 1 1
stores result in acc
Add the data in add with acc and
ADD A, ADD Direct 2 1
stores result in acc
Add the data at the address in Rp
ADD A, @RP with acc and stores result in acc Indirect 1 1
No. of
Addressing No. of bytes
Mnemonics cycles
mode occupied
Operational description used
AND each bit of acc with same
ANLA,
bit of immediate num, stores Immediate 2 1
#NUM
result in acc
AND each bit of acc with same
ANL A, ADD bit of content in add, stores result Direct 2 1
in acc
AND each bit of acc with same
ANL A, RX bit of content of Rx, stores result Register 1 1
in acc
AND each bit of acc with same
ANL A, @RP bit of content of add given by Indirect 1 1
Rp, stores result in acc
AND each bit of acc with same
ANL ADD, A bit of direct add num, stores Direct 2 1
result in add
AND each bit of direct add with
ANL ADD,
same bit of immediate num, direct 3 2
#NUM
stores result in add
OR each bit of acc with same bit
ORL A,
of immediate num, stores result Immediate 2 1
#NUM
in acc
OR each bit of acc with same bit
ORL A, ADD of content in add, stores result in Direct 2 1
acc
OR each bit of acc with same bit
ORL A, RX of content of Rx, stores result in Register 1 1
acc
OR each bit of acc with same bit
ORL A, @RP of content of add given by Rp, Indirect 1 1
stores result in acc
OR each bit of acc with same bit
ORL ADD,
of direct add num, stores result in Direct 2 1
A
add
OR each bit of direct add with
ORL ADD,
same bit of immediate num, direct 3 2
#NUM
stores result in add
XRL A, XOR each bit of acc with same
Immediate 2 1
#NUM bit of immediate num, stores
result in acc
XOR each bit of acc with same
XRL A, ADD bit of content in add, stores result Direct 2 1
in acc
XOR each bit of acc with same
XRL A, RX bit of content of Rx, stores result Register 1 1
in acc
XOR each bit of acc with same
XRL A,
bit of content of add given by Indirect 1 1
@RP
Rp, stores result in acc
XOR each bit of acc with same
XRL ADD, A bit of direct add num, stores Direct 2 1
result in add
XOR each bit of direct add with
XRL ADD,
same bit of immediate num, direct 3 2
#NUM
stores result in add
CLR A Clear each bit of acc Direct 1 1
CPL A Complement each bit of acc direct 1 1
AND carry with given bit b,
ANL C, B -- 2 2
stores result in carry
AND carry with complement of --
ANL C, /B 2 2
given bit b, stores result in carry
OR carry with given bit b, stores --
ORL C, B 2 2
result in carry
OR carry with complement of --
ORL C, /B 2 2
given bit b, stores result in carry
CPL C Complement carry flag -- 1 1
CPL B Complement bit b -- 2 1
CLR C Clear carry flag -- 1 1
CLR B Clear given bit b -- 2 1
MOV C, B Copy bit b to carry -- 2 1
MOV B, C Copy carry to bit b -- 2 2
SETB C Set carry flag -- 1 1
SETB B Set bit b -- 2 1
RL A Rotate acc one bit left -- 1 1
RR A Rotate acc one bit right -- 1 1
RLC A Rotate acc one bit left with carry -- 1 1
Rotate acc one bit right with
RRC A -- 1 1
carry
Exchange upper and lower nibble
SWAP A -- 1 1
of acc
acc
MOV RX,A Copy the data from acc to Rx Register 1 1
MOV A,RX Copy the data from Rx to acc Register 1 1
MOV Copy the immediate data num in to
Immediate 2 1
RX,#NUM Rx
Copy the data from direct address
MOV A,ADD Direct 2 1
add to acc
Copy the data from acc to direct
MOV ADD, A Direct 2 1
address add
MOV Copy the immediate data num in to
Direct 3 2
ADD,#NUM direct address
MOV Copy the data from add2 to add1
Direct 3 2
ADD1,ADD2
Copy the data from direct address
MOV RX,ADD Direct 2 2
add to Rx
Copy the data from Rx to direct
MOV ADD,RX Direct 2 2
address add
MOV @RP,A Copy the data in acc to address in Rp Indirect 1 1
Copy the data that is at address in Rp
MOV A,@RP Indirect 1 1
to acc
MOV Copy the data that is at address in Rp
Indirect 2 2
ADD,@RP to add
MOV Copy the data in add to address in
Indirect 2 2
@RP,ADD Rp
MOV Copy the immediate byte num to the
Indirect 2 1
@RP,#NUM address in Rp
Copy the content of external add in
MOVX A,@RP Indirect 1 2
Rp to acc
MOVX Copy the content of external add in
Indirect 1 2
A,@DPTR DPTR to acc
Copy the content of acc to the
MOVX @RP,A Indirect 1 2
external add in Rp
MOVX Copy the content of acc to the
Indirect 1 2
@DPTR,A external add in DPTR
The address is formed by adding acc
MOVC
and DPTR and its content is copied Indirect 1 2
A,@A+DPTR
to acc
The address is formed by adding acc
MOVC A,
and PC and its content is copied to Indirect 1 2
@A+PC
acc
Increment SP and copy the data from
PUSH ADD source add to internal RAM address Direct 2 2
contained in SP
copy the data from internal RAM
POP ADD address contained in SP to Direct 2 2
destination add and decrement SP
Exchange the data between acc and
XCH A, RX Register 1 1
Rx
XCH A, ADD Exchange the data between acc and Direct 2 1
given add
Exchange the data between acc and
XCH A,@RP Indirect 1 1
address in Rp
XCHD A, Exchange only lower nibble of acc
Indirect 1 1
@RP and address in Rp
4.5.1 Introduction:
In this introductory chapter, we consider some important decisions that must be made at
the start of any embedded project:
• The choice of processor.
• The choice of programming language.
• The choice of operating system.
• We begin by considering the meaning of the phrase ‘embedded system’.
back off your dishwasher, you will not find any of these processors sitting inside, nor will
there be anywhere to plug in a keyboard, graphics display or mouse.
Typical desktop processors cost more than US $100.00 a piece (often much more).
This cost puts them out of reach of all but the most expensive embedded application. (Who
would pay more than US $100 for a TV remote-control unit?)
Overall, the state-of-the art technology used in desktop processors matches the needs
of the PC user very well: however, their key features – an ability to execute industry-standard
code at a rate of more than 1000 million instructions per second –come with a heavy price tag
and are simply not required in most embedded systems.
The 8051 device is very different. It is a well-tested design, introduced in its original
form by Intel in 1980 The development costs of this device have now been fully recovered,
and prices of modern 8051 devices now start at less than US $1.00. At this price, you get a
performance of around 1 million instructions per second, and 256 bytes (not megabytes!) of
on-chip RAM. You also get 32 port pins and a serial interface. The 8051’s profile (price,
performance, available memory, serial interface) match the needs of many embedded systems
very well. As a result, it is now produced in more than 400 different forms by a diverse range
of companies including PHILIPS, INFINEON, ATMEL and DALLAS. Sales of this vast
family are estimated to have the largest share (around 60%) of the microcontroller market as
a whole, and to make up more than 50% of the 8-bit microcontroller market. Versions of the
8051 are currently used in a long list of embedded products, from children’s toys to
automotive systems.
Having opted to create our 8051-based applications using C, we can now begin to
consider how this language can be used. In doing so, we will begin to probe some of the
differences between software development for desktop and embedded systems. In the desktop
environment, the program the user requires (such as a word processor program) is usually
loaded from disk on demand, along with any required data (such as a word processor file). It
shows a typical operating environment for such a word processor. Here the system is well
insulated from the underlying hardware. For example, when the user wishes to save his or her
latest novel on disk, the word processor delegates most of the necessary work to the operating
system, which in turn may delegate many of the hardware-specific commands to the BIOS
(basic input/output system).
The desktop PC does not require an operating system (or BIOS). However, for most
users, the main advantage of a personal computer is its flexibility: that is, that the same piece
of equipment has the potential to run many thousands of different programs.
If the PC had no operating system, each of these programs would need to be able to
carry out all the low-level functions for itself. This would be very inefficient and would tend
to make systems more expensive. It would also be likely to lead to errors, as many simple
functions would have to be duplicated in even the smallest of programs. One way of viewing
this is that a desktop PC is used to run multiple programs, and the operating system provides
the ‘common code’ (for printing, file storage, graphics, and so forth) that is required by this
set of programs.
We assume that the boiler, temperature sensor and temperature dial are connected
To the system via appropriate ports.
4.7 ASSEMBLER
Definition
An assembler is a program that acquires basic computer instructions and converts them
into a pattern of bits that the computer's processor can use to perform its basic operations.
Some people call these instructions assembler language and others use the term assembly
language.
• Most computers come with a specified set of very basic instructions that correspond
to the basic machine operations that the computer can perform. For example, a "Load"
instruction causes the processor to move a string of bits from a location in the
processor's memory to a special holding place called a register. Assuming the
processor has at least eight registers, each numbered, the following instruction would
move the value (string of bits of a certain length) at memory location 3000 into the
holding place called register 8:
L 8, 3000
In the earliest computers, programmers actually wrote programs in machine code, but
assembler languages or instruction sets were soon developed to speed up programming.
Today, assembler programming is used only where very efficient control over processor
operations is needed. It requires knowledge of a particular computer's instruction set,
however. Historically, most programs have been written in "higher-level" languages such as
COBOL, FORTRAN, PL /C., and I these languages are easier to learn and faster to write
programs with than assembler language. The program that processes the source code written
in these languages is called a compiler. Like the assembler, a compiler takes higher-level
language statements and reduces them to machine code.
4.7.2 Compiler:
A compiler is a special program that progression statements written in a particular
programming language and turns them into machine language or "code" that a computer's
processor uses. Naturally, a programmer writes language statements in a language such as
Pascal or C one line at a time using an editor. The file that is created contains what are called
the source statements. The programmer then runs the appropriate language compiler,
specifying the name of the file that contains the source statements
When executing (running), the compiler first parses (or analyzes) all of the language
statements syntactically one after the other and then, in one or more successive stages or
"passes", builds the output code, making sure that statements that refer to other statements are
referred to correctly in the final code. Traditionally, the output of the compilation has been
called object code or sometimes an object module
4.9 ARCHITECTURE
Most microcontrollers have two vital architectures, each with two departures. One
architecture refers to the type of bus design used for the program and data memory: The other
cataloging describes the type of instruction set and the density of the CPU
4.9.2 Harvard
Harvard architecture has separate program and data memory busses. The program
memory bus is up-and-down in width and optimized for a particular device. The data bus
width is usually a standard 8 or 16 bits. The special function registers (timer settings, port
configuration, etc.) are also mapped onto the data bus for the reason they are in essence
variable. This architecture allows the simultaneous access of both program memory and data
memory.
Harvard architecture has several benefits, mainly a long word instruction that
occupies only one location in program memory. A single word instruction increases the
execution speed because the operation code and associated data are all contained in a single
word. The single cycle instruction execution is also easily performed in the Harvard
architecture because the program and data memory can be accessed at the same time.
• ATMEL maker of the AVR RISC controller and various 8051 clones.
• Intel which large line of microprocessor and microcontroller families (Pentium, i960,
8051, etc.), as well as the world leader in flash memory technologies.
• Texas Instruments maker of the TMS370 line of 8-bit controllers, as well as the
world-leader in DSP technologies.
• Hitachi, maker of the H8 and Super line of powerful microcontrollers.
• NEC Electronics. Ultra fast VR4xxx line of low power processors, as well as other 8,
16, and 32-bit controllers.
• Philips. 8051 clones and enhanced derivatives.
• Motorola. Very popular microprocessor and microcontroller manufacturer, plus many
cellular and wireless technologies.
• Siemens. Manufacturer of multiple microcontrollers including various 8051 clones.
• Microchip. Maker of the popular "PIC" line of controllers, as well as an extensive line
of serial access EPROM’s.
• National Semiconductor. Maker of the "COP8" controller series, as well as an
embedded version of the Intel 486.
• SGS Thomson. Maker of various 8 and 16-bit microcontrollers.
• Analog Devices. DSPs and many analog ICs.
• Digital Equipment (DEC). The Strong-Arm SA-110 and SA-1110.
• ARM. Licenses the ARM core used in many processors and ASIC’s.
• Advanced Micro Devices (AMD). Manufacturer of various RISC and Intel x86
clones, as well as a large line of embedded x86 derivatives.
Summary
• Covers key techniques required in all embedded systems in detail, including the
control of port pins and the reading of switches.
• Presents a complete embedded operating system, which uses less than 1% of the
available processor power of an embedded 8051 microcontroller.
• Covers the microcontroller serial interface, which is widely used for debugging
embedded systems, as well as for system maintenance and in data acquisition
applications.
• Includes a substantial and realistic case study.
• Uses 100% C code: no knowledge of assembly language is needed. An industry-
standard C compiler from Kiel Software is also included on the CD, along with
copies of the source code from the book. Programmers with experience of Java,
C++ or C on a desktop PC or workstation will therefore be able to get up and
running very quickly.
• The type of embedded systems that will be discussed
• The choice of programming language for embedded systems.
• The choice of operating system for embedded systems.
• The process of creating executable code for an embedded processor on a desktop
PC.
• The process of testing the embedded code.
Technical questions
2. Treat r6-r7 and r4-r5 as two 16-bit registers. Perform subtraction between them. Store
the result in 20h (lower byte) and 21h (higher byte).
Exercise
1) Divide the content of r0 by r1. Store the result in r2 (Solution) and r3 (reminder).
Then restore the original content of r0.
2) Transfer the block of data from 20h to 30h to external location 1020h to 1030h.
CHAPTER 5
RISC (Reduced Instruction Set Computer) and CISC (Complex Instruction Set
Computer) stands for two different competing philosophies in designing modern computer
architecture. The difference between RISC and CISC can lie on many levels, many plausible
arguments are put forward by both sides, such as code density, transistor counts, memory
bottlenecks, complier and decode complexity etc.
As time passed, one of the non-RISC architecture with large market is the Intel
x 86 families; it has some specific characteristics associated with CISC:
Segmented memory model
Few registers
Crappy floating point performance
5.2.1 MICROCONTROLLER
Microcontrollers are used in a wide number of electronic systems such as:
Engine management systems in automobiles.
Keyboard of a PC.
Electronic measurement instruments (such as digital millimeters, frequency
oscilloscopes)
Printers.
Mobile phones.
Televisions, radios, CD players, tape recording equipment.
Hearing aids.
Security alarm systems, fire alarm systems, and building services systems
5.2.2 Microprocessor
Microprocessor is the integration of a number of useful functions into a single IC
Package. These functions are:
The ability to execute a stored set of instructions to carry out user defined tasks.
The ability to be able to access external memory chips to both read and write
From the memory.
MICROCONTROLLER MICROPROCESSOR
In built memory External memory
Internal I/O Circuit External I/O Circuit
More bit handling Instructions Few bit handling instructions.
That we can interface a microcontroller Microprocessor we can't interface
Directly means, "for example we can directly...we
directly connect a Keyboard to require a circuit board since it requires
microcontroller to any of its ports". RAM, IC.....etc
Designed to perform a small set of Designed to perform a wider set of
specific functions general-purpose functions.
RISC architecture CISC architecture
5.5.1 PORT 0
Port 0 is an 8-bit open drain bidirectional I/O port. As an output port, each pin
can sink eight TTL inputs. When 1s are written to port 0 pins, the pins can be used as high-
impedance inputs. Port 0 can also be configured to be the multiplexed low-order address/data
bus during accesses to external program and data memory. In this mode, P0 has internal pull-
ups. Port 0 also receives the code bytes during Flash programming and outputs the code bytes
during program verification. External pull-ups are required during program verification.
5.5.2 PORT 1
Port 1 is an 8-bit bidirectional I/O port with internal pull-ups. The Port 1 output
buffers can sink/source four TTL inputs. When 1s are written to Port 1 pins, they are pulled
high by the internal pull-ups and can be used as inputs. As inputs, Port 1 pins that are
externally being pulled low will source current (IIL) because of the internal pull-ups.
5.5.3 PORT 2
Port 2 is an 8-bit bidirectional I/O port with internal pull-ups. The Port 2 output
buffers can sink/source four TTL inputs. When 1s are written to Port 2 pins, they are pulled
high by the internal pull-ups and can be used as inputs. As inputs, Port 2 pins that are
externally being pulled low will source current (IIL) because of the internal pull-ups. Port 2
emits the high-order address byte during fetches from external program memory and during
accesses to external data memory that uses 16-bit addresses (MOVX @ DPTR). In this
application, Port 2 uses strong internal pull-ups when emitting 1s. During accesses to external
data memory that uses 8-bit addresses (MOVX @ RI); Port 2 emits the contents of the P2
Special Function Register. Port 2 also receives the high-order address bits and some control
signals during Flash programming and verification.
5.5.4 PORT 3
Port 3 is an 8-bit bidirectional I/O port with internal pull-ups. The Port 3 output
buffers can sink/source four TTL inputs. When 1s are written to Port 3 pins, they are pulled
high by the internal pull-ups and can be used as inputs. As inputs, Port 3 pins that are
externally being pulled low will source current (IIL) because of the pull-ups. Port 3 receives
some control signals for Flash programming and verification. Port 3 also serves the functions
of various special features of the 8051.
5.5.6 RST
Reset input. A high on this pin for two machine cycles while the oscillator is running
resets the device. This pin drives high for 98 oscillator periods after the Watchdog times out.
The DISRTO bit in SFR AUXR (address 8EH) can be used to disable this feature. In the
default state of bit DISRTO, the RESET HIGH out feature is enabled.
5.5.7 ALE/PROG
Address Latch Enable (ALE) is an output pulse for latching the low byte of the
address during accesses to external memory. This pin is also the program pulse input (PROG)
during Flash programming. In normal operation, ALE is emitted at a constant rate of 1/6 the
oscillator frequency and may be used for external timing or clocking purposes. Note,
however, that one ALE pulse is skipped during each access to external data memory. If
desired, ALE operation can be disabled by setting bit 0 of SFR location 8EH. With the bit set,
ALE is active only during a MOVX or MOVC instruction. Otherwise, the pin is weakly
pulled high. Setting the ALE-disable bit has no effect if the microcontroller is in external
execution mode.
5.5.8 PSEN
Program Store Enable (PSEN) is the read strobe to external program memory. When
the AT89S52 is executing code from external program memory, PSEN is activated twice
each machine cycle, except that two PSEN activations are skipped during each access to
external data memory.
5.5.9 EA/VPP
External Access Enable. (EA) must be strapped to GND in order to enable the device
to fetch code from external program memory locations starting at 0000H up to FFFFH. Note,
however, that if lock bit 1 is programmed, EA will be internally latched on reset. EA should
be strapped to VCC for internal program executions. This pin also receives the 12-volt
programming enable voltage (VPP) during Flash programming.
5.6.0 XTAL1
Input to the inverting oscillator amplifier and input to the internal clock operating
circuit.
5.6.1 XTAL2
MOV A, #20h
This instruction uses Immediate Addressing because the Accumulator will be loaded
with the value that immediately follows; in this case 20 (hexadecimal).
Immediate addressing is very fast since the value to be loaded is included in the
instruction. However, since the value to be loaded is fixed at compile-time it is not very
flexible.
MOV A, 30h
This instruction will read the data out of Internal RAM address 30 (hexadecimal) and
store it in the Accumulator.
Direct addressing is generally fast since, although the value to be loaded isn’t
included in the instruction, it is quickly accessible since it is stored in the 8051s Internal
RAM. It is also much more flexible than Immediate Addressing since the value to be loaded
is whatever is found at the given address--which may be variable.
Also, it is important to note that when using direct addressing any instruction which
refers to an address between 00h and 7Fh is referring to Internal Memory. Any instruction
which refers to an address between 80h and FFh is referring to the SFR control registers that
control the 8051 microcontroller itself.
The obvious question that may arise is, "If direct addressing an address from 80h
through FFh refers to SFRs, how can I access the upper 128 bytes of Internal RAM that are
available on the 8052?" The answer is: You cant access them using direct addressing. As
stated, if you directly refer to an address of 80h through FFh you will be referring to an SFR.
However, you may access the 8052s upper 128 bytes of RAM by using the next addressing
mode, "indirect addressing".
Indirect addressing is a very powerful addressing mode which in many cases provides
an exceptional level of flexibility. Indirect addressing is also the only way to access the extra
128 bytes of Internal RAM found on an 8052.
MOV A,@R0
This instruction causes the 8051 to analyze the value of the R0 register. The 8051 will
then load the accumulator with the value from Internal RAM which is found at the address
indicated by R0.
For example, let us say R0 holds the value 40h and Internal RAM address 40h holds
the value 67h. When the above instruction is executed, the 8051 will check the value of R0.
Since R0 holds 40h, the 8051 will get the value out of Internal RAM address 40h (which
holds 67h) and store it in the Accumulator. Thus, the Accumulator ends up holding 67h.
Indirect addressing always refers to Internal RAM; it never refers to an SFR. Thus, in
a prior example we mentioned that SFR 99h could be used to write a value to the serial port.
Thus, one may think that the following would be a valid solution to write the value 1 to the
serial port:
This is not valid. Since indirect addressing always refers to Internal RAM these two
instructions would write the value 01h to Internal RAM address 99h on an 8052. On an 8051,
these two instructions would produce an undefined result since the 8051 only has 128 bytes
of Internal RAM.
External Memory is accessed using a suite of instructions, which use what I call
"External Direct" addressing. I call it this because it appears to be direct addressing, but it is
used to access external memory rather than internal memory.
There are only two commands that use External Direct addressing mode:
MOVXA,@DPTR
MOVX @DPTR, A
As you can see, both commands utilize DPTR. In these instructions, DPTR must first
be loaded with the address of external memory that you wish to read or write. Once DPTR
holds the correct external memory address, the first command will move the contents of that
external memory address into the Accumulator. The second command will do the opposite: it
will allow you to write the value of the Accumulator to the external memory address pointed
to by DPTR.
External memory can also be accessed using a form of indirect addressing which I call
External Indirect addressing. This form of addressing is usually only used in relatively small
projects that have a very small amount of external RAM. An example of this addressing
mode is:
MOVX @R0, A
Once again, the value of R0 is first read and the value of the Accumulator is written to
that address in External RAM. Since the value of @R0 can only be 00h through FFh the
project would effectively be limited to 256 bytes of External RAM. There are relatively
simple hardware/software tricks that can be implemented to access more than 256 bytes of
memory using External Indirect addressing; however, it is usually easier to use External
Direct addressing if your project has more than 256 bytes of External RAM.
Many computer operations are concerned with moving data from one location to
another. The 8051 uses five different types of instruction to move data:
MOV
In the 8051 the MOV instruction is concerned with moving data internally, i.e.
between Internal RAM, SFR registers, general registers etc. MOVX and MOVC are used in
accessing external memory data. The MOV instruction has the following format:
MOVX
The 8051 the external memory can be addressed using indirect addressing only. The
DPTR register is used to hold the address of the external data (since DPTR is a 16-bit
register, it can address 64KByte locations: 216 = 64K). The 8 bit registers R0 or R1 can also
be used for indirect addressing of external memory but the address range is limited to the
lower 256 bytes of memory (28 = 256 bytes).
The MOVX instruction is used to access the external memory (X indicates external
memory access). All external moves must work through the A register (accumulator).
Examples of MOVX instructions are:
MOV DPTR, # 2000h ; Copy the data value 2000h to the DPTR register
MOV A, #80h ; Copy the data value 80h to register A
MOVC A, @A+DPTR ; Copy the contents of the address 2080h (2000h +
80h)
; To register A
Note, for the MOVC the program counter, PC, can also be used to form the address.
PUSH and POP instructions are used with the stack only. The SFR register SP
contains the current stack address. Direct addressing is used as shown in the following
Examples
POP 80h; the data from current SP address is copied to 80h and SP is
Decremented.
XCH
The above move instructions copy data from a source location to a destination
location, leaving the source data unaffected. A special XCH (exchange) instruction will
actually swap the data between source and destination, effectively changing the source data.
Immediate addressing may not be used with XCH. XCH instructions must use register A.
XCHD is a special case of the exchange instruction where just the lower nibbles are
exchanged. Examples using the XCH instruction are:
5.8.1 ARITHMETIC
Some key flags within the PSW, i.e. C, AC, OV, P, are utilised in many of the
arithmetic instructions. The arithmetic instructions can be grouped as follows:
A) Addition
B) Subtraction
C) Increment/decrement
D) Multiply/divide
E) Decimal adjust
EXPLANATION
A) ADDITION
Register A (the accumulator) is used to hold the result of any addition operation.
Some simple addition examples are:
The flags in the PSW register are affected by the various addition operations, as
follows:
The C (carry) flag is set to 1 if the addition resulted in a carry out of the accumulator’s
MSB bit, otherwise it is cleared.
The AC (auxiliary) flag is set to 1 if there is a carry out of bit position 3 of the
accumulator, otherwise it is cleared.
For signed numbers the OV flag is set to 1 if there is an arithmetic overflow (described
elsewhere in these notes)
Simple addition is done within the 8051 based on 8 bit numbers, but it is often
required to add 16 bit numbers, or 24 bit numbers etc. This leads to the use of multiple byte
(multi-precision) arithmetic. The least significant bytes are first added, and if a carry results,
this carry is carried over in the addition of the next significant byte etc. This addition process
is done at 8-bit precision steps to achieve multi-precision arithmetic. The ADDC instruction
is used to include the carry bit in the addition process. Example instructions using ADDC are:
ADDC A, #55h ; Add contents of A, the number 55h, the carry bit; and put
the Sum in A
ADDC a, R4; Add the contents of a, the register R4, the carry bit; and put
The sum in A.
B) SUBTRACTION
Computer subtraction can be achieved using 2’s complement arithmetic. Most
computers also provide instructions to directly subtract signed or unsigned numbers. The
accumulator, register A, will contain the result (difference) of the subtraction operation. The
C (carry) flag is treated as a borrow flag, which is always subtracted from the minuend during
a subtraction operation. Some examples of subtraction instructions are:
SUBB A, #55d ; Subtract the number 55 (decimal) and the C flag from and
Put the result in A.
SUBB A, R6 ; Subtract R6 the C flag from A; and put the result in A.
SUBB A, 58h ; Subtract the number in RAM location 58h and the C flag
From A; and put the result in A.
C) INCREMENT/DECREMENT
The increment (INC) instruction has the effect of simply adding a binary 1 to a
number while a decrement (DEC) instruction has the effect of subtracting a binary 1 from a
number. The increment and decrement instructions can use the addressing modes: direct,
indirect and register. The flags C, AC, and OV are not affected by the increment or
decrement instructions. If a value of FFh is increment it overflows to 00h. If a value of 00h is
decrement it underflows to FFh. The DPTR can overflow from FFFFh to 0000h. The DPTR
register cannot be decremented using a DEC instruction (unfortunately!). Some example INC
and DEC instructions are as follows:
D) MULTIPLY / DIVID
The 8051 supports 8-bit multiplication and division. This is low precision (8 bit)
arithmetic but is useful for many simple control applications. The arithmetic is relatively fast
since multiplication and division are implemented as single instructions. If better precision, or
indeed, if floating point arithmetic is required then special software routines need to be
written. For the MUL or DIV instructions the A and B registers must be used and only
unsigned numbers are supported.
(i) MULTIPLICATION
The MUL instruction is used as follows (note absence of a comma between the A and
B operands):
MUL AB ; Multiply A by B.
The resulting product resides in registers A and B, the low-order byte is in A and the
high order byte is in B.
(ii)DIVISION
The DIV instruction is used as follows:
DIV AB ; A is divided by B.
The remainder is put in register B and the integer part of the quotient is put in register A.
and the zone wiring could not operate over any long distances. However, the example will
suffice to demonstrate the concept.
The burglar alarm’s output consists of a seven-segment display device and an alarm bell.
The alarm bell is connected to Port 1, bit 7, and the bell is sounded when this output pin is set
to a logic high level by the software. The seven-segment display device is connected to Port
1, bits 0 to 6. Each output pin is fed to the relevant display segment via a non-inverting buffer
device. The seven-segment display device is a common-cathode device so writing a logic
high level to any segment will cause that segment to light.
5.9 TIMERS/COUNTERS
The 8051 comes equipped with two timers, both of which may be controlled, set,
read, and configured individually. The 8051 timers have three general functions: 1) Keeping
time and/or calculating the amount of time between events, 2) Counting the events
themselves, or 3) Generating baud rates for the serial port.
The three timer uses are distinct so we will talk about each of them separately. The
first two uses will be discussed in this chapter while the use of timers for baud rate generation
will be discussed in the chapter relating to serial ports.
How does a timer count? The answer to this question is very simple: A timer always
counts. It does not matter whether the timer is being used as a timer, a counter, or a baud rate
generator: A timer is always incremented by the microcontroller.
Programming Tip: Some derivative chips actually allow the program to configure
whether the timers count up or down. However, since this option only exists on some
derivatives it is beyond the scope of this tutorial, which is aimed at the standard 8051. It is
only mentioned here in the event that you absolutely need a timer to count backwards, you
will know that you may be able to find an 8051-compatible microcontroller that does it.
Obviously, one of the primary uses of timers is to measure time. We will discuss this
use of timers first and will subsequently discuss the use of timers to count events. When a
timer is used to measure time it is also called an "interval timer" since it is measuring the time
of the interval between two events.
First, it is worth mentioning that when a timer is in interval timer mode (as opposed to
event counter mode) and correctly configured, it will increment by one every machine cycle.
As you will recall from the previous chapter, a single machine cycle consists of 12 crystal
pulses. Thus, a running timer will be incremented:
11,059,000 / 12 = 921,583
Obviously, it is not very useful to know .0542 seconds have passed. If you want to
execute an event once per second you have to wait for the timer to count from 0 to 50,000
18.45 times. How can you wait "half of a time?" You cannot. Therefore, we come to another
important calculation.
Let us say we want to know how many times the timer will be incremented in .05
seconds. We can do simple multiplication:
This tells us that it will take .05 seconds (1/20th of a second) to count from 0 to
46,079. Actually, it will take it .049999837 seconds--so were off by .000000163 seconds--
however, that’s close enough for government work. Consider that if you were building a
watch based on the 8051 and made the above assumption your watch would only gain about
one second every 2 months. Again, I think that is accurate enough for most applications--I
wish my watch only gained one second every two months!
Obviously, this is a little more useful. If you know it takes 1/20th of a second to count
from 0 to 46,079 and you want to execute some event every second you simply wait for the
timer to count from 0 to 46,079 twenty times; then you execute your event, reset the timers,
and wait for the timer to count up another 20 times. In this manner you will effectively
execute your event once per second, accurate to within thousandths of a second.
Thus, we now have a system with which to measure time. All we need to review is
how to control the timers and initialize them to provide us with the information we need.
We have given SFRs names to make it easier to refer to them, but in reality, an SFR
has a numeric address. It is often useful to know the numeric address that corresponds to an
SFR name. The SFRs relating to timers are:
When you enter the name of an SFR into an assembler, it internally converts it to a
number. For example, the command:
Timer 0 has two SFRs dedicated exclusively to itself: TH0 and TL0. Without making
things too complicated to start with, you may just think of this as the high and low byte of the
timer. That is to say, when Timer 0 has a value of 0, both TH0 and TL0 will contain 0. When
Timer 0 has the value 1000, TH0 will hold the high byte of the value (3 decimal) and TL0
will contain the low byte of the value (232 decimal). Reviewing low/high byte notation, recall
that you must multiply the high byte by 256 and add the low byte to calculate the final value.
That is to say:
Since there are, only two bytes devoted to the value of each timer it is apparent that
the maximum value a timer may have is 65,535. If a timer contains the value 65,535 and is
subsequently incremented, it will reset--or overflow--back to 0.
Lets first talk about our first control SFR: TMOD (Timer Mode). The TMOD SFR is
used to control the mode of operation of both timers. Each bit of the SFR gives the
microcontroller specific information concerning how to run a timer. The high four bits (bits 4
through 7) relate to Timer 1 whereas the low four bits (bits 0 through 3) perform the exact
same functions, but for timer 0.
As you can see in the above chart, four bits (two for each timer) are used to specify a
mode of operation. The modes of operation are:
Timer mode "0" is a 13-bit timer. This is a relic that was kept around in the 8051 to
maintain compatibility with its predecessor, the 8048. Generally, the 13-bit timer mode is not
used in new development.
When the timer is in 13-bit mode, TLx will count from 0 to 31. When TLx is
incremented from 31, it will "reset" to 0 and increment THx. Thus, effectively, only 13 bits of
the two timer bytes are being used: bits 0-4 of TLx and bits 0-7 of THx. This also means, in
essence, the timer can only contain 8192 values. If you set a 13-bit timer to 0, it will overflow
back to zero 8192 machine cycles later.
Again, there is very little reason to use this mode and it is only mentioned so you will
not be surprised if you ever end up analyzing archaic code, which has been passed down
through the generations (a generation in a programming shop is often about 3 or 4 months).
Timer mode "1" is a 16-bit timer. This is a very commonly used mode. It functions
just like 13-bit mode except that all 16 bits are used.
TLx is incremented from 0 to 255. When TLx is incremented from 255, it resets to 0
and causes THx to be incremented by 1. Since this is a full 16-bit timer, the timer may
contain up to 65536 distinct values. If you set a 16-bit timer to 0, it will overflow back to 0
after 65,536 machine cycles.
Timer mode "2" is an 8-bit auto-reload mode. What is that, you may ask? Simple.
When a timer is in mode 2, THx holds the "reload value" and TLx is the timer itself. Thus,
TLx starts counting up. When TLx reaches 255 and is subsequently incremented, instead of
resetting to 0 (as in the case of modes 0 and 1), it will be reset to the value stored in THx.
For example, let us say TH0 holds the value FDh and TL0 holds the value FEh. If we
were to watch the values of TH0 and TL0 for a few machine cycles this is what wed see:
As you can see, the value of TH0 never changed. In fact, when you use mode 2 you
almost always set THx to a known value and TLx is the SFR that is constantly incremented.
What is the benefit of auto-reload mode? Perhaps you want the timer to always have a
value from 200 to 255. If you use mode 0 or 1, you would have to check in code to see if the
timer had overflowed and, if so, reset the timer to 200. This takes precious instructions of
execution time to check the value and/or to reload it. When you use mode 2 the
microcontroller takes care of this for you. Once you’ve configured a timer in mode 2 you
don’t have to worry about checking to see if the timer has overflowed nor do you have to
worry about resetting the value--the microcontroller hardware will do it all for you. The auto-
reload mode is very commonly used for establishing a baud rate, which we will talk more
about in the Serial Communications chapter.
While Timer 0 is in split mode, the real Timer 1 (i.e. TH1 and TL1) can be put into
modes 0, 1 or 2 normally--however, you may not start or stop the real timer 1 since the bits
that do that are now linked to TH0. The real timer 1, in this case, will be incremented every
machine cycle no matter what.
The only real use I can see of using split timer mode is if you need to have two
separate timers and, additionally, a baud rate generator. In such case, you can use the real
Timer 1 as a baud rate generator and use TH0/TL0 as two separate timers.
Finally, there is one more SFR that controls the two timers and provides valuable
information about them. The TCON SFR has the following structure:
Bit
Bit Name Explanation of Function Timer
Address
Timer 1 Overflow. This bit is set by the
7 TF1 8Fh 1
microcontroller when Timer 1 overflows.
Timer 1 Run. When this bit is set Timer 1 is turned on.
6 TR1 8Eh 1
When this bit is clear, Timer 1 is off.
Timer 0 Overflow. This bit is set by the
5 TF0 8Dh 0
microcontroller when Timer 0 overflows.
Timer 0 Run. When this bit is set Timer 0 is turned on.
4 TR0 8Ch 0
When this bit is clear Timer, 0 is off.
As you may notice, we have only defined 4 of the 8 bits. That is because the other 4
bits of the SFR do not have anything to do with timers--they have to do with Interrupts and
they will be discussed in the chapter that addresses interrupts.
A new piece of information in this chart is the column "bit address." This is because
this SFR is "bit-addressable." What does this mean? It means if you want to set the bit TF1--
which is the highest bit of TCON--you could execute the command:
Alternatively, since the SFR is bit-addressable, you could just execute the command:
SETB TF1
This has the benefit of setting the high bit of TCON without changing the value of any
of the other bits of the SFR. Usually when you start or stop a timer you do not want to modify
the other values in TCON, so you take advantage of the fact that the SFR is bit-addressable.
Now that we have discussed the timer-related SFRs, we are ready to write code that
will initialize the timer and start it running.
As you will recall, we first must decide what mode we want the timer to be in. In this
case, we want a 16-bit timer that runs continuously; that is to say, it is not dependent on any
external pins.
We must first initialize the TMOD SFR. Since we are working with timer 0, we will
be using the lowest 4 bits of TMOD. The first two bits, GATE0 and C/T0 are both 0 since we
want the timer to be independent of the external pins. 16-bit mode is timer mode 1 so we
must clear T0M1 and set T0M0. Effectively, the only bit we want to turn on is bit 0 of
TMOD. Thus to initialize the timer we execute the instruction:
SETB TR0
Upon executing these two instructions timer 0 will immediately begin counting, being
incremented once every machine cycle (every 12 crystal pulses).
There are two common ways of reading the value of a 16-bit timer; which you use
depends on your specific application. You may either read the actual value of the timer as a
16-bit number, or you may simply detect when the timer has overflowed.
If your timer is in an 8-bit mode--that is, either 8-bit Auto Reload mode or in split
timer mode--then reading the value of the timer is simple. You simply read the 1-byte value
of the timer.
However, if you are dealing with a 13-bit or 16-bit timer the chore is a little more
complicated. Consider what would happen if you read the low byte of the timer as 255, then
read the high byte of the timer as 15. In this case, what actually happened was that the timer
value was 14/255 (high byte 14, low byte 255) but you read 15/255. Why? Because you read
the low byte as 255. Nevertheless, when you executed the next instruction a small amount of
time passed--but enough for the timer to increment again at which time the value rolled over
from 14/255 to 15/0. Nevertheless, in the process you have read the timer as being 15/255.
Obviously, there is a problem there.
The solution? It’s not too tricky, really. You read the high byte of the timer, then read
the low byte, then read the high byte again. If the high byte read the second time is not the
same as the high byte read the first time you repeat the cycle. In code, this would appear as:
In this case, we load the accumulator with the high byte of Timer 0. We then load R0
with the low byte of Timer 0. Finally, we check to see if the high byte we read out of Timer
0--which is now stored in the Accumulator--is the same as the current Timer 0 high byte. If it
isn’t it means we’ve just "rolled over" and must reread the timer’s value--which we do by
going back to REPEAT. When the loop exits we will have the low byte of the timer in R0 and
the high byte in the Accumulator.
Another much simpler alternative is to simply turn off the timer run bit (i.e. CLR
TR0), read the timer value, and then turn on the timer run bit (i.e. SETB TR0). In that case,
the timer isn’t running so no special tricks are necessary. Of course, this implies that your
timer will be stopped for a few machine cycles. Whether or not this is tolerable depends on
your specific application.
Often it is necessary to just know that the timer has reset to 0. That is to say, you are
not particularly interest in the value of the timer but rather you are interested in knowing
when the timer has overflowed back to 0.
Whenever a timer overflows from its highest value back to 0, the microcontroller
automatically sets the TFx bit in the TCON register. This is useful since rather than checking
the exact value of the timer you can just check if the TFx bit is set. If TF0 is set it means that
timer 0 has overflowed; if TF1 is set it means that timer 1 has overflowed.
We can use this approach to cause the program to execute a fixed delay. As you’ll
recall, we calculated earlier that it takes the 8051 1/20th of a second to count from 0 to
46,079. However, the TFx flag is set when the timer overflows back to 0. Thus, if we want to
use the TFx flag to indicate when 1/20th of a second has passed we must set the timer
initially to 65536 less 46079, or 19,457. If we set the timer to 19,457, 1/20th of a second later
the timer will overflow. Thus we come up with the following code to execute a pause of
1/20th of a second:
In the above code the first two lines initialize the Timer 0 starting value to 19,457.
The next two instructions configure timer 0 and turn it on. Finally, the last instruction JNB
TF0, $, reads "Jump, if TF0 is not set, back to this same instruction." The "$" operand means,
in most assemblers, the address of the current instruction. Thus as long as the timer has not
overflowed and the TF0 bit has not been set the program will keep executing this same
instruction. After 1/20th of a second timer 0 will overflow, set the TF0 bit, and program
execution will then break out of the loop.
The 8051 provides another cool toy that can be used to time the length of events.
For example, let's say we're trying to save electricity in the office and we're interested
in how long a light is turned on each day. When the light is turned on, we want to measure
time. When the light is turned off we don't. One option would be to connect the light switch
to one of the pins, constantly read the pin, and turn the timer on or off based on the state of
that pin. While this would work fine, the 8051 provides us with an easier method of
accomplishing this.
Looking again at the TMOD SFR, there is a bit called GATE0. So far we've always
cleared this bit because we wanted the timer to run regardless of the state of the external pins.
However, now it would be nice if an external pin could control whether the timer was
running or not. All we need to do is connect the light switch to pin INT0 (P3.2) on the 8051
and set the bit GATE0. When GATE0 is set Timer 0 will only run if P3.2 is high. When P3.2
is low (i.e., the light switch is off) the timer will automatically be stopped.
Thus, with no control code whatsoever, the external pin P3.2 can control whether or
not our timer is running or not.
We've discussed how a timer can be used for the obvious purpose of keeping track of
time. However, the 8051 also allows us to use the timers to count events.
How can this be useful? Let's say you had a sensor placed across a road that would
send a pulse every time a car passed over it. This could be used to determine the volume of
traffic on the road. We could attach this sensor to one of the 8051's I/O lines and constantly
monitor it, detecting when it pulsed high and then incrementing our counter when it went
back to a low state. This is not terribly difficult, but requires some code. Let's say we hooked
the sensor to P1.0; the code to count cars passing would look something like this:
JNB P1.0,$ ;If a car hasn't raised the signal, keep waiting
JB P1.0,$ ;The line is high which means the car is on the sensor right now
INC COUNTER ;The car has passed completely, so we count it
As you can see, it's only three lines of code. However, what if you need to be doing
other processing at the same time? You can't be stuck in the JNB P1.0, $ loop waiting for a
car to pass if you need to be doing other things. Of course, there are ways to get around even
this limitation but the code quickly becomes big, complex, and ugly.
Since the 8051 provides us with a way to use the timers to count events we don't have
to bother with it. It is actually painfully easy. We only have to configure one additional bit.
Let's say we want to use Timer 0 to count the number of cars that pass. If you look
back to the bit table for the TCON SFR you will there is a bit called "C/T0"--it's bit 2
(TCON.2). Reviewing the explanation of the bit we see that if the bit is clear then timer 0 will
be incremented every machine cycle. This is what we've already used to measure time.
However, if we set C/T0 timer 0 will monitor the P3.4 line. Instead of being incremented
every machine cycle, timer 0 will count events on the P3.4 line. Therefore, in our case we
simply connect our sensor to P3.4 and let the 8051 do the work. Then, when we want to know
how many cars have passed, we just read the value of timer 0--the value of timer 0 will be the
number of cars that have passed.
So what exactly is an event? What does timer 0 actually "count?" Speaking at the
electrical level, the 8051 counts 1-0 transitions on the P3.4 line. This means that when a car
first runs over our sensor it will raise the input to a high ("1") condition. At that point the
8051 will not count anything since this is a 0-1 transition. However, when the car has passed
the sensor will fall back to a low ("0") state. This is a 1-0 transition and at that instant the
counter will be incremented by 1.
5.9.9 SUMMARY
5.11Exercise
1. Write a program to switch on a buzzer for every 14 seconds, using timer 0 modes 2.
2. Write a program to toggle a led after every 5 seconds using timer 0 modes 2.
CHAPTER 6
Bit manipulation is the act of algorithmically manipulating bits or other pieces of data
shorter than a byte. Programming tasks that require bit manipulation include low-level device
control, error detection and correction algorithms, encryption algorithms, and optimization.
For most other tasks, modern programming languages allow the programmer to work directly
with abstractions instead of bits that represent those abstractions.
Thus we have seen instructions that move data (from/to memory or registers),
calculate arithmetic functions (add, sub) or that change the control flow. There are other
classes of instructions in 68k that are also commonly found in most modern processors. The
first class of instructions we will discuss, implements bit-wise Boolean logic operations. The
second class operates on single bits. The third class performs shifts and rotates.
As an example let’s consider the AND.L instruction. All bitwise instructions treat
their arguments as a collection or 32 independent bits (or 16 bits or 8 bits) without assigning
an arithmetic value to the collection of all bits. For them, a register or a memory value is just
an ordered collection of 32 bits (or 16 or 8 – OK we will stop saying this from this point on,
but please do recall that the following discussion applies to words and bytes also). They then
operate on each of those 32 bits separately.
Note that this is equivalent to the “&” operation in C. Also note that “&” is the bitwise
operation in C. There “&&” operation in C operates on TRUE and FALSE values (non-zero
and zero respectively on most C dialects – some define <= 0 as false).
These operations are called bitwise because they treat their operands as a collection of
bits that are operated upon individually.
AND operations are useful among other things for masking out bits out of long
values. For example, say we are interested in whether an integer is even. In this case, the
lower bit of the integer must be 0. Accordingly we can use the following sequence:
ANDI.L #1, D0
BEQ ISEVEN
What we have done is use a constant that had a 1 only at the bit position that we were
interested in. By doing a logical AND with this constant we essentially zeroed out all bits
except the last one. As a result, the outcome of the AND operation would be zero if the least
significant bit was zero otherwise it will be non-zero.
Such operations are very handy when accessing data that uses long data types to
encapsulate a collection of different information pieces. We will see more concrete examples
when we talk about I/O devices.
Where EOR is the Exclusive OR, or also called XOR. So 0 EOR 0 = 1 EOR 1 = 0 and
1 EOR 0 = 0 EOR 1 = 0.
As a side note, here’s a quick way to swap the values of two registers:
eor.l d1, d0
eor.l d0, d1
eor.l d1, d0
Try a couple of examples, and then try to express the outcome of each instruction as a
function of the original values of d0 and d1 and XOR. Keep in mind that A XOR A = 0, A
XOR 0 = A and A XOR 1…1 = not (A). Some machines provide a swap instruction.
The C equivalents of the aforementioned bitwise operations are:
a AND b a & b
a OR b a | b
a EOR b a ^ b
NOT a ~a
The first three respectively clear, reverse and set the (bit no) bit of the destination.
Before changing the bit value, the bit is copied into the Z condition code. The last instruction
simply does that and does not affect the operand (tests for a bit value).
Examples:
Bits are numbered starting from 0 (leftmost – least significant). The data type can be either a
byte or a long word.
6.3 SHIFTS
The third class of bit manipulation instructions treats their operands as bits placed in
series one after the other. They displace these bits by a number of positions. Lets us look at
each one of these instructions. The shifts correspond to the “>>” and “<<” operations in C.
There are no C equivalents for the rotate instructions (although we can synthesize them using
shifts and bitwise logical operations).
First are logical shifts. For clarity we will restrict our attention to the 8 bit data type
however the discussion applies to all three data types.
Logical shifts can be performed either to the left or to the right. In shifts, the bits of the
operands being shifted are treated as 8 bits placed in order one after the other and on a
straight line. The instruction shifts those bits either to the left or to the right by a number of
bit positions. The positions that are left empty are filled with zeroes and the bits that are
shifted out of limits are simply discarded.
Assume that initially the value of the lower byte of d0 is 11001101. Shifting left by
one position gives 10011010. Note the 1 that was at the most significant bit position in the
source operand was discarded and the empty position that was created by shifting the bits to
the left was filled with a 0.
In summary, logical shifts move the bits by a specified number of bit positions to the
left or right. Bits positions that are emptied are filled with zeroes and bits that are moved out
of the bit positions that are available in the data type are discarded.
6.4 ROTATES
The last class of bit manipulation instructions treats their source/destination operand
as a sequence of bits that are placed on a circle. That is the bits are ordered (bit 1 is next to bit
2, which is next to bit 3 and so on) and bits 0 and 7 (for byte instructions) are also adjacent.
Similarly,
Here’s the code for multiplying d0 by 11 with the result stored in d1:
move.l d0, d1 ; make a copy of d0 in d1, so now d1 = d0 x 1
lsl.l #1, d0 ; d0 = d0 x 2
add.l d0, d1; d1 = d0 + d0 x 2
lsl.l #2, d0 ; d0 = d0 x 4 but since we changed d0 to 2 times its original value, now d0 is 8
times its original value
add.l d0, d1 ; d1 = d0 + d0 x 2 + d0 x 8
Here’s the code for multiplying d0 by 17:
move.l d0, d1 ; d1 = d0
lsl.l #4, d0 ; d0 = 16 x d0
add.l d0, d1 ; d1 = d0 + 16 x d0
In general, if we need to calculate A x B then looks at the binary representation of B
focusing on the bits that are 1. If B’s binary representation has a 1 at bit i, then we need to
include A x 2^i into our sum. So, if B = 10101 the sum will include the following terms: A x
2^0, A x 2^2 and A x 2^4.
The upper 128 bytes of RAM space can be accessed only by indirect addressing, and
SFR space can be accessed only by direct addressing. The stack space resides in on-chip
RAM in addition, grows upward. The PUSH instruction first increments the Stack Pointer
(SP), then copies the byte into the stack. PUSH and POP use only direct addressing to
identify the byte being saved or restored, but the stack itself is accessed by indirect
addressing using the SP register. Instructions with MOVX work on data transfer that access
external RAM memory. Instructions with MOVC work on moving constants for reading
look-up tables in program memory. The Data transfer instructions include a 16-bit MOV that
can be used to initialize the Data pointer for look-up tables in program memory or for 16-bit
data memory accesses.
DATA
Internal
Memory 000 Memory
Internal
SFRs FFF External
Internal CODE
RAM
000 Memory
Figure 1.5 8051 Memory representation
The 8051’s on-chip memory consists of 256 memory bytes organized as follows:
We will discuss a few specific SFR registers here to help explain the SFR concept.
Other specific SFR will be explained later.
CARRY FLAG. C
This is a conventional carry, or borrows, flag used in arithmetic operations. The carry
flag is also used as the ‘Boolean accumulator’ for Boolean instruction operating at the bit
level. This flag is sometimes referenced as the CY flag.
This is a conventional auxiliary carry (half carry) for use in BCD arithmetic.
FLAG 0. F0
This is a general-purpose flag for user programming.
Register bank select 0 and register bank select 1. RS0 and RS1
These bits define the active register bank (bank 0 is the default register bank).
OVERFLOW FLAG. OV
This is a conventional overflow bit for signed arithmetic to determine if the result of a
signed arithmetic operation is out of range.
EVEN PARITY FLAG. P
The parity flag is the accumulator parity flag, set to a value, 1 or 0, such that the number of
‘1’ bits in the accumulator plus the parity bit add up to an even number.
6.11 ACCUMULATOR
This is the conventional accumulator that one expects to find in any computer, which
is used to the hold result of various arithmetic and logic operations. Since the 8051
microcontroller is just an 8-bit device, the accumulator is, as expected, an 8 bit register.
The accumulator, referred to as ACC or A, is usually accessed explicitly using
instructions such as:
INC A ; Increment the accumulator
However, the accumulator is defined as an SFR register at address E0h. Therefore, the
following two instructions have the same effect:
MOV A, #52h ; Move immediate the value 52h to the accumulator
MOV E0h, #52h ; Move immediate the value 52h to Internal RAM location E0h,
Which is, in fact, the accumulator SFR register?
Usually the first method, MOV A, #52h, is used as this is the most conventional (and happens
to use less space, 2 bytes as oppose to 3 bytes!)
B REGISTER
The B register is an SFR register at addresses F0h that is bit-addressable. The B
register is used in two instructions only: i.e. MUL (multiply) and DIV (divide). The B register
can also be used as a general-purpose register.
The PC (Program Counter) is a 2 byte (16 bit) register, which always contains the
memory address of the next instruction to be executed. When the 8051 is reset the PC is
always initialized to 0000h. If a 2 byte instruction is executed the PC is incremented by 2 and
if a 3 byte instruction is executed the PC is incremented by three so as to correctly point to
the next instruction to be executed. A jump instruction (e.g. LJMP) has the effect of causing
the program to branch to a newly specified location, so the jump instruction causes the PC
contents to change to the new address value. Jump instructions cause the program to flow in a
non-sequential fashion.
TCON, the Timer Control register is an SFR at address 88h, which is bit-addressable.
TCON is used to configure and monitor the 8051 timers. The TCON SFR also contains some
interrupt control bits.
TMOD, the Timer Mode register is an SFR at address 89h and is used to define the
operational modes for the timers.
TL0 (Timer 0 Low) and TH0 (Timer 0 High) are two SFR registers addressed at 8Ah
and 8Bh respectively. The two registers are associated with Timer 0.
TL1 (Timer 1 Low) and TH1 (Timer 1 High) are two SFR registers addressed at 8Ch
and 8Dh respectively. These two registers are associated with Timer 1.
The SCON (Serial Control) is an SFR register located at addresses 98h, and it is bit-
addressable. SCON configures the behavior of the on-chip serial port, setting up parameters
such as the baud rate of the serial port, activating send and/or receive data, and setting up
some specific control flags.
The SBUF (Serial Buffer) is an SFR register located at address 99h. SBUF is just a
single byte deep buffer used for sending and receiving data via the on-chip serial port
6.16 INTERRUPT REGISTERS
Interrupts will be discussed in more detail later. The associated SFR registers are:
IE (Interrupt Enable) is an SFR register at addresses A8h and is used to enable and
disable specific interrupts. The MSB bit (bit 7) is used to disable all interrupts.
IP (Interrupt Priority) is an SFR register at addresses B8h and it is bit addressable.
The IP register specifies the relative priority (high or low priority) of each interrupt. On the
8051, an interrupt may either be of low (0) priority or high (1) priority. .
6.17 ROM
ROM is an acronym for Read-Only Memory. It refers to computer memory chips
containing permanent or semi-permanent data. Unlike RAM, ROM is non-volatile; even after
you turn off your computer, the contents of ROM will remain.
Almost every computer comes with a small amount of ROM containing the boot
firmware. This consists of a few kilobytes of code that tell the computer what to do when it
starts up, e.g., running hardware diagnostics and loading the operating system into RAM. On
a PC, the boot firmware is called the BIOS.
configuring the second memory to store the instructions for normal operational use of the
microcontroller or data after the debugging of the instructions within the first memory is
completed. Storing instructions for normal operational use of the microcontroller in a first
memory includes storing the instructions for normal operational use of the microcontroller in
a read-only memory; and storing patch code instructions in a second memory includes storing
the patch code instructions in a bi-dimensional random access memory (RAM) array. The bi-
dimensional random access memory (RAM) array comprises a plurality of random access
memories (Rams) of a pre-determined size. The pre-determined size is one of 8-bits, 16-bits,
32-bits, 64-bits, or 128-bits. configuring the second memory includes configuring the second
memory according to one of the following storage configurations after the debugging of the
instructions within the first memory is completed: to only store the data, to only store the
instructions for normal operational use of the microcontroller, or to store both the data and
the instructions for normal operational use of the microcontroller. Comprising designating an
instruction portion of the second memory for storing instructions and designating a data
portion of the second memory for storing data. Further comprising storing, in a third memory,
data required by the CPU to execute the instructions stored in the first memory. The
microcontroller is a Harvard 8-bit data, 16-bit instruction microcontroller.A system for
performing a specific task, the system comprising: a microcontroller operable to execute
instructions associated with the task, the microcontroller including, a first memory operable
to store the instructions associated with the task; a second memory operable to store patch
code instructions during debugging of the instructions associated with the task; and a central
processing unit (CPU) operable to fetch the instructions from the first memory and the patch
code instructions from the second memory, wherein the second memory is operable to store
the instructions associated with the task or data for performing the task after the debugging of
the instructions within the first memory is completed. The first memory is a read-only
memory and the second memory is a bi-directional random access memory (RAM) array.
The microcontroller is a Harvard 8-bit data, 16-bit instruction microcontroller. The system is
associated with one of a data storage system, wireless system, or a computer system
6.19 Summary
In this chapter we learned about Microcontroller
Types of memories .
Electrically erasable(but unlike EEPROM memory) it does not have such a great
number of cycles of writing and erasing at memory locations.
It does not hold back the contents as the previous when there is supply shortage.
Thus, program is not stored in it, but it Serves for different variables and inter-results.
Boolean logic, rotateand swap instructions are covered in this chapter.
Byte-level operations involve each individual bit of a source byte operating on the
same bit position in the destination byte; the results are put in the destination, while
the source is not changed.
Technical Question
1. What is Bit and Byte?
2. What is Bit manipulation?
3. What is difference between ROM and RAM?
4. What is data transfer?
5. How many instructions available in 8051?
Exercise
1. Find a number that, at pc from microcontroller using TMOD, SCON registers.
2. Write program to Specifying the ISR Register Bank
CHAPTER -7
INTERRUPT
This chapter will give information about interrupts and its types.
We can learn about how to debug an interrupt.
7.1INTERRUPT
We can configure the 8051 so that any of the following events will cause an interrupt:
Timer 0 Overflow.
Timer 1 Overflow.
Reception/Transmission of Serial Character.
External Event 0.
External Event 1.
In other words, we can configure the 8051 so that when Timer 0 overflows or when a
character is sent / received, the appropriate interrupt handler routines are called.
By consulting the above chart we see that whenever Timer 0 overflows (i.e., the TF0
bit is set), the main program will be temporarily suspended and control will jump to 000BH.
It is assumed that we have code at address 000BH that handles the situation of Timer 0
overflowing.
Setting up Interrupts
By default at powerup, all interrupts are disabled. This means that even if, for
example, the TF0 bit is set, the 8051 will not execute the interrupt. Your program must
specifically tell the 8051 that it wishes to enable interrupts and specifically which interrupts it
wishes to enable.
Your program may enable and disable interrupts by modifying the IE SFR (A8h):
As you can see, each of the 8051s interrupts has its own bit in the IE SFR. You enable
a given interrupt by setting the corresponding bit. For example, if you wish to enable Timer 1
Interrupt, you would execute either:
However, before Timer 1 Interrupt (or any other interrupt) is truly enabled, you must
also set bit 7 of IE. Bit 7, the Global Interrupt Enable/Disable, enables or disables all
interrupts simultaneously. That is to say, if bit 7 is cleared then no interrupts will occur, even
if all the other bits of IE are set. Setting bit 7 will enable all the interrupts that have been
selected by setting other bits in IE. This is useful in program execution if you have time-
critical code that needs to execute. In this case, you may need the code to execute from start
to finish without any interrupt getting in the way. To accomplish this you can simply clear bit
7 of IE (CLR EA) and then set it after your time-critical code is done.
So, to sum up what has been stated in this section, to enable the Timer 1 Interrupt the
most common approach is to execute the following two instructions?
SETB ET1
SETB EA
The 8051 automatically evaluates whether an interrupt should occur after every
instruction. When checking for interrupt conditions, it checks them in the following order:
• External 0 Interrupt
• Timer 0 Interrupt
• External 1 Interrupt
• Timer 1 Interrupt
• Serial Interrupt
This means that if a Serial Interrupt occurs at the exact same instant that an External 0
Interrupt occurs, the External 0 Interrupt will be executed first and the Serial Interrupt will be
executed once the External 0 Interrupt has completed.
The 8051 offers two levels of interrupt priority: high and low. By using interrupt
priorities you may assign higher priority to certain interrupt conditions.
For example, you may have enabled Timer 1 Interrupt, which is automatically called
every time Timer 1 overflows. Additionally, you may have enabled the Serial Interrupt,
which is called every time a character is received via the serial port. However, you may
consider that receiving a character is much more important than the timer interrupt. In this
case, if Timer 1 Interrupt is already executing you may wish that the serial interrupt itself
interrupts the Timer 1 Interrupt. When the serial interrupt is complete, control passes back to
Timer 1 Interrupt and finally back to the main program. You may accomplish this by
assigning a high priority to the Serial Interrupt and a low priority to the Timer 1 Interrupt.
Interrupt priorities are controlled by the IP SFR (B8h). The IP SFR has the following
format:
When an interrupt is triggered, the following actions are taken automatically by the
microcontroller:
Take special note of the third step: If the interrupt being handled is a Timer or
External interrupt, the microcontroller automatically clears the interrupt flag before passing
control to your interrupt handler routine. This means it is not necessary that you clear the bit
in your code.
Serial Interrupts are slightly different than the rest of the interrupts. This is due to the
fact that there are two interrupt flags: RI and TI. If either flag is set, a serial interrupt is
triggered. As you will recall from the section on the serial port, the RI bit is set when a byte is
received by the serial port and the TI bit is set when a byte has been sent.
This means that when your serial interrupt is executed, it may have been triggered
because the RI flag was set or because the TI flag was set--or because both flags were set.
Thus, your routine must check the status of these flags to determine what action is
appropriate. Also, since the 8051 does not automatically clear the RI and TI flags you must
clear these bits in your interrupt handler.
INT_SERIAL: JNB RI,CHECK_TI ;If the RI flag is not set, we jump to check TI
MOV A,SBUF ;If we got to this line, its because the RI bit *was* set
CLR RI ;Clear the RI bit after wave processed it
CHECK_TI: JNB TI,EXIT_INT ;If the TI flag is not set, we jump to the exit point
CLR TI ;Clear the TI bit before we send another character
MOV SBUF,#A ;Send another character to the serial port
EXIT_INT: RETI
As you can see, our code checks the status of both interrupts flags. If both flags were
set, both sections of code will be executed. Also note that each section of code clears its
corresponding interrupt flag. If you forget to clear the interrupt bits, the serial interrupt will
be executed over and over until you clear the bit. Thus it is very important that you always
clear the interrupt flags in a serial interrupt.
One very important rule applies to all interrupt handlers: Interrupts must leave the
processor in the same state as it was in when the interrupt initiated.
Remember, the idea behind interrupts is that the main program isn’t aware that they
are executing in the "background." However, consider the following code:
After the above three instructions are executed, the accumulator will contain a value
of 35h.
But what would happen if right after the MOV instruction an interrupt occurred.
During this interrupt, the carry bit was set and the value of the accumulator was changed to
40h. When the interrupt finished and control was passed back to the main program, the
ADDC would add 10h to 40h, and additionally add an additional 1h because the carry bit is
set. In this case, the accumulator will contain the value 51h at the end of execution.
In this case, the main program has seemingly calculated the wrong answer. How can
25h + 10h yield 51h as a result? It doesn’t make sense. A programmer that was unfamiliar
with interrupts would be convinced that the microcontroller was damaged in some way,
provoking problems with mathematical calculations.
What has happened, in reality, is the interrupt did not protect the registers it used.
Restated: An interrupt must leave the processor in the same state as it was in when the
interrupt initiated.
What does this mean? It means if your interrupt uses the accumulator, it must insure
that the value of the accumulator is the same at the end of the interrupt as it was at the
beginning. This is generally accomplished with a PUSH and POP sequence. For example:
PUSHACC
PUSHPSW
MOVA,#0FFh
ADDA,#02h
POPPSW
POP ACC
The guts of the interrupt are the MOV instruction and the ADD instruction. However,
these two instructions modify the Accumulator (the MOV instruction) and also modify the
value of the carry bit (the ADD instruction will cause the carry bit to be set). Since an
interrupt routine must guarantee that the registers remain unchanged by the routine, the
routine pushes the original values onto the stack using the PUSH instruction. It is then free to
use the registers it protected to its hearts content. Once the interrupt has finished its task, it
pops the original values back into the registers. When the interrupt exits, the main program
will never know the difference because the registers are exactly the same as they were before
the interrupt executed.
• PSW
• DPTR (DPH/DPL)
• PSW
• ACC
• B
• Registers R0-R7
Remember that PSW consists of many individual bits that are set by various 8051
instructions. Unless you are absolutely sure of what you are doing and have a complete
understanding of what instructions set what bits, it is generally a good idea to always protect
PSW by pushing and popping it off the stack at the beginning and end of your interrupts.
Note also that most assemblers (in fact, ALL assemblers that I know of) will not allow
you to execute the instruction:
PUSH R0
This is due to the fact that depending on which register bank is selected, R0 may refer
to either internal ram address 00h, 08h, 10h, or 18h. R0, in and of itself, is not a valid
memory address that the PUSH and POP instructions can use.
Thus, if you are using any "R" register in your interrupt routine, you will have to push
that registers absolute address onto the stack instead of just saying PUSH R0. For example,
instead of PUSH R0 you would execute:
PUSH 00h
Of course, this only works if you’ve selected the default register set. If you are using
an alternate register set, you must PUSH the address, which corresponds, to the register you
are using.
Few embedded systems are so simple they can work without at least a few interrupt
sources. Few designers manage to get their product to market without suffering metaphorical
scars from battling interrupt service routines (ISRs).
There's no science to debugging these beasts, which are often the most complex part
of any real time system. Too many of us become experts at ISRs the same way we picked up
the secrets of the birds and the bees - from quick conversations in the halls and on the streets
with our pals. There's got to be a better way!
Fortunately there are only a few ways that interrupts are commonly handled. By far
the most prevalent is the Vectored scheme. A hardware device, either external to the chip or
an internal I/O port (as on a high integration CPU like the 188 or 68332) asserts the CPU's
interrupt input.
If interrupts are enabled (via an instruction like STI or EI), and if that particular
interrupt is not masked off (high integration processors almost always have some provision to
selectively enable interrupts from each device), then the processor responds to the interrupt
request with some sort of acknowledge cycle.
The requesting device then supplies a Vector, typically a single byte pointer to a table
maintained in memory. The table contains at the very least a pointer to the ISR.
The CPU pushes the program counter so at the conclusion of the interrupt the ISR can
return to where the program was running. Some CPUs push other data as well, like the flag
register. It then uses the vector to look up the ISR address and branches to the routine.
At first glance the vectoring seems unnecessarily complicated. Its great advantage is
support for many varied interrupt sources. Each device inserts a different vector; each vector
invokes a different ISR. Your UART Data Ready ISR called independently of the UART
Transmit_Buffer_Full interrupt.
7.4.2 C or Assembly?
If the routine will be in assembly language, convert the time to a rough number of
instructions. If an average instruction takes x microseconds (depending on clock rate, wait
states and the like), then it's easy to get this critical estimate of the code's allowable
complexity.
An old software adage recommends coding for functionality first, and speed second.
Since 80% of the speed problems are usually in 20% of the code, it makes sense to get the
system working and then determine where the bottlenecks are. Unfortunately, real time
systems by their nature usually don't work at all if things are slow. You've often got to code
for speed up front.
If the interrupts are coming fast - a term that is purposely vague and qualitative,
measured by experience and gut feel - then I usually just take the plunge and code the silly
thing in assembly. Why cripple the entire system due to little bit of interrupt code? If you
have broken the ISRs into small chunks, so the real time part is small, then little assembly
will be needed.
Before you can debug your ISR, the processor must accept the interrupt and properly
vector to the handler. Most processors service an interrupt with the following steps:
Your hardware generates the interrupt pulse
• The interrupt controller (if any) prioritizes multiple simultaneous requests, and issues
a single interrupt to the processor
• The CPU responds with an interrupt acknowledge cycle
• The controller drops an interrupt vector on the data bus
• The CPU reads the vector, and computes the address of the user-stored vector in
memory. It then fetches this value.
• The CPU pushes the current context, disables interrupts, and jumps to the ISR
Interrupts from internal peripherals (those on the CPU itself) will generally not
generate an external interrupt acknowledge cycle. The vectoring is handled internally and
invisibly to the wary programmer, tools in hand, trying to discover his system's faults.
or maybe there's a dozen complex configuration registers needing setup. Work with your
system, understand its quirks, and develop notes about how to drive each I/O device. Use
these notes to write your code.
If the ISR is not fast enough ;your system will fail. Unfortunately, few of the
developers I talk to have any idea what "fast enough" means. Unless you generate the
interrupt map I've discussed, only random luck will save you from speed problems.
Assume each ISR will be too slow, and plan accordingly. A performance analyzer
will instantly show the minimum, maximum, and average execution time required by your
code, including your ISRs.
Set a bit to a one when the ISR starts, and set it to zero when it completes. Connect a
scope and measure how long the bit says up. If the routine can run for varying lengths of
time, use a digital scope set to accumulate sweeps, and watch for the longest iteration.
It's important to look at total interrupt overhead in a system as well. If your ISR runs
in 100 microseconds, but gets invoked 10,000 times/second, there's serious trouble brewing.
Watch how long the bit stays asserted over long periods of time - a second or more - and
make sure it's not eating most of the CPU resources.
Set and reset this bit in all of the ISRs to see total interrupt overhead. It's sometimes
frightening to see just how close to the wire some systems run!
Suppose your main line routine and the ISRs are all coded in C. The compiler will
certainly invoke runtime functions to support floating point math, I/O, string manipulations,
etc. If the runtime package is only partially reentrant, than your ISRs may very well corrupt
the execution of the main line code. This problem is common, but is virtually impossible to
troubleshoot since symptoms result only occasionally and erratically. Can you imagine the
difficulty of isolating a bug which manifests itself only occasionally and with totally different
characteristics each time?
If you’re ISR merely increments a global 32 bit value, say, to maintain time, it would
seem legal to produce code that does nothing more than a quick and dirty increment.
Especially when writing code on an 8 or 16 bit processor, remember that the C compiler will
surely generate several instructions to do the deed. On a 186, the construct ++j might
produce:
mov ax,[j]
An interrupt in the middle of this code will leave j just partially changed; if the ISR is
reincarnated with j in transition, its value will surely be corrupt.
Watch out for noise on the NMI line. NMI is usually an edge-triggered signal. Any bit
of noise will cause perhaps hundreds of interrupts. Since it cannot be masked, you'll almost
certainly cause a reentrancy problem. This is yet another reason to avoid NMI for anything
other than a catastrophic failure.
Even the perfectly coded reentrant ISR leads to problems. If such a routine runs so
slowly that interrupts keep giving birth to additional copies of it, eventually the stack will fill.
Once the stack bangs into your variables the program is on its way to oblivion. You must
insure that the average interrupt rate is such that the routine will return more often than it is
invoked.
The best defense is a strong offense. Build a stack monitor into your code.
A stack monitor is just a few lines of assembly language that compares the stack
pointer to some limit you've set. Estimate the total stack use, and then double or triple the
size. Use this as the limit.
Put the stack monitor into one or more frequently called ISRs. Jump to a null routine,
where a breakpoint is set, when the stack grows too much.
Be sure that the compare is "fuzzy". The stack pointer will never exactly match the
limit.
7.6 Summary
Technical Question
1. What is interrupt?
2. What are types of interrupt?
3. What is Interrupt Priorities?
4. What is vector interrupt?
5. What Happens When an Interrupt Occurs?
6. What is the difference between the RET and RET1 instructions?
7.7 Exercise
1. Write a C program that continuously gets a single bit of data from P1.7 and sends it to
P1.0 in the main, while simultaneously
a. Creating a squire wave of 200 micro sec period on pin P2.5, and
b. Sending letter ‘A’ to the serial port. Use Timer 0 to create the square wave.
2. Write a C program using interrupts to do the following:
a. Receive data serially and send it to P0.
b. Read port P1, transmit data serially and give a copy to P2,
c. Make timer 0 generate a square wave of 8 kHz frequency on P0.1.
CHAPTER -8
PERIPHERAL DEVICE
About this Chapter
8.1 Introduction
One common requirement for many different digital devices is a visual numeric
display. Individual LEDs can of course display the binary states of a set of latches or flip-
flops. However, we're far more used to thinking and dealing with decimal numbers. To this
end, we want a display of some kind that can clearly represent decimal numbers without any
requirement of translating binary to decimal or any other format.
One possibility is a matrix of 28 LEDs in a 7×4 array. We can then light up selected
LEDs in the pattern required for whatever character we want. Indeed, an expanded version of
this is used in many ways, for fancy displays. However, if all we want to display is numbers,
this becomes a bit expensive. A much better way is to arrange the minimum possible number
of LEDs in such a way as to represent only numbers in a simple fashion.
This requires just seven LEDs (plus an eighth one for the decimal point, if that is
needed). A common technique is to use a shaped piece of translucent plastic to operate as a
specialized optical fiber, to distribute the light from the LED evenly over a fixed bar shape.
The seven bars are laid out as a squared-off figure given blow. The result is known as a
seven-segment LED.
Character display that is commonly used these days is called seven segment displays
because they are easy to read under low ambient light. Another type of display is called LCD
display, which is useful in low power, or battery operated system. Unlike LEDs, LCDs are
visible in bright ambient light. Since LCDs do not emit light, they are visible in low light
environment. These days, a combination of LCDs and LEDs are used to enable LCDs to be
visible even in low ambient light environment. LCDs are not efficient at low temperature
environment. The characters size available are in 0.3 inch, 0.6 inch and larger sizes
The illustration to the above shows the basic layout of the segments in a seven-
segment display. The segments themselves are identified with lower-case letters "a" through
"g," with segment "a" at the top and then counting clockwise. Segment "g" is the center bar.
Most seven-segment digits also include a decimal point ("dp"), and some also include
an extra triangle to turn the decimal point into a comma. This improves readability of large
numbers on a calculator, for example. The decimal point is shown here on the right, but some
display units put it on the left, or have a decimal point on each side.
In addition, most displays are actually slanted a bit, making them look as if they were
in italics. This arrangement allows us to turn one digit upside down and place it next to
another, so that the two decimal points look like a colon between the two digits. The
technique is commonly used in LED clock displays.
One limitation of the DIP package is that it cannot support larger digits. To get larger
displays for easy reading at a distance, it is necessary to change the package size and shape.
The package on the right above is larger than the other two, and thus can display a digit that
is significantly larger than will fit on a standard DIP footprint. Even larger displays are also
available; some digital clocks sport digits that are two to five inches tall.
displays require special treatment that we are not yet ready to discuss. Therefore, we will
work with a seven-segment LED display in this experiment.
Seven segment displays can be divided into 2 types of connection. One is called
common anode of which all the anodes of the LEDs are connected together, leaving the
cathodes open for connection. The other one is called common cathode of which all the
cathodes of the LEDs are connected together, leaving the anodes open for connection.
0 0 0 0 1 1 1 1 1 1 0
0 0 0 1 0 1 1 0 0 0 0
0 0 1 0 1 1 0 1 1 0 1
0 0 1 1 1 1 1 1 0 0 1
0 1 0 0 0 1 1 0 0 1 1
0 1 0 1 1 0 1 1 0 1 1
0 1 1 0 0 0 1 1 1 1 1
0 1 1 1 1 1 1 0 0 0 0
1 0 0 0 1 1 1 1 1 1 1
1 0 0 1 1 1 1 0 0 1 1
There are two important types of 7-segment LED display. In a common cathode
display, the cathodes of all the LEDs are joined together and the individual segments are
illuminated by HIGH voltages. In a common anode display, the anodes of all the LEDs are
joined together and the individual segments are illuminated by connecting to a LOW voltage.
The 4511 is designed to drive a common cathode display and won't work with a
common anode display. You need to check that you are using the right kind of display before
you start building.
In normal operation, the lamp test and ripple blanking inputs are connected HIGH,
and the enable (store) input is connected LOW. The circuit diagram shows the 4511 and a 7-
segment common cathode display connected to the outputs of a 4510 BCD counter:
When the lamp test input, pin 3, is made LOW, all the segment outputs go HIGH
regardless of all other input conditions.
With lamp test HIGH, if the ripple blanking input, pin 4, is made LOW, all the
segment outputs are forced LOW. This input can be used to blank leading zeros in a multi-
digit display.
The enable input controls the action of a 4-bit latch inside the 4511. With enable
LOW, the outputs of the latch follow the logic states of the BCD inputs and the 7-segment
outputs change accordingly. If enable is made HIGH, the logic states present on the BCD
inputs are stored. The 7-segment outputs remain unchanged until enable is made LOW once
more. This action allows the display to be updated at intervals.
When you need these inputs, you can work out how to use them by investigating the
behavior of the 4511 in a prototype circuit.
BCD stands for Binary Coded Decimal. A BCD counter has four outputs usually
labeled A, B, C, and D. By convention A is the least significant bit, or LSB. The easiest way
to understand what a BCD counter does is to follow the counting sequence in truth table.
When pulses are delivered to the CLOCK input (and all the other connections needed
for basic operation are made), the outputs of the 4510 follow a sequence starting from 0 0 0 0
up to 1 0 0 1, the binary equivalent of the decimal number 9. The next pulse causes the 4510
to RESET and counting starts again from 0 0 0 0.
In other words, the counter outputs follow a binary sequence representing the decimal
numbers 0-9.... this is why the 4510 is called a binary coded decimal counter.
To make the 4510 work, you need lots of connections. Every INPUT of a CMOS
integrated circuit must be connected to something. The CLOCK input, for example, will be
connected to the output of source of pulses such as an astable. You will also need to connect
all the load inputs, the carry in and the up/down input.
The 4093 Schmitt trigger NAND gate provides one of the easiest ways of making an
astable. When you have built this part of the circuit, the LED next to the 4093 should flash at
approximately 1 Hz, possibly a little faster
8.6.3 Applications
8.7.1 Introduction
Liquid Crystal Display (LCD) is the one of the important Display devices in
Embedded System. As we know already the Embedded System has the very limited input and
output devices. To know the stage of embedded system as well as to view the output we
require the one detailed output and/or display devices. One among the best is LCD display.
Other output display devices are LED and 7Segment LED. The comparison leads to
find out the merits and demerits of the LCD displays
Costly Cheaper
Display clear, cursor home, display on/off, cursor on/off, display character blink,
cursor shift, display shift
Automatic reset circuit that initializes the controller/driver after power on
Internal oscillator with external resistors
Low power consumption
Above is the quite simple schematic. The LCD panel's Enable and Register Select is
connected to the Control Port. The Control Port is an open collector / open drain output.
While most Parallel Ports have internal pull-up resistors, there are a few which don't.
Therefore by incorporating the two 10K external pull up resistors, the circuit is more portable
for a wider range of computers, some of which may have no internal pull up resistors.
We make no effort to place the Data bus into reverse direction. Therefore we hard
wire the R/W line of the LCD panel, into write mode. This will cause no bus conflicts on the
data lines. As a result we cannot read back the LCD's internal Busy Flag, which tells us if the
LCD has accepted and finished processing the last instruction. This problem is overcome by
inserting known delays into our program. The 10k Potentiometer controls the contrast of the
LCD panel.
8.7.10 Applications
Summary
Character display is commonly used these days are called seven segment displays
because they are easy to read under low ambient light.
Seven segment displays can be divided into 2 types of connection. One is called
common anode of which all the anodes of the LEDs are connected together, leaving
the cathodes open for connection.
The other one is called common cathode of which all the cathodes of the LEDs are
connected together, leaving the anodes open for connection.
Liquid Crystal Display has two transparent layers. The gap between two transparent
layers is filled with liquid crystal.
The molecules in liquid crystal are arranged in order. When the voltage is passed
through the Liquid crystal, they become to move randomly.
Technical Question
1. Different type of seven segment display?
2. Different between LCD and 7 segment display.
3. Write the LCD pin details?
4. Explain function of LCD control pins?
5. Different type of command using in LCD?
Exercise
1. Write a program to get a data from a peripheral and display it using LCD.
CHAPTER 9
This chapter will give information about ADC, DAC and Keypad.
You can learn how to interface the above mentioned peripherals to the
controller.
ignals in the real world are analog: light, sound, etc.Therefore, real-world signals must
be converted into digital, using a circuit called ADC (Analog-to-Digital Converter), before
they can be manipulated by digital equipment. In this tutorial we will give an in-depth
explanation about analog-to-digital conversion yet keeping a very easy to follow language.
hen you scan a picture with a scanner what the scanner is doing is an analog-to-digital
conversion: it is taking the analog information provided by the picture (light) and converting
into digital.
hen you record your voice, you are using an analog-to-digital converter to convert
your voice, which is analog, into digital information.
igital information isn’t only restricted to computers. When you talk on the phone, for
example, your voice is converted into digital .since your voice is analog and the
communication between the phones switches is done digitally.
evertheless, why digital? There are some basic reasons to use digital signals instead of
analog, noise being the number one.
Analog to digital (A/D, ADC) converters are electrical circuit devices that convert
continuous signals, such as voltages or currents, from the analog domain to the digital domain
where the signals are represented by numbers. Most processing equipment today are digital in
nature, and they work with signals which are binary valued. In a digital or binary
representation, a signal is represented by a word, which is composed of a finite number of
bits. The processing of signals is preferably carried out in the digital domain because digital
processing is fast, accurate and reliable.
9.3 OPERATION
The sample and hold circuit samples the analog input on a rising edge of the sample signal.
The comparator output is logic “1” if the sampled analog voltage is greater than the output of
the DAC,”0” otherwise. The circuit in this example has to control signals go and done. At
any point if go is 0”.Theircuit is reset. When go becomes a “1” the process of sampling and
converting takes place. When a conversion is finished valid is set to “1” and the result is
available
This circuit serves as an interface between the ADC’s input or the input analog signal
to be encoded and the rest of the ADC. The S/H (Sample/Hold) control circuit sustains a
certain point of an input analog signal for a certain amount of time (i.e. necessary for the rest
of the circuit to react on this value). The S/H circuit is typically a pair of voltage follower op-
amps in an open-loop or closed-loop configuration linked by a switch (CMOS or MOSFET,
etc) and a holding capacitor. It is regulated by its own specifications such as its acquisition
time, droop rate, sample-to-hold settling time, and slew rate, just to name a few.
9.3.2 Timing
The end of conversion is generally indicated by an end of convert (EOC), data –ready
(DRDY), or busy signal (actually, not busy indicates EOC).the polarities and name of the
signal maybe different for different SAR ADCs, but fund medal concepts is same. At the
beginning of the conversion interval , the signal goes high (or low) and remains in that states
until the conversion is completed, at which time it goes low(or high). The trailing edge is
generally an indication of valid output data.
9.3.3 Comparator
The SAR has three inputs and two outputs. The first of these inputs is a clock signal
that will usually be an input pin to the ADC. This will determine the rate at which the ADC
encodes the input analog signal. The next input is a “start conversion” signal from the S/H
control circuit. This signal clears the SAR thus starting the encoding of a new signal. The
third input is the output from the comparator. If this output is high (the DAC output is too
low, as above), this tells the SAR to increase the digital number that it outputs. Vice versa, if
this output is too low (the DAC output is too high, as above), this tells the SAR to decrease
the digital number that it outputs. The two outputs are a digital output (whose number of bits
depend on the specs of the ADC) and an “end of conversion” (EOC) output that is ‘true’ or
‘false’ and indicates whether the current digital output data is “data valid”. This is an overall
output from the chip as well as an input to the output latch.
The sequence of successive approximation in the SAR occurs as follows:
§ T=0; clear all digital output bits, set EOC=’F’.
§ T=1; set the MSB to ‘1’. If this is too much, clear it; if too little, keep it.
§ T=2; set the next bit to ‘1’. If too much, clear it; if too little, keep it.
§ T=3 to N; continue as above until after LSB, then set EOC=’T’.
The DAC is part of the feedback loop inside the ADC. It converts the current digital
output (output from SAR) to an analog signal to be used as the second input to the
comparator (to be compared with the current analog input signal). A ladder configuration
DAC works as follows:
Based upon a certain input reference voltage, this type of DAC is essentially
achieving a set of binary weighted currents the come together into the summing junction of
an op-amp. For example, if the MSB is logic ‘1’, then a switch (CMOS, MOSFET, etc.) is
closed that allows a current “0.5*I” or “I/2” (i.e. half the maximum possible current; as the
MSB represents half of a total digital value) through to the summing junction. If the next
most significant bit is logic ‘1’, then a current “0.25*I” or “I/4” is allowed through to the
summing junction. Thus, for a 4-bit digital signal of ‘1001’, a current of I/2 + I/16 = 9/16*I
would appear at the input to the op-amp, added to an offset of I/16 equals 5/8*I or 5/8* Vref.
This makes sense as ‘1001’+’1’ is 5/8ths of ‘1111’+’1’ or the maximum total in this case.
The output latch simply serves as an interface between the digital output from the
SAR and the overall digital output of the ADC. If the EOC signal from the SAR is ‘true’,
then the SAR digital output is relayed through the output latch as the ADC’s main output.
After examining all the comprising parts, one can see how the ADC comes together.
An analog signal is imputed and compared with a D/A conversion of the current digital
output. As the starting digital output will be zeros, this will be gradually increased by the
SAR until the comparator tells the SAR that the input signal and analog conversion of the
output signal match. At this point, the next sample of the analog signal will enter into the
picture, the comparator will no longer detect a match, and the SAR will adjust the digital
output until it matches the changed value of the analog input. The process then continually
repeats itself.
A direct conversion ADC or flash ADC has a comparator that fires for each decoded
voltage range. The comparator bank feeds a logic circuit that generates a code for each
voltage range. Direct conversion is very fast, but usually has only 8 bits of resolution (256
comparators) or fewer, as it needs a large, expensive circuit. ADCs of this type have a large
die size, a high input capacitance, and are prone to produce glitches on the output (by
outputting an out-of-sequence code). They are often used for video or other fast signals.
resolution desired. For example, to sample audio at 44.1 kHz with 32 bit resolution, a clock
frequency of over 1.4 MHz would be required. ADCs of this type have good resolutions and
quite wide ranges. They are more complex than some other designs.
A delta-encoded ADC has an up-down counter that feeds a digital to analog converter
(DAC). The input signal and the DAC both go to a comparator. The comparator controls the
counter. The circuit uses negative feedback from the comparator to adjust the counter until
the DAC's output is close enough to the input signal. The number is read from the counter.
Delta converters have very wide ranges, and high resolution, but the conversion time is
dependent on the input signal level, though it will always have a guaranteed worst-case. Delta
converters are often very good choices to read real-world signals. Most signals from physical
systems do not change abruptly. Some converters combine the delta and successive
approximation approaches; this works especially well when high frequencies are known to be
small in magnitude.
A Sigma-Delta ADC (also known as a Delta-Sigma ADC) over samples the desired
signal by a large factor and filters the desired signal band. Generally a smaller number of bits
than required are converted using a Flash ADC after the Filter. The resulting signal, along
with the error generated by the discrete levels of the Flash, is fed back and subtracted from
the input to the filter. This negative feedback has the effect of noise shaping the error due to
the Flash so that it does not appear in the desired signal frequencies. A digital filter
(decimation filter) follows the ADC, which reduces the sampling rate, filters off unwanted
noise signal and increases the resolution of the output. (Sigma-delta modulation, also called
delta-sigma modulation).
Resolution
The resolution of the converter indicates the number of discrete values an ADC can
produce over the range of voltage values. It is usually expressed in bits. For example, an
ADC that encodes an analog input to one of 255 discrete values (0.255) has a resolution of
eight bits, since
28 − 1 = 255.
Resolution can also be defined electrically, and expressed in volts. The voltage resolution of
an ADC is equal to its overall voltage measurement range divided by the number of discrete
values as in the formula:
Where Q is resolution in volts, EFSR is the full scale voltage range, and M is resolution in
bits.
• Example 1
• xample 2
In practice, the resolution of the converter is limited by the signal-to-noise ratio of the
signal in question. If there is too much noise present in the analog input, it will be impossible
to accurately resolve beyond a certain number of bits of resolution, the "effective number of
bits" (ENOB). While the ADC will produce a result, the result is not accurate, since its lower
bits are simply measuring noise. The signal-to-noise ratio should be around 6 dB per bit of
resolution required
ADC207 – 7-bit flash A/D converter,20MHz sampling rate, Low power (250mW),Single
+5V Supply, 1.2 micron CMOS technology,7-bit latched 3-state output with overflow bit,
Surface-mount versions, High-reliability version, No missing codes.
ADC228 - 8-Bit flash A/D converter,20MHz sampling rate, Complete support circuitry, low
power1.5W, 7MHz full power bandwidth, and Sample-hold not required, Three-state outputs
MIL-STD-883 versions.
General Description
Successive approximation conversions are performed using either the internal clock or
external serial interface clock. The max1112 is available in 20 pin sop and DIP packages. The
Max1113 is available in small 16 pin sop DIP packages
General Description:
The ADC0808, ADC0809 data acquisition is a monolithic CMOS device with an 8 bit
analog to digital converter, 8 channels multiplexer and microprocessor compatible control
logic. The 8 bit A/D converter uses successive approximation as the conversion technique.
The converter features a high impedance chopper stabilized comparator a 256R voltage
divider with analog switch tree and a successive approximation register. The 8 channel
multiplexer can directly access any of 8 single ended analog signals.
The device eliminates the need for external zero and full scale adjustments. Easy
interfacing to microprocessor is provided by the latch and decoded multiplexer address inputs
and latched TTL TRI-STATE outputs.
#include<REGX51.H>
Sbit ch0=P3^2;
Sbit ch1=P3^3;
Sbit ch2=P3^4;
Void main()
{
While (1)
{
ch0=0; //selection of channel 0
ch1=0;
ch2=0;
ch0=1; //selection of channel 1
ch1=0;
ch2=0;
9.7 APPLICATION
Digital cameras, cellular telephones, audio devices such as MP3 players, and video
equipment such as digital video disk (DVD) players, high definition digital television.
Exercise
1. Write a program to interface ADC with controller using 2 channels
(ch0 and ch1).
2. Capturing the rapid variation to LCD display through controller from
analog device.
3. Analysis the analog equivalent digital value from temperature
Sensor.
Introduction
Digital-to-analog (D/A) converters (sometimes called DACs) are used to present the
results of digital computation, storage, or transmission, typically for graphical display or for
the control of devices that operate with continuously varying quantities. D/A converter
circuits are also used in the design of analog-to-digital converters that employ feedback
The output of the D/A converter is proportional to the product of the digital input
value and the reference. In many applications, the reference is fixed, and the output bears a
fixed proportion to the digital input. In other applications, the reference, as well as the digital
input, can vary; a D/A converter that is used in these applications is thus called a multiplying
D/A converter. It is principally used for imparting a digitally controlled scale factor, or
“gain,” to an analog input signal applied at the reference terminal. See also Amplifier; Analog
computer.
Except for the highest resolutions (beyond 18 bits), commercially available D/A
converters are generally manufactured in the form of integrated circuits, using bipolar, MOS,
and hybrid technologies. A single chip may include just the resistor network and switches; it
may also include a reference circuit, output amplifier, and one or more sets of registers (with
control logic suitable for direct microprocessor interfacing). See also Integrated circuits
9.10 Principle
Generate a current of magnitude proportional to the value of each bit in the
parallel digital word. Sum the currents of all the bits that are logic 1.
BLOCK DIAGRAM
Bias circuit
Bias circuit for power amplifier operated as a digital to analog converter.
An apparatus and method for biasing a power amplifier circuit operating as a Digital to
Analog Converter (DAC) are described. The bias circuit comprises a first transistor with a
reference voltage coupled to its base terminal, a second transistor coupled to the emitter
terminal of the first transistor at its collector terminal, and a third transistor with its base
terminal coupled to the first and second transistors, and to an input signal.
Switch circuit
DACs are at the beginning of the analog signal chain, which makes them very
important to system performance. The most important characteristics of these devices are:
Resolution: This is the number of possible output levels the DAC is designed to reproduce.
This is usually stated as the number of bits it uses, which is the base two logarithm of the
number of levels. For instance a 1 bit DAC is designed to reproduce 2 (21) levels while an 8
bit DAC is designed for 256 (28) levels. Resolution is related to the Effective Number of Bits
(ENOB), which is a measurement of the actual resolution attained by the DAC.
Maximum sampling frequency: This is a measurement of the maximum speed at which the
DACs circuitry can operate and still produce the correct output. As stated in the Shannon-
Nyquist sampling theorem, a signal must be sampled at over twice the bandwidth of the
desired signal. For instance, to reproduce signals in the entire audible spectrum, which
includes frequencies of up to 20 kHz, it is necessary to use DACs that operate at over 40 kHz.
The CD standard samples audio at 44.1 kHz, thus DACs of this frequency are often used. A
common frequency in cheap computer sound cards is 48 kHz - many work at only this
frequency, offering the use of other sample rates only through (often poor) internal
resampling.
Monotonic: This refers to the ability of DACs analog output to increase with an increase in
digital code or the converse. This characteristic is very important for DACs used as a low
frequency signal source or as a digitally programmable trim element.
The Pulse Width Modulator, the simplest DAC type. A stable current or voltage is
switched into a low pass analog filter with a duration determined by the digital input code.
This technique is often used for electric motor speed control, and is now becoming common
in high-fidelity audio.
Over sampling DACs such as the Delta-Sigma DAC, use a pulse density conversion
technique. The over sampling technique allows for the use of a lower resolution DAC
internally. A simple 1-bit DAC is often chosen because the over sampled result is inherently
linear. The DAC is driven with a pulse density modulated signal, created with the use of a
low-pass filter, step nonlinearity (the actual 1-bit DAC), and negative feedback loop, in a
technique called delta-sigma modulation. This results in an effective high-pass filter acting on
the quantization (signal processing) noise, thus steering this noise out of the low frequencies
of interest into the high frequencies of little interest, which is called noise shaping (very high
frequencies because of the over sampling). The quantization noise at these high frequencies
are removed or greatly attenuated by use of an analog low-pass filter at the output (sometimes
a simple RC low-pass circuit is sufficient). Most very high resolution DACs (greater than 16
bits) is of this type due to its high linearity and low cost. Higher over sampling rates can
either relax the specifications of the output low-pass filter or enable further suppression of
quantization noise. Speeds of greater than 100 thousand samples per second (for example,
192kHz) and resolutions of 24 bits are attainable with Delta-Sigma DACs. A short
comparison with pulse width modulation shows that an 1-bit DAC with a simple first-order
integrator would have to run at 3 THz (which is physically unrealizable) to archive 24
meaningful bits of resolution, requiring a higher order low-pass filter in the noise-shaping
loop. A single integrator is a low pass filter with a frequency response inversely proportional
to frequency and using one such integrator in the noise-shaping loop is a first order delta-
sigma modulator. Multiple higher order topologies (such as MASH) are used to achieve
higher degrees of noise-shaping with a stable topology.
The Binary Weighted DAC, which contains one resistor or current source for each bit
of the DAC connected to a summing point. These precise voltages or currents sum to the
correct output value. This is one of the fastest conversion methods but suffers from poor
accuracy because of the high precision required for each individual voltage or current. Such
high-precision resistors and current-sources are expensive, so this type of converter is usually
limited to 8-bit resolution or less.
The R-2R Ladder DAC, which is a binary weighted DAC that uses a repeating
cascaded structure of resistor values R and 2R. This improves the precision due to the relative
ease of producing equal valued matched resistors (or current sources). However, a wide
converter performs slowly due to increasingly large RC-constants for each added R-2R link.
the Thermometer coded DAC,
which contains an equal resistor or current source segment for each possible value of
DAC output? An 8-bit thermometer DAC would have 255 segments, and a 16-bit
thermometer DAC would have 65,535 segments. This is perhaps the fastest and highest
precision DAC architecture but at the expense of high cost. Conversion speeds of >1 billion
samples per second have been reached with this type of DAC.
The Segmented DAC, which combines the thermometer, coded principle for the
most significant bits and the binary weighted principle for the least significant bits. In this
way, a compromise is obtained between precision (by the use of the thermometer coded
principle) and number of resistors or current sources (by the use of the binary weighted
principle). The full binary weighted design means 0% segmentation; the full thermometer
coded design means 100% segmentation. Hybrid DACs, which use a combination of the
above techniques in a single converter. Most DAC integrated circuits are of this type due to
the difficulty of getting low cost, high speed and high precision in one device.
General description
The DAC0808 is an 8 bit monolithic digital to analog converter featuring a full scale
output current setting time of 150ns while dissipating only 33mw with +5 v supplies. No
reference current trimming is required for most applications since the full scale output current
is typically +or- 1 LSB of 255 Iref/256. relative accuracies of better than + or - o.19% assure
8 bit monotonic and linearity while zero level output current of less than 4uA provides 8 bit
zero accuracy for I ref>=2 mA. The power supply current of the DAC0808 is independent of
bit codes.
Application:
Audio
CD players,
Digital music players,
PC sound cards.
Video
2.1 memory (RAM),
2.2 contrast and brightness.
Define resolution. What is the resolution of DAC that you have used in the lab?
Exercise
RD VCC
8051 WR Vref (+)
P1.0 D0 OUT -
P1.1 D1 +
P1.3 D3
P1.4 D4
P1.5 D5
P1.6 D6
P1.7 D7
GND
VEE COMP
9.15.1 Introduction
Keypads are a part of HMI or Human Machine Interface and play really
important role in a small embedded system where human interaction or human input is
needed. Matrix keypads are well known for their simple architecture and ease of interfacing
with any microcontroller. In this part of tutorial we will learn how to interface a 4x4 matrix
keypad with AVR and 8051 microcontroller. In addition, we will see how to program then in
Assembly and C.
Construction of a keypad is really simple. As per the outline shown in the figure below we
have four rows and four columns. In between each overlapping row and column line there is
a key.
There are many methods depending on how you connect your keypad with your
controller, but the basic logic is same. We make the Coolum’s as I/p and we drive the rows
making them o/p, this whole procedure of reading the keyboard is called scanning.
In order to detect which key is pressed from the matrix, we make row lines low one
by one and read the columns. Let’s say we first make Row1 low, and then read the columns.
If any of the key in row1 is pressed will make the corresponding column as low i.e. if
second key is pressed in Row1, then column2 will give low. Therefore, we come to know that
key 2 of Row1 is pressed. This is how scanning is done.
Therefore, to scan the keypad completely, we need to make rows low one by one and
read the columns. If any of the buttons is pressed in a row, it will take the corresponding
column to a low state which tells us that a key is pressed in that row. If button 1 of a row is
pressed then Column 1 will become low, if button 2 then column2 and so on...
9.15.4 Application
(I).. Looking at the figure, you’ll notice a familiar 4x4 keypad with a single
difference —each row and column are separated by a resistor. If key #1 is pressed, the
resistance between nodes A and B (R1AB) is equal to 1.5*R; for key #2—R2AB = 1.5*R+R =
2.5*R; and so on ... key #N—RNAB = N.5*R. This variable resistor network is connected to a
555 timer (CMOS version), configured as an oscillator with the period of oscillation equal to
T = 1.4*RAB*C, directly proportional to RAB.
The oscillator runs only when a key is pressed, causing an interrupt request for the
microcontroller. The INT0 pin is set up as edge-sensitive. The general algorithm can be
described as: 1) after detecting the edge on the INT0 pin, wait 20 ms to eliminate ringing; 2)
detect the next edge and start the internal timer; 3) the following edge stops the internal timer.
The measured period (the time between two consecutive positive edges) will define the key
number. Any microcontroller with a built-in timer (the vast majority of microcontrollers) can
implement this idea.
For a specific example, I will use the 8051-family microcontroller with a 12-MHz
clock. In this situation, the single count of the timer will be 1 µs. If we choose 47 nF for the
capacitor and 3.9 kΩ as the resistor value, we will have T = 1.4*R*C = 256.6 ≈ 256 µs. That
is the period difference between oscillations produced by two serial keys. After calculating
the period interval produced by any key pressed, we need only to make integer division by
0xFF (25610) to get the key number of the depressed key. The value for R1 =1.5*R is chosen
to provide the highest error margin for the elements by moving the period value in the middle
of two consecutive numbers.
1. If D3-D0-0111 is the data read from the columns, which column does the pressed key long
to?
2. To see if any key is pressed ,all rows grounded or not?
3. To identify the pressed key, one row at a time is grounded or not?
4. Key pressed detection and key identification require two different processes or not?
9.15.6Exercise
Write a c program to read a data from the 2x4 keypad and display it in LCD ?
(i)P2.0-P2.3 connected to rows.
(ii)P2.4-P2.7 connected to columns.
a)create password and check it with the keypad data.
9.15.7 Summary
How signals in the real world, which are analog, is converted to digital, using a ADC
circuit.
Analog to digital (A/D, ADC) converters are electrical circuit devices that convert
continuous signals, such as voltages or currents, from the analog domain to the digital
domain where the signals are represented by numbers.
ADC works by using a digital to analog converter and a comparator to perform a
binary search to input voltage
The voltage resolution of an ADC is equal to its overall voltage measurement range
divided by the number of discrete values as in the formula:
After completing this chapter you can be able to read and examine a value from ADC, how
select the channels and get a data from a peripheral.
In addition, saw DAC, there is Generate a current of magnitude proportional to
the value of each bit in the parallel digital word. Also how to interface keypad with
microcontroller.
CHAPTER 10
COMMUNICATION
This chapter will give information about serial and parallel communication.
You can learn about application of interfacing with PC and External
Peripherals.
One of the 8051s many powerful features is its integrated UART, otherwise known as
a serial port. The fact that the 8051 has an integrated serial port means that you may very
easily read and write values to the serial port. If it were not for the integrated serial port,
writing a byte to a serial line would be a rather tedious process requiring turning on and off
one of the I/O lines in rapid succession to properly "clock out" each individual bit, including
start bits, stop bits, and parity bits.
However, we do not have to do this. Instead, we simply need to configure the serial
ports operation mode and baud rate. Once configured, all we have to do is write to an SFR to
write a value to the serial port or read the same SFR to read a value from the serial port. The
8051 will automatically let us know when it has finished sending the character we wrote and
will also let us know whenever it has received a byte so that we can process it. We do not
have to worry about transmission at the bit level--which saves us quite a bit of coding and
processing time.
The evaluation board consists of three major parts and provides a function to convert
the parallel data bus to RS232 serial port and vice versa. In addition, it provides an in-system
programming function. The functions of the three major parts are described as follows:
µC INTERFACE WITH PC
The first things we must do when using the 8051s integrated serial port is, obviously,
configure it. This lets us tell the 8051 how many data bits we want, the baud rate we will be
using, and how the baud rate will be determined.
First, let’s present the "Serial Control" (SCON) SFR and define what each bit of the SFR
represents:
Additionally, it is necessary to define the function of SM0 and SM1 by an additional table:
(*) Note: The baud rate indicated in this table is doubled if PCON.7 (SMOD) is set.
The SCON SFR allows us to configure the Serial Port. Thus, well go through each bit
and review its function.
Bits SM0 and SM1 let us set the serial mode to a value between 0 and 3, inclusive.
The four modes are defined in the chart immediately above. As you can see, selecting the
Serial Mode selects the mode of operation (8-bit/9-bit, UART or Shift Register) and also
determines how the baud rate will be calculated. In modes 0 and 2 the baud rate is fixed
based on the oscillator’s frequency. In modes 1 and 3 the baud rate is variable based on how
often Timer 1 overflows. Well talk more about the various Serial Modes in a moment.
The next bit, REN, is "Receiver Enable." This bit is very straightforward: If you want
to receive data via the serial port, set this bit. You will almost always want to set this bit.
The last four bits (bits 0 through 3) are operational bits. They are used when actually
sending and receiving data--they are not used to configure the serial port.
The TB8 bit is used in modes 2 and 3. In modes 2 and 3, a total of nine data bits are
transmitted. The first 8 data bits are the 8 bits of the main value, and the ninth bit is taken
from TB8. If TB8 is set and a value is written to the serial port, the data bits will be written to
the serial line followed by a "set" ninth bit. If TB8 is clear the ninth bit will be "clear."
The RB8 also operates in modes 2 and 3 and functions essentially the same way as
TB8, but on the reception side. When a byte is received in modes 2 or 3, a total of nine bits
are received. In this case, the first eight bits received are the data of the serial byte received
and the value of the ninth bit received will be placed in RB8.
TI means "Transmit Interrupt." When a program writes a value to the serial port, a
certain amount of time will pass before the individual bits of the byte are "clocked out" the
serial port. If the program were to write another byte to the serial port before the first byte
was completely output, the data being sent would be garbled. Thus, the 8051 lets the program
know that it has "clocked out" the last byte by setting the TI bit. When the TI bit is set, the
program may assume that the serial port is "free" and ready to send the next byte.
Finally, the RI bit means "Receive Interrupt." It functions similarly to the "TI" bit, but
it indicates that a byte has been received. That is to say, whenever the 8051 has received a
complete byte it will trigger the RI bit to let the program know that it needs to read the value
quickly, before another byte is read.
Once the Serial Port has been properly configured as explained above, the serial port
is ready to be used to send data and receive data. If you thought that configuring the serial
port was simple, using the serial port will be a breeze.
To write a byte to the serial port one must simply write the value to the SBUF (99h)
SFR. For example, if you wanted to send the letter "A" to the serial port, it could be
accomplished as easily as:
MOV SBUF,#A
Upon execution of the above instruction the 8051 will begin transmitting the character
via the serial port. Obviously transmission is not instantaneous--it takes a measurable amount
of time to transmit. And since the 8051 does not have a serial output buffer, we need to be
sure that a character is completely transmitted before we try to transmit the next character.
The 8051 lets us know when it is done transmitting a character by setting the TI bit in
SCON. When this bit is set we know that the last character has been transmitted and that we
may send the next character, if any. Consider the following code segment:
Reading data received by the serial port is equally easy. To read a byte from the serial
port one just needs to read the value stored in the SBUF (99h) SFR after the 8051 has
automatically set the RI flag in SCON.
For example, if your program wants to wait for a character to be received and
subsequently read it into the Accumulator, the following code segment may be used:
The first line of the above code segment waits for the 8051 to set the RI flag; again,
the 8051 sets the RI flag automatically when it receives a character via the serial port. So as
long as the bit is not set the program repeats the "JNB" instruction continuously.
Before going to implement we should know about SFR, which is used for serial
communication.
SCON (Serial Control, Addresses 98h, Bit-Addressable): The Serial Control SFR is
used to configure the behavior of the 8051's on-board serial port. This SFR controls the baud
rate of the serial port, whether the serial port is activated to receive data, and also contains
flags that are set when a byte is successfully sent or received.
Programming Tip: To use the 8051's on-board serial port, it is generally necessary to
initialize the following SFRs: SCON, TCON, and TMOD. This is because SCON controls the
serial port. However, in most cases the program will wish to use one of the timers to establish
the serial port's baud rate. In this case, it is necessary to configure timer 1 by initializing
TCON and TMOD.
SBUF (Serial Control, Addresses 99h): The Serial Buffer SFR is used to send and
receive data via the on-board serial port. Any value written to SBUF will be sent out the
serial port's TXD pin. Likewise, any value which the 8051 receives via the serial port's RXD
pin will be delivered to the user program via SBUF. In other words, SBUF serves as the
output port when written to and as an input port when read from.
IE (Interrupt Enable, Addresses A8h): The Interrupt Enable SFR is used to enable
and disable specific interrupts. The low 7 bits of the SFR are used to enable/disable the
specific interrupts, where as the highest bit is used to enable or disable ALL interrupts. Thus,
if the high bit of IE is 0 all interrupts are disabled regardless of whether an individual
interrupt is enabled by setting a lower bit.
TCON (Timer Control, Addresses 88h, and Bit-Addressable): The Timer Control
SFR is used to configure and modify the way in which the 8051's two timers operate. This
SFR controls whether each of the two timers is running or stopped and contains a flag to
indicate that each timer has overflowed. Additionally, some non-timer related bits are located
in the TCON SFR. These bits are used to configure the way in which the external interrupts
are activated and contain the external interrupt flags which are set when an external interrupt
has occurred.
TMOD (Timer Mode, Addresses 89h): The Timer Mode SFR is used to configure the
mode of operation of each of the two timers. Using this SFR your program may configure
each timer to be a 16-bit timer, an 8-bit auto reload timer, a 13-bit timer, or two separate
timers. Additionally, you may configure the timers to only count when an external pin is
activated or to count "events" that are indicated on an external pin.
1. Write the program for sending string (“you can”) to PC using serial communication.
BR is 9600. Result should be displayed at hyper terminal
Implementation:
#include <REGX51.H>
#include<intrins.h>
void delay(unsigned int);
Void transmit data (char); // transmit the data
unsigned char transmit; // variable declaration to transmit
Void delay (unsigned int Valid) // delay routine
{
unsigned int i=0;
for(i=0;i<valid; i++)
{
_nop_();
}
}
/*####################MAINSTARTS#########################*/
void main()
{
P3=0xFF; // initialization
delay(100);
TMOD=0x20; //timer selection and mode selection for baud
rate generation
TH1=0xFD; // 9600 BR value
SCON=0x50; // serial communication enable
IE=0x80; // interrupt enable
TR1=1; // timer starts here
P0=0xFF; // pins initialization
P2=0xFF;
delay(500);
while(1)
{
delay(6000);
transmit data('Y');
transmit data('O');
transmit data('U');
transmit data(' ’);
transmit data('C');
transmit data('A');
transmit data('N');
delay(7000);
}
}
void transmit data(char x)
{
SBUF=x;
while(TI==0);
TI=0;
}
//*************************************************************************
Exercise:
1. Write programming for receiving data from PC , according to that control the relays….
In computers, ports are used mainly for two reasons: Device control and
communication. We can program PC's Parallel ports for both. Parallel ports are mainly meant
for connecting the printer to the PC. But we can program this port for many more
applications beyond that.
Parallel ports are easy to program and faster compared to the serial ports. But main
disadvantage is it needs more number of transmission lines. Because of this reason parallel
ports are not used in long distance communications. Let us know the basic difference
between working of parallel port and serial port. In serial ports, there will be two data lines:
One transmission and one receive line. To send a data in serial port, it has to be sent one bit
after another with some extra bits like start bit, stop bit and parity bit to detect errors. But in
parallel port, all the 8 bits of a byte will be sent to the port at a time and a indication will be
sent in another line. There will be some data lines, some control and some handshaking lines
in parallel port. If three bytes of data 01000101 10011100 10110011 is to be sent to the port,
following figures will explain how they are sent to the serial and parallel ports respectively.
We can understand why parallel port communication is faster compared to that of serial.
In computers, ports are used mainly for two reasons: Device control and communication.
We can program PC's Parallel ports for both. Parallel ports are mainly meant for connecting
the printer to the PC. But we can program this port for many more applications beyond that
Parallel ports are easy to program and faster compared to the serial ports. But main
disadvantage is it needs more number of transmission lines. Because of this reason parallel
ports are not used in long distance communications. In parallel port, all the 8 bits of a byte
will be sent to the port at a time and a indication will be sent in another line. There will be
some data lines, some control and some handshaking lines in parallel port. If three bytes of
data 01000101 10011100 10110011 is to be sent to the port, following figures will explain
how they are sent to and parallel port. We can understand why parallel port communication is
faster compared to that of serial.
In the PC there will be D-25 type of female connector having 25 pins and in the
printer, there will be a 36-pin Centronics connector. Connecting cable will combine these
connecter using following convention. Pin structure of D-25 and Centronics connecters are
explained bellow.
Pin Details
Now let us know how communication between PC and printer takes place. Computer
places the data in the data pins, and then it makes the strobe low. When strobe goes low,
printer understands that there is a valid data in data pins. Other pins are used to send controls
to the printer and get status of the printer; you can understand them by the names assigned to
the pins.
To use the printer port for applications other than printing, we need to know how ports
are organized. There are three registers associated with LPT port: Data register, Control
register and Status register. Data register will hold the data of the data pins of the port. That
means, if we store a byte of data to the data register, that data will be sent to the data pins of
the port. Similarly control and status registers. The following table explains how these
registers are associated with ports.
Data pins- 2 to 9
Ground-18 to 25
Exercise
1. Write the program for sending string (‘First come, First Served) to PC using Parallel
communication. Result should be displayed on visual basic screen.
2. Write programming for receiving data from PC, according to that the 5 relays which is
connected to microcontroller.
Summary
The serial interrupt TI,RI are the important for serial communication
The SFR ‘s are very important for communication, especially TMOD,SCON,TCON.
The crystal frequency is used to calculate the timer value which is used to determine
the baud rate.
Visual basic and Hyper terminal is used to send the data through serial port
Technical questions
CHAPTER 11
APPLICATION OF MOTORS
This chapter will give information about motor speed controlling methods.
You can learn about application of stepper motor.
11.1 INTRODUCTION
The major application of motor is robotic control. Robot is an automatic device which
can be controlled by motors. The stepper motor is most suitable for robotic control. Because
the movement will be slow. If we want fast action the DC motor is suitable.
Motor is a device, which converts electrical energy into mechanical energy. The
important motor types are
1. DC motor
2. Stepper motor
11.2.1 Dc Motor
The operating voltage of DC motor is 12V DC. We can change the motor direction by
changing the supply input. Two relays are used to control the direction. The motor terminals
are connected from the COM terminal of the two relays. If relay1 is in ON condition (Relay2
is in OFF condition) then the motor will be in clockwise direction. If relay2 is in ON
condition (Relay1 is in ON condition) then the relay will be in anti-clockwise direction. We
see about relay function.
Relay
A relay is an electrically operated switch. Current flowing through the coil of the
relay creates a magnetic field, which attracts a lever and changes the switch contacts. The coil
current can be on or off so relays have two switch positions and they are double throw
(changeover) switches.
Relays allow one circuit to switch a second circuit which can be completely separate
from the first. For example a low voltage battery circuit can use a relay to switch a 230V AC
mains circuit. There is no electrical connection inside the relay between the two circuits; the
link is magnetic and mechanical.
The coil of a relay passes a relatively large current; typically 30mA for a 12V relay,
but it can be as much as 100mA for relays designed to operate from lower voltages. Most ICs
(chips) cannot provide this current and a transistor is usually used to amplify the small IC
current to the larger value required for the relay coil. The maximum output current for the
popular 555 timers IC is 200mA so these devices can supply relay coils directly without
amplification.
Relays are usually SPDT or DPDT but they can have many more sets of switch
contacts, for example relays with 4 sets of changeover contacts are readily available. For
further information about switch contacts and the terms used to describe them please see the
page on switches.
Most relays are designed for PCB mounting but you can solder wires directly to the
pins providing you take care to avoid melting the plastic case of the relay.
The supplier's catalogue should show you the relay's connections. The coil will be
obvious and it may be connected either way round. Relay coils produce brief high voltage
'spikes' when they are switched off and this can destroy transistors and ICs in the circuit. To
prevent damage you must connect a protection diode across the relay coil.
The animated picture shows a working relay with its coil and switch contacts. You
can see a lever on the left being attracted by magnetism when the coil is switched on. This
lever moves the switch contacts. There is one set of contacts (SPDT) in the foreground and
another behind them, making the relay DPDT.
Relays
Choosing a relay
The relay's switch contacts must be suitable for the circuit they are to control. You
will need to check the voltage and current ratings. Note that the voltage rating is usually
higher for AC, for example: "5A at 24V DC or 125V AC".
5. Switch Contact Arrangement :( SPDT, DPDT etc)
Most relays are SPDT or DPDT which are often described as "single pole
changeover" (SPCO) or "double pole changeover" (DPCO). For further information
please see the page on switches.
Advantages of relays:
• Relays can switch AC and DC, transistors can only switch DC.
• Relays can switch high voltages, transistors cannot.
• Relays are a better choice for switching large currents (> 5A).
• Relays can switch many contacts at once.
Disadvantages of relay
When a transistor is used as a switch it must be either OFF or fully ON. In the fully
ON state the voltage VCE across the transistor is almost zero and the transistor is said to be
saturated because it cannot pass any more collector current Ic. The output device switched
by the transistor is usually called the 'load'.
This means that the transistor should not become hot in use and you do not need to
consider its maximum power rating. The important ratings in switching circuits are the
maximum collector current IC (max) and the minimum current gain hFE (min). The
transistor's voltage ratings may be ignored unless you are using a supply voltage of more than
about 15V.
Here relay coil act as a load. One end of the relay coil is connected with supply and
another one end is connected with transistor collector output. When the collector output is
high, the relay coil is not energized. Therefore the COM terminal is normally the COM
terminal will energize depending upon the collector output.
The above figure shows the relay driver using ULN 2003. The input pins from 1 to 7
are connected with microcontroller. Output pins are connected with relay coil. If input is high
the output will be low. Therefore the relay is energized. If input pins are low the output will
be high.
Hardware Description:
The total number of terminals in the relay is five. They are Coils, COM, NC, NO. The
NC and NO terminals should be inter-connected to each other. These inter connected
terminals are connected with power supply (+12V and GND). The one end of the relay coil is
connected with +12V and other end are connected with relay driver output. The two COM
terminals are connected with motor.
We can write small instruction for relay control. Assume two relays relay1 and relay2.
Relay1=1;
Relay=0;
Delay;
Relay1=0;
Relay=1;
Delay;
Definition
A motor that rotates in small, fixed increments and is used to control the movement of
the access arm on a disk drive.
Stepper motors were developed in the early 1960's as a low cost alternative to position
servo systems in the emerging computer peripheral industry. The main advantage of stepper
motors is that they can achieve accurate position control without the requirement for position
feedback. In other words, they can run "open-loop", which significantly reduces the cost of a
position control system.
Stepper motors utilize a doubly-salient topology, which means they have "teeth" on
both the rotor and stator. Torque is generated by alternately magnetizing the stator teeth
electrically, and the permanent magnet rotor teeth try to line up with the stator teeth. There
are many different configurations of stepper motors, and even more diverse ways to drive
them.
The most common stator configuration consists of two coils (A and B). These coils
are arranged around the circumference of the stator in such a way that if they are driven with
square waves which have a quadrate phase relationship between them, the motor will rotate.
To make the motor rotate in the opposite direction, simply reverse the phase relationship
between the A and B signals. A transition of either square wave causes the rotor to move by a
small amount, or a "STEP". Thus, the name "stepper motor".
The size of this step is dependent on the teeth arrangement of the motor, but a
common value is 1.8 degrees, or 200 steps per revolution. Speed control is achieved by
simply varying the frequency of the square waves.
Because stepper motors can be driven with square waves, they are easily controlled by
inexpensive digital circuitry and do not even require PWM. For this reason, stepper motors
have often been inappropriately referred to as "digital motors". However, by utilizing power
modulation techniques to change the quadrate square waves into sine and cosine waveforms,
even MORE step resolution is possible. This is called "micro-stepping", where each discrete
change in the sine and cosine levels constitutes one micro step.
Key characteristics
The circuit diagram of stepper driver is shown in below. The current supplied from
microcontroller to stepper motor is not sufficient. Therefore we should improve the current.
The stepper driver circuit is used to improve the current from the microcontroller.
P2=0x05;
delay(750);
P2=0x09;
delay(750);
P2=0x0a;
delay(750);
P2=0x06;
delay(750);
Applications:
• Cruise control
• Auto air vents
• Light leveling
• Printers
• Industrial machines
• Automotive gauges
• Office equipment
• Computer drives
• Medical scanners
• Scientific Instrumentation.
Summary:
The stepper driver circuit is used to improve the current rating of the pulse.
The DC motor can be controlled using two relays.
The step angle is the angle when applying the single pulse from microcontroller.
Technical questions:
Exercise:
2. Write a program for clockwise and anti clockwise direction of different DC motors
Connected in mechanism.
CHAPTER 12
ENCODERS/DECODERS
About this Chapter
12.1 Encoder
An encoder is a device used to change a signal (such as a bit stream) or data into a
code. The code may serve any of a number of purposes such as compressing information for
transmission or storage, encrypting or adding redundancies to the input code, or translating
from one code to another. This is usually done by means of a programmed algorithm,
especially if any part is digital, while most analog encoding is done with analog circuitry.
12.1.1 Examples
12.2 DECODER
A decoder is a device which does the reverse of an encoder, undoing the encoding so
that the original information can be retrieved. The same method used to encode is usually just
reversed in order to decode.
Enable inputs must be on for the decoder to function, otherwise its outputs assume a
single "disabled" output code word. Decoding is necessary in applications such as data
multiplexing, 7 segment display and memory address decoding.
12.4 HT12E/ENCODER
Using this encoder can be sending the 4 bit data to the remote place; here the four pins
are connected to the microcontroller which can be used to send the data.
But the transmitter enable pin -14 is important, using this pin can control the entire
transmission, it should be active low pin i.e. Works when it is low.
VCC
HT12E 5V
IO1 IO10
IO2 IO11
IO3 IO12 RF-TX
IO4
IO5
IO13
IO14
R1 antenna
IO6 IO15 1.0MΩ
IO7 IO16
IO8 IO17 TX ENBLE
IO9 IO18
18 VCC
J1 5V
data in
HDR1X4
TO MICROCONTROLLER PORT
12.5 HT12D/DECODER
Using this decoder can decode the data from encoder; here the address should be same
at both encoder and decoder. Decoder receives the serial data from RF module, and then it
will be converted into parallel using decoder HT12D. Hence data can be used by
microcontroller according to application.
J1
RF-RX
433MHZ
antenna
HT12D
HDR1X4
TO MICROCONTROLLER PORT
NC
IO1 IO10
IO2 IO11
IO3 IO12
IO4 IO13 DATA IN
IO5 IO14 R1 VCC
IO6 IO15
IO7 IO16 data in 5V
IO8 IO17 1.0MΩ
IO9 IO18
18 LED1
VCC
5V R2 1.0kΩ
12.7 IMPLEMENTATION
Write program for counting pulses from external, eye blink count from sensor and tell
the status of driver to remote using RF encoder and decoder.
12.7 EXERCISE
The following diagrams describe how to connect the 8 bit data encoder and decoder,
have to write the code for this application.
12.8 ENCODER/HT640
TRANSMITTER
J2
A0
A1 RF-TX
A2
A3
A4
A5 VCC
data out to mc
A6 5V
J1
HT640 A8
IO1 IO13 A7
IO2 IO14
IO3 IO15 A9
IO4 IO16
IO5 IO17
IO6 IO18 HDR2X10 DATA OUT
IO7 IO19
IO8 IO20
IO9 IO21
IO10 IO22
R1 IO11
IO12
IO23
IO24
24 VCC
HDR1X8 5V VCC
1.0MΩ
TX ENBLE 5V
12.9 DECODER/HT648
Receive the value from encoder and display the value on LCDs which is connected to micro
controller.
RECEIVER RF-RX
433MHZ
J2 antenna
A0
A1
A2
A3 NC
A4
A5 VCC
data out to mc
A6 data in 5V
J1
HT648 A8
IO1 IO13 A7
IO2 IO14
IO3 IO15 A9
IO4 IO16
IO5 IO17
IO6 IO18 HDR2X10
IO7 IO19
IO8 IO20
IO9 IO21
IO10 IO22
R1 IO11
IO12
IO23
IO24
R2
1.0kΩ
LED1
Here write the code for the above application and test, and implement the Rf transmitter and
Rf receiver.
Summary
The encoder is used to convert the parallel data into serial data, because we are using
FSK modulation for sending the data.
The decoder is used to decode the data which is sent by transmitter,i.e the serial data
is converted into parallel.
The transmitter enable pin is used to control the transmission .
The receiver Vt pin is used to find out the reception of the data.
Technical questions
1. What is the distance between transmitter and receiver if the frequency is 433 MHz?
2. Which type of register used at encoder and decoder ic?
3. Is there possibility to send multi data at single channel using encoder and decoder?
CHAPTER13
I2C/TCP/IP/SPI
About this Chapter
This chapter will give information about i2c, tcp/ip, spi protocols for
communication.
You can learn about application of interfacing microcontroller with slave
devices.
BIT TRANSFER
One data bit is transferred during each clock pulse. The data on the SDA line must
remain stable during the HIGH period of the clock pulse as changes in the data line at this
time will be interpreted as a control signal.
Both data and clock lines remain HIGH when the bus is not busy. A HIGH-to-LOW
transition of the data line, while the clock is HIGH, is defined as the start condition (S). A
LOW-to-HIGH transition of the data line while the clock is HIGH is defined as the stop
condition (P).
SYSTEM CONFIGURATION
A device generating a message is a ‘transmitter’; a device receiving a message is the
‘receiver’. The device that controls the message is the ‘master’ and the devices which are
controlled by the master are the ‘slaves’.
Acknowledge
The number of data bytes transferred between the start and stop conditions from
transmitter to receiver is not limited. Each data byte of eight bits is followed by one
acknowledge bit. The acknowledge bit is a HIGH level put on the bus by the transmitter
whereas the master also generates an extra acknowledge related clock pulse. A slave receiver
which is addressed must generate an acknowledge after the reception of each byte. Also a
master must generate an acknowledge after the reception of each byte that has been clocked
out of the slave transmitter. The device that acknowledges has to pull down the SDA line
during the acknowledge clock pulse, so that the SDA line is stable LOW during the HIGH
period of the acknowledge related clock pulse. A master receiver must signal an end of data
to the transmitter by not generating an acknowledge on the last byte that has been clocked out
of the slave. In this event the transmitter must leave the data line HIGH to enable the master
to generate a stop condition.
I2C-bus protocol
After a start condition a valid hardware address has to be sent to a PCF8591 device.
The read/write bit defines the direction of the following single or multiple byte data transfer.
For the format and the timing of the start condition (S), the stop condition (P) and the
acknowledge bit (A) refer to the I2C-bus characteristics. In the write mode a data transfer is
terminated by sending either a stop condition or the start condition of the next data transfer.
EXAMPLE PROGRAMS
void ipdel (void)
{ // I2C delay
_nop_ ();
_nop_ ();
_nop_ ();
_nop_ ();
_nop_ ();
_nop_ ();
_nop_ ();
_nop_ ();
}
void ipchigh (void)
{ // I2C clock high
IPSCL = 1;
ipdel ();
}
Technical questions
SPI
The Serial Peripheral Interface Bus or SPI bus is a synchronous serial data link standard
named by Motorola that operates in full duplex mode. Devices communicate in master/slave
mode where the master device initiates the data frame. Multiple slave devices are allowed
with individual slave select (chip select) lines. Sometimes SPI is called a "four wire" serial
bus, contrasting with three, two, and one wire serial busses.
Operation
The SPI bus can operate with a single master device and with one or more slave devices.
If a single slave device is used, the SS pin may be fixed to logic low if the slave permits it.
Some slaves require the falling edge (high->low transition) of the slave select to initiate an
action such as the MAX1242 by Maxim, an ADC, which starts conversion on said transition.
With multiple slave devices, an independent SS signal is required from the master for each
slave device.
Most devices have tri-state outputs that become high impedance ("disconnected") when the
device is not selected. Devices without tristate outputs can't share SPI bus segments with
other devices; only one such slave may talk to the master, and only its chip select may be
activated.
Data Transmission
A typical hardware setup using two shift registers to form an inter-chip circular buffer
To begin a communication, the master first configures the clock, using a frequency less than
or equal to the maximum frequency the slave device supports. Such frequencies are
commonly in the range of 1-70 MHz.
The master then pulls the slave select low for the desired chip. If a waiting period is required
(such as for analog-to-digital conversion) then the master must wait for at least that period of
time before starting to issue clock cycles.
During each SPI clock cycle, a full duplex data transmission occurs:
• the master sends a bit on the MOSI line; the slave reads it from that same line
• the slave sends a bit on the MISO line; the master reads it from that same line
Not all transmissions require all four of these operations to be meaningful but they do
happen.
Transmissions normally involve two shift registers of some given word size, such as
eight bits, one in the master and one in the slave; they are connected in a ring. Data is usually
shifted out with the most significant bit first, while shifting a new least significant bit into the
same register. After that register has been shifted out, the master and slave have exchanged
register values. Then each device takes that value and does something with it, such as writing
it to memory. If there is more data to exchange, the shift registers are loaded with new data
and the process repeats.
Transmissions may involve any number of clock cycles. When there are no more data
to be transmitted, the master stops toggling its clock. Normally, it then deselects the slave.
Transmissions often consist of 8-bit words, and a master can initiate multiple such
transmissions if it wishes/needs. However, other word sizes are also common, such as 16-bit
words for touch screen controllers or audio codec’s, like the TSC2101 from Texas
Instruments; or 12-bit words for many digital-to-analog or analog-to-digital converters.
Every slave on the bus that hasn't been activated using its slave select line must disregard the
input clock and MOSI signals, and may not drive MISO. The master selects only one slave at
a time.
A timing diagram showing clock polarity and phas In addition to setting the clock
frequency, the master must also configure the clock polarity and phase with respect to the
data. Free scale’s SPI Block Guide [1] names these two options as CPOL and CPHA
respectively, and most vendors have adopted that convention.
The timing diagram is shown to the right. The timing is further described below and
applies to both the master and the slave device.
• At CPOL=0 the base value of the clock is zero
o For CPHA=0, data are read on the clock's rising edge (low->high transition)
and data are changed on a falling edge (high->low clock transition).
o For CPHA=1, data are read on the clock's falling edge and data are changed on
a rising edge.
• At CPOL=1 the base value of the clock is one (inversion of CPOL=0)
o For CPHA=0, data are read on clock's falling edge and data are changed on a
rising edge.
o For CPHA=1, data are read on clock's rising edge and data are changed on a
falling edge.
That is, CPHA=0 means sample on the leading (first) clock edge, while CPHA=1
means sample on the trailing (second) clock edge, regardless of whether that clock edge is
rising or falling. Note that with CPHA=0, the data must be stable for a half cycle before the
first clock cycle. Also, note that no matter what the CPOL and CPHA modes say, the initial
clock value must be stable before the chip select line goes active.
This adds more flexibility to the communication channel between the master and slave.
Mode Numbers
The combinations of polarity and phases are often referred to as modes which are
commonly numbered according to the following convention, with CPOL as the high order bit
and CPHA as the low order bit:
In the independent slave configuration, there is an independent slave select line for
each slave. This is the way SPI is normally used. Since the MISO pins of the slaves are
connected together, they are required to be tri-state pins.
Some slave devices are designed to ignore any SPI communications in which the
number of clock pulses is greater than specified. Others don't care, ignoring extra inputs and
continuing to shift the same output bit. It is common for different devices to use SPI
communications with different lengths, as, for example, when SPI is used to access the scan
chain of a digital IC by issuing a command word of one size (perhaps 32 bits) and then
getting a response of a different size (perhaps 153 bits, one for each pin in that scan chain).
Interrupts
SPI devices sometimes use another signal line to send an interrupt signal to a host CPU.
Examples include pen-down interrupts from touch screen sensors, thermal limit alerts from
temperature sensors, alarms issued by real time clock chips, and headset jack insertions from
the sound codec in a cell phone.
Advantages
Disadvantages
• Requires more pins on IC packages than I²C, even in the "3-Wire" variant
• No in-band addressing; out-of-band chip select signals are required on shared busses
• No hardware flow control
• No slave acknowledgment (the master could be "talking" to nothing and not know it)
• Supports only one master device
• Without a formal standard, validating conformance is not possible
• Only handles short distances compared to RS-232, RS-485, or CAN-bus
Applications
The board real estate savings compared to a parallel I/O bus are significant, and have
earned SPI a solid role in embedded systems. That's true for most System-on-a-chip
processors, both with higher end 32-bit processors such as those using ARM and with lower
end microcontrollers such as the AVR, PIC and MSP430. These chips usually include SPI
controllers capable of running in either master or slave mode.
Chip or FPGA based designs sometimes use SPI to communicate between internal
components; on-chip real estate can be as costly as its on-board cousin.
The full-duplex capability makes SPI very simple and efficient for single
master/single slave applications. Some devices use the full-duplex mode to implement an
efficient, high-speed data stream for applications such as digital audio, digital signal
processing, or telecommunications channels, but most off-the-shelf chips stick to half-duplex
request/response protocols.
TCP can detect errors or lost data and can trigger retransmission until the data is
received, complete and without errors. TCP/IP (Transmission Control Protocol/Internet
Protocol) is a set of protocols independent of the physical medium used to transmit data. The
Rabbit Development Board module that is the RCM2200 uses an Ethernet interface to
communicate with other computers. The Ethernet can use either a bus or a star topology.
TCP/IP is the protocol suite upon which all Internet communications are based. Different
vendors have developed other networking protocols, but even most networking operating
systems with their own protocols, such as Netware support TCP/IP. It has become the de
facto standard.
The TCP/IP protocol is divided into five layers such as the Application Layer, which
specifies a particular application uses a network. Transport layer specifies how to ensure
reliable transport of data. Internet Layer specifies packet format and routing Network layer
and specifies frame organization and transmittal. Physical Layer specifies the basic network
hardware.
Each host or router in the Internet must run a protocol stack. The software hides the
details of the underlying physical connections. The sending software at each layer
communicates with the corresponding layer at the receiving side through information stored
in header. The Web server uses this set of protocols to communicate between the Web server
and the Web browser.
A network is a system of hardware and software, put together for the purpose of
communication and resource sharing. A network includes transmission hardware, devices to
interconnect transmission media and to control transmissions, and software to decode and
format data, as well as to detect and correct problems.
TCP/IP is the protocol suite upon which all Internet communication is based.
Different vendors have developed other networking protocols, but even most network
operating systems with their own protocols, such as Netware, support TCP/IP. It has become
the de facto standard.
Each host or router in the Internet must run a protocol stack. The details of the
underlying physical connections are hidden by the software. The sending software at each
layer communicates with the corresponding layer at the receiving side through information
stored in headers. Each layer adds its header to the front of the message from the next higher
layer. The header is removed by the corresponding layer on the receiving side.
The most widely deployed type of network, LANs were designed as an alternative to the
more expensive point-to-point connection. A LAN has high throughput for relatively low
cost. LANs often rely on shared media, usually a cable, for connecting many computers.
This reduces cost. The computers take turns using the cable to send data.
Physical Connections
The TCP/IP Development Board can be connected to your computer using a hub and
standard cable or directly to the computer using a cross-over cable. The Development Board
can also be a host connected directly to an Ethernet network.
Port Numbers
Port numbers are the mechanism for identifying particular client and server
applications. Servers select a port to wait for a connection. Most services have well-known
port numbers. For example, HTTP uses port 80. When a web browser (the client) requests a
web page it specifies port 80 when contacting the server. Clients usually have ephemeral port
numbers since they exist only as long as the session lasts.
Some of the common well-known TCP port numbers are listed in the table below.
7 Echo request
20/21 File Transfer Protocol (FTP)
23 Telnet
25 Simple Mail Transfer Protocol (SMTP)
53 Domain Name Server
80 HTTP Server
IP (INTERNET PROTOCOL)
IP provides communication between hosts on different kinds of networks. It is a
connectionless, unreliable packet delivery service. Connectionless means that there is no
handshaking, each packet is independent of any other packet. It is unreliable because there is
no guarantee that a packet gets delivered; higher-level protocols must deal with that.
IP Address
For routing efficiency, the IP address is considered in two parts: the prefix, which
identifies the physical network, and the suffix, which identifies a computer on the network. A
unique prefix is needed for each network in an Internet. For the global Internet, network
numbers are obtained from Internet Service Providers (ISPs). ISPs coordinate with a central
organization called the Internet Assigned Number Authority.
IP (Internet Protocol) addresses are expressed as 4 decimal numbers separated by periods, for
example:
216.103.126.155
10.1.1.6
Each decimal number must be between 0 and 255. The total IP address is a 32-bit
number consisting of the 4 bytes expressed as shown above. A local network uses a group of
adjacent IP addresses. There are always 2N IP addresses in a local network. The net mask
(also called subnet mask) determines how many IP addresses belong to the local network.
The net mask is also a 32-bit address expressed in the same form as the IP address. An
example net mask is:
• 255.255.255.0
This net mask has 8 zero bits in the least significant portion, and this means that 28
addresses are a part of the local network.
3) The IP address of the router that connects the host's network to the rest of the world
(the default gateway).
4) The IP address of the local DNS server for the host's network. This is only necessary
if DNS backups are needed.
In either case, there is an IP address on the local network to which the packet must be
sent. A table is maintained to allow the protocol driver to determine the MAC address
corresponding to a particular IP address. If the table is empty, the MAC address is determined
by sending an Ethernet broadcast packet to all devices on the local network asking the device
with the desired IP address to answer with its MAC address. In this way, the table entry can
be filled in. If no device answers, then the device is nonexistent or inoperative, and the packet
cannot be sent.
IP addresses are arbitrary and can be allocated as desired provided that they don't
conflict with other IP addresses. However, if they are to be used with the Internet, then they
must be numbers that are assigned to your connection by proper authorities, generally by
delegation via your service provider.
In a typical corporate network that is isolated from the Internet by a firewall and/or
proxy server using address translation, the IP addresses are not usually actual Internet
addresses and may be assigned statically or dynamically. If they are assigned statically, you
only have to get an unused IP address and assign it to the RCM2200 board. If the IP
addresses are assigned dynamically, they you will have to get an IP address that is valid but
outside of the range of IP addresses that are assigned dynamically.
This will enable you to communicate from a PC on the network to the RCM2200
board. If you want to communicate to the RCM2200 board from the external Internet, then an
actual Internet IP address must be assigned to the RCM2200 board. It may be possible to
setup the firewall to pass a real IP address, or it may be necessary to connect the RCM2200
board in front of the firewall to accomplish this.
Net masks
Net masks are used to identify which part of the address is the Network ID and which
part is the Host ID. This is done by a logical bitwise-AND of the IP address and the net mask.
For class a networks the net mask is always 255.0.0.0; for class B networks it is 255.255.0.0
and for class C networks the net mask is 255.255.255.0.
Subnet Address
All hosts are required to support subnet addressing. While the IP address classes are the
convention, IP addresses are typically sub netted to smaller address sets that do not match the
class system. The suffix bits are divided into a subnet ID and a host ID. This makes sense for
class A and B networks, since no one attaches as many hosts to these networks as is allowed.
Whether to subnet and how many bits to use for the subnet ID is determined by the local
network administrator of each network.
If sub netting is used, then the net mask will have to reflect this fact. On a class B
network with sub netting, the net mask would not be 255.255.0.0. The bits of the Host ID that
were used for the subnet would need to be set in the net mask.
TCP Connection/Socket
A TCP connection is done with a 3-way handshake between a client and a server. The
following is a simplified explanation of this process.
The client asks for a connection by sending a TCP segment with the SYN control bit
set.
The server responds with its own SYN segment that includes identifying information
that was sent by the client in the initial SYN segment.
The client acknowledges the server's SYN segment.
The connection is then established and is uniquely identified by a 4-tuple called a socket or
socket pair:
(Destination IP address, destination port number)
(Source IP address, source port number)
During the connection setup phase, these values are entered in a table and saved for the
duration of the connection.
Checksum - This 16-bit number is the one's complement of the one's complement sum of all
bytes in the TCP header, any data that is in the segment and part of the IP packet. A
checksum can only detect some errors, not all, and cannot correct any.
TCP/IP
Detailed Layers
Technical questions
CHAPTER 14
This chapter will give information about serial and parallel communication.
You can learn about application of interfacing with PC and External
Peripherals.
We will use VB control "MSComm" that you should refer the control by Custom
control.
This programming guide assumes the user has a basic knowledge of Visual Basic
programming. The teaching method used is to show a basic example of a VB6.0 program
which communicates with an modem or PC to PC together by sending and receiving ASCII
data, and then direct the program to understand its operation.
PC's serial data acquisition interfaces require the sending and receiving of ASCII data
to operate. To communicate with the serial port using Visual Basic, the MsComm control
must be utilized to allow serial data transfer via a serial port (Com1-Com4). MSComm is a
custom control shipped with VB5.0 and VB6.0 and must be loaded using the Tools menu.
Follow to select in check box name is MSComm after it will display a telephone icon on
control box dialog that drag and drop it to your form of Project Please see thus picture below.
Step one Select at top menu bar of Visual Basic thus as picture below
Step two Select Control name is "Microsoft Comm. Control 6" thus picture below.
Step three drag MS Comm. control from Toolbox to paste on Form thus as picture
Below.
1. Interrupt communication.
Interrupt process is check device signal if the devices has already in sending code to
comm. port of computer. We are programming in COM Event and OnCommEvent that these
event will be active when coming signal from device.
2. Polling Communication
In PC system, the polling has some transferring between terminal and CPU in case
data is byte type that keyboard send coming.
The polling will be through checking signal from device such as keyboard polling as user
press button.
For CPU polling to check signal, we call “Wet Poll" that will be loss time 90%,We
can avoid the cycle time lose with using polling technique that call is "Round Robin" About
in VB programming ,we use Timer control for checking data from Serial port. MSComm
control has Event which use one only in Oncomm Event that communication is interrupt.For
programming in Serial Port communication normally using comm. event are comEvReceive,
comEvSend if it is communication in MODEM then using many one in check signal, please
refer help or MSDN.
1. ComNone
2. ComXonXoff
3. ComRTS
4. ComTRSXonXoff
About Hardware
1. Property Comport Select comm. port that we are using it thus as source code below
Example MSComm1.CommPort=1
in this using is Com1
2. Property Settings mean is setting value for receive /send data that will know baud rate of
device which connect ,how much thus as detail below
MSComm1.Settings="Baud(rate for receive/send data),Parity(N,Number of bits, bits Stop"
Example MSComm1.Settings="1200,N,8,1"
4. Property Port Open mean is open port to communicate Open =True, Close =False
Example MSComm1.PortOpen=True
5. Property Rthresholdmean is do activate occur with Event-driven when has data in receive
buffer (comm. port) that active the CommEvent in procedure OnComm Event
Example MSComm1.Rthreshold =1
We can use the MSComm properties allow the setting of communication parameters
including port selection and port enabling functions. Or we will be write to your code
from detail above, we will programming in VB procedure at Sub Form Load () or create new
Sub in case call in the future
MSComm1.Settings="1200, N, 8, 1"
MSComm1.CommPort=1
MSComm1.InputLen=1
MSComm1.PortOpen=True
MSComm1.Rthreshold =1
End Sub
It defines the starting value of the communication port and open port to communicate with
RS-232 So, we can get data and send data with Property Output and Input
Output =send data to serial port
Input =receive data from port but this will being command to write at Event Property
OnComm that has in Sub MSComm_OnComm that read data from serial port or RS-232
Example:-
If we want print data to port while we are typing data to keyboard, we use event the Key
Press of Control Textbox
I have get example program which is control step motor with command ASCII communicate
to Micro controller
A99 ' accelerate setting
V3 ' speed setting
D5000 ' step setting
H- 'direction setting
G ' go ,it is start motor command
We are assume use a button in my program thus as below
End If
End Sub
1. Port Enabling
- Port selection and enable functions can be programmed in the "load" and "unload"
subroutines in the "form" object or they may be controlled by radio buttons or pull down
menus.
2. Receiving Data
When receiving data from the serial port, be sure to wait for the correct number of
characters to be received in the serial buffer. Check your serial port programming manual for
the correct number of characters to be received and add one for the carriage return. The
command sends both a carriage return and line feed thus two must be added to the number of
characters expected.
3. Using Variables
- In many cases it may be desired to send a string incorporating a command and some
variable. For example, the "GO" command outputs to port A, the integer value position. If the
position is a variable 1500, a string to set the port to the value of this variable would look
like;
You may be many question how to communicate with microcontroller, so, we can use
concept on above to apply in your project, process for communicate is like my example
programming but you will be know protocol of those device.
If you have built any of the interfaces on my circuit’s page and now want to know
how to actually make use of them, this page is for you. This is a simple introduction to
programming the parallel port in Visual Basic. Note that most of the concepts in this page
apply to both 16 bit and 32 bit versions of VB. This document assumes that you are familiar
with the basic functions of Visual Basic itself.
Now before we go any further, we must figure out a way around some limitations
built into Visual Basic. VB cannot directly access the hardware on a system. All hardware
requests must go through Windows. Because of this, the closest we can get to manipulate the
parallel port is wit the Printer object. While this is all fine and good when you want to
actually print something, it is useless when we want direct hardware control. There may be
API calls to get round this, but as of yet I have been unable to find any. In order to control the
port directly, we must use something external to our program. It just so happens that there is a
great, free product that does exactly what we want. It is a DLL from a company called Soft
Circuits. You can download this DLL from their Programming Tools and Libraries page
Now that we have that finished with, let's get to the port. The parallel port is made up
of three different sections. These are the data lines, control lines and status lines. There are 8
data lines, and they are the primary means of getting information out of the port. In simple
projects, you will be concentrating mostly on the data lines. The control lines are another 4
outputs. They are meant to provide control signals to the printer (such as form feed or
initialize). The status lines are a standard parallel port's only inputs. There are 5 of them.
They were meant to allow the printer to communicate things such as error, paper out and
busy to the PC.
Each section is accessed by its own address and will act independently from the rest.
This is almost as if they were different ports. The addresses are as follows:
You need to know the address of the port you want to use. You will also need two
other things; the command to access the port and the number you want to set it to. The
command will be explained in a little while. The ports work with numbers. These can be
expressed in hex, binary or decimal, but for this document all values will be expressed in
decimal. It's just easier that way. Anyway, you operate the port by sending it a number that
represents the binary pattern of the physical outputs on the port. For example, to set the 8 data
lines to 11111111, you would send 255. To set them to 00000000 you would send 0. Note
that these are all 8 bit binary numbers, and the port is also 8 outputs.
Here in this article, we are using a third party tool called inpout32.dll to connect to
ports available in your PC. We are using it because in Windows NT based versions, all the
low-level hardware access is prohibited and a separate I/O driver is needed. When we read
the status of the port, we have to take the support of that third party application.
In inpout32.dll, all of the system drivers and small tools needed to activate and run
that system driver are included. So, we don't have to consider much or think about how this
happens; it will do everything for us… As far as we are using a DLL file to communicate
with the hardware, we have to know the links that this particular file provides for the user, or
the entry points for that particular file. Here, I will describe all the entry points one by one.
The Inp32 function can be used to read values from any address that is given through
its Port Address parameter. Also, the Out32 function is specifically used to write values to
data ports. A long description on both functions can be found below.
Parallel Port
Inpout32.dll or Dllport.dll that is cover the sample source code ,The DLL compatible with
my Win9x inpout32.dll but works under all Windows editions from Win95/98/Me to
WinNT/2000/XP. For Windows NT etc., a kernel mode device driver is embedded in the
DLL in binary form. Get Port Address is a Visual Basic 6 application that retrieves parallel-
port addresses.
SAMPLE PROGRAM
Dim l As Integer
MSComm1.Output = Text1.Text
End Sub
MSComm1.PortOpen = True
End Sub
Case comEvReceive
StrBuff = MSComm1.Input
Do
StrBuff = MSComm1.Input
StrTmp = MSComm1.Input
Text2.Text = strBuff
End Select
End Sub
Summary
Technical questions
CHAPTER 15
PIC MICROCONTROLLERS
Microcontrollers are wonderfully useful devices. They incorporate all necessary parts
of a complete computer into a single IC that need almost no external parts to run.
Microcontrollers usually cost from $1-$20 depending on features and size.
Anything that is computerized but does not have a full-fledged PC inside most likely
uses a microcontroller. This includes things such as audio/video equipment, watches,
microwaves ovens, and more. A microcontroller is different from a microprocessor in that a
microprocessor usually requires a number of external parts such as RAM or ROM to operate.
A microprocessor such as a PC processor can't do anything by itself without a motherboard
and associated chips connected.
In most microcontrollers all components are contained inside a single chip. Only a
few external parts are usually required to make the micro run. The major parts of a
microcontroller are:
• CPU - The CPU core. Many small micros use an 8-bit CPU, although 16 and 32 CPUs
also exist.
• Program Memory - Memory used to store the program to be run. Flash RAM is used
on modern micros.
• RAM - Temporary memory used during program execution. SRAM is usually used.
• EEPROM - Permanent storage to allow programs to save settings and other data when
the power is off.
• Oscillator - Support for different types of clock sources are usually available, including
crystals, resonators, external clock sources, and internal clocks. The clock affects the
speed of the program execution, timers and other parts. Speeds from 4-40MHz are
typical.
• I/O Ports - Pins for interfacing the micro to other devices. Most micros allow
individual control of each pin, making them very flexible.
• Peripherals - Many useful peripherals are common, such as:
o USARTs - Serial ports which can send and receive data at up to 1Mbps or
more.
o Comparators and A/D Converters - For sensing and measuring analog signals.
o Timers - For counting pulses and measuring accurate time intervals.
o Interrupts - A method of responding to external triggers or special conditions
of the other peripherals. (such as data being received on a USART)
o Pulse Width Modulators (PWM) - For controlling motors, lamps, LEDs and
other power control devices.
Perhaps you've got a project in mind that you think would be good with a micro. Or maybe
you've heard about microcontrollers and don't know where to start. This page should help you
learn how to use microcontrollers in your own applications. We will focus on the PIC brand
of microcontrollers made by Microchip in this article.
Unlike other electronics projects, using a micro involves both software and hardware. You
can build a circuit with a PIC, but unless you put some software into it, the circuit will
probably be useless. But this is great for people that want to play with electronics but come
from the purely software side of things. Imagine coding for a device of your very own
design! It's also great because you can make simple circuits that do very sophisticated things.
I can't remember the last time I built a circuit that didn't have a micro in it. Modern circuits
can almost always benefit from being computerized.
Playing with PIC microcontrollers can be a lot of fun, but you need to have a basic set of
parts, tools, and software before you begin. The following is a list of parts and supplies that
are recommended:
• Development Software / Compiler - You need some way of writing code and
compiling it. The Source boost IDE and compiler are highly recommended. A free
version supports all the features of the PIC16F627A.
• PIC Programmer Hardware / Software - You need some way of getting your compiled
program into the PIC. There are many free plans for PIC programmers on the web,
but the TechTools Quick Writer is worth every penny. I built and used many of the
free programmers on the web, and none of them were ever as good as the Quick
Writer. You need reliable tools for reliable results.
Once you've got all the bits and pieces you need, you're ready to get started. But you might be
wondering: How the heck do I get something happening? With a mix of hardware and
software, it's hard to know where to begin. You're probably eager to make something real, so
don't bother playing with simulators and the like. The most important thing is to make
something happen on a real circuit so that you can feel the excitement that comes from
powering up a micro and having it run your program at do something, even if it's just blinking
an LED.
It seamless migration path with standard pin schemes and code compatibility allows
engineers to reuse verified code and proven PCB layout. Adding higher memory options,
incremental I/O and analog peripherals can be accomplished without losing their software
investment, reducing time to market.
An appropriate integration of both analog and digital peripherals, reading from simple
digital peripherals, ranging from simple digital to sophisticated analog modules. These
integrated peripherals minimize component count and thereby lower total system cost while
increasing reliability.
15.3.4 ADVANTAGES
12, 14 and 16 bit wide instructions are upward compatible and tailored to maximize
processing efficiency and boost performance.
Instructions and data are transferred on separate buses, avoiding processing
bottlenecks and increasing overall system performance.
Two stage pipeling enables one instruction to be executed while the next instruction is
fetched.
Single wide word instructions increase software code efficiency and reduce required
program memory.
With only 33-79 instructions, programming and debugging tasks are easy to learn and
perform.
Upward device compatibility allows designers to retain their capital investment in
code development.
Data EPROM is an available option for those applications which require secure, non-
volatile memory for data that changes frequently.