You are on page 1of 34

i

3
i
n
d
y
a
T
e
c
h
n
o
l
o
g
i
e
s
ADVANCE
MODULE
ADVANCE
MODULE
i3
in
d
y
a
T
e
ch
n
o
lo
g
ie
s
i3
in
d
y
a
T
e
c
h
n
o
lo
g
ie
s
i3
in
d
y
a
T
e
c
h
n
o
lo
g
ie
s
i
3
i
n
d
y
a

T
e
c
h
n
o
l
o
g
i
e
s
i
3
i
n
d
y
a

T
e
c
h
n
o
l
o
g
i
e
s
i
3
i
n
d
y
a

T
e
c
h
n
o
l
o
g
i
e
s
ADVANCE MODULE CONTENT
INDEX
q DTMF ----------------------------- Page 1
q RELAY ----------------------------- Page 3
q TOUCHSCREEN ----------------------------- Page 6
q R.F ----------------------------- Page 8
q USART ----------------------------- Page 11
q ACCELEROMETER ----------------------------- Page 18
q INTERRUPTS ----------------------------- Page 20
q EEPROM ----------------------------- Page 22
q MANUALS ----------------------------- Page 29
q INTERFACING CODES ------------------------------ Page 30
| 1|
DTMF Signaling System
DTMF stands for Dual Tone Multiple Frequency. It is system which consists of two frequencies superimposed.
Individual frequencies are chosen such that it is easy to design filters and easy to transmit the tones through a
telephone line having bandwidth of approximately 3.5 kHz. DTMF was not intended to be used for data
transfer, it was meant to be used for sending the control signals along the telephone line. With standard
decoders it is possible to send 10 beeps per second i.e., five bits per second. DTMF standard specifies 50ms
tones and 600ms duration between two successive tones.
DTMF
Note that the last column is not commonly seen in the telephones that we used, but telephone exchanges use
them quite often. Nowadays, DTMF is used for dialing the numbers in telephones, configuring telephone
exchanges etc. A CB transceiver of 2.7 MHz is normally used to send floating codes. DTMF was designed to be
able to send the codes using microphone. Each beep (or digit you dial on the telephone) is composed of two
concurrent frequencies, which are superimposed on amplitude. The higher of the two frequencies is normally
aloud by 4dB, and this shift is termed as twist. If the twist is equal to 4dB, the higher frequency is loud by 4dB. If
the lower frequency is loud, then the twist is said to be negative.
Generating DTMF
DTMF signals can be generated through dedicated ICs or by using RC networks connected to a microprocessor.
MT8880 is an example of a dedicated IC. But getting the latter method work is a bit difficult if high accuracy is
needed. The crystal frequency needs to be sacrificed for a nonstandard cycle length. Hence this method is used
for simple applications. Most often, DTMF encoder software in P.C or inbuilt dialing pulse of landline/ mobile
can be used for encoding purpose of generating DTMF signals.
Decoding DTMF
Detecting DTMF with satisfactory precision is a hard thing. Often, a dedicated IC such as MT8870 is used for
this purpose. It uses two 6th order band-pass filters using switched capacitor filters and it suppresses any
harmonics. Hence they can produce pretty good sine waves from distorted input. Hence it is preferred. Again
microprocessors can also be used, but their application is limited.AVR microcontrollers with i3indya
development board is best suited for experimental and project purpose.
Are DTMF & G.S.M both same?
Office : G-85, Preet Vihar, New Delhi-110092. Ph. : +91 - 95 6060 5666. Website : www.i3indya.com
Copyright All Right Reserved
i
3
i
n
d
y
a

T
e
c
h
n
o
l
o
g
i
e
s
2|
Ok this question is coming in everyone's mind first, the best answer is to check yourself, use the DTMF tone of
your mobile without inserting any SIM in your cell phone, it'll again generate the same tone, but can you use
G.S.M without any SIM card? since in GSM we are transferring data through our voice or text, but in DTMF there
is nothing like data transfer, it's just the dialing of pulse, that is called the tone dialing, not an7y data transfer, ok
just make a call to your friend and tell him/ her to on the speaker, now from your side press any key, see the
magic on the other side!! Yes your DTMF tone will be heard by your friend on the other side.
Let's have some application of this DTMF technology with i3indya board/
microcontrollers:-
As we know the basic concepts of microcontrollers and the way to interface any input/ output devices from the
controller, so let's start interfacing DTMF,
Just have a look of this fig.
Since the input would be of sound and as we know that with the help of decoder IC we can convert this sound to
binary outputs (corresponding to the frequency combination/ key pressed).
Now take a look of above figure once (frequency combination of keys)
q If I am pressing a key let say 1, then it will give the combination of frequencies 1209 & 697, and this will
directly be given to our sound converter IC , the output of that IC would be 0001(Q1,Q2,Q3,Q4)
Office : G-85, Preet Vihar, New Delhi-110092. Ph. : +91 - 95 6060 5666. Website : www.i3indya.com
Copyright All Right Reserved
i
3
i
n
d
y
a

T
e
c
h
n
o
l
o
g
i
e
s
i
3
i
n
d
y
a

T
e
c
h
n
o
l
o
g
i
e
s
| 3|
Ok , above table is much helpful , now we are having digital outputs, which means that we are having 5 volts
at each logic level 1,for TTL logic level (refer to i/ o operations for more details) .
Now if we are having 5volts we have everything on the microcontroller world!
In the above diagram, we are taking the example of glowing LED according to the DTMF inputs,
Refer to the i/ o section of this book, lets say there is a key pressed 1, means frequency combination would
be 1209 & 679 Hz, this would be the input of 8870, which would give the binary output of 0001, means at
Q4, we are having pulse 1 means, at that point we have 5v.
Now if we want to glow an LED connected to PORTB.3 then we can directly connect to the corresponding
output of 8870 to the input of ATmega16 PORT. (Refer to the masking concept in input operations).
RELAY
Relays are amazingly simple devices. There are four parts in every relay:
q Electromagnet
q Armature that can be attracted by the electromagnet
q Spring
q Set of electrical contacts
A relay is a simple electromechanical switch made up of an electromagnet and a set of contacts. Relays are
found hidden in all sorts of devices. In fact, some of the first computers ever built used relays to implement
Boolean gates.
Innovat i on
3 i ndya Tec hnol ogi es
Int el l i gence Inf or mat i on
TM
TM
CLOUD CAMPUS
CLOUD CAMPUS
+91 - 95 6060 5666
Call:
www.i3indya.com
Log on to:
Office : G-85, Preet Vihar, New Delhi-110092. Ph. : +91 - 95 6060 5666. Website : www.i3indya.com
Copyright All Right Reserved
i3
in
d
y
a
T
e
ch
n
o
lo
g
ie
s
4|
In this figure, you can see that a relay consists of two separate and completely independent circuits.(1-3 &
2-4) The first is at the bottom and drives the electromagnet/ coil. In this circuit, a switch is controlling
power to the electromagnet (2-4). When the switch is on, the electromagnet is on, and it attracts the
armature. The armature is acting as a switch in the second circuit. When the electromagnet is energized,
the armature completes the second circuit and the light is on. When the electromagnet is not energized, the
spring pulls the armature away and the circuit is not complete. In that case, the light is dark.
When you purchase relays, you generally have control over several variables:
q The voltage and current that is needed to activate the armature
q The maximum voltage and current that can run through the armature and the armature contacts
q The number of armatures (generally one or two)
q The number of contacts for the armature (generally one or two -- the relay shown here has two, one of
which is unused)
q Whether the contact (if only one contact is provided) is normally open (NO) or normally closed (NC)
So to provide a particular current rating / amplification, ULN2803 is used (see L293D). (Refer to IC
chapter).
Now we have to control only coil section (1-3) that can easily be controlled by connecting it through any of
the PORT that will be defined as an output PORT. And if there is 5v to that particular PORT means the coil is
energized and switch (2-4) would be ON, if it is 0 means coil is de-energized and the switch is OFF., this
switch can be replaced by normal switching system of our 220v home appliances.
Remember the connection of bulb in your home, is it like a 220v power board connected to your 100watts
of bulb. It will glow continuously, but if we add a switch in between then it will be ON or OFF corresponding
to the switch inputs.
+91 - 95 6060 5666
w w w.i 3i ndya.c om
TECHNICAL WORKSHOPS
TECHNICAL WORKSHOPS
i3indya Technologies
Office : G-85, Preet Vihar, New Delhi-110092. Ph. : +91 - 95 6060 5666. Website : www.i3indya.com
Copyright All Right Reserved
i
3
i
n
d
y
a

