Professional Documents
Culture Documents
Name
Registration Number
Class
Instructor’s Name
Introduction
This Lab Manual has been developed for the CPE342 Microprocessor Systems and Interfacing
course offered at the Department of Electrical and Computer Engineering, at COMSATS
University Islamabad (CUI). The work demonstrated by the students in the labs constitute 25 %
of the total marks for this course. During the labs, students will work in groups comprising 2 to
3 students.
This manual comprises 12 laboratory exercises, each exercise comprises sections; a ‘Pre-Lab’,
an ‘In-Lab’ task and a ‘Post Lab’ task. Student are expected to have completed the ‘Pre-Lab’
tasks prior to entering the laboratory. In the lab, they will be required to perform ‘In-Lab’ task.
The ‘Post-Lab’ task is to be completed after the students leave the lab.
Students are graded on the ‘Pre-Lab’ and ‘In-Lab’ tasked via an oral exam and demonstration.
Students are not allowed to copy the work from other groups and must demonstrate original
effort. CUI has a zero tolerance anti-plagiarism policy.
In addition to the exercises in the manual, students will be required to complete two projects. A
‘Mini Lab Project’ and a ‘Final Lab Project’ that counts towards the second Lab Sessional and
Lab Final Exam respectively. The detailed grading policy is available in the Course Description
File (CDF).
Acknowledgement
The labs for EEE-342 Microprocessor Systems and Interfacing were originally designed by Dr.
Omar Ahmad. The first draft of the manual was prepared by Ms. Kiran Nadeem, Mr. Raheel
Ahmed, Ms. Asma Ramay and Mr. Ali Ra-za Shahid. The first version was completed in Spring
2016 session. The sec-ond version was completed during the summer break of 2016. Typesetting
and formatting of this version was supervised by Dr. Omar Ahmad and was carried out by Mr.
Abdul Rehman, Mr. Suleman & Mr. Baqir Hussain. The third version was completed in
September 2017 in which all the tasks were updated from the ATmega16 to the ATmega328p
microcontroller. The fourth version was completed in February 2018 in which some lab manuals
and lab tasks were improved. The fifth revision has been carried out by Dr. Haroon Ahmed Khan,
Dr. Omar Ahmed and Ms. Asma Ramay. The whole document was reformatted in this version
and all the laboratory tasks have been updated and upgraded. A summary of the revisions is
given in the table below:
History of Revision
Version and
Team Comments
Date of Issue
This is the first editable draft of EEE – 342 lab manual.
Version 1. Dr. Omar Ahmad
Labs were designed by Dr. Omar Ahmad and this
May 2016 Ms. Kiran Nadeem
manuscript was prepared by Ms. Kiran Nadeem.
Version 5. Dr. Haroon Khan The entire document has been reformatted. All the
September Dr. Omer Ahmed laboratory tasks have been revised, with a special
2021 Ms. Asma Ramay emphasis towards show casing the students’ ability to
work independently
Safety Precautions
Be calm and relaxed, while working in lab.
When working with voltages over 40 V or current over 10 A , there must be at least two
Be sure about the locations of fire extinguishers and first aid kit.
No loose wires or metals pieces should be lying on the table or neat the circuit.
Avoid using long wires, that may get in your way while making adjustments or changing
leads.
Be aware of bracelets, rings, and metal watch bands (if you are wearing any of them). Do
When working with energize circuit use only one hand while keeping rest of your body
o Disconnect the power source from the circuit breaker and pull out the plug using
insulated material.
Table of Contents
Introduction .................................................................................................................................. 2
Acknowledgement ...................................................................................................................... 3
History of Revision ..................................................................................................................... 3
Safety Precautions ........................................................................................................................ 4
Lab # 01 Introduction to Development Tools and Lab Softwares ............................................... 7
Objectives ................................................................................................................................. 7
Pre Lab ..................................................................................................................................... 7
In-Lab ..................................................................................................................................... 11
Post Lab .................................................................................................................................. 21
Lab # 02 Introduction to AVR Microcontroller Hardware Circuitry and Digital I/O Ports ..... 22
Objectives: .............................................................................................................................. 22
Pre-Lab ................................................................................................................................... 22
In Lab: .................................................................................................................................... 29
Post Lab .................................................................................................................................. 32
Lab # 03 Interfacing 7-Segment Display Using Digital I/O Ports ............................................. 33
Objectives: .............................................................................................................................. 33
Pre-Lab ................................................................................................................................... 33
Pre-Lab Task: ......................................................................................................................... 35
In Lab: .................................................................................................................................... 36
Post lab task:........................................................................................................................... 39
Critical Analysis / Conclusion ............................................................................................... 40
Lab # 04 LCD Interfacing with AVR Microcontroller .............................................................. 41
Objectives: .............................................................................................................................. 41
Pre-Lab ................................................................................................................................... 41
In Lab: .................................................................................................................................... 45
Post Lab .................................................................................................................................. 47
Lab # 05 Introduction to Assembly Language Programming of AVR Microcontrollers .......... 48
Objectives ............................................................................................................................... 48
Pre Lab ................................................................................................................................... 48
In-Lab ..................................................................................................................................... 51
Post Lab .................................................................................................................................. 57
COMSATS University Islamabad (CUI) , Islamabad Campus Page 5
EEE342 Microprocessor Systems & Interfacing
Objectives
Learn to use software development tools such as Arduino, Integrated Development
Environment (IDE) (Atmel Studio, AVR Studio), Compiler (WinAVR), and Simulator
(Proteus) for the AVR ATmega 328P microcontroller.
Learn to program Arduino and ATmega328P.
Softwares Used
Arduino
Microchip Studio (Version 7)
AVR Studio (Version 4)
Proteus ISIS
WinAVR (Version 2010)
Pre Lab
One of the learning outcomes for the lab work during this semester is for students to gain
proficiency in using microcontrollers while interfacing them with multiple devices and
connecting them to a variety of networks. Microcontrollers are “programmable” chips. Users
can program these chips to do a variety of tasks. The main objective of this course would be to
learn how to effective program microcontrollers make them perform most common kinds of
tasks. The particular chip students will program in these labs is the AVR
ATmega328p microcontroller.
Programming would require the use of Integrated Development Environments (IDEs) with cross
compilers built in. Cross compilers can compile code for platforms in-addition to those they are
installed on. For example, most students will either use Windows (or Apple or Linux) based
computers/laptops. A cross compiler installed on Windows can be used to generate code that
will run on a microcontroller. This code has to be copied/burned on to the microcontroller for it
to run (Figure 1.1).
In case the actual hardware microcontroller is not available, the hardware can be emulated on
a Modelling and Simulation software. In this software you can model the microcontroller and
then burn/write the program/hex file onto the model and simulate it on the
software (Figure1.2).
In the lab we will be using either Microchip Studio or AVR Studio as the cross-compiling IDE
and Proteus for modelling and simulation.
Arduino:
Arduino is an open-source platform used for building electronics projects. It consists of both a
physical programmable circuit board and an IDE (Integrated Development Environment) that
runs on your computer. Most Arduino boards consist of an Atmel 8-bit AVR microcontroller
with varying amounts of flash memory, pins and features. Arduino is programmed using
the Arduino Software (IDE) which is a cross-platform application for windows, macOS and
Linux. It is connected to a PC via USB cable to upload computer code to the physical board.
This also provides power to the board, as indicated by a LED.
AVR Studio:
AVR Studio is an Integrated Development Environment (IDE) used to develop projects
(software part) for AVR microcontrollers. This IDE consists of a project management tool,
source filer editor, assembler and front-end for C/C++ programming, a debugger and a hardware
(MCU registers) Simulator. With AVR Studio, you can develop code in C as well as in Assembly
Language. Both approaches are different from each other. Each has its own merits as you will
learn during the coursework.
Microchip Studio:
Microchip Studio 7 is the integrated development platform (IDP) for developing and debugging
Atmel SMART ARM-based and Atmel AVR microcontroller (MCU) applications. Studio 7
supports all AVR MCUs. The Microchip Studio 7 IDP gives you a seamless and easy-to-use
environment to write, build and debug your applications written in C/C++ or assembly code. It
also connects seamlessly to Atmel debuggers and development kits.
WinAVR:
WinAVR is a suite of executable, open source software development tools for the Atmel AVR
series of microprocessors hosted on the Windows platform. It includes the GNU GCC compiler
for C and C++. You will install this software (release 2010) on your PC/Laptop and it will be
used to compile your C/C++ code for the AVR microcontroller. IDEs such as AVR Studio will
automatically detect and use WinAVR installation and you will not need to run this software
yourself.
Proteus:
The Proteus Design Suite is a complete software solution for circuit simulation and PCB
design.Proteus can simulate electric/electronic and microcontroller based circuits. It supports
number of microcontrollers available in the market.
ATmega 328p:
The Atmel AVR ATmega328P is a low-power 8-bit microcontroller architecture.It has 131
Powerful Instructions. Most of them require single clock cycle for execution. It has 32K bytes
of In-System Programmable Flash Program memory with Read-While-Write capabilities, 1K
bytes EEPROM, 2K bytes SRAM, 23 general purpose I/O pins and 32 general purpose working
registers.
DDRx (Data Direction Register) - Sets the direction of each pin as input or output.
PORTx - Used to output/write values on a Port.
PINx - Used to input/ read values from a Port.
Where x is the port B, C or D. All of these registers are 8-bit registers. Figure 1.3 shows the three
registers associated with Port B.
In-Lab
In-Lab Task 1: Arduino Learning Tutorial
1. Launch Arduino IDE.
2. Some built-in examples are included in Arduino software. Click on the toolbar menu: File
> Examples > Basics > Blink. This will turn an LED on Arduino board on and off with
some delay.
3. Compile the sketch. After successful compilation, the code can be uploaded to the
Arduino board.
2. After selecting New Project, two options will be displayed (AVR Assembler and AVR
GCC). AVR Assembler is selected for the assembly code and AVR GCC is selected to
compile C-code. In this tutorial, we will use C-code so select AVR GCC. Write project
name (lab1 for this tutorial) and select the path directory path to save files for this new
project (Select desktop and lab1 as folder name) and Click Next (Figure 1.7).
Figure 1.7: Compiler selection and Project name description with location
3. In the next menu, select AVR Simulator in debug platform and ATmega328P in device
menu. After selection click finish as shown in Figure 1.8.
4. Layout shown in Figure 1.9 will appear on the screen. Layout will consist of source
Window, I/O window, message window and I/O toolbar.
generating delays*/
int main()
Press F7 button to build output files of the project including object file and hex file.
COMSATS University Islamabad (CUI) , Islamabad Campus Page 14
Lab # 01 Introduction to Development Tools & Lab Software
Note:
As stated in the previous section, you can use either AVR studio or Microchip studio
to compile and debug your code. However, it is recommended that you use
Microchip Studio.
Figure 1.10 – How to create new project using Microchip Studio installed in Lab
Figure 1.11 – Compiler selection and Project name description with location
4. Layout shown in figure 1.13 will appear on the screen. Layout will consist of
source code window and message window. Write the code given below in
the source window.
5. Press F7 button to build output files of the project including object file and
hex file. Try it out with the code given in task2.
1. Launch Proteus from start menu or by desktop icon. Proteus layout shown below will
appear on the screen as shown in Figure 1.14. There is a root sheet to draw circuit. The
device window will initially be empty and you need to pick components from library.
Proteus component library is equipped with lots of components and ICs including
COMSATS University Islamabad (CUI) , Islamabad Campus Page 16
Lab # 01 Introduction to Development Tools & Lab Software
2. After Clicking Pick devices menu as in figure 1.15 will appear on the screen. There is a
keyword prompt which can refine your search. Write ATmega328P in keyword prompt
and result window will display components having keyword of ATmega328P. Double
click ATmega328P component in result window to add it to device list.
i. ATmega328 Microcontroller
ii. Animated LED
iii. 470 ohms resistor
4. To add any component on root sheet, simply select that component from device window
and click anywhere in the root sheet to place that component. To draw wire connection
between two pins of any components, simply move mouse cursor to the tip of the pin and
click. Then click on tip of the other pin you wanted to connect. Draw a circuit shown in
figure 1.16 on Proteus root sheet by using components indicated above.
5. On the left side of Proteus layout, different modes can be selected. To add ground
terminal to the circuit, click terminal mode from buttons on left side of screen and then
select ground terminal. You can change characteristic properties of any component. To
change, simply double click the required component. An edit component menu will
appear for that particular component where you can change the characteristic properties
of that component.
6. You also need to load your required program into the microcontroller memory as shown
in Figure 1.17. Program is loaded into microcontroller memory through hex file. Double
click microcontroller, edit menu will have prompt for load program. Select the hex file
generated from Atmel Studio tutorial. This hex (Lab1.hex) file can be found in the Lab1
directory you created on desktop for the Atmel Studio tutorial.
7. The default frequency of ATmega328p is 1MHz. To change it to 16MHz, we will provide
external clock source of 16MHz. Select CKSEL Fuses (0000) Ext. Clock, In Clock
Frequency, write 16MHz and select CLKDIV8 fuse to be unprogrammed.
In Lab Task 4:
a. The following code is written to generate fibonacci series output at PortB which is
given as (0, 1, 2, 3, 5, 8, 13, 21, 34, 55).
b. Build the following code in AVR Studio or Atmel Studio. Read the error messages,
identify and correct any syntax errors and rebuild the solution.
c. Use Debugging mode of AVR Studio or Atmel Studio to debug and correct the
code to get the desired output. In debug mode, open watch window to check the
value of the variables.
Code:
//This code will generate fibanocci series.
generating delays*/
int main(void)
int t1 = 1, t2 = 1, nextTerm = 0, i = 1;
PORTB = nextTerm;
nextTerm = t1 - t2;
t1 = t2;
t2 = nextTerm;
i = i + 1;
while (1)
return 0; }
Lab Assessment
Pre Lab /1
In Lab /5
Data
Post Lab /4 /4
Presentation
Writing Style /4
Objectives:
Understand the minimal circuit required to start using a microcontroller
Learn to program (download code to program memory of) a microcontroller using
Arduino board.
To understand and use digital I/O ports of AVR microcontroller
Required Tools:
Software Tools:
Microchip Studio (Version 7) or AVR Studio (Version 4)
Proteus ISIS
Arduino IDE
AVRDUDESS
Hardware Tools:
Name Value Quantity
Arduino Nano With USB Cable - 1
Breadboard - 1
LEDs - 8
Switches - 8
Resistor 470Ω 8
Table 2.1 List of Components
Pre-Lab
For this lab, students need to use a microcontroller. A microcontroller is a programmable IC that
has many functionalities built-in the chip itself. Furthermore, microcontrollers have the ability
to send and receive both digital and analogue data via pins. The main outcome of these lab
sessions is that students should be able to program microcontrollers for a variety of tasks by the
end of the semester.
System Clock and Clock Options
The system clock frequency refers to the frequency generated from the system clock pre-scaler.
The AVR microcontroller unit (MCU) sports internal clock as well as external clock source.
System can run on 1MHz internal clock or external crystal oscillator circuits. The device is
shipped with internal RC oscillator at 8.0MHz and with the fuse CKDIV8 programmed, resulting
in 1.0MHz system clock.
The ATmega328p can operate up to 20 MIPS at 20-MHz.
On-board Controller
While it is possible to use a chip directly, it is sometimes much easier to use and program them
when the controller is mounted on a board. It so happens, that the ATmega328p comes mounted
on a number of boards. Students are recommended to use one of the two most popular variants
of these boards, namely:
1. Arduino Nano
2. Arduino Uno
The Arduino Uno is more flexible to use with a removable microcontroller, the Nano is a cheaper
alternative that matches most relevant capabilities of the Uno.
Arduino Nano
An Arduino Nano is small, cheap and breadboard friendly platform with the ATmega328p
surface mounted on it. The Arduino Nano is programmed using the Arduino Software (IDE). To
program Arduino Nano in offline mode, you need to install the Arduino Desktop IDE. Arduino
after connecting a PC via USB cable. This also provides power to the board, as indicated by an
LED (On the bottom of the Arduino Nano 2.x and the top of the Arduino Nano 3.0).
Arduino Nano Specifications:
Arduino Uno
Please review figure 2.3 and 2.4 for Arduino Uno. Do note that both boards use the AVR
Atmega328P microcontroller.
AVRDUDE - AVR Downloader Uploader - can be used to upload the Hex file generated by
software programming in AVR microcontrollers. It is a program for downloading and uploading
the on-chip memories of Atmel's AVR microcontrollers. It can program the Flash and EEPROM,
and when supported by the serial programming protocol, it can program fuse and lock bits.
COMSATS University Islamabad (CUI) , Islamabad Campus Page 25
Lab # 02 Introduction to AVR Microcontroller Hardware Circuitry and Digital I/O Ports
Avrdude is a command line program, AVRDUDESS is a GUI for AVRDUDE. It supports all
programmers and MCUs that AVRDUDE supports.
Each of the AVR Digital I/O port is associated with three I/O registers.
DDRx
PORTx
PINx
DDRx is an 8-bit register which stores configuration information for the pins of Portx. The bits
in this register set the data direction of the individual pins of a port. The direction of each pin
can be input or output. Writing a 1 in the pin location in the DDRx makes the physical pin of
that port an output pin and writing a 0 makes that pin an input pin.
The prefix 0x signifies hexadecimal number. 0xFF means decimal 255 or binary 11111111
which means all the bits in register are at high logic level. 0x00 means all the bits in the register
are at low logic level. Each physical pin of a port is configured independently and thus a port
can have some of its pins configured as input and the others as output pins. For example:
DDRD = (1<<0)|(1<<4)|(1<<5)|(1<<7);
This is equivalent to
DDRD = 0b10110001;
Or
DDRD= 0xB1;
In the above example, port D is initialized such that the pins PD0, PD4, PD5 and PD7 are output
pins whereas pins PD1, PD2, PD3 and PD6 are input pins.
We can change the value of a single bit without disturbing the previous value of all the other bits
of the register. For example:
DDRD |= (1<<5);
This will set bit 5 of DDRD while retaining the values of all other bits.
Similarly,
This will clear bit 5 of DDRD while retaining the values of all other bits.
PORTx is an 8-bit register which stores the logic values that are to be transferred on the physical
pins of Portx if the pins are configured as output pins. In short, once the direction of DDRx
register is defined as an output pins, we need to set them to give an output of HIGH logic or
LOW logic. So to write values to a port, you need to write the values to the “PORT” register of
that port.
This is equivalent to
PORTD = 0b01001001;
Or
PORTD = 0x49;
PINx is an 8-bit register that stores the logic value, the current state, of the physical pins on
Portx. When you set any port as input you have to read its status using this register.
This is equivalent to
PINB = 0b01001001;
Or
PINB = 0x49;
Task 2:
Install AVRDUDESS on to your computer/laptop.
Task 3:
Please download datasheets of ATmega328P and Arduino Uno/ Nano.
In Lab:
Task 1
Write and test following program in AVR Studio/Atmel Studio. Also, simulate it on
Proteus.
/*This code will configure Port B for output and then toggle
generating delays*/
int main()
} }
1. AVRDUDE require LibUSB drivers. LibUSB should be installed along with Arduino
IDE or with any LibUSB device but if you don’t have any such devices then you will
need to download this driver.
2. Connect Arduino nano with your PC via USB cable. The power LED on Arduino should
turn on.
3. In device manager, a COM Port will be listed under Ports (COM and LPT). If your device
is not detected you can try installing CH340 drivers.
4. Run AVRDUDESS, Select Arduino as programmer and ATMega328P as MCU. Under
Port, select the COM port which was listed under Ports in device manager. Set the baud
rate to 57600 (Fig 2.7).
5. Now select the .hex file generated in Task 1 and click program button, program will be
burned in your ATmega 328P memory.
Set up your Arduino Nano or Uno with a resistor and LED as per the following figure and test
the hardware.
.INCLUDE <M328PDEF.INC>
LDI R18, 0XFF
OUT DDRB, R18
LDI R21, 3
LOOP:
LDI R16, 10
LDI R20, 0
AGAIN:
ADD R20, R21
OUT PORTB, R20
DEC R16
BRNE AGAIN
RJMP LOOP
Task 3:
(To be assigned by Lab instructor_
Switches are connected to one port of ATmega328p for input and LEDs are connected to
another port for output. Using these, perform a task assigned by your lab instructor.
Students should write the code for given task, simulate it on proteus and then implement
it on hardware.
Post Lab:
Write Arduino code for In lab task 3. Simulate it on Proteus using Arduino nano.
Lab Assessment
Pre Lab /1
In Lab /5
Data
Post Lab /4 /4
Presentation
Writing Style /4
Objectives:
Learn to interface components like seven-segment display using digital I/O ports.
Required Tools:
Software Tools:
AVR Studio/ Microchip Studio
Proteus ISIS
AVRDUDESS
Hardware Tools:
Pre-Lab
Seven-segment displays are commonly used in digital clocks, clock radios, timers, wristwatches,
and calculators. They can also be found in motor-vehicle odometers, speedometers, radio
frequency indicators, and practically any other display that makes use
of alphanumeric characters alone.
In Common Cathode configuration, the negative terminals of all LEDs are connected to the
common pin. The common is connected to ground and a particular LED glows when its
corresponding pin is given high.
In Common anode arrangement, the positive terminals of all LEDs are connected to common
pin .The common pin is given a high logic and the LED pins are given low logic to display a
number.
The figure below shows Pin diagram of a 7- segment display. For common anode, COM pins
are given Vcc and for common cathode, COM pins are given ground.
Pre-Lab Task:
A seven segment display is connected with Port D. Write a code to toggle all the segments
simultaneously with some delay.
The pins PD0 and PD1 are connected to the receiver and transmitter of of USART respectively.
To use these pins for digital I/O, we have to disable the transmitter and receiver. This can be
done by disabling TXEN0 and RXEN0 bits in UCSR0B register.
UCSR0B&=~(1<<RXEN0);
In Lab:
Task 1:
a. Implement Pre-lab task on hardware to test all segments of a 7-Segment display.
b. Use DMM to test the 7-segment display and identify whether it is common cathode or
common anode (Lab instructor should explain the method of testing a 7-segment with
DMM).
Task 2:
Interfacing of Seven Segment Display with AVR Microcontroller:
In this task a seven segment display is connected to Port D. On Port B a 4 inputs 7-segment
display is connected which takes BCD number and displays it on seven segment. An array is
created which is currently zero. This array will be filled with hexa-decimal numbers after
creating a Look-up table for 7-segment display.
0 0 0 1 1 1 1 1 1 0x3F
Part b- Code:
#include <avr/io.h> /*This header file includes the apropriate
generating delays*/
int main(void)
I/O*/
unsigned char
seven_seg_array[10]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
};
_delay_ms(500);
if(counter==10)
counter=0;
return 0;
Part c-Simulation:
Download the hex file of your project in Atmega328P microcontroller using AVRDUDESS and
implement this task on hardware.
In Lab Task 2:
(To be specified by lab instructor)
Switches are connected to Port B for input and a seven segment display is connected to PORT
D of ATmega328p for output. Using these, perform a task assigned by your lab instructor.
Code:
Lab Assessment
Pre Lab /1
In Lab /5
Data
Post Lab /4 /4
Presentation
Writing Style /4
Objectives:
Overview of controller to controller communication
To understand LCD interfacing with AVR microcontroller
Software Tools:
Microchip Studio/ AVR Studio
Proteus ISIS
AVRDUDESS
Hardware Tools:
Pre-Lab
LCD provides an output interface to AVR microcontroller. It comes in various configurations
such as 20 x 2, 16 x 1, 40 x 1, 16 x 2 etc. with 5 x 8 or 5 x 11 dots resolution. Out of these, 16 x
2 is widely used.
LCD also has a microcontroller in it. This microcontroller is already coded to display characters
on the screen. Therefor to use an LCD a controller to controller interface is required.
LCD control unit (Controller)
The LCD controller is responsible for all the operations with the LCD. These operations may
include (but are not limited to):
movement of curser,
clearing display,
printing characters,
special character generation etc.
HD44780U and S6A0069 are common examples of LCD control unit. An LCD controller’s
internal memory comprises of Character Generator ROM (CGROM), Character Generator RAM
(CGRAM) and Display Data RAM (DDRAM).d
Character Generator ROM (CGROM) contain predefined character fonts table.
LCD Interfacing
Command Register allows the user to send commands such as clear display, cursor at
home etc.
Data register allows the user to send the data to be displayed on LCD
Since same pins from D0 to D7 are used for both command and data, RS pin is used to identify
between the command and data.
To initialize the LCD for 5x7 matrix and 8 bit communication mode, following commands
should be send to LCD. See Table 5.3 for description of each command.
Function Set: Select LCD mode to 8-bit interface, 2 line, and character size to 5x7.
Display On/Off control: Display On, turn on the cursor, No blinking.
Clear Display
Entry mode set: Increment Cursor, No display shift
Sending Commands to LCD:
1. Clear the RS pin (logic zero)
2. Pass the appropriate Command to the data pins (via connected buffer/port)
3. The command should be sent as per command syntax specified in the Datasheet (see
Table 5.2)
4. Set the EN pin (logic one) and hold for at least 450ns
In Lab:
Task-1
Consider the basic wiring shown between an ATmega328P chip and an LCD in figure 4.2.
Write and execute a C-program on Proteus that is able print your name on the first row of the
LCD and your roll-number on the second row of the LCD.
Simulation:
Task-2
Consider your controller connected to an 8×dipswitch, a push-button and an LCD. Program your
controller in a way that whenever the push-button is pressed, the input from the dipswitch should
be pushed on to the LCD as an ASCII character. Execute your code on Proteus.
Post lab:
Task 1:
Implement the in-lab task 2 for the 4-pin communication mode on Proteus. Additionally, add a
5×dip-switch array at an input. Use the dip switch to pass 8-bit ASCII code, one nibble at a time,
to be displayed on the LCD. Toggle the 5th switch to indicate that one nibble is ready to load.
Lab Assessment
Pre Lab /1
In Lab /5
Data
Post Lab /4 /4
Presentation
Writing Style /4
Objectives
To get started with assembly language programming for AVR microcontrollers.
Implementing loops and conditional execution instructions in Assembly language
Required Tools:
Software Tools:
AVR Studio/ MicrochipStudio
Proteus ISIS
AVRDUDESS
Hardware Tools:
Pre Lab
This lab would introduce students to the ATmega328P assembly language comprising 132
instructions. There are various advantages of using assembly, including, but not limited to:
Program written in assembly is faster to execute
The execution time can be measured precisely
It is possible to generate very specific delays
Code with a small program size can be generated
Programmers can control the controller directly without abstractions
Programmers can optimize the code for latency
Whenever a program for ATmega328P is compiled, a .hex file is generated that comprises
the machine coded version of the program. Assembly language is an English type
representation of machine code. Every line machine code can be represented by a
corresponding line of assembly code, and vice versa.
An assembly language program written by a programmer can be “assembled” into machine
code. Once the machine code (.hex file) is loaded into the program memory of the
microcontroller, the ALU starts executing each instruction 1 at a time. The ATmega328P
operates in a two-stage pipeline.
In every instruction cycle, every instruction is fetched, then it is decoded (to ascertain the
“instruction” and the operands), executed and stored back.
All assembly language instructions are 1 of 7 kinds:
1. Mathematical instructions
2. Logical instructions
3. Bit manipulation instructions
4. Branching instructions
5. Data transfer instructions
6. I/O instructions
7. Configuration and control of MCU components (Timers, ADCs, serial comms etc.)
Invariably, almost all instructions involve movement of data between general purpose
registers (GPRs) and other memory components. This is because all mathematical, logical,
and branching instructions work with general purpose registers (GPRs) only. The types of
movements are illustrated in figure 5.1. and the instructions summarized in table 5.2.
Figure 5.1 – A summary of all possible data movements and their corresponding assembly language instruction
Processor Registers:
There are 32 general-purpose 8-bit registers, R0–R31. All arithmetic and logic operations operate
on those registers; only load and store instructions access RAM. A limited number of instructions
operate on 16-bit register pairs.
The last three register pairs are used as pointer registers for memory addressing. They are known
as X (R27:R26), Y (R29:R28) and Z (R31:R30). Instructions which allow an immediate value
are limited to registers R16–R31 (8-bit operations) In addition to these 32 general-purpose
registers, the CPU has a few special-purpose registers:
PC: 16 bit program counter
SP: 16 bit stack pointer
SREG: 8 bit status register
BRNE k Branch if Not Equal. Conditional relative branch tests If (Z=0), then PC ←
the Zero Flag (Z) and branches relatively to PC if Z is PC+k+1
cleared.
BREQ k Branch if Equal. Conditional relative branch tests Z=1 If (Z=1), then PC ←
PC+k+1
Pre-Lab Task:
Understand the operation of all instructions from Atmel AVR 8 bit instruction Set.
In-Lab
Task 1:
Generate a square wave signal of frequency 1 KHz and 40% duty cycle on a digital I/O pin of
ATmega328P.
Steps:
1: Initialize stack pointer.
2: Configure Pin 0 of Port B as output.
3: Send 1 on PB0.
5: Call Delay of 400us.
6: Send 0 on PB0.
7: Call delay of 600us.
8: Repeat forever
Code :
.include "m328Pdef.inc"
ldi r16,HIGH(RAMEND)
ldi r16,LOW(RAMEND)
start:
forever:
rcall delay_400us
ldi r19,0x00
rcall delay_600us
ldi r20,4
loop1:
rcall delay_100us
dec r20
brne loop1
ret
ldi r20,6
loop2:
rcall delay_100us
dec r20
brne loop2
ret
; Delay = (1/16M)*4*4*100
ldi r18, 4
l2:
nop
dec r19
brne l2
dec r18
brne l1
ret
Simulation:
Hardware:
Implement the above task on hardware.
In Lab Task 2:
Write a program to toggle all bits of PORT D with some delay (Specified by Lab
Instructor). Simulate it on Proteus and implement it on Hardware.
Steps:
1: Initialize stack pointer.
2: Make Port B an output port.
3: Load 0x55 in any general purpose register, say R16.
4: Output R16 on Port B.
5: Call Delay.
6: Complement R16.
7: Repeat Forever
Code:
Simulation:
Description:
Connect 4 LED’s to PORT B of AT mega 328P.Using loops and conditions write an assembly
program that makes these LED blinks.
Simulate on proteus.
CODE:
Simulation:
Lab Assessment
Pre Lab /1
In Lab /5
Data
Post Lab /4 /4
Presentation
Writing Style /4
Objectives:
Using digital I/O ports of AVR microcontroller for digital Inputs.
Use I/O ports To Interface matrix keypad with microcontroller.
Tools:
Software Tools:
Hardware Tools:
Pre Lab:
6.1 4x4 Membrane Keypad:
The Keypad 4x4 features 16 push buttons arranged in 4x4 matrix to form standard alphanumeric
keypad. It provides a useful human interface component for microcontroller projects.Matrix
keypads uses a combination of four rows and four columns to provide button states to the
microcontroller. Underneath each key is a pushbutton, with one end connected to one row, and
the other end connected to one column. These connections are shown in figure 6.1.
Key Specifications
This keypad can be used in Security systems, Menu selection, Data entry for embedded systems
and various other applications.
To use a keypad with a microcontroller, it should be connected to in a way where either the
rows are the input to the controller and the columns are the output to the microcontroller, or
vice-versa. Suggested connections are shown in figure 6.3.
You should remember the role of IO-registers in the ATmega328p as illustrated in figure
6.4. Assume all the 4 rows are initially set as input (by virtue of DDRx register). The
programmer will have to scan the rows to determine if a button is pressed. Normally, the
values on the row would be all 0 i.e. R4-R1 == 0000. When the button is pressed as shown
in figure 5.2, the value would change to R4-R1 == 0010.
The fundamental idea is that the program keeps scanning the rows as long as no button is
pressed. However, as soon as a button is pressed, inverse the rows to outputs and the columns
to input. This would happen so fast that the button will still be pressed. So, on scanning the
columns, C4-C1 == 0010. In this one can identify the button that is pressed, which in this
case is ‘5’. [hint: the sequence 0010-0010 could signify ‘5’, or R1-C4 can be represented by
1000-0001 signifying ‘A’]
In order for the microcontroller to determine which button is pressed, following steps are
followed:
1) Create a look-up table filled with 16 entries for all keys of the keypad.
2) Four microcontroller pins should be defined as outputs, and other four pins should be defined
as inputs.
3) Connect columns of the keypad to input port and rows to the output port. Pull up the input
port and then read the value of columns.
4) Now connect rows of the keypad to input port and columns to the output port. Pull up the
input port and then read the value of rows.
5) If no key is pressed, the value of rows and columns will be 0000. If any key is pressed, the
value of rows and columns can be 0000,0001,0010,0100,1000 (1,2,4,8).
6) If no key is pressed, return 0. If a key is pressed, find its location in the keypad look-up table
and return the key pressed.
In-Lab:
Interfacing Atmega 328P with Keypad:
Connect a keypad to the microcontroller. Scan the keypad for key press and display the pressed
key on the serial monitor using serial communication.
Task 1- Code:
Understand the following code and complete the readkeypad function.
/* Module description:
In this lab the students will use the digital I/O Ports to
#include "debug_prints.c"
//***********************************************************/
int main()
UART0_init(MYUBRR);
printSerialStr("MYUBRR = ");
printSerialInt(MYUBRR);
printSerialStrln("");
printSerialStr("F_CPU = ");
printSerialInt((int)(F_CPU/1000000));
while (1)
key_pressed = read_keypad();
key_pressed = 0;
return 0;
_delay_us(100);
key = 0;
else
key = keypad_tbl2[temp];
_delay_ms(200);
return key;
Task 2-Simulation:
Download the hex file of your project in Arduino Nano using AVRDUDESS and implement
this task on hardware. Use serial monitor of Arduino IDE for display.
Task 4:
Write a code that passes out the ASCII code of the character that is pressed, on to PORTD
of an ATmega328p.
Lab Assessment
Pre Lab /1
In Lab /5
Data
Post Lab /4 /4
Presentation
Writing Style /4
Objectives:
Understand the function of ADC in microcontroller.
Learn different mode of operation of ADC
Interfacing of LM35 temperature sensor with Atmega328p.
Software Tools:
Microchip Studio/AVR Studio
Arduino
Proteus ISIS
AVR DUDESS
Hardware Tools:
Pre-Lab
Analog to digital converters are the most widely used devices for data acquisition. Most of the
physical quantities are analog e.g. temperature, humidity, pressure, light, etc. Therefore, we need
an analog to digital converter to convert the data into digital data in order to communicate with
the digital processors like microcontrollers and microprocessors.
These bits select the voltage reference for the ADC, as shown in Table 8.2
The ADLAR bit affects the presentation of the ADC conversion result in the ADC Data Register.
Write one to ADLAR to left adjust the result. Otherwise, the result is right adjusted.
The value of these bits selects which analog input is connected to the ADC. Table 8.3shows these
bit settings for selecting various single ended input channels:
Writing this bit to one enables the ADC. By writing it to zero, the ADC is turned off.
In Single Conversion mode, write this bit to one to start each conversion. ADSC will read as
one as long as a conversion is in progress. When the conversion is complete, it returns to zero.
Writing zero to this bit has no effect.
When this bit is written to one, Auto Triggering of the ADC is enabled (This mode is not covered
in this lab).
This bit is set when an ADC conversion completes and the Data Registers are updated. The ADC
Conversion Complete Interrupt is executed if the ADIE bit and the I-bit in SREG are set. ADIF
is cleared by hardware when executing the corresponding interrupt handling vector.
Alternatively, ADIF is cleared by writing a logical one to the flag.
When this bit is written to one and the I-bit in SREG is set, the ADC Conversion Complete
Interrupt is activated.
These bits determine the division factor between the XTAL frequency and the input clock to the
ADC.
ADLAR=0:
ADLAR=1
Following are the steps required to configure the ADC of AVR microcontrollers.
Registers belongs to the same conversion. The ADC has its own interrupt which can be
triggered when a conversion completes.
7. A single conversion is started by writing a '1' to the ADC Start Conversion bit in the ADC
Control and Status Register A (ADCSRA.ADSC). ADCS will stay high as long as the
conversion is in progress, and will be cleared by hardware when the conversion is
completed. If a different data channel is selected while a conversion is in progress, the
ADC will finish the current conversion before performing the channel change.
8. Auto Triggering is enabled by setting the ADC Auto Trigger Enable bit
(ADCSRA.ADATE). The trigger source is selected by setting the ADC Trigger Select
bits in the ADC Control and Status Register B (ADCSRB.ADTS).
Where VIN is the voltage on the selected input pin, and VREF the selected voltage reference
Operates From 4 V to 30 V
In order to understand the working principle of LM35 temperature sensor we have to
understand the linear scale factor. In the features of LM35 it is given to be +10 mills volt
per degree centigrade. It means that with increase in output of 10 mills volt by the sensor
Vout pin the temperature value increases by one. For example, if the sensor is outputting
100 mills volt at Vout pin the temperature in centigrade will be 10-degree centigrade. The
same goes for the negative temperature reading. If the sensor is outputting -100 mills volt
the temperature will be -10 degrees Celsius.
The LM35 can be used in multiple configurations. Each configuration will have different
outcomes. In the configuration shown in figure 7.2, you can only measure the positive
temperature from 2 degrees Celsius to 150 degrees Celsius.
In this configuration, we simply power the LM35 and connect the output directly to analogue to
the ADC. In this mode, the temperature can be calculated as follows:
𝑉𝑜𝑙𝑡𝑎𝑔𝑒 𝑟𝑒𝑎𝑑 𝑏𝑦 𝐴𝐷𝐶
𝐶𝑒𝑙𝑐𝑖𝑢𝑠 =
10𝑚𝑉
It is recommended that the output is pulled down (or grounded) with an 80KΩ –100KΩ resistor
for stable output as shown in figure 7.3.
In Lab:
Task-1
Use LM35 to sense the room temperature. Convert this data into digital using atmega328P ADC and
display temperature value on virtual terminal.
Complete the Code and simulate on Proteus.
Code:
// Module description:
// In this lab the students will learn to use the Analog to Digital
Converter
//********************************************************************
************/
#include <inttypes.h>
#include <stdlib.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <string.h>
#include <math.h>
#include "debug_prints.c"
/*********************************************************************
************/
#define ADC_CHANNEL0 0
#define ADC_CHANNEL1 1
#define ADC_CHANNEL2 2
/*****************************************************************/
int main(void)
ADC_Initialize();
DDRD = 0xFF;
UART0_init(MYUBRR);
printSerialStrln("Lab 8: ");
while(1)
temprature = read_temp_sensor(TEMP_SENSOR_CHANNEL);
printSerialInt(temprature);
printSerialStr("\r \n");
PORTD = temprature;
// Prescaler = 128
return 0;
_delay_us(10);
ADC_lo = ADCL;
ADC_hi = ADCH;
return result;
/** This function takes the floating point Voltage value as input and
converts it to corresponding Temprature in Celsius for an LM35 in
Basic Configuration.
/** This function reads the Value of Temprature Sensor (LM35) from
return temp_celsius;
Proteus Simulation
Hardware:
Interface a temperature sensor with Arduino Nano and use serial monitor of Arduino IDE to
display temperature.
In Lab Task 2:
Interface any analog sensor assigned by your lab instructor, Find mapping function for its
output and implement ADC for the sensor using ATmega328p.
Lab Assessment
Pre Lab /1
In Lab /5
Data
Post Lab /4 /4
Presentation
Writing Style /4
Objectives
To learn the concepts related to interrupts in AVR microcontroller.
To configure and use the external interrupt or user input tasks
To configure and use the internal interrupts
Software Tools
Pre Lab
What is Interrupt?
like timers and other interfaced peripherals like sensors, serial port etc. The programmer needs
to monitor their status regularly like whether the sensor is giving output, whether a signal has
been received or transmitted, whether timer has finished counting, or if an interfaced device
needs service from the controller, and so on. This state of continuous monitoring is known as
polling.
In polling, the microcontroller keeps checking the status of other devices and while doing so it
does no other operation and consumes all its processing time for monitoring. This problem can
be addressed by using interrupts. In interrupt method, the controller responds to only when an
interruption occurs. Thus in interrupt method, controller is not required to regularly monitor the
status (flags, signals etc.) of interfaced and inbuilt devices.
To understand the difference better, consider the following. The polling method is very much
similar to a salesperson. The salesman goes door-to-door requesting to buy its product or service.
Like controller keeps monitoring the flags or signals one by one for all devices and caters to
whichever needs its service. Interrupt, on the other hand, is very similar to a shopkeeper.
Whosoever needs a service or product goes to him and apprises him of his/her needs. In our case,
when the flags or signals are received, they notify the controller that they need its service.
External Interrupts:
The ATmega328p has two classes of interrupts. 2 are known as external interrupts that can
respond to any kind of change on PD2 and PD3. The associated registers with external interrupts
are:
EICRA
EIMSK &
EIFR
3 interrupts are known as pin-change interrupts that are associated with Ports B, C and D
respectively. They can respond to any change on the pins of all ports on the ATmega328p. the
associated registers are:
PCMSK0 (associated with PORTB)
PCMSK1 (associated with PORTC)
PCMSK2 (associated with PORTD)
PCICR &
PCIFR
Internal Interrupts:
ATmega328p has 20 internal interrupts. These internal interrupts are generated by the internal
peripherals of Microcontroller like Timer, ADC etc. The internal interrupts are used for efficient
operation of the internal peripherals. They can be enabled through the registers of these
peripherals.
In-Lab:
How to use interrupts:
First we have to configure and enable the global interrupts. The most significant bit of
status register called ‘I’ bit is used for this purpose. If ‘I’ is set 1 using register SREG
this means interrupt is enabled otherwise disabled.
We write functions called Interrupt Service Routine (ISR) to handle interrupts. These
functions are defined outside the main function because the event that causes interrupt is
not known by the programmer; hence the function can’t be called inside the main
function.
Enable the external interrupts locally in External Interrupt Mask Register (EIMSK). Then
configure the interrupts for falling edge, rising edge, low level or any logical change by
using EICRA register.
Enable the internal interrupts locally by writing 1 to interrupt enable bit in the registers
of the peripheral under use. For example, ADC system consists of ADIE bit in ADCSRA
register. ADIE bit is enabled to use ADC interrupts.
Advantages of Interrupt method:
Priority can be assigned.
Controller does not waste time checking if a device needs service or not.
Steps involved executing an interrupt:
Upon activation of an interrupt the microcontroller goes through the following steps as shown
in figure 7.1:
2. The program branches to the address of corresponding interrupt in the interrupt vector
table. The code starting here is called interrupt handler.
COMSATS University Islamabad (CUI) , Islamabad Campus Page 81
Lab # 08 External and Internal Interrupts in AVR Microcontrollers
5. Upon executing the last instruction in ISR the microcontroller returns to the place
where it was interrupted using reti instruction. First it gets the program counter
address by popping it from the stack. Then it starts to execute from that address.
Register Description:
The registers involved in configuring the external interrupts are shown in below.
External Interrupt Control Register A(EICRA):
The External Interrupt Control Register A contains control bits for interrupt sense control.
In addition to above registers you will need to set Global Interrupt Enable (GIE) bit. GIE is
bit7 of status register SREG.
For interrupt handling we need to include following header file into our project:
#include <avr/interrupt.h>
The following format is used to declare interrupt service routine:
ISR(ISR_Vect)
{
//Interrupt handling code goes here…..
}
In-Lab Task 1:
Generate binary counting with the help of LED’s interfaced by MCU and controlled by 2
Switches. One for enabling the circuit and the other is to reset it. Switch pressing is an external
event, that’s why we use external interrupts. Write the C code for Interrupts and simulate in
Proteus.
Code:
#include<avr/interrupt.h>
#include<avr/io.h>
ISR(INT0_vect)
ISR(INT1_vect)
int main()
DDRB= 0XFF;
counter=0;
while(1)
Proteus schematic:
Hardware:
Implement In Lab task 1 on hardware.
Task 2:
Assume that INT1 pin is connected to a switch that is normally low. Write a program that
toggles PORTC 20 times with some delay whenever INT1 pin goes high.
Code:
Simulation:
Task 3
Record a signal using ADC. Use ADC in free running mode. Add 8 bit DAC at Port D and
convert back the signal in analog and display result on oscilloscope for comparison.
Task description:
Code:
//Record an analog signal using the ADC and output to a DAC after
processing
//********************************************************************
************/
#include <inttypes.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
/*********************************************************************
************/
#define ADC_CHANNEL0 0
#define ADC_CHANNEL1 1
#define ADC_CHANNEL2 2
ISR(ADC_vect)
/*****************************************************************/
int main(void)
ADC_Initialize();
//Disable digital IO
while(1);
// Enable ADC
return 0;
_delay_us(10);
ADC_lo = ADCL;
ADC_hi = ADCH;
return result;
Simulation:
Lab Assessment
Pre Lab /1
In Lab /5
Data
Post Lab /4 /4
Presentation
Writing Style /4
Objectives:
Introduction to Timers/Counters
Delay and Waveform generation using timers
Using PWM signals to control Servo Motors
Tools:
Software Tools:
Hardware Tools:
9.1 Timers/Counters:
Timers built into the ATmega328p are essentially “Counters” that are independent of the
program cycle. i.e. once the Counter/Timer starts counting, it does not consume any program
cycles. It runs in parallel to the program being executed, incrementing after a fixed time interval,
depending on how it is configured. In the simplest mode of execution, once a timer starts, it will
increment every cycle of the system clock, while the program in the program memory will run
at tandem.
Timer values can be monitored, and automatically compared to other values. Events like timer
overflowing or matching a constant value can be bound to interrupts, i.e. the main program can
be interrupted in case any of these events happens. This capability can be leveraged in a number
of ways, Timers can be used to
Generate delays,
To produce general timed events (i.e. display of a clock),
To trigger the ADC,
To generate PWM signals or
Analyse incoming signals etc.
At ATMega328p has 3 timers namely:
Timer0 (8-bit)
Timer1 (16-bit)
Timer2 (8-bit)
As mentioned before, the timers are essentially counters, incrementing every clock cycle. The
clock can be the system clock as it is. It can also slow down the system clock by fixed factors.
Additionally, AVR Timers are also capable of using external clock sources.
Each timer construct broadly comprises the following registers:
TCNTn (The timer/counter)
TCCRn (Multiple configurations & control registers)
OCRn (Two comparison registers, to compare constant with the timer)
TIMSKn (Masking register, to enable interrupts)
TIFRn (Flag register, to monitor timer events)
Please refer to the ATmega328P Datasheet or your lecture material for detailed working of these
registers for timers 0, 1 & 2, before you proceed. These registers are referred to and used in the
sections that follow.
Timer0 has two signal generation channels (A and B). The mode of operation, i.e., the behavior
of the Timer/Counter and the Output Compare pins, is defined by the combination of the
Waveform Generation mode (WGM01:0) bits.
Compare Output mode (COMA01:0, COMB01:0) bits.
Waveform Generation mode bits affect the counting sequence, while the COM0A1:0bits control
whether the PWM output generated should be inverted or not (inverted or non-inverted PWM).
For non-PWM modes the COM0A1:0 bits control whether the output should be set, cleared, or
toggled at a compare match.
Next these modes are discussed in detail one by one.
The simplest mode of operation is the normal mode (WGM01:0 = 0). In this mode the counting
direction is always up (incrementing), and no counter clear is performed. The counter simply
overruns when it passes its maximum 8-bit value (TOP = 0xFF) and then restarts from the bottom
(0x00). In normal operation the Timer/Counter Overflow Flag (TOV0) will be set in the same
timer clock cycle as the TCNT0 becomes zero. The TOV0 Flag in this case behaves like a ninth
bit, except that it is only set, not cleared. However, combined with the timer overflow interrupt
that automatically clears the TOV0 Flag, the timer resolution can be increased by software. There
are no special cases to consider in the normal mode, a new counter value can be written anytime.
Using the output compare to generate waveforms in Normal mode is not recommended, since
this will occupy too much of the CPU time.
9.2.2 Clear Timer on Compare Match (CTC) Mode:
In Clear Timer on Compare or CTC mode (WGM01:0 = 2), the OCR0A, OCR0B registers are
used to manipulate the counter resolution. In CTC mode the counter is cleared to zero when the
counter value (TCNT0) matches the OCR0A/B. OCR0A/B define the top value for the counter,
hence also its resolution. This mode allows greater control of the compare match output
frequency. It also simplifies the operation of counting external events.
The timing diagram for the CTC mode is shown in figure below. The counter value (TCNT0)
increases until a compare match occurs between TCNT0 and OCR0A/B, and then counter
(TCNT0) is cleared.
An interrupt can be generated each time the counter value reaches the TOP value by using the
OCF0 Flag. If the interrupt is enabled, the interrupt handler routine can be used for updating the
TOP value.
For generating a waveform output in CTC mode, the OC0A/B output can be set to toggle its
logical level on each compare match by setting the Compare Output mode bits to toggle mode
(COM0A1:0 = 1). The OC0A/B value will not be visible on the port pin unless the data direction
for the pin is set to output. The waveform generated will have a maximum frequency of fOC0A/B
= fclk_io/2 when OCR0A/B is set to zero (0x00). The waveform frequency is defined by the
following equation:
The N variable represents the prescale factor (1, 8, 64, 256, or 1024).
The fast Pulse Width Modulation or fast PWM mode (WGM01:0 = 3) provides a high frequency
PWM waveform generation option. The fast PWM differs from the other PWM option by its
single-slope operation. The counter counts from BOTTOM to MAX then restarts from
BOTTOM. In non-inverting Compare Output mode, the Output Compare (OC0A) is cleared on
the compare match between TCNT0 and OCR0A/B, and set at BOTTOM. In inverting Compare
Output mode, the output is set on compare match and cleared at BOTTOM.
In fast PWM mode, the counter is incremented until the counter value matches the MAX value.
The counter is then cleared at the following timer clock cycle. The timing diagram for the fast
PWM mode is shown in Figure below. The TCNT0 value is in the timing diagram shown as a
histogram for illustrating the single-slope operation. The diagram includes non-inverted and
inverted PWM outputs. The small horizontal line marks on the TCNT0slopes represent compare
matches between OCR0A and TCNT0.
In fast PWM mode, the compare unit allows generation of PWM waveforms on the OC0A/B
pin. Setting the COM0A1:0 bits to 2 will produce a non-inverted PWM and an inverted PWM
output can be generated by setting the COM0A1:0 to 3.
The PWM frequency for the output can be calculated by the following equation:
The N variable represents the prescale factor (1, 8, 64, 256, or 1024).
The phase correct PWM mode (WGM01:0 = 1) provides a high resolution phase correct PWM
waveform generation option. The phase correct PWM mode is based on a dual slope operation.
The counter counts repeatedly from BOTTOM to MAX and then from MAX to BOTTOM. In
non-inverting Compare Output mode, the Output Compare (OC0A/B) is cleared on the compare
match between TCNT0 and OCR0A/B while up counting, and set on the compare match while
down counting. In inverting Output Compare mode, the operation is inverted. The dual-slope
operation has lower maximum operation frequency than single slope operation. However, due to
the symmetric feature of the dual-slope PWM modes, these modes are preferred for motor
control applications.
The PWM resolution for the phase correct PWM mode is fixed to eight bits. The counter is
incremented until the counter value matches MAX. When the counter reaches MAX, it changes
the count direction. The TCNT0 value will be equal to MAX for one timer clock cycle. The
timing diagram for the phase correct PWM mode is shown on Figure 3. The TCNT0 value is in
the timing diagram shown as a histogram for illustrating the dual-slope operation. The diagram
includes non-inverted and inverted PWM outputs. The small horizontal line marks on the TCNT0
slopes represent compare matches between OCR0A/B and TCNT0.
In phase correct PWM mode, the compare unit allows generation of PWM waveforms on the
OC0A/B pins. Setting the COM0A/B1:0 bits to 2 will produce a non-inverted PWM on OC0A/B.
An inverted PWM output can be generated by setting the COM0A/B1:0 to 3.The PWM
frequency for the output when using phase correct PWM can be calculated by the following
equation:
The N variable represents the prescale factor (1, 8, 64, 256, or 1024).
In Lab:
Task 1:
Code:
#include <inttypes.h>
#include <stdlib.h>
#include <avr/io.h>
#include <util/delay.h>
#include <string.h>
#include <math.h>
//********************************************************************
*
#define ADC_CHANNEL0 0
// ***********************************************************
// Main program
int main(void)
ADC_Initialize();
int adc_value;
while(1)
adc_value = ADC_Read(0);
_delay_ms(20);
move_motor(adc_value);
}}
void init_timer0()
// Enable ADC
return(0);
_delay_us(10);
ADC_lo = ADCL;
ADC_hi = ADCH;
return result;
Simulation:
Hardware Design:
Implement the above task on hardware.
In Lab task 2:
(To be specified by Lab Instructror)
Generate different waveforms using Timer0,1 and 2 as specified by your lab instructor.
View the generated waveforms on oscilloscope.
Lab Assessment
Pre Lab /1
In Lab /5
Data
Post Lab /4 /4
Presentation
Writing Style /4
Objectives:
To introduce input capture feature of the Timers/Counters in microcontrollers.
To emphasize preference of interrupt based designs over polling mechanisms.
Tools:
Software Tools:
Hardware Tools:
Pre-Lab:
Timer1 provided in the ATmega328p has an input capture utility. To put it very simply, if you
connect ICP1 pin to a periodic signal source, the microcontroller can detect falling or rising
edges. Therefore, a transition from low to high or high to low is a detectable event. Timer 1 input
capture can be summarised as follows:
1. Timer1 can be configured in way that, whenever either a rising edge or a falling edge on
ICP1 is detected, the value of Timer1 is stored in the 16-bit ICR1 register
2. The running program can detect this event either by pooling the ICF1 flag or by using
interrupts (TIMER1_CAPT). The program should copy the value from the ICR1 register
on to a general-purpose register (GPR) before it is overwritten)
Use-Cases
Input capture capability has many potential benefits. The most common use case is to use input
capture to study the nature of an incoming signal. One can use input capture to determine the
period and frequency of some types incoming signals. This may be achieved by capturing two
consecutive rising edges (i.e. timer 1 value at edgen and edgen+1) and measure the period in
terms of number of cycles. If one is aware of the system frequency (i.e. period of one cycle), the
period and frequency of the incoming signal can be calculated.
Furthermore, it may be used to determine the duty cycle of a signal as well by capturing the
consecutive rising, falling, and rising edges, as illustrated in figure 10.2.
Figure 10.2 – Calculating duty cycle of incoming signal with input capture
Another example is to use input capture with an ultrasonic sensor as shown in figure 10.3. These
sensors generate a continuous low signal output (on the “Echo” pin). When triggered (on the
“Trig” pin):
1. The output changes from low to high.
2. An ultrasonic sound wave (chirp) is sent out via a transducer
When the wave encounters a solid obstacle, it reflects back the echo. This echo is captured by
the second transducer. At this point the output transitions back to low.
Input capture can be used to capture the echo-time pulse (the number of cycles the pulse
remained high. This represents the time for the round trip of the sound wave. Half that time
represents time for the one-way travel. We know that the speed of sound at ambient temperatures
is approximately 340 m/s. If the time of the one-way trip is computed (considering the system
clock), the distance of the sensor from the solid object can be calculated.
Working
Timer 1 has to be running for this work. The input capture can be activated by setting the
ICES1 bit in the TCCR1B register. Typical steps for capturing edge arrival time for input
capture function (ICF) can be summarized as follows:
1. Initialize TCCR1 registers for proper mode, enabling/disabling noise canceller,
selection of edge (positive/negative)
2. Monitor the ICF flag in TIFR1
3. Upon arrival of the edge, the TCNT1 value is loaded into the ICR1 register
automatically
4. The value in ICR1 needs to be transferred to a GPR. When the low byte is read form
ICR1L, the high byte is copied into the high byte temporary register (TEMP). When
the CPU reads the ICR1H, I/O location it will access the TEMP Register. Therefore,
always read the low byte first
Figure 10.4 – Set the ICIE flag to 1 to enable input capture interrupt
In Lab:
Task 1:
The expected input signal is a periodic pulse train. The task is to find the frequency/time period
and duty cycle of this signal. The frequency of this signal is expected to be less than 4 KHz. The
given code configures Atmega328P interrupt subsystem to work with external interrupts and
input capture of Timer1. It also performs the necessary calculations to find the frequency and
duty cycle of the input signal and displays it on a terminal. You will have to understand the code
and then configure Timer1 for input capture.
Code:
// This program configures the 16-bit Timer1 of Atmega328p for Input
Capture.
//
**********************************************************************
*****/
#include <inttypes.h>
#include <stdlib.h>
#include <avr/io.h>
#include <util/delay.h>
#include <string.h>
#include <math.h>
#include "debug_prints.c"
/*********************************************************************
************/
float sig_freq = 0;
float sig_dc = 0;
/************************************************************/
#define TRUE 1
#define FALSE 0
void display_counter_values(void);
void display_signal_parameters(void);
void calculate_signal_param(void);
// ***********************************************************
// Main program
//
int main(void)
UART0_init(MYUBRR);
printSerialInt(MYUBRR);
printSerialStrln("");
printSerialStr("F_CPU = ");
printSerialInt((int)(F_CPU/1000000));
printSerialStrln("MHz");
timer_init();
int i=0;
while(1)
if(capture_complete == TRUE)
capture_complete = FALSE;
_delay_ms(250);
*/
TCNT1L = 0;
TCNT1H = 0;
ISR(INT0_vect)
rising1 = 0;
rising2 = 0;
falling1 = 0;
capture_complete = FALSE;
input_capt_counter = 0;
sig_freq = 0;
sig_dc = 0;
ISR(TIMER1_CAPT_vect)
icp_low = ICR1L;
icp_high = ICR1H;
input_capt_counter ++;
//printSerialInt((int)input_capt_counter);
//printSerialStrln("");
if(input_capt_counter == 2)
if(input_capt_counter == 3)
if(input_capt_counter == 4)
'falling1'.
*/
void display_counter_values()
printSerialStr("Rising 1: ");
printSerialStrln("");
printSerialStr("Rising 2: ");
printSerialStrln("");
printSerialStr("Falling 1: ");
printSerialStrln("");
void display_signal_parameters(void)
printSerialStr("Frequency = ");
printSerialFloat(sig_freq);
printSerialStrln(" Hz");
printSerialFloat(sig_dc);
printSerialStrln(" %");
variables.*/
void calculate_signal_param(void)
display_counter_values();
display_signal_parameters();
Simulation:
Hardware Design:
Implement In lab task on hardware. Connect a function generator to supply the input signal, and
a push button for interrupts. Use serial monitor of Arduino IDE to display the values.
Lab Assessment
Pre Lab /1
In Lab /5
Data
Post Lab /4 /4
Presentation
Writing Style /4
Objectives:
To implement serial communication using UART of Atmega328p
To establish Bluetooth connectivity between Atmega328p and an Android mobile device.
Tools:
Software Tools:
Hardware Tools:
Pre-Lab:
Serial Communication:
Microcontrollers must often exchange data with other microcontrollers or devices. Data may be
exchanged by using parallel or serial communication links. With parallel techniques, an entire byte
of data is typically sent simultaneously from the transmitting device to the receiver device.
Although this is efficient from a time point of view, it requires eight separate lines for the data
transfer. In serial transmission, a byte of data is sent a single bit at a time. Once 8 bits have been
received at the receiver, the data byte is reconstructed. Although this is inefficient from a time
point of view, it only requires a line (or two) to transmit the data.
The ATmega328P is equipped with a host of different serial communication subsystems, including
the serial USART, SPI, and TWI. What all of these systems have in common is the serial
transmission of data. Before discussing the different serial communication features aboard the
ATmega328P, we review serial communication terminology.
The serial communications protocols with built-in support in the ATmega series controllers are
shown in figure 11.2. This lab will cover UART/USART only.
USART/UART in ATmega328p
The UART mode in the ATmega328p has the following features:
Full Duplex Operation (Independent Serial Receive and Transmit Registers)
Asynchronous or Synchronous Operation
Figure 11.3 – UART Frame Example with start (1-low), 9 bits for data, 1 parity bit and stop bits
(2-high)
Please refer to the ATmega328P Datasheet or your lecture material for detailed working
of these registers for UART/USART communication before you proceed. These registers are
referred to and used in the sections that follow.
In Lab:
Task 1:
You will configure (i.e. set baud rate, frame format, parity settings etc ) UART present in
Atmega328P for Asynchronous Serial Communication. The rest of the code implements the
transmit and receive functionality and uses them in an echo back mechanism. This means that the
program waits for any data received on the UART receiver and then transmits it back.
Code:
//*********************** Lab 11 ****************************
// UBRRL registers for the desired Baud Rate. Then the Trans-
/*************************************************************/
#include <util\delay.h>
#include <string.h>
// ***********************************************************
// ***********************************************************
// Main program
int main(void)
USART_Init((unsigned int)UBRR_VAL);
while(1)
data = USART_Receive();
USART_Transmit(data);
char i=0;
USART_Transmit(str[i]);
char ch;
char i;
do
ch = USART_Receive();
str[i] = ch;
while(ch != '\0');
Simulation:
Figure 11.5: Serial Communication setup using UART of Atmega328P and a Virtual Terminal
Hardware Design:
Use Serial Monitor of Arduino IDE to test this circuit. The main() function in the program
implements a loop-back. This means that whatever is received by the UART from the Serial
Monitor, it transmits it again to the Monitor. So whenever you type something on the Monitor, it
will get printed twice (once when you type it and once when it loops back).
Task 2: Interfacing HC-05 Bluetooth device and Communicating with an Android Device
HC-05 is a module that is used to provide Bluetooth wireless connectivity to your microcontrollers.
HC-05 has a close cousin, the HC-06 also available in the market. Both devices are Bluetooth
transceiver modules but HC-05 can operate both as a Master or a Slave device whereas HC-06 can
only operate in the Slave mode. A Bluetooth master device can look for other BT devices and then
make a connection with them (called Paring in BT terminology). It is recommended that you get
an HC-05 device since the price is the same for the two modules. Following figure shows the two
modules side by side. The HC-05 has 6 pins compared to 5 pins of HC-06.
Once paired with a device, the HC-05 acts as a communication bridge between the microcontroller
and the connected device.
The following figure shows the electrical interface between the HC-05 and Arduino Nano. HC-05
is powered from the 5V and the GND pins of the Arduino, the TX and RX pins of the module are
connected to D8 and D9 of the Arduino board.
Upload the given code (for Arduino IDE) to the Arduino Nano and power up the HC-05 module
in Command mode. Now you can type in the AT commands (given in the link) and start
configuring your module. You have to implement the following sub tasks:
1. Find the configuration of your HC-05 Module
2. Change its password
3. Power the module in Communication mode
4. Connect (pair) it with your Mobile phone’s Bluetooth.
5. Demonstrate wireless communication using an Android App such as
https://play.google.com/store/apps/details?id=de.kai_morich.serial_bluetooth_terminal&
hl=en
6. End
Code:
#include<SoftwareSerial.h>
void setup() {
delay(500);
myserial.begin(9600);
delay(500);
void loop() {
if(myserial.available())
Serial.print((char)myserial.read());
Post Lab:
Program your ATmega328 on Proteus so that it is connected to an LCD and 8-switch panel and a
virtual terminal
Whenever the AVR starts, it must send a “YES” to the virtual terminal screen once. After that the
initial status of the switches should be transferred to the virtual terminal once. Thereafter, the
values should be updated on the virtual terminal only if any of the switch is changed.
At the same time, any character typed & entered on the virtual terminal should be displayed on
the connected LCD panel.
Lab Assessment
Pre Lab /1
In Lab /5
Data
Post Lab /4 /4
Presentation
Writing Style /4
Objectives:
To learn about Serial Peripheral Interfacing (SPI) and SPI programming
Implementation of SPI using microcontroller (ATmega328P) in proteus.
Tools:
Software Tools:
Microchip Studio/ AVR Studio
Proteus ISIS
AVR DUDESS
Hardware Tools:
Pre Lab:
Introduction to Serial Peripheral Interfacing (SPI)
Serial Peripheral Interface (SPI) is an interface bus commonly used to send data between
microcontrollers and small peripherals such as shift registers, sensors, and SD cards. It uses
separate clock and data lines, along with a select line to choose the device you wish to talk to.
Some of the features of SPI are as follows:
A Single Master – Multiple Slave topology
Four-wire protocol (developed by Motorola)
Synchronous communication
Full Duplex
Flexible number of bits
4 modes of operation
High Speed (supports up to 32MHz)
SPI is a “synchronous” data bus, which means that it uses a dedicated line for “clock” (in addition
to data) that keeps all connected devices in perfect sync. The clock is an oscillating signal that
tells the receiver exactly when to sample the bits on the data line. This could be the rising (low to
high) or falling (high to low) edge of the clock signal, depending upon the mode of operation.
When the receiver detects that edge, it will immediately look at the data line to read bits on one
the SDI line while at the same time passing bits from the SDO on to the MISO (as shown in Figure
12.1.
HOW SPI WORKS:
SPI consists of two shift or more registers. One in the “Master” device and the others in the “Slave”
device. In SPI, only the Master generates the clock signal.
Figure 12.1 – SPI Master connected to an SPI slave device (in a peer-to-peer topology)
An SPI network can only contain one Master but multiple slaves. When data is sent from the master
to a slave, it’s sent on a data line called MOSI, for “Master Out / Slave In”. If the slave needs to
send a response back to the master, the master will continue to generate a prearranged number of
clock cycles, and the slave will put the data onto a third data line called MISO, for “Master In /
Slave Out”.
Figure 12.2 – Shift registers in the Master and the Slave. Bits move simultaneously from Master to Slave, and
Slave to Master
Where CPOL denotes the clock polarity, while CPHA denotes the clock phase. The clock
polarity indicates the leading signal of the clock that would indicate the start of a
communication, while the clock phase dictates the point in the clock cycle when the data
will be sampled from the data line.
SPI in ATmega328p
The ATmega328p controller offers SPI with the following features:
Full-duplex, Three-wire Synchronous Data Transfer
Master or Slave Operation
LSB First or MSB First Data Transfer
Seven Programmable Bit Rates
End of Transmission Interrupt Flag
The ATmega328p can be programmed to communicate using SPI by leveraging the
following three registers:
SPDR0 (Data Register)
SPDSR0 (Status Register)
SPCR0 (Control Registers)
The bits in the control register are summarized as follows (refer to figure 12.6):
SPIE0: To enable SPI interrupt
SPE0: To enable SPI and all relevant operations
DORD0 (Data Order): When set, the LSB of the data word is transmitted first. When
clear, the MSB of the data word is transmitted first.
MSTR0 (Master/Slave Select): This bit selects Master SPI mode when set and Slave
SPI mode when clear.
CPOL0: for clock polarity
CPHA0: for clock phase
SPR01 – SPR00: To control clock rate for MASTER mode only:
Please refer to the ATmega328P Datasheet or your lecture material for detailed working of
these registers for SPI before you proceed. These registers are referred to and used in the
sections that follow.
Introduction to 25AA128:
The Microchip Technology Inc. 25AA128 (25XX128* series) is a 128k-bit Serial
Electrically Erasable PROMs. The memory is accessed via a simple Serial Peripheral
Interface (SPI) compatible serial bus. The bus signals required are a clock input (SCK) plus
separate data in (SI) and data out (SO) lines. Access to the device is controlled through a
Chip Select (CS) input. Some of its features are:
Max. Clock 10 MHz
Principals of Operation
The 25AA128 operates at SPI Mode0. The leading edge of the clock is rising, and data is
sampled on the first rising edge of the SCK after slave select.
Read Sequence:
The device is selected by pulling CS low. The 8-bit READ instruction is transmitted to the
25XX128 followed by the 16-bit address, with two MSBs of the address being “don’t care”
bits. After the correct READ instruction and address are sent, the data stored in the memory
at the selected address is shifted out on the SO pin. The data stored in the memory at the next
address can be read sequentially by continuing to provide clock pulses. The internal Address
Pointer is automatically incremented to the next higher address after each byte of data is
shifted out.
Write Sequence:
Prior to any attempt to write data to the 25XX128, the write enable latch must be set by
issuing the WREN instruction. This is done by setting CS low and then clocking out the
proper instruction into the 25XX128. After all, eight bits of the instruction are transmitted,
the CS must be brought high to set the write enable latch. If the write operation is initiated
immediately after the WREN instruction without CS being brought high, the data will not be
written to the array because the write enable latch will not have been properly set.
Once the write enable latch is set, the user may proceed by setting the CS low, issuing a
WRITE instruction, followed by the 16-bit address, with two MSBs of the address being
“don’t care” bits, and then the data to be written. Up to 64 bytes of data can be sent to the
device before a write cycle is necessary. The only restriction is that all of the bytes must
reside in the same page.
MCP4821 DAC:
MCP4821 is a single channel 12-bit Digital-to-Analog converter (DAC) with internal voltage
reference. This device offers high accuracy and low power consumption, and is available in various
packages. Communication with the device is accomplished via a simple serial interface using SPI
protocols.
12-bit Resolution
Single Channel Voltage Output
2.7V to 5.5V Operation
Operating Current 330 µA (typ)
Internal Voltage Reference 2.048V
Selectable Unity or 2x Gain Output
works with SPI mode 0
(where 𝐺 is gain)
Fig 12.13: Sending data from AVR to MCP 4821 Data register
In Lab:
Task 1:
The given code contains functions to write bytes to SPI and writing to DAC. Your task is to
write code to send a sequence of numbers to the DAC to generate a saw-tooth wave. Use gain
=2x
Code:
Complete and build the given code.
#define MOSI 3
#define SCK 5
#define SS 2
void SPI_Init(void);
int main(void)
DDRC=0xFF;
SPI_Init();
while (1)
//PORTC = SPSR;
SPDR = ebyte;
//clear SS
//Set SS
PORTB |= (1<<SS);
//_delay_us(50);
void SPI_Init()
Simulation:
Task-2
Please configure the ATmega328 on proteus as connected to 25AAXXX EEPROM as shown
in figure 12.8. Also connect an oscillator and monitor the signals on SCK, MOSI and MISO.
Write a program that stores your complete first name at consecutive elements of main
memory starting from the address equal to 0x(128 + “your_roll_number”)
Your program should then, pick up your name, character, by character from the main
memory, and stores it on to the external EEPROM via SPI.
Document some instances of the oscillator output during write operation.
Lab Assessment
Pre Lab /1
In Lab /5
Data
Post Lab /4 /4
Presentation
Writing Style /4