AVR Studio & Proteus Lab Guide
AVR Studio & Proteus Lab Guide
SEMESTER V
5047 - EMBEDDED SYSTEMS LAB
PRACTICAL RECORD
Name:………………………………………………………
Roll No:…………………………………………………….
Register No:……………………………………………..
Batch:…………..….…… Class:……………………….
Embedded Systems Lab - 5047 Prepared by:
Arjun P, Lr. in Electronics Engg
Notes:
SYLLABUS
Requirements:
PC running Windows XP or later version with AVR Studio and Proteus Installed.
Theory:
The Proteus Design Suite is a proprietary software tool suite used primarily for
electronic design automation. It is a Windows application for schematic capture,
Simulation, and Printed Circuit Board(PCB) layout design. It can be found in many
configurations, depending on the size of designs being produced and the
requirements for microcontroller simulation. Proteus is used mainly by electronic
design engineers and technicians to create schematics and electronic prints for
manufacturing printed circuit boards(PCBs) and also as a rapid prototyping tool for
R&D
2. In new projects page ensure that C/C++ is selected in Installed Templates and AVRGCC C
Executable Project is selected. Give a suitable project name (here name given as Exp0).
Click OK.
3. In search window type atmega32. Now select Atmega32 from the list shown and click
OK.
6. Now select Build->Build Exp0 to build the project and generate Hex File. If build is
successful without any error, we get a Build successful message in Output window.
7. Hex file with same name as project will be generated inside Debug folder in the location
where we saved the project during Step 2. This Hex file will be used for Proteus
simulation.
2. Give project name and set path where the project will be saved. Click Next
6. Click Finish
8. Include parts by clicking on ‘P’ beside the toolbar. Now Pick Devices window will pop up.
In keyword search window type atmega32 and select ATMEGA32 from the list and click
OK.
11. Now our project has 3 components ATMEGA32, LED RED and RES as shown. Click on
ATMEGA32 and click anywhere on the right grid. Now ATMEGA32 will be placed at that
location as shown
13. Now wire the circuit. For this place mouse pointer at any terminal of a device. When the
cursor turns to a pencil symbol and a red dot appears, click left mouse button and drag
to the corresponding terminal to be connected in another device.
14. Circuits need to be properly grounded. To add Ground click on Terminals mode, select
GROUND and click on the right grid.
16. Now we need to program ATMEGA32. For this Right click on ATMEGA32 and select Edit
Properties.
17. In Edit Component window that pops up, click on the folder symbol next to Program
File selection option. Browse to the location where the Hex file was created in Step 7 of
AVR studio project creation (Hex file will be inside Debug folder). Select the Hex file and
click Open. Then click OK in Edit Component window.
18. The resistor value is now 10 Kilo Ohms. We need to change the resistor value to 330
Ohms. For this right click on the resistor R1 and select Edit properties.
19. In the Edit Component window that pops up, type 330 in the box corresponding to
Resistance and click OK.
20. The completed circuit is shown below. Now click on the Run simulation button at the
bottom.
22. You can Stop the simulation by clicking on Stop Simulation button as shown
Appendix 0:
VCC and GND pins of ATmega32 are hidden in an EDA software like Proteus. Proteus
inherently connects them to the internal VCC net and GND net. To see the default
voltage values in VCC net and GND net go to Design -> Configure power rails as shown
Now power rail configuration menu pops up. Under Power rails section click on the drop
down menu next to Name and select VCC/VDD to see VCC net voltage. The default
VCC/VDD Net voltage will be shown (here it’s 5V as shown) below. If required we can
change this voltage to a different value. Similarly select GND to see GND net voltage.
GND net voltage is set to 0V and is not editable.
LED Blinking
Aim:
Requirements:
PC running Windows XP or later version with AVR Studio and Proteus Installed.
Theory:
Blink an LED connected to any port B pin of ATMEGA32. PORTB is configured as an output port.
The LED is made to switch on and off in regular intervals of 1s. So PORTB is made high and low
continuously in regular intervals of 1s.
Circuit Diagram:
Algorithm:
Code:
#define F_CPU 1000000UL //1 MHz clock
#include <avr/io.h>
#include <util/delay.h>
int main(void)
{
DDRB = 0xFF; //port B configured as output port
while(1)
{
PORTB = 0x01; //PORTB Pin0 made high, Pin1 made low
_delay_ms(1000); //call delay
PORTB = 0x02; //PORTB pin0 made low, pin1 made high
_delay_ms(1000); //call delay
}
return 0;
}
Result:
Completion of Experiment
Aim:
To read the status (ON/OFF) of a switch and display the status by turning ON/OFF an LED
Requirements:
PC running Windows XP or later version with AVR Studio and Proteus Installed.
Theory:
PORTC is configured as an input port and PORTB is configured as an output port. Switch is
connected to PORTC Pin 2 and LED connected to PORTB Pin 0.
Circuit Diagram:
Algorithm:
Code:
#include <avr/io.h>
int main(void)
{
DDRB = 0xFF; //port b is output
DDRC = 0x00; //port c is input
PORTB = 0x00;
while(1)
{
if (PINC & (1<<2))
{
PORTB = 0x00;
}
else
{
PORTB = 0xFF;
}
}
return 0;
}
Result:
Completion of Experiment
Aim:
Requirements:
PC running Windows XP or later version with AVR Studio and Proteus Installed.
Theory:
PORTC is configured as an input port and PORTB is configured as an output port. Switch is
connected to PORTC Pin 2 and Relay connected to PORTB Pin 0. Lamp and series battery are
connected to ‘Normally Open’ terminal of relay.
Components/Terminals in Proteus: ATMEGA32, RELAY, RES, CELL, SWITCH, LAMP, DC, GND
Circuit Diagram:
Algorithm:
Code:
#include <avr/io.h>
int main(void)
{
DDRB = 0xFF; //port b is output
DDRC = 0x00; //port c is input
PORTB = 0x00;
while(1)
{
if (PINC & (1<<2))
{
PORTB = 0x00;
}
else
{
PORTB = 0xFF;
}
}
return 0;
}
Result:
Completion of Experiment
Optoisolator Interfacing
Aim:
Requirements:
PC running Windows XP or later version with AVR Studio and Proteus Installed.
Theory:
PORTC is configured as an input port and PORTB is configured as an output port. Switch is
connected to PORTC Pin 2 and Relay connected to PORTB Pin 0. Lamp and series battery are
connected to Optoisolator output
Components/Terminals in Proteus: ATMEGA32, 4N35, RES, CELL, SWITCH, LAMP, DC, GND
Circuit Diagram:
Algorithm:
Code:
#include <avr/io.h>
int main(void)
{
DDRB = 0xFF; //port b is output
DDRC = 0x00; //port c is input
PORTB = 0x00;
while(1)
{
if (PINC & (1<<2))
{
PORTB = 0x00;
}
else
{
PORTB = 0xFF;
}
}
return 0;
}
Result:
Optoisolator interfaced with AVR and a lamp has been turned ON using it.
Completion of Experiment
Aim:
Requirements:
PC running Windows XP or later version with AVR Studio and Proteus Installed.
Theory:
To use ATmega32 ADC, the analog input need to be connected to PORTA pins which are
multiplexed as ADC input pins (labeled as ADC0 to ADC7). LM34 Temperature sensor (Pin 2) is
connected to PORTA Pin 0(ADC0 pin) of ATmega32. PORTA is configured as an input port and
PORTD is configured as an output port. 8 LEDs connected to PORTD will display the LM34
Temperature reading in 8 bit binary.
LM34 series are precision integrated-circuit temperature sensors whose output voltage is
linearly proportional to the Fahrenheit temperature. It outputs 10 mV for each degree of
Fahrenheit temperature.
The ADC has 10-bit resolution. So number of steps will be 1024. We use the internal 2.56 V
reference voltage as Vref, so the step size would be 2.56 V/1024 = 2.5 mV. LM34 sensor
produces 10 mV for each degree of temperature change and the ADC step size is 2.5 mV. So
each degree of temperature change corresponds to 4 ADC steps(10 mV/2.5 mV = 4).This makes
the binary output number for the ADC four times the real temperature. So the 10-bit output of
the ADC is divided by 4 to get the real temperature. To divide the 10-bit output of the ADC by 4
we choose the left-justified option and only read the ADCH register. It is same as shifting the
result 2 bits right (division by 4 in binary).
A 100nF capacitor is connected between the AREF pin and GND to make Vref voltage more
stable and increase the precision of ADC. LM34 Pin 1 and ATmega32 AVCC pins are connected
to 5V DC.
Circuit Diagram:
Algorithm:
1. Set PORTD as output by initializing DDRD register with 0xFF and PORTA as input by
initializing DDRA register with 0x00.
2. Write 0x87 to ADCSRA register. This will enable ADC and set ADC Prescaler Select bits to
111 (to select Fosc/128 for ADC clock, where Fosc is the crystal frequency connected to
the AVR)
3. Write 0xE0 to ADMUX register. This will the set Reference selection bits to 11 (to select
Internal 2.56 V for Vref) and set ADLAR bit to 1 so that the10 bit conversion result will be
left adjusted and set Analog Channel and Gain Selection Bits to 00000 to select single
ended channel ADC0.
4. In a continuous while loop first set ADSC bit to 1 to start conversion.
5. Check whether ADIF flag of ADCSRA register is set. This bit is set when an ADC
conversion completes and the data registers are updated.
6. After the ADIF bit has gone HIGH, read the ADCH registers to PORTD to get the digital
data output in PORTD which lights up the corresponding LEDs to indicate binary value.
Code:
#include <avr/io.h>
int main(void)
while(1)
return 0;
Result:
Interfaced LM34 temperature sensor IC using ADC peripheral of ATmega32 and observed the
binary output corresponding to the analog temperature value through LEDs.
Completion of Experiment
Aim:
To monitor the status of a switch and perform the following:
Requirements:
PC running Windows XP or later version with AVR Studio and Proteus Installed.
Theory:
PORTA is configured as an input port and PORTC is configured as an output port. Switch is
connected to PORTA Pin 0. DC Motor is interfaced to AVR through L298 Motor driver IC. Input
pins IN1 and IN2 of L298 are connected to PORTC pins 1 & 2 respectively. Enable pin ENA of
L298 connected to PORTC pin 0. DC Motor is connected across the output pins Out1 and Out2
of L298. L298 IC is provided with separate 5V DC supply.
Circuit Diagram:
Algorithm:
1. Set PORTC as output by initializing DDRC register with 0xFF and PORTA as input by
initializing DDRA register with 0x00
2. Initially disable L298 and set L298 IN1 = 0, L298 IN2 = 0 by writing 0xF8 to PORTC.
3. In a continuous loop, first enable L298 by writing 1 to PORTC pin 0.
4. Read status of switch by reading value of PORTA Pin 0. If it is low(Switch is closed), set
L298 IN1 = 0 and L298 IN2 = 1 by writing 0 to PORTC pin 1 and 1 to PORTC pin 2.
5. If it is high (Switch is open), set L298 IN1 = 1 and L298 IN2 = 0 by writing 1 to PORTC pin
1 and 0 to PORTC pin 2.
Code:
#include <avr/io.h>
int main(void)
DDRA = 0;
DDRC = 0xFF;
PORTC &= 0xF8; //initially disable L298, L298 IN1 = 0, L298 IN2 = 0
while(1)
else
return 0;
Result:
Interfaced DC motor with AVR microcontroller using L298 motor driver and using a switch
controlled the direction of rotation.
Completion of Experiment
Requirements:
PC running Windows XP or later version with AVR Studio and Proteus Installed.
Theory:
PORTC pin 0 is configured as an output port. Servo Motor control input pin is connected to
PORTC pin 0.
Servo Motor is a DC Motor equipped with error sensing negative feedback to control the exact
angular position of the shaft. Unlike DC Motors it will not rotate continuously. It is used to make
angular rotations such as 0-90°, 0-180° etc. Servo motor control is simple and needs no extra
drivers like stepper motor and only angular motion is possible. The angular position is
determined by the width of the pulse at the control input. Angular position can be controlled by
varying the pulse width between 1ms to 2ms.
Applying a pulse of appx 1ms pulse width will rotate the servo motor to 0 degree, a pulse of 1.5
ms pulse width will rotate the servo motor to 90 degrees and a pulse of 2 ms pulse width will
rotate the servo motor to 180 degrees.
Circuit Diagram:
Algorithm:
Code:
int main(void)
PORTC = 0x01;
_delay_ms(1000);
PORTC = 0x00;
_delay_ms(2000);
PORTC = 0x01;
_delay_us(1500);
PORTC = 0x00;
_delay_ms(2000);
PORTC = 0x01;
_delay_ms(2000);
PORTC = 0x00;
_delay_ms(2000);
return 0;
Result:
Interfaced Servo motor with AVR microcontroller and observed the angle of rotation by
applying pulses of different widths.
Completion of Experiment
Aim:
To monitor the status of a switch and perform the following:
(a) If Switch is open, the Stepper motor rotates clockwise.
(b) If Switch is closed, the Stepper motor rotates counterclockwise.
Requirements:
PC running Windows XP or later version with AVR Studio and Proteus Installed.
Theory:
PORTA is configured as an input port and PORTC is configured as an output port. Switch is
connected to PORTA Pin 0. A Unipolar Stepper Motor is interfaced to AVR through ULN2003A
driver IC. Because the AVR lacks sufficient current to drive the stepper motor windings, we
must use a driver such as the ULN2003A to energize the stator. ULN2003A has an internal diode
to take care of back EMF. 4 Input pins (pin 1 to 4) of ULN2003A are connected to PORTC pins 0
to 3 respectively. Windings A, B, C and D of Stepper Motor are connected to 4 output pins (pin
1 to 4) of ULN2003A. ULN2003A IC is provided with separate 5V DC supply. 2 COM windings of
Stepper motor are connected to 12V DC.
Circuit Diagram:
Algorithm:
1. Set PORTC as output by initializing DDRC register with 0xFF and PORTA as input by
initializing DDRA register with 0x00
2. In a continuous loop, read the status of switch by reading value of PORTA Pin 0. If it is
low(Switch is closed), output the sequence 0x66, 0xCC, 0x99 and 0x33 to PORTC in order
with a delay of 100ms between each sequence.
3. If it is high (Switch is open), output the sequence 0x66, 0x33, 0x99 and 0xCC to PORTC in
order with a delay of 100ms between each sequence.
Code:
int main(void)
DDRA = 0;
DDRC = 0xFF;
while(1)
PORTC = 0x66;
_delay_ms(100);
PORTC = 0xCC;
_delay_ms(100);
PORTC = 0x99;
_delay_ms(100);
PORTC = 0x33;
_delay_ms(100);
else
PORTC = 0x66;
_delay_ms(100);
PORTC = 0x33;
_delay_ms(100);
PORTC = 0x99;
_delay_ms(100);
PORTC = 0xCC;
_delay_ms(100);
return 0;
Result:
Interfaced Stepper motor with AVR microcontroller using ULN2003A motor driver and using a
switch controlled the direction of rotation.
Completion of Experiment
Aim:
Requirements:
PC running Windows XP or later version with AVR Studio and Proteus Installed.
Theory:
PORTC is configured output port. A common cathode 7 segment relay is connected to PORTC.
Port C Pins 0 to 6 are connected to D1 to D7 segment pins of 7 segment display which
correspond to segments a to g in 7 segment display. Digits 0 to 9 are displayed with 1s delay by
turning ON the appropriate segments of 7 segment display.
Circuit Diagram
Algorithm:
Code:
#define F_CPU 1000000UL //1 MHz clock
#include <avr/io.h>
#include <util/delay.h>
int main(void)
{
DDRC = 0xFF; //port C is output
PORTC = 0x00;
int i= 0;
while(1)
{
PORTC = seg_7[i];
_delay_ms(1000);
i+=1;
if(i>=10)
{
i=0;
}
}
return 0;
}
Result:
Completion of Experiment
Aim:
Requirements:
PC running Windows XP or later version with AVR Studio and Proteus Installed.
Theory:
In DAC0808, the digital inputs are converted to current (Iout), and by connecting a resistor to
the Iout pin, we convert the result to voltage. Iref current output is isolated by connecting it to
an op-amp such as the 741. PORTD is configured as an output port. 8 digital input pins A1 to A8
of DAC0808 are connected to PORT. 12V DC is connected to VREF+ pin of DAC0808 and -12V DC
is connected to VEE pin of DAC0808. 741 Op Amp is configured as a I to V converter.
Circuit Diagram:
Algorithm:
Code:
int main(void)
{
unsigned char i = 0;
DDRD = 0xFF;
while(1)
{
PORTD = i;
_delay_us(100); //for oscilloscope ramp display
//_delay_ms(200); //for DC voltmeter display
i++;
}
return 0;
}
Result:
Interfaced DAC0808 with ATMEGA32 and observed the following Ramp Waveform on
Oscilloscope
Completion of Experiment
Aim: To interface ADC module PCF8591 with AVR and display binary data
Requirements:
PC running Windows XP or later version with AVR Studio and Proteus Installed.
Theory:
The PCF8591 is a single-chip, single-supply low power 8-bit CMOS data acquisition device with
four analog inputs, one analog output and a serial I2C-bus interface. Three address pins AO, A1
and A2 are used for programming the hardware address. Address, control and data to and from
the device are transferred serially via the two-line bidirectional I2C bus.
SCL and SDA pins of PCF8591 are connected to the SCL and SDA pins of ATmega32. LM34
Temperature sensor is connected to Analog Input pin AIN0. A0,A1,A2 are grounded to make
device address as 000.
VREF pin of PCF8591 is provided with 2.56V either directly through a DC source or through a
potentiometer. AGND pin is grounded. PCF8591 is configured as an ADC and has 8-bit
resolution. So the number of steps will be 256. The step size is calculated as (VREF – AGND)/256
= (2.56 V – 0 V)/256 = 10 mV. LM34 sensor produces 10 mV for each degree of temperature
change and the ADC step size is also 10 mV. So each degree of temperature change
corresponds to 1 ADC step. So the binary output of the ADC directly corresponds to the real
temperature.
An A/D conversion cycle is always started after sending a valid read mode address to a PCF8591
device. Once a conversion cycle is triggered an input voltage sample of the selected channel is
stored on the chip and is converted to the corresponding 8-bit binary code. The conversion
result is stored in the ADC data register and awaits transmission.
Circuit Diagram:
Algorithm:
1. Call i2c_init() function which initializes I2C communication module of ATmega32 and
then call i2c_start() function which is used to set start condition and initiate an I2C
communication,
2. i2c_write() function is called with 0x90 which is the address of PCF8591 (1001000) and 0
in LSB which corresponds to write mode.
3. i2c_write() function is called with 0x00 to select single ended input channel 0 AIN0.
4. In a continuous loop first call i2c_start() function and then call i2c_write() function with
0x91 which is the address of PCF8591 (1001000) and 1 in LSB which corresponds to
read mode.
5. i2c_read_ack() function is then called to read a byte from PCF8591 device with
acknowledgement, which is fetched to the TWDR register in ATmega32. This function
returns the TWDR value which is the value read from PCF8591.
6. Then i2c_read_no_ack() function is called to read a byte from PCF8591 device with NO
acknowledgement, which is fetched to the TWDR register in ATmega32. This function
returns the TWDR value which is the value read from PCF8591 and is stored in a variable
temp.
7. PORT D is configured as output by writing 0xFF in DDRD. 8 LEDs are connected to
PORTD.
8. The digital value read from PCF8591 is written to PORTD, and the LEDs connected to
PORTD show the digital value.
Code:
#define F_CPU 1000000UL //1 MHz clock
#include <avr/io.h>
#include <util/delay.h>
void i2c_init(void)
{
TWSR = 0x00; //set pre-scaler bits to 0
TWBR = 0x47; //set SCL freq = CPU freq/(16+(2*71))
TWCR = 0x04; //enable TWI
}
void i2c_start(void)
{
TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN); //set TWI interrupt, generate START
//condition & TWI enable
while((TWCR & (1<<TWINT)) == 0); //wait till TWINT bit in TWCR is set to 1 after
//successful TWI operation
}
void i2c_stop(void)
{
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO); //set TWI interrupt,TWI enable
//& generate STOP condition.
for (int k = 0; k<100; k++) //To add a small delay.
{
}
}
int main(void)
{
DDRD = 0xFF; //portD as output
i2c_init();
i2c_start();
i2c_write(0x90); //address of PCF8591 (1001000) + W(0)
i2c_write(0x00); //select single ended input channel 0 AIN0
i2c_stop();
while(1)
{
i2c_start();
i2c_write(0x91); //address of PCF8591 (1001000) + R(1)
i2c_read_ack();
temp = i2c_read_no_ack();
i2c_stop();
PORTD = temp; //display digital value in led
}
return 0;
}
Result:
Interfaced PCF8591 module in ADC mode with ATmega32. LM34 temperature sensor IC was
connected to PCF8591 ADC module and observed the binary output from PCF8591
corresponding to the analog temperature value through LEDs connected to PORTD.
Completion of Experiment
Date: / /