T
e
c
h
n
o
l
o
g
i
e
s
| 5|
Now we are going to replace the direct connection to switch controlled.
Now this switch can be replaced by RELAY.
One thing that can be noticed , if we are using RELAY as a switch then how it differs from the normal switches
that we use in our home! Just see the first figure in which we have directly connected the 220v to bulb, if we are
using a normal switch we have to attach by cutting any of the two wires, but in relays, we don't need any
connected circuitry, see the figure of relay in which, one end is connected to 220v and another end to
controller, there is no connection in between these two.
Office : G-85, Preet Vihar, New Delhi-110092. Ph. : +91 - 95 6060 5666. Website : www.i3indya.com
Copyright All Right Reserved
i3in
dya Techn
ologies
i3
in
d
y
a
T
e
ch
n
o
lo
g
ie
s
i3
in
d
y
a
T
e
ch
n
o
lo
g
ie
s
i
3
i
n
d
y
a

T
e
c
h
n
o
l
o
g
i
e
s
6|
Types of relays:-
Relays with contacts:-
Other types include three and five pin relays. A 3-PIN relay instead of two input sources, this relay has one input
at pin 1. Current splits inside the relay, supplying power to both the control and load circuits. A 5-PIN relay has
a single control circuit, but two separate current paths for the switch: One when the relay is de-energized (OFF
no current through the control coil) and the other the energized (ON - current is flowing through the control
coil). When the 5-PIN relay is de-energized (OFF), pins 4 and 5 have continuity. When the relay is energized
(ON), pins 3 and 5 have continuity.
Detecting a Touch
To know if the coordinate readings are valid, there must be a way to detect whether the screen is being touched
or not. This can be done by applying a positive voltage (VCC) to Y+through a pull up resistor and applying
ground to X. The pull up resistor must be significantly larger than the total resistance of the touch screen,
which is usually a few hundred ohms. When there is no touch, Y+is pulled up to the positive voltage. When
there is a touch, Y+is pulled down to ground as shown in Figure1. This voltage-level change can be used to
generate a pin-change interrupt.
TOUCH SCREEN
Principles of Operation
A resistive touch screen is constructed with two transparent layers coated with a conductive material stacked
on top of each other. When pressure is applied by a finger or a stylus on the screen, the top layer makes contact
with the lower layer. When a voltage is applied across one of the layers, a voltage divider is created. The
coordinates of a touch can be found by applying a voltage across one layer in the Y direction and reading the
voltage created by the voltage divider to find the Y coordinate, and then applying a voltage across the other
layer in the X direction and reading the voltage created by the voltage divider to find the X coordinate.
Office : G-85, Preet Vihar, New Delhi-110092. Ph. : +91 - 95 6060 5666. Website : www.i3indya.com
Copyright All Right Reserved
i
3
i
n
d
y
a

T
e
c
h
n
o
l
o
g
i
e
s
i3
in
d
y
a
T
e
c
h
n
o
lo
g
ie
s
| 7|
i
3
i
n
d
y
a

T
e
c
h
n
o
l
o
g
i
e
s
Reading a 4-Wire Screen
A 4-wire resistive touch screen is constructed as shown in Figure.
The x and y coordinates of a touch on a 4-wire touch screen can be read in two steps. First, Y+is driven high,
Yis driven to ground, and the voltage at X+is measured. The ratio of this measured voltage to the drive voltage
applied is equal to the ratio of the y coordinate to the height of the touch screen. The y coordinate can be
calculated as shown in Figure3. The x coordinate can be similarly obtained by driving X+high, driving Xto
ground, and measuring the voltage at Y+. The ratio of this measured voltage to the drive voltage applied is
equal to the ratio of the x coordinate to the width of the touch screen. This measurement scheme is shown in
Figure.
The way the touch screen is connected to the microcontroller:
Office : G-85, Preet Vihar, New Delhi-110092. Ph. : +91 - 95 6060 5666. Website : www.i3indya.com
Copyright All Right Reserved
i
3
i
n
d
y
a

T
e
c
h
n
o
l
o
g
i
e
s
i
3
i
n
d
y
a

T
e
c
h
n
o
l
o
g
i
e
s
i
3
i
n
d
y
a

T
e
c
h
n
o
l
o
g
i
e
s
8|
RF
You've probably heard about "AM radio" and "FM radio," "VHF" and "UHF" television, "citizens band radio,"
"short wave radio" and so on. Have you ever wondered what all of those different names really mean? What's
the difference between them?
A radio wave is an electromagnetic wave propagated by an antenna. Radio waves have different
frequencies, and by tuning a radio receiver to a specific frequency you can pick up a specific signal.
In India Wireless and Planning and Coordination Wing (WPC), a branch of the Ministry of Communications and
Information Technology decides who is able to use which frequencies for which purposes, and it issues
licenses to stations for specific frequencies. In addition, the WPC allocates frequency spectrum in India. When
you listen to a radio station and the announcer says, "You are listening to 92.7 FM BIG The Rock!," what the
announcer means is that you are listening to a radio station broadcasting an FM radio signal at a frequency of
92.7 megahertz, with WPC-assigned call letters of MCIT. Megahertz means "millions of cycles per second," so
"92.7 megahertz" means that the transmitter at the radio station is oscillating at a frequency of 92,700,000
cycles per second. Our FM (frequency modulated) radio can tune in to that specific frequency and give you
clear reception of that station. All FM radio stations transmit in a band of frequencies between 88 megahertz
and 108 megahertz. This band of the radio spectrum is used for no other purpose but FM radio broadcasts.
In the same way, AM radio is confined to a band from 535 kilohertz to 1,700 kilohertz (kilo meaning
"thousands," so 535,000 to 1,700,000 cycles per second). So an AM (amplitude modulated) radio station that
says, "This is AM 123 " means that the radio station is broadcasting an AM radio signal at 123 kilohertz and its
WPC-assigned call letters are MCIT
An RF Module is a (usually) small electronic circuit used to transmit, receive, or transceiver radio waves on one
of a number of carrier frequencies, so BIG FM uses these kinds of RF modules and we too at the receiver end.
RF module
Office : G-85, Preet Vihar, New Delhi-110092. Ph. : +91 - 95 6060 5666. Website : www.i3indya.com
Copyright All Right Reserved
i
3
i
n
d
y
a

T
e
c
h
n
o
l
o
g
i
e
s
i
3
i
n
d
y
a

T
e
c
h
n
o
l
o
g
i
e
s
| 9|
Several carrier frequencies are commonly used in commercially-available RF modules, including 433.92MHz,
315MHz, 868MHz and 915MHz.They come in Pair. One is RX or the receiver and other is a TX or Transmitter.
Since it would be serial communication (refer to the communication protocols chapter), so we'll be needing an
encoder & decoder IC for communication, because at transmitter end we are doing parallel communication
with our kit but to transfer it at a long distance we have to send serially, so we will use an encoder IC HT12E at
the transmitter side, and the same couple IC HT12D will be used at the receiver side to convert it back parallel.
Connection through IC and Module.
Office : G-85, Preet Vihar, New Delhi-110092. Ph. : +91 - 95 6060 5666. Website : www.i3indya.com
Copyright All Right Reserved
i
3
i
n
d
y
a

T
e
c
h
n
o
l
o
g
i
e
s
i
3
i
n
d
y
a
T
e
c
h
n
o
l
o
g
i
e
s
i
3
i
n
d
y
a
T
e
c
h
n
o
l
o
g
i
e
s
| 10|
Interfacing with microcontroller:
It's time to recall the I/ O chapters again, as we have seen in DTMF, just like that to transmit we can send 4 data
bits at a time (serially), and the same at the receiver end again we have the same 4 data bits,
Now let us take an example, in which we'll be controlling the movement of our robot wirelessly,
First, burn the simple program of 4 motor direction movement in a controller board, now connect the 4 data bit
pins of TX to the output of the program, like in our case motors are connected to PORTB, so output would be at
PORTB, then we'll be connecting our TX pins to PORTB.
Since it will be transmitting +ve high pulse, so again we are having 5v, which will be received at the receiver end
also, let say for forward movement I am having 1010, means the same would be received at the RX end, so just
connect the 4 data pins of receiver to the corresponding PORT for which output is needed, since both the
boards are i3indya board in which motors are connected to PORTB, and we have to control the movement of
motor remotely, so again at the receiving end also 4 pins would be connected to PORTB itself, now whatever
will happen in now whatever will happen at the transmitting end's PORTB, the same will happen at the RX end
of PORTB.
If we want more than one operation then we have to burn the receiving program at the receiver end's
controller. (Refer to the input operations)
TRAINING
SHORT TERM
COURSE
Innovat i on
3 i ndya Tec hnol ogi es
Int el l i gence Inf or mat i on
TM
TM
EMBEDDED SYSTEM & ROBOTICS
ETHICAL HACKING & CYBER SECURITY
1, 3 and 6 Month Training
For More Detail Call: +91 - 95 6060 5666
Office : G-85, Preet Vihar, New Delhi-110092. Ph. : +91 - 95 6060 5666. Website : www.i3indya.com
Copyright All Right Reserved
i
3
i
n
d
y
a

T
e
c
h
n
o
l
o
g
i
e
s
| 11|
USART
A brief description to understand the USART (Universal Synchronous Asynchronous Transmitter/ Receiver).
That is to say, the information contained here is an interpretation of the datasheet so it is easily
understandable. The USART feature of the AVR microcontroller can communicate with another
microcontroller (not necessarily another AVR microcontroller), multiple microcontrollers, or a computer
using a voltage level shifter or converter. The USART can transmit data using a buffer and a shift register (more
on that later), receive data using a shift register and buffer, create a frame of data that is recognized on both the
receiving end and the transmitting end. All of this works according to an agreed upon speed from both sides, or
with synchronous mode where the clock line (a wire) is directly connected.
Sending information and receiving information in UART and USART communication is like riding on a train.
The train sends you to a destination like it sends data to another computer or microcontroller. The train station
is like the internal transmitter and receiver inside the microcontroller. There must be a place that the train
riders queue to get on the train. First, a passenger will get the ticket and sit down to wait for the next train to
arrive. The passenger then must queue up to get on the train. Then the passenger gets on the train. This is
exactly how a USART transmitter functions. The data is sent to a buffer, which is like the waiting room for the
train. The shift registers is like the queue to get on the train. The data moves from the buffer and onto the shift
registers. This is after the previous data has left the shift registers. From the shift registers, the data moves
along the transmit wire, just like a train moves along a track.
Receiving information is the same but in reverse. In the human analogy, the train arrives to the train station.
The person gets off of the train and must wait in a queue so that the people in front of them makes space. In the
microcontroller reception of data, the data gets off the wire and goes straight into the shift registers. With the
Atmega32, there are two buffers that the data can use to wait to be used by the program in the microcontroller.
With the shift register, this gives the receive area three total buffers for the data to sit, waiting to be used. This is
established with the chip so Data Over Runs (DOR) are less likely. The DOR is a flag that you can look at.
The train is actually similar to the baud rate. The baud is the clock that pushes the data along the line. There are
a couple types of clocks you can apply using UART and USART. The UART only allows you to apply an agreed
upon baud rate from both parties (each microcontroller must be set with this specific baud rate). In USART, a
clock wire must be connected between each microcontroller. This wire will pulse like a heartbeat. In the case of
asynchronous, each microcontroller has its own clock and since the data is being sent with the transmitting
microcontroller using this clock (baud rate), the receiving microcontroller must be receiving this data at the
same pace, so its clock (baud rate) must be the same.
Clock Modes:
Pick between Synchronous or Asynchronous
UCSRC =(1 <<UMSEL); / / setting the UMSEL bit to 1 for synchronous mode
UCSRC &=~(1 <<UMSEL); / / setting the UMSEL bit to 0 for asynchronous mode
Asynchronous:
Asynchronous is where the microcontroller's clock is not connected together by a wire with the other
microcontroller, but they need the same clock beat to process the data on the data line.
Office : G-85, Preet Vihar, New Delhi-110092. Ph. : +91 - 95 6060 5666. Website : www.i3indya.com
Copyright All Right Reserved
| 12|
This beat, or baud rate is determined by the UBBR formula:
UBBR =( (regular microcontroler clock speed) / 16 * baud ) - 1
Example: UBBR =( 1,000,000 / 16 * 2400 ) - 1
=( 1,000,000 / 38,400 ) - 1
=26.0416667 - 1
=25.0416667 =25
It's 25 because the UBBR will not accept a decimal value, but that introduces a 0.2% error, which is acceptable.
You can find a table of commonly used UBBR numbers in the "Examples of baud rate settings" under the USART
section of the datasheet.
Finding the baud from the UBBR is optional:
baud =(regular microcontroler clock speed) / ( 16 * (UBBR +1) )
Example: baud =1,000,000 / (16 * (25 +1))
=1,000,000 / (16 * 26)
=1,000,000 / 416
=2403.84615 =2400
Pretty close to the standard 2400 baud with 0.2% error which is acceptable. Check your datasheet for
acceptable error percentages.
Setting the baud rate:
UBBRH &=~(1 <<URSEL);
UBBRH =(unsigned char) (# from table >>8);
UBBRL =(unsigned char) # from table;
The URSEL is set to 0 because UBBRH shares the same I/ O as UCSRC, the URSEL must be set to 0 to write to
UBBRH. The UBBRH sets the high portion of the baud rate - from bit 8 to bit 11. The UBBRL puts the remaining
bits 0 to 7 into the low UBBR register.
Setting the Asynchronous mode:
Normal Asynchronous
Double Speed Asynchronous- U2X bit in UCSRA controls double speed asynchronous
UCSRA =(1 <<U2X); / / setting the U2X bit to 1 for double speed asynchronous
UCSRA &=~(1 <<U2X); / / setting the U2X bit to 0 for normal asynchronous
Synchronous
Where the clock is connected with a wire between the two microcontrollers - DDR_XCK Data Direction Register
controls which microcontroller is the master and which is the slave. If the DDR_XCK is set to output, then the
XCK pin on that microcontroller is the master since it will be creating the clock output on that XCK pin.
Office : G-85, Preet Vihar, New Delhi-110092. Ph. : +91 - 95 6060 5666. Website : www.i3indya.com
Copyright All Right Reserved
| 13|
Data Frame:
This is the actual data that is transmitted. It's the train with the data riding on-board. This is with 9 bits for the
data bits, one start bit, two stop bits, one parity bit which is the maximum frame size.
Idle state: The train track - idle state of the signal - always high (5v)
Bit 01: The train engine - Bit 1: Start bit - always low (0)
Bit 02: Person #1 on the train - Data bit #0 - high or low depending on the data
Bit 03: Person #2 on the train - Data bit #1 - high or low depending on the data
Bit 04: Person #3 on the train - Data bit #2 - high or low depending on the data
Bit 05: Person #4 on the train - Data bit #3 - high or low depending on the data
Bit 06: Person #5 on the train - Data bit #4 - high or low depending on the data
Bit 07: Person #6 on the train - Data bit #5 - high or low depending on the data
Bit 08: Person #7 on the train - Data bit #6 - high or low depending on the data
Bit 09: Person #8 on the train - Data bit #7 - high or low depending on the data
Bit 10: Person #9 on the train - Data bit #8 - high or low depending on the data
Bit 11: Train car just before the caboose watching over everything - Parity bit - high or low depending on the 1's
of the data
Bit 12: The caboose - Stop Bit - always high
Bit 13: The extra caboose - stop bit - always high and always ignored by the receiver
back to high idle state - or to a new start bit.
There is a maximum of 13 bits in the largest data frame.
Setting the Data Bit Size - Number of data bits you want in the frame. Use the UCSZ2:0 (UCSZ0, UCSZ1,
UCSZ2) bits in the UCSRC register. Note, keeping all the bits in UCSZ2:0 not set establishes a 5-bit data bit
length.
UCSZ - Character Size
UCSRC |=(1 <<UCSZ0); / / 6-bit data length
UCSRC |=(1 <<UCSZ1); / / 7-bit data length, or
UCSRC |=(2 <<UCSZ0); / / Alternative code for 7-bit data length
UCSRC |=(1 <<UCSZ1) | (1 <<UCSZ0); / / 8-bit data length, or
UCSRC |=(3 <<UCSZ0); / / Alternative code for 8-bit data length
UCSRC |=(1 <<UCSZ2) | (1 <<UCSZ1) | (1 <<UCSZ0); / / 8-bit data length, or
UCSRC |=(7 <<UCSZ0); / / Alternative code for 8-bit data length
Huh, what's that "2, 3 and 7"?!? Well, it's about time you learned a shorthand way of setting bits. The UCSZ0 is
the equavilant to the one's place in binary. If you put another number, like 7, you are actually putting the binary
equivalent of the number 7 in that location which fills up the next binary digits, because the number 7 is 111 in
binary.
Note: If you want to change any of this frame stuff shown below, take a look at the TXC and RXC flags and make
sure they are not set. If they are set, then there is still transmissions going on. For most microcontroller
projects, this may never be needed.
Another note: For some strange reason, UBBRH and UCSRC share the same I/ O location, so you need to make
sure:
Office : G-85, Preet Vihar, New Delhi-110092. Ph. : +91 - 95 6060 5666. Website : www.i3indya.com
Copyright All Right Reserved
| 14|
URSEL bit is set in the UBBRH if you want to put stuff in that register, or URSEL bit is set in the UCSRC if you want
to put stuff in that register.
Setting the Parity Mode - This is where you set the error checking feature of UART and USART
communication. The parity is set only by the transmitter.
If the parity is set for "even" then there are an odd number of ones in the data bits, the transmitter will set the
parity bit to a "1" so there will be an even number of ones including the parity bit.
If the parity is set for "odd" then there are an even number of ones in the data bits, the transmitter will set the
parity bit to a "1" so there will be an odd number of ones including the parity bit.
UPM - Parity Mode
UCSRC |=(1 <<UPM1); / / Sets parity to EVEN
UCSRC |=(1 <<UPM1) | (1 <<UPM0); / / Sets parity to ODD, or
UCSRC |=(3 <<UPM0); / / Alternative way to set parity to ODD
Setting the number of Stop Bits to use - Do you want one or two cabooses on the end of your train?
Remember that the receiver will ignore the second stop bit, so why did they put it in there in the first place?
Who knows, but I think that it adds a "bit" of breathing room for the next data frame. How do you like that pun?
Huh!
USBS - Stop Bit Select
UCSRC |=(1 <<USBS); / / Sets 2 stop bits
UCSRC &=~(1 <<USBS); / / clears the USBS for 1 stop bit, only needed if the bit was already set
Note: If the microcontroller receiving the data frame (the choochoo train) sees a stop bit that is low (it is
supposed to be high), then the Frame Error Flag Bit (FE) will be set.
Example Initialization for the USART or UART:
In this example, the baud is being set, the transmitter (TXEN - Transmitter Enable) and receiver (RXEN -
Receiver Enable) is being enabled, and in the UCSRC, the URSEL is set so we can modify UCSRC, 2 stop bits used
and the length of the data bits is 8-bit.
You'll notice that, first, this is a function and, second, an unsigned int is being passed into this function. The void
in the beginning means that this function will not return anything when it completes. This is the same example
that the Atmega324 datasheet shows. Notice that the parity is not set in this example.
Office : G-85, Preet Vihar, New Delhi-110092. Ph. : +91 - 95 6060 5666. Website : www.i3indya.com
Copyright All Right Reserved
| 15|
(WORKSHOP)
ROBOTI CS
ROBOTI CS
ROBOTI CS
Innovat i on
3 i ndya Tec hnol ogi es
Int el l i gence Inf or mat i on
TM
TM
For more detail log on to: www.i3indya.com
voidUSART_Init (unsigned int baud)
{
/ / Put the upper part of the baud number here (bits 8 to 11)
UBBRH =(unsigned char) (baud >>8);
/ / Put the remaining part of the baud number here
UBBRL =(unsigned char) baud;
/ / Enable the receiver and transmitter
UCSRB =(1 <<RXEN) | (1 <<TXEN);
/ / Set 2 stop bits and data bit length is 8-bit
UCSRC =(1 <<URSEL) | (1 <<USBS) | (3 <<UCSZ0);
}
Note: When TXEN is set (Transmitter Enabled), the General Purpose function of that pin is not availble until the
TXEN is disabled. In other words, you cannot use TX pin to light up LEDS, or receive button presses and stuff
like that. Same idea goes for the RXEN and the RX pin. One other thing, the TXEN cannot be disabled while there
is a pending transmission. If you are using the XCK pin for synchronous operation, then the other general
purpose function at the XCK pin is disabled.
Transmit Something!!
In this next example, we will actually transmit something. We are gonig to throw our data into the UDR (USART
I/ O Data Register) train station. I will let you in on a secret here, because you may get confused a bit later: You
will put the data you want to transmit in the UDR register, and you will also get received data from the UDR as
well. That seems totally off, doesn't it. If that's true then how would we be able to transmit and receive at the
same time when we only have one data register to use... I mean, if full duplex is available, why is there only one
register to transmit data and receive data. Seems odd.
Office : G-85, Preet Vihar, New Delhi-110092. Ph. : +91 - 95 6060 5666. Website : www.i3indya.com
Copyright All Right Reserved
| 16|
Well, here is the secret! Shhhhh, don't tell anyone! The UDR actually has two places. The secret locations are
called TXB and RXB (these are 8-bit locations). The microcontroller is so smart that when you place
information into the UDR register, the stuff you put in is actually going into the TXB location. If you take the data
from the UDR register, then you are actually taking the stuff out of the RXB location. You might be asking, what if
we decided to set our data-bit lenght to 9 bits, cause TXB and RXB is 8-bits only? Those bits are located in the
UCSRB register and their called, you guessed it, TXB8 and RXB8. Oh, one more thing, this is a polling example
which means that we are going to wait (tap our toes) for the UDRE (USART Data Register Empty) signal to say
its ok to go. It's like a stop light. You can't put anything into the UDR if the system is not ready for you. Ok enough
jibber jabber, lets get to the example:
voidUSART_Transmit (unsigned int data)
{
/ / Wait until the Transmitter is ready
while (! (UCSRA & (1 <<UDRE)) );
/ / Make the 9th bit 0 for the moment
UCSRB &=~(1 <<TXB8);
/ / If the 9th bit of the data is a 1
if (data & 0x0100)
/ / Set the TXB8 bit to 1
USCRB |=(1 <<TXB8);
/ / Get that data outa here!
UDR =data;
}
The condition in the while statement may look foriegn to you. It is seemingly complicated, but it is the same
type of (and) and (not) bitwise operation that we learned in an earlier video. The !is a (not) and & is an (and).
Remember when we say register &=~(1 <<bit)? We are doing an & (and) calculation and reversing the bits
with the ! (not). We can also put this in a condition like this: If you want to check if a bit is (not) 0, then we use (!
(register & (1 <<bit)) ).
Ok, so here is an explanation of the flags that inform us about the transmit process:
Polling Resources:
UDRE =USART Data Register Empty - This is cleared when the UDR is written to.
TXC =Transmit complete - You can use this resource if your are doing half duplex. This flag happens when the
data leaves the shift register. Remember that queue that we talked about earlier.
Interrupt Resources: Remember to set your global interrupt variable before using these cool resources!
UDRIE =Data Register Empty Interrupt Enable if UDRE is set to 1 - This will be handy when using interrupts.
The microcontroller will stop what you are doing so you can go and put your data into the UDR train station.
TXCIE =Transmit Complete Interrupt Enable - Use this if you are doing half-duplex and you want the
microcontroller to interrupt you so you can go and put your data into the UDR train station.
Office : G-85, Preet Vihar, New Delhi-110092. Ph. : +91 - 95 6060 5666. Website : www.i3indya.com
Copyright All Right Reserved
| 17|
Receive Something!!
The process for the microcontroller to receive data that exists on a wire from the other microcontroller goes
like this:
q The microcontroller detects a start bit
q The data bits come next and there are taken in concert with the baud rate (or XCK for sychronous) heart
beat
q The data goes to the shift register (like people getting off the train and waiting in queue to get off of the
train platform)
q This happens until the first stop bit is received (remember, the second stop bit is ignored)
q The contents of the data then go directly to the UDR (well, really the RXB, but we still get it from the UDR)
Here is an example how to receive data:
unsigned char USART_Receive( void )
{
while ( !(UCSRA & (1 <<RXC)) ); / / Wait for the RXC to not have 0
return UDR; / / Get that data outa there and back to the main program!
}
Do you notice the unsigned char at the beginning of our function statement? That is the type of return we will
provide. The UDR will be an 8-bit unsigned value (char). We use the return statement to release the data from
the UDR and pass it back to the main program.
Let me know if you want to see a 9-bit example.
Ok, so here is an explanation of the flags that inform us about the receive process:
Polling Resource:
RXC =Receive complete - Indicates unread data in the buffer if this flag is set (1), or 0 if empty.
Interrupt Resource: Remember to set your global interrupt variable when using this!
RXCIE =Receive Complete Interrupt Enable - Use this so you can go and get your data out of the UDR register.
Super important!! Make sure you clear the RXC flag right after you get the data out of the UDR register!
CYBER STUDY
i3indya Technologies
www.i3indya.com
+91- 95 6060 566
Log on to:
For More Detail
Call Us At:
Office : G-85, Preet Vihar, New Delhi-110092. Ph. : +91 - 95 6060 5666. Website : www.i3indya.com
Copyright All Right Reserved
ACCELEROMETER
| 18|
An accelerometer measures acceleration (change in speed) of anything that it's mounted on. How does it
work? Inside an accelerator MEMS device are tiny micro-structures that bend due to momentum and gravity.
When it experiences any form of acceleration, these tiny structures bend by an equivalent amount which can
be electrically detected
Axis of Acceleration
The tiny micro-structures can only measure force in a single direction, or axis of acceleration. This means with
a single axis measured, you can only know the force in either the X, Y, or Z directions, but not all. So if say your X-
axis accelerometer endowed robot was running around and ran into a wall (in the X direction). Your robot
could detect this collision. But if say another robot rammed into it from the side (the Y direction), your robot
would be oblivious to it. There are many other situations where a single axis would not be enough. It is always a
good idea to have at least 2 axes (more than one axis).
Axis of Acceleration
The tiny micro-structures can only measure force in a single direction, or axis of acceleration. This means with
a single axis measured, you can only know the force in either the X, Y, or Z directions, but not all. So if say your X-
axis accelerometer endowed robot was running around and ran into a wall (in the X direction). Your robot
could detect this collision. But if say another robot rammed into it from the side (the Y direction), your robot
would be oblivious to it. There are many other situations where a single axis would not be enough. It is always a
good idea to have at least 2 axes (more than one axis).
Gravity
Gravity is acceleration. As such, your accelerometer will always be subject to a -9.81 m/ s^2 acceleration
(negative means towards the ground). Because of this, your robot can detect what angle it is in respect to
gravity. If your robot is a biped, and you want it to always remain balanced and standing up, just simply use a 2-
axis accelerometer. As long as the X and Y axes detect zero acceleration, this means your robot device is
perfectly level and balanced.
Office : G-85, Preet Vihar, New Delhi-110092. Ph. : +91 - 95 6060 5666. Website : www.i3indya.com
Copyright All Right Reserved
i3
in
d
y
a
T
e
c
h
n
o
lo
g
ie
s
i3
in
d
y
a
T
e
c
h
n
o
lo
g
ie
s
| 19|
Calculate Acceleration and Angle wrt Gravity
To calculate the magnitude of acceleration for a single-axis accelerometer
acceleration_max =sqrt(x^2) =x
2-axis accelerometer
acceleration_max =sqrt(x^2+y^2)
3-axis accelerometer
acceleration_max =sqrt(x^2+y^2+z^2)
To calculate the detected force on an accelerometer due to gravity:
Force_gravity =-g*cos(angle)(depends on starting axis of sensor)
Chances are you would have no need to measure the force, but if you reverse the equation you can calculate the
angle by knowing the detected force:

cos(sensor_value*conversion_constant / -g)^-1 =angle
LAB SETUP
Log on to : www.i3indya.com
ROBOTI CS
Office : G-85, Preet Vihar, New Delhi-110092. Ph. : +91 - 95 6060 5666. Website : www.i3indya.com
Copyright All Right Reserved
i
3
i
n
d
y
a

T
e
c
h
n
o
l
o
g
i
e
s
| 20|
INTERRUPTS
The interrupts generated from an external source are referred as external interrupts. The external sources are
basically outside the system. Atmel generally provides 4 external interrupt pins which can be used to interrupt
the microcontroller by an activity occurring outside the system. They are:
q RESET
q INT0
q INT1
q INT2
RESET: It is the highest priority external interrupt. When it is set to zero, microcontroller get reset and the
initial memory address is loaded in PC (Program Counter). It is same as restarting your PC by pressing the
restart button. It is used when we want that a particular eternal event should make the microcontroller starts
its work from beginning. It is located on pin no. 9 in most of the AVR microcontrollers.
INT0, INT1 and INT2: The priority order among these is as follows: INT0, INT1 and INT2. These
interrupts are used to tell the microcontroller that a particular event in the external world has happened and
the microcontroller needs to respond to that event. In AVR microcontrollers, they are available on PD2, PD3
and PB2 pins of the microcontroller.
Register for configuring Eternal Interrupts:
1. MCUCR (Microcontroller Control Register):
This register determines the nature of signal at which the interrupt 0 (INT0) and interrupt 1 (INT1) should
occur.
SM2, SE, SM1, SM0: These four bits of the register are used when the microcontroller operates in sleep
mode.
ISC11, ISC 10: These bits are used to configure INT1 interrupt. These bits decides, when the ISR
corresponding to INT1 should get executed i.e. when should INT1 get enabled. The bits are chosen from the
table given below:
Office : G-85, Preet Vihar, New Delhi-110092. Ph. : +91 - 95 6060 5666. Website : www.i3indya.com
Copyright All Right Reserved
i3indya Technologies
i
3
i
n
d
y
a

T
e
c
h
n
o
l
o
g
i
e
s
| 21|
ISC01, ISC 00: These bits are used to configure INT0 interrupt. These bits decides, when the ISR
corresponding to INT1 should get executed i.e. when should INT0 get enabled. The bits are chosen from the
table given below:
2. MCUCSR (Microcontroller Control and Status Register):
This register determines the nature of signal at which the external interrupt 2 (INT2) should occur. INT2 is
edge triggered only, it cannot be used for level triggering like INT0 and INT1.
ISC2: These bits are used to configure INT0 interrupt. These bits decides, when the ISR corresponding to
INT1 should get executed i.e. when should INT0 get enabled. The bits are chosen from the table given below:
3. GICR (General Interrupt Control Register):
The register is used for activating and deactivating of external interrupts.
The respective interrupt is enabled/ activated by setting the corresponding bit to 1. E.g. to activate INT0 bit 6 of
the register is set to 1.
Note: These eternal interrupts can only be used if the global interrupt bit in SFIOR register is set. So before
using the eternal interrupt you need to set the global interrupt bit in SFIOR register. The bit can set by calling a
predefined function sei(), available in <interrupt.h>. The sei() is followed by clear interrupt function, cli()
available in the same header file <interrupt.h>
Office : G-85, Preet Vihar, New Delhi-110092. Ph. : +91 - 95 6060 5666. Website : www.i3indya.com
Copyright All Right Reserved
i
3
i
n
d
y
a
T
e
c
h
n
o
l
o
g
i
e
s
i3indya Technologies
i
3
i
n
d
y
a
T
e
c
h
n
o
l
o
g
i
e
s
i3indya Technologies
| 22|
EEPROM
What is the EEPROM memory and why would I use it?
Most of the 8-bit AVRs in Atmel's product line contain at least some internal EEPROM memory. EEPROM, short
for Electronically Erasable Read-Only Memory, is a form of non-volatile memory with a reasonably long
lifespan. Because it is non-volatile, it will retain its information during periods of no power and thus is a
great place for storing data such as device parameters and system configuration at runtime so that it can
persist between resets of the application processor.
One important fact to note is that the AVR's internal EEPROM memory has a limited lifespan of
100,000 writes per EEPROM page reads are unlimited. Keep this in mind in your application; try to keep
writes to a minimum, so that you only write the least amount of information required for your application each
time you update the EEPROM.
How is accessed?
The AVR's internal EEPROM is accessed via special registers inside the AVR, which control the address to be
written to (EEPROM uses byte addressing), the data to be written (or the data which has been read) as well as
the flags to instruct the EEPROM controller to perform the requested read or write operation.
The C language does not have any standards mandating how memory other than a single flat model (SRAM in
AVRs) is accessed or addressed. Because of this, just like storing arbitrary data into flash memory via your
program, every compiler's standard library has a unique implementation based on what the author
believed was the most logical system.
This tutorial will focus specifically on the AVR-GCC compiler; other compilers may have alternative syntax and
APIs.
The avr-libc EEPROM functions
Including the avr-libc EEPROM header
The avr-libc library, included with WinAVR and (more recently) the Atmel AVR Toolchain, con- tains
prebuilt library routines for EEPROM access and manipulation to simplify its use in user applications.
Before we can make use of those routines, we need to include the EEPROM library header <avr/ eeprom.h>
with the preprocessor directive #include <avr/ eeprom.h>.
HACKED
s M
S
r p . P Oo
y P B o d were
G P
ROU
Innovat i on
3 i ndya Tec hnol ogi es
Int el l i gence Inf or mat i on
TM
TM
ETHICAL HACKING
CYBER SECURITY
Office : G-85, Preet Vihar, New Delhi-110092. Ph. : +91 - 95 6060 5666. Website : www.i3indya.com
Copyright All Right Reserved
| 23|
Once added to your application, you now have access to the EEPROM memory, via the routines now
provided by the <avr/ eeprom.h> module of avr-libc. There are five main types of EEPROM access: byte,
word, dword, float and block. Each type has three types of functions; a write, an update, and a read variant. The
names of the routines exposed by our new headers are:
uint8_t eeprom_read_byte ( const uint8_t * addr )
void eeprom_write_byte ( uint8_t *addr , uint8_t value )
void eeprom_update_byte ( uint8_t *addr , uint8_t value )
uint16_t eeprom_read_word ( const uint16_t * addr )
void eeprom_write_word ( uint16_t *addr , uint16_t value )
void eeprom_update_word ( uint16_t *addr , uint16_t value )
uint16_t eeprom_read_dword ( const uint32_t * addr )
void eeprom_write_dword ( uint32_t *addr , uint32_t value )
void eeprom_update_dword ( uint32_t *addr , uint32_t value )
uint16_t eeprom_read_float ( const float * addr )
void eeprom_write_float ( float *addr , float value )
void eeprom_update_float ( float *addr , float value )
void eeprom_read_block ( void * pointer_ram , const void * pointer_eeprom , size_t n) void eeprom_write_block (
const void * pointer_ram , void * pointer_eeprom , size_t n) void eeprom_update_block ( const void * pointer_ram ,
void * pointer_eeprom , size_t n)
In AVR-GCC, a word is two bytes long and a double word is twice that (4-bytes), while a block is an arbitrary
number of bytes which you supply (think string buffers, or customer data types you create) and a float is
also four bytes long (but can hold fractional values).
The update vs. Write functions
Historically, there were only two types of EEPROM functions per data type; a write function, and a read
function. In the case of the EEPROM write functions, these functions simply wrote out the requested
data to the EEPROM without any checking performed; this resulted in a reduced EEPROM lifespan if the
data to be written already matches the current contents of the EEPROM cell. To reduce the wear on the AVR's
limited lifespan EEPROM, the new update functions were added which only perform an EEPROM write if
the data differs from the current cell contents.
Reading data from the EEPROM
To start, let's try a simple example and try to read a single byte of EEPROM memory, let's say at location 46. Our
code might look like this:
# include <avr / eeprom .h>
void main ( void )
{
uint8_t ByteOfData ;
ByteOfData =eeprom_read_byte (( uint8_t *) 46) ;
}
Office : G-85, Preet Vihar, New Delhi-110092. Ph. : +91 - 95 6060 5666. Website : www.i3indya.com
Copyright All Right Reserved
| 24|
This will read out location 46 of the EEPROM and put it into our new variable named ByteOfData. How does it
work? Firstly, we declare our byte variable, which I'm sure you're familiar with:
uint8_t ByteOfData ;
Now, we then call our eeprom_read_byte() routine, which expects a pointer to a byte in the EEPROM space.
We're working with a constant and known address value of 46, so we add in the typecast to transform that
number 46 into a pointer for the eeprom_read_byte() function to make the compiler happy.
EEPROM words (two bytes in size) can be written and read in much the same way, except they require a pointer
to an int:
# include <avr / eeprom .h>
void main ( void )
{
uint16_t WordOfData ;
WordOfData =eeprom_read_word (( uint16_t *) 46) ;
}
And double words and floats can be read using the eeprom_read_dword() and eeprom_read_float() functions
and a pointer to a uint32_t or float variable.
Writing data to the EEPROM
Alright, so now we know how to read bytes and words from the EEPROM, but how do we write data? The same
principals as reading EEPROM data apply, except now we need to supply the data to write as a second argument
to the EEPROM functions. As explained earlier, we will use the EEPROM update functions rather than the old
write functions to preserve the EEPROM lifespan where possible.
# include <avr / eeprom .h>
void main ( void )
{
uint8_t ByteOfData ;
ByteOfData =0 x12 ;
eeprom_update_byte (( uint8_t *) 46 , ByteOfData );
}
Office : G-85, Preet Vihar, New Delhi-110092. Ph. : +91 - 95 6060 5666. Website : www.i3indya.com
Copyright All Right Reserved
| 25|
Unsurprisingly, the process for writing words of data to the EEPROM follows the same pattern:
# include <avr / eeprom .h>
void main ( void )
{
uint16_t WordOfData ;
WordOfData =0 x1232 ;
eeprom_update_word (( uint16_t *) 46 , WordOfData );
}
And double words and floats can be written using the eeprom_update_dword() and
eeprom_update_float() functions and a uint32_t or float variable.
EEPROM Block Access
Now we can read and write bytes and words to EEPROM, but what about larger datatypes, or strings? This is
where the block commands come in.
The block commands of the avr-libc <avr/ eeprom.h>header differ from the word and byte functions shown
above. Unlike its smaller cousins, the block commands are both routines which return nothing, and thus
operate on a variable you supply as a parameter. Let's look at the function declaration for the block reading
command
void eeprom_read_block ( void * pointer_ram , const void * pointer_eeprom , size_t n)
Wow! It looks hard, but in practice it's not. It may be using a concept you're not familiar with however, void-
type pointers.
Normal pointers specify the size of the data type in their declaration (or typecast), for example uint8_t* is a
pointer to an unsigned byte and int16_t* is a pointer to a signed int. But void is not a variable type we can
create, so what does it mean?
A void type pointer is useful when the exact type of the data being pointed to is not known by a function, or is
unimportant. A void is merely a pointer to a memory location, with the data stored at that location being
important but the type of data stored at that location not being important. Why is a void pointer used?
Using a void pointer means that the block read/ write functions can deal with any data type you like, since all
the function does is copy data from one address space to another. The function doesn't care what data it copies,
only that it copies the correct number of bytes.
Ok, that's enough of a derail back to our function. The block commands expect a void* pointer to a RAM
location, a void* pointer to an EEPROM location and a value specifying the number of bytes to be written or
read from the buffers. In our first example let's try to read out 10 bytes of memory starting from EEPROM
address 12 into a string.
Office : G-85, Preet Vihar, New Delhi-110092. Ph. : +91 - 95 6060 5666. Website : www.i3indya.com
Copyright All Right Reserved
| 26|
# include <avr / eeprom .h>
void main ( void )
{
uint8_t StringOfData [10];
eeprom_read_block (( void *) StringOfData , ( const void *) 12 , 10) ;
}
Again, looks hard doesn't it! But it isn't; let's break down the arguments we're sending to the
eeprom_read_block() function.
( void *) StringOfData
EEPROM BLOCK ACCESS
The first argument is the RAM pointer. The eeprom_read_block() routine modifies our RAM buffer and so
the pointer type it's expecting is a void* pointer. Our buffer is of the type uint8_t, so we need to typecast its
address to the necessary void type.
( const void *) 12
Reading the EEPROM won't change it, so the second parameter is a pointer of the type const void. We're
currently using a fixed constant as an address, so we need to typecast that constant to a pointer just like with
the byte and word reading examples.
Obviously, this number of bytes to be read. We're using a constant but a variable could be supplied instead.
The block update function is used in the same manner, except for the update routine the RAM pointer is of
the type const void and the EEPROM is just a plain void pointer, as the data is sourced from the RAM location
and written to the EEPROM location:
# include <avr / eeprom .h>
void main ( void )
{
uint8_t StringOfData [10] =" TEST ";
eeprom_update_block (( const void *) StringOfData , ( void *) 12 , 10) ;
}
Office : G-85, Preet Vihar, New Delhi-110092. Ph. : +91 - 95 6060 5666. Website : www.i3indya.com
Copyright All Right Reserved
| 27|
Using the EEMEM attribute
You should now know how to read and write to the EEPROM using fixed addresses. But that's not very
practical! In a large application, maintaining all the fixed addresses is an absolute nightmare at best. But
there's a solution to push this work onto the compiler the EEMEM attribute.
Defined by the same <avr/ eeprom.h header that gives us our access functions for the EEPROM, the EEMEM
attribute instructs the GCC compiler to assign your variable into the EEPROM address space, instead of the
SRAM address space like a normal variable. For example, we could add the following code to our application:
# include <avr / eeprom .h>
uint8_tEEMEM NonVolatileChar ;
uint16_t EEMEM NonVolatileInt ;
uint8_tEEMEM NonVolatileString [10];
And the compiler will automatically allocate addresses for each of the EEPROM variables within the EEPROM
address space, starting from location 0. Although the compiler allocates addresses for the EEMEM variables
you declare, it cannot directly access them. This means that the following code will NOT work as intended:
# include <avr / eeprom .h>
uint8_tEEMEM NonVolatileChar ;
uint16_t EEMEM NonVolatileInt ;
uint8_tEEMEM NonVolatileString [10];
int main ( void )
{
uint8_t SRAMchar ;
SRAMchar =NonVolatileChar ;
}
That code will instead assign the RAM variable SRAMchar to whatever is located in SRAM at the address
of NonVolatileChar, and so the result will be incorrect. Like variables stored in program memory, we need
to still use the eeprom read and write routines discussed above to access the seperate EEPROM memory space.
So let's try to fix our broken code. We're trying to read out a single byte of memory. Let's try to use the
eeprom_read_byte() routine.
- Android Application Development
- Facebook Application Development
APPLICATION DEVELOPMENT
(WORKSHOP)
Office : G-85, Preet Vihar, New Delhi-110092. Ph. : +91 - 95 6060 5666. Website : www.i3indya.com
Copyright All Right Reserved
| 28|
# include <avr / eeprom .h>
uint8_tEEMEM NonVolatileChar ;
uint16_t EEMEM NonVolatileInt ;
uint8_tEEMEM NonVolatileString [10];
int main ( void )
{
uint8_t SRAMchar ;
SRAMchar =eeprom_read_byte (& NonVolatileChar );
}
It works! Why don't we try to read out the other variables while we're at it. Our second variable is an int, so
we need the eeprom_read_word() routine:
# include <avr / eeprom .h>
uint8_tEEMEM NonVolatileChar ;
uint16_t EEMEM NonVolatileInt ;
uint8_tEEMEM NonVolatileString [10];
int main ( void )
{
uint8_tSRAMchar ;
uint16_t SRAMint ;
SRAMchar =eeprom_read_byte (& NonVolatileChar ); SRAMint = eeprom_read_word (&
NonVolatileInt );
}
And our last one is a string, so we'll have to use the block read command:
# include <avr / eeprom .h>
uint8_tEEMEM NonVolatileChar ;
uint16_t EEMEM NonVolatileInt ;
uint8_tEEMEM NonVolatileString [10];
int main ( void )
{
uint8_tSRAMchar ;
uint16_t SRAMint ;
uint8_tSRAMstring [10];
SRAMchar =eeprom_read_byte (& NonVolatileChar ); SRAMint = eeprom_read_word (&
NonVolatileInt );
eeprom_read_block (( void *) SRAMstring , ( const void *) NonVolatileString , 10) ;
}
Office : G-85, Preet Vihar, New Delhi-110092. Ph. : +91 - 95 6060 5666. Website : www.i3indya.com
Copyright All Right Reserved
| 29|
Interfacing UART with microconroller
Check 1
#include<avr/ io.h>
#define F_CPU 1000000UL
#include<util/ delay.h>
#define Baud_Rate 1200UL
#define ubrr_value ((F_CPU/ (16UL*Baud_Rate)) - 1)
voidusart_send(unsigned char);
unsigned char usart_rec();
voidusart_init();
i
3
i
n
d
y
a

T
e
c
h
n
o
l
o
g
i
e
s
MANUALS
Features of i3indya AT mega 16 Development Board.
q On board AT mega 16, L293D, 7805 ICs. (14,10)
q 8 internally connected LEDs for experiment. (3) (internal connections through B.0 to B.7)
q 8 ADC channels (4) (internal connection through A.0 to A.7)
q Two extra 5V power ports for external supply. (6)
q Internal connection of motors through B.0,B.1,B.2,B.3.
Office : G-85, Preet Vihar, New Delhi-110092. Ph. : +91 - 95 6060 5666. Website : www.i3indya.com
Copyright All Right Reserved
| 30|
void main()
{
unsigned int x;
usart_init();
DDRB=0XFF;
while(1)
{
x=usart_rec();
usart_send(x);
if(x=='f')
PORTB=0b00101000;
else if(x=='b')
PORTB=0b00010100;
else if(x=='l')
PORTB=0b00100000;
else if(x=='r')
PORTB=0b00001000;
else
PORTB=0X00;
}
}
void usart_init()
{
UBRRL =ubrr_value;
UBRRH =(ubrr_value>>8);
UCSRC=(1<<URSEL)|(1<<UCSZ0)|(1<<UCSZ1);
UCSRB=(1<<RXEN)|(1<<TXEN);
}
void usart_send(unsigned char data)
{
while(!(UCSRA & (1<<UDRE)))
{
}
UDR=data;
}
unsigned char usart_rec()
{
while(!(UCSRA & (1<<RXC)))
{
}
return UDR;
}
Office : G-85, Preet Vihar, New Delhi-110092. Ph. : +91 - 95 6060 5666. Website : www.i3indya.com
Copyright All Right Reserved
i
3
i
n
d
y
a

T
e
c
h
n
o
l
o
g
i
e
s
| 31|
Interfacing DTMF with microcontroller
Check 1
#include<avr/ io.h>
#include<util/ delay.h>
void main()
{
DDRA=0b00000000;
DDRB=0b11111111;
while(1)
{
int x=PINA & 0b00001111;
if(x==0b00000001)
PORTB=0b00001010;
else if(x==0b00000010)
PORTB=0b00000101;
else
PORTB=0b00000000;
}
}
ROBO SHOP
ROBO SHOP
i3indya
www.i3indya.com
Office : G-85, Preet Vihar, New Delhi-110092. Ph. : +91 - 95 6060 5666. Website : www.i3indya.com
Copyright All Right Reserved
i
3
i
n
d
y
a

T
e
c
h
n
o
l
o
g
i
e
s
| 32|
Using external interrupts
Check 1
#include<avr/ io.h>
#include<util/ delay.h>
#include<avr/ interrupt.h>
void interrupt();
int main()
{
interrupt();
while(1)
{
DDRC=0b11111111;
DDRB=0b11111111;
PORTB=0b11111111;
_delay_ms(1000);
PORTB=0b00000000;
_delay_ms(1000);
}
return 0;
}
void interrupt(void)
{
MCUCR=(0<<ISC00)|(1<<ISC01);
GICR=(1<<INT0);
sei();
}
ISR(INT0_vect)
{
PORTC=0b00001000;
}
WINTER TRAINING
2013
Embedded System & Robotics
Ethical Hacking & Cyber Security
Office : G-85, Preet Vihar, New Delhi-110092. Ph. : +91 - 95 6060 5666. Website : www.i3indya.com
Copyright All Right Reserved

You might also like