Embedded Systems Lab 06
Embedded Systems Lab 06
LAB MANUAL
EMBEDDED SYSTEMS
(EE-354) For T.E.(EE)
Instructor name:
Student name:
Roll # Batch:
Semester: Year:
LAB MANUAL
For the course
EMBEDDED SYSTEMS
(EE-354) For T.E.(EE)
Developed by:
Mr. Hassan-ul-Haq, Mr. Hafiz Muhammad Furqan & Ms. Aiman
Spring, 2023
Approved By
____________________ ____________________
____________________ ___________________
____________________ ____________________
CONTENTS
Psychomotor: P3
CLO: Duplicate wiring connections for given circuit design while manipulating the embedded software with
C/Assembly IDE in order to change system behavior.
PLO: Lifelong Learning- PLO 12
10
11
12
LAB SESSION 01
OBJECTIVE:
To set-up the Code::Blocks IDE with AVR toolchain and test an AVR project on the ATmega328P
microcontroller
LAB OUTCOMES:
By the end of the lab, you would be able to:
1) Install the Code::Blocks IDE with an AVR toolchain using (WinAVR)
2) Create an AVR project with the required compiler settings
3) Test the created project on ATmega328P microcontroller using AVRDUDE
BACKGROUND:
The ATmega328P is an 8-bit microcontroller based on the AVR RISC architecture. It is produced by
Microchip Technology. The ATmega328P has 32 KB of flash memory, 2 KB of RAM, and 1 KB of
EEPROM. It has 23 general-purpose I/O pins, a 16-bit timer/counter, a 8-bit timer/counter, a real-time
clock, a pulse-width modulation (PWM) unit, a serial communication interface (USART), a two-wire
interface (TWI), and an analog-to-digital converter (ADC).
The ATmega328P is a popular microcontroller for a variety of projects, including robotics, home
automation, and wearables. It is also used in the Arduino Uno, Arduino Pro Mini, and Arduino Nano
microcontroller development boards. The ATmega328P is a powerful and versatile microcontroller that can
be used in a wide variety of applications. It is a popular choice for hobbyists and professionals alike.
We will be utilizing ATmega328P (Arduino UNO DIP R3) throughout Embedded Systems Lab work and
will program it in C-language. To program the microcontroller, we will use the following:
Avrdude is a command-line utility for programming AVR microcontrollers. It can be used to write
firmware to the microcontroller's flash memory, erase the flash memory, and read the contents of the
flash memory.
WinAVR is a software package that includes avrdude, as well as a compiler, assembler, and a number
of other tools for developing applications for AVR microcontrollers.
Code::Blocks is an integrated development environment (IDE) that can be used to develop applications
for AVR microcontrollers. It includes a graphical user interface for editing and compiling code, as well
as a debugger for stepping through and debugging code.
Avrdude and Winavr are essential tools for developing applications for AVR microcontrollers.
Code::Blocks is a powerful IDE that can make the development process easier.
LAB TASKS
The first two lab tasks guide you to installation of the required IDE and toolchain. The setup files can be
easily found and downloaded from the internet. However, these setup files are available on this shared
folder too.
1
Embedded Systems Lab Lab 01 Setting-up the Code::Blocks IDE with AVR Toolchain
NED University of Engineering & Technology Electrical Engineering Department
2
Embedded Systems Lab Lab 01 Setting-up the Code::Blocks IDE with AVR Toolchain
NED University of Engineering & Technology Electrical Engineering Department
3
Embedded Systems Lab Lab 01 Setting-up the Code::Blocks IDE with AVR Toolchain
NED University of Engineering & Technology Electrical Engineering Department
3) The Code::Blocks IDE is now ready and would allow you to create projects. Since our aim is to develop
AVR Projects, therefore, we first need to install AVR Toolchain. For this we will make use of WinAVR.
4) Search for WinAVR and go to https://sourceforge.net/projects/winavr/files/latest/download. Click on
Download. It will start downloading the latest WinAVR package.
5) Click on the downloaded file to start the setup wizard. Follow the steps shown in figures and select the
correct features to be installed. The WinAVR package has the required avrdude as well as GNU GCC
Compilers.
Figure 11: Source to Download WinAVR Figure 12: Run Dwonloaded Application File
Figure 15: Destination Folder Figure 16: Choose Components for Installation
4
Embedded Systems Lab Lab 01 Setting-up the Code::Blocks IDE with AVR Toolchain
NED University of Engineering & Technology Electrical Engineering Department
6) Before you create and start working on a project, verify that directories are correctly added to the system
path. To do this, open the command prompt by searching cmd in the Windows search option. In the
command prompt, simply write avrdude. You will see the message shown in Figure if it is correctly
added else you will see the error message shown in Figure.
5
Embedded Systems Lab Lab 01 Setting-up the Code::Blocks IDE with AVR Toolchain
NED University of Engineering & Technology Electrical Engineering Department
7) After this write path to verify that the required directories shown in the figure are added to the system
path.
1) Open the Code::Blocks. Go to File> Create >Project…. Select AVR Project and click Go. Select
Next.
2) At this step, you are asked to give project title and select folder to create project files. Give any
suitable name to your project for example here, we have called it Project1. A new folder ES Labs is
created on the desktop and is chosen as project folder. After this, click Next.
3) Now, make sure the selected compiler is GNU GCC for AVR and keep the remaining settings as
shown in the figure. Then click Next.
4) The processor we have selected for ES labs is ATmega328P. Select it from the dropdown menu
carefully and keep the rest of the settings as shown in the Figure. Then click Finish
5) You will see your created project Project1 folder created in the Projects tab workspace. Click on the
Project Name > Sources. This folder will show 2 files; main.c and fuse.c, double click on the main.c
file to open it. It is a blank file template created for the AVR project. This is where you will write a
code.
6
Embedded Systems Lab Lab 01 Setting-up the Code::Blocks IDE with AVR Toolchain
NED University of Engineering & Technology Electrical Engineering Department
7
Embedded Systems Lab Lab 01 Setting-up the Code::Blocks IDE with AVR Toolchain
NED University of Engineering & Technology Electrical Engineering Department
b) Compiler Settings:
Before we write instructions for our first test project, let’s first complete the required compiler settings
that will be needed for all AVR projects.
6) Now, go to Settings > Compiler.
8
Embedded Systems Lab Lab 01 Setting-up the Code::Blocks IDE with AVR Toolchain
NED University of Engineering & Technology Electrical Engineering Department
Figure 28: Specifying the Compiler and Installation Directory in Toolchain Executables
This will update a number of things for these settings. Verify each as shown in the following figures.
Figure 29: Specifying the Program Files in the Compiler’s Installation Directory
The Program Files and Additional Paths tabs under the Toolchain executables will be updated as
shown.
9
Embedded Systems Lab Lab 01 Setting-up the Code::Blocks IDE with AVR Toolchain
NED University of Engineering & Technology Electrical Engineering Department
Go to Search directories tab and check that C:WinAVR\avr\include is added in the Compiler tab.
10
Embedded Systems Lab Lab 01 Setting-up the Code::Blocks IDE with AVR Toolchain
NED University of Engineering & Technology Electrical Engineering Department
#include <avr/io.h>
#define BLINK_DELAY_MS 1000
#include <util/delay.h>
int main (void)
{
// Arduino digital pin 13 (pin 5 of PORTB) for output
DDRB |= 0B100000; // PORTB5
while(1) {
// turn LED on
PORTB |= 0B100000; // PORTB5
_delay_ms(BLINK_DELAY_MS);
// turn LED off
PORTB &= ~ 0B100000; // PORTB5
_delay_ms(BLINK_DELAY_MS);
}
}
11
Embedded Systems Lab Lab 01 Setting-up the Code::Blocks IDE with AVR Toolchain
NED University of Engineering & Technology Electrical Engineering Department
12
Embedded Systems Lab Lab 01 Setting-up the Code::Blocks IDE with AVR Toolchain
NED University of Engineering & Technology Electrical Engineering Department
There are 2 approaches to upload the generated code on ATmega328P flash memory. First we will
use AVRDUDE through Command Prompt instructions. Through this, you will be able to understand
the working of AVRDUDE for uploading the file to our microcontroller. Later, we will integrate this tool
to our Code::Blocks to eliminate the manual Command Prompt steps for our ease. Let’s begin the
interesting part of this lab.
a) Uploading code to ATmega328P microcontroller using AVRDUDE through Command
Prompt
13
Embedded Systems Lab Lab 01 Setting-up the Code::Blocks IDE with AVR Toolchain
NED University of Engineering & Technology Electrical Engineering Department
3) Now, type avrdude to verify that it is recognized (as has already been done). It display a list
of options available for usage with avrdude command. Read the description written with
each.
4) For now, we will use only the required ones and the details of which are given below. Note
that these are case sensitive.
Table 1: avrdude Usage Options and Description
Options Description Example as applicable to the test case
-p Part No. (To specify the AVR device) In our case, it is m328p (Atmega 328p)
-U Memory operation specification. In our case, flash is the memory type where
Required format is: we want to write the code saved in the
<memory type>:w:<file name> generated Project1.hex file
Where, w shows
read the specified file and write it to the
specified device memory
5) Based on the above, write (type, don’t copy-paste) the following command in the Command
Prompt.
avrdude –p m328p –P com3 –c arduino –U flash:w:Project1.hex
It will display some messages shown in Figure below. For successful upload of the hex file,
you will see the LED blinking at the specified rate.
Figure 40: Uploading the .hex File to ATmega328P through Command Prompt avrdude
b) Uploading code to ATmega328P microcontroller using Code::Blocks tool
14
Embedded Systems Lab Lab 01 Setting-up the Code::Blocks IDE with AVR Toolchain
NED University of Engineering & Technology Electrical Engineering Department
To avoid the time-consuming and intimidating Command Prompt interface, we will now add the
AVRDUDE tool to Code::Blocks. Follow the following steps:
1) In your Code:Blocks IDE, click on Tools > Configure Tools > Add. In the Edit Tool
window, set the Name, Executable, Parameters and Working Directory as shown in Figure.
To set the executable browse the specified path of WinAVR folder, and select avrdude.exe.
Note, that in the parameters option, we have written the same avrdude command used earlier.
The working directory is set to be the one containing the .hex file. Click OK and close the
Tools Window.
15
Embedded Systems Lab Lab 01 Setting-up the Code::Blocks IDE with AVR Toolchain
NED University of Engineering & Technology Electrical Engineering Department
4) Go to Tools> Configure Tools. Either Edit the previous tool or use Add to add another
one. This time set the Parameters and Working Directory in terms of macros replacing
project name and path. Click OK.
Congratulations! You have successfully created, built and tested your first AVR project on
ATmega328P using Code::Blocks with AVR Toolchain.
16
Embedded Systems Lab Lab 02 AVR Port Programming for Digital Input & Output
NED University of Engineering & Technology Electrical Engineering Department
LAB SESSION 02
OBJECTIVE:
To program the AVR ATmega328P I/O (Input/Output) ports for digital input and output
LAB OUTCOMES:
By the end of the lab, you would be able to:
1) Identify the AVR ATmega328P I/O ports
2) Utilize DDR (Direct Data Registers) for setting direction of ports
3) Take digital input and set digital output through I/O ports
4) Build required logics for digital inputs and outputs in pure C-language codes and test them on
ATmega328P microcontroller
5) Utilize logical operations for bit-wise manipulation of ports
BACKGROUND:
ATmega328P Pin Diagram and I/O Ports
Figure 1 shows ATmega328P pin diagram. Here, we can see total 28 pins (14 at each side). Throughout the
labs, we will be exploring functions of these pins and their utilization. Most port pins are multiplexed with
alternate functions for the peripheral features on the device i.e. they have dual roles. Note that enabling the
alternate function of some of the port pins does not affect the use of the other pins in the port as general
digital I/O. However, in this lab, we will focus on the pins that can be utilized for digital input and
output i.e. simple I/O function, so don’t get intimidated by the pin diagram shown in Figure 1.
17
Embedded Systems Lab Lab 02 AVR Port Programming for Digital Input & Output
NED University of Engineering & Technology Electrical Engineering Department
Figure 2: Pins on the ATmega328P with the corresponding locations on the Arduino Uno board.
18
Embedded Systems Lab Lab 02 AVR Port Programming for Digital Input & Output
NED University of Engineering & Technology Electrical Engineering Department
19
Embedded Systems Lab Lab 02 AVR Port Programming for Digital Input & Output
NED University of Engineering & Technology Electrical Engineering Department
Header files:
The #include is a preprocessor directive that instructs the compiler to find the file in the < > brackets and
tack it on at the head of the file you are about to compile. The io.h provides appropriate I/O definitions for
the device we are using, and the delay.h provides the definitions for the delay function.
Statements control the program flow and consist of keywords, expressions, and other statements. A
semicolon ends a statement.
main ( ): All C programs contain the main( ) function that contains the code and is first run when the
program begins. main (void) means the function doesn’t take any input. ‘int main’ means that the function
needs to return some integer at the end of the execution and we do so by returning 0 at the end of the
program.
While Loop: It is a control flow statement that allows code to be executed repeatedly based on a given
Boolean condition. The while loop can be thought of as a repeating if statement. The while(1) will run the
loop forever because ‘1’ is the definition of true (false is defined as 0).
Data Types: A good understanding of C data types for the AVR can help programmers to create smaller
hex files. In declaring variables, we must pay careful attention to the size of the data type and data range,
refer to the Table 1.
Remember that C compilers use the signed char as the default unless we put the keyword unsigned in front
of the char. In many situations, such as setting a counter value, where there is no need for signed data, we
should use the unsigned char instead of the signed char. Using the int instead of the unsigned char leads to
the need for more memory space.
21
Embedded Systems Lab Lab 02 AVR Port Programming for Digital Input & Output
NED University of Engineering & Technology Electrical Engineering Department
22
Embedded Systems Lab Lab 02 AVR Port Programming for Digital Input & Output
NED University of Engineering & Technology Electrical Engineering Department
Similarly, the OR operation of a bit with 1, results in setting the bit high. However, OR operation with 0
leaves the bit unchanged.
Table 2: Bit-wise Logical Operators in C
To invert all bits, the bit-wise NOT (~) operator can be used.
PORTD = ~PORTD;
Example 3 – Using logical operators for bit-wise I/O from ATmega328P ports
The following examples get the status of bit 3 of Port D and send it to the bit 0 of port D continuously.
24
Embedded Systems Lab Lab 02 AVR Port Programming for Digital Input & Output
NED University of Engineering & Technology Electrical Engineering Department
Example 4 – Using compound assignment operators for bit-wise I/O from ATmega328P ports
The Example 3 is re-written using the compound bit-wise operators. Observe the difference. Note that the
compound assignment operators ‘|=’ don’t have a space ‘| =’ in between.
LAB TASKS
From Task 2 to 5, create AVR projects and test them on ATmega328P. Feel free to use different conditional
statements, loops, switch-case structure to complete the C-programming related tasks.
TASK 1: Explain what makes the Blinky.c blink?
The code we tested in Lab 01 is given below. Explain what makes this Blinky.c blink?
25
Embedded Systems Lab Lab 02 AVR Port Programming for Digital Input & Output
NED University of Engineering & Technology Electrical Engineering Department
TASK 2: To check and indicate the status of a sensor using the specified ports and bits of
ATmega328P
A door sensor (here, assume the switch) is connected to pin 1 of Port B, and an LED is connected to pin 5
of Port C. Write an AVR C program to monitor the door sensor and, when it opens, turn on the LED.
TASK 3: To use the general I/O pins of ATmega328P as input or output pin based on the
given condition
Write an AVR C program to monitor bit 7 of Port B. If it is 1, make bit 4 of Port B input; otherwise, change
pin 4 of Port B to output.
TASK 4: To control the specified pins of a given port without disturbing the rest of the pins
Write an AVR C program to control a set of 8 LEDs connected to port D such that the first 4 LED glow
when input from a switch is high, and remain off when the input from switch is low. The remaining 4 LED
toggle continuously without disturbing the rest of the pins of port D.
TASK 5: To control the output based on combination of 2 input pins
Write an AVR C program to read pins 0 and 1 of Port B and update the LEDs at pin 0, 1 & 2 of Port D
according to the following logic. You can use switch-case structure.
Input Port B [1:0] Status Output Port D [2:0] Status
0b 00 0b 000
0b 01 0b 011
0b 10 0b 101
0b 11 0b 111
26
Embedded Systems Lab Lab 03 ADC Programming of AVR
NED University of Engineering & Technology Electrical Engineering Department
LAB SESSION 03
OBJECTIVE:
To program the ATmega328P for reading analog input through its Analog-to-Digital Converter ADC
module
LAB OUTCOMES:
By the end of the lab, you would be able to:
1) Identify the AVR ATmega328P pins associated with the ADC module
2) Identify the purpose of different bits of ADC registers and utilize them for their set purposes like
setting reference voltage, selecting source of analog input, and indicating start / end of conversion
3) Take analog input through the ADC pins and indicate its digital equivalent
4) Build required logics for reading analog input in pure C-language codes and test them on
ATmega328P microcontroller
5) Verify the analog to digital conversion ADC of microcontroller pins by testing the digital output
through external DAC (digital-to-analog) R-2R circuit / DAC0808 IC
BACKGROUND:
Digital computers use binary (discrete) values, but in the physical world the signals are analog (continuous).
Most physical variables are analog in nature and can take on any value within a continuous range of values.
Temperature, pressure, humidity, and velocity are a few examples of physical quantities that we deal with
every day. For acquisition of analog signals, we need Analog-to-Digital (ADC) module for conversion.
Microcontrollers are therefore generally featured with ADC module. In this lab, we will explore
ATmega328P ADC input channels that enable us to capture analog signals.
Basics of Analog-to-Digital Conversion (ADC)
An analog-to-digital converter takes an analog input voltage and after a certain amount of time produces a
digital output code which represents the analog input. ADC involves the following steps:
● Sampling: Sampling is the processes of converting
continuous- time analog signal into a discrete-time
signal by taking the “samples” at discrete-time
intervals. Sampling analog signals makes them
discrete in time but still continuous valued.
Sampling frequency determines the intervals at
which samples are taken. Nyquist criterion requires
that the sampling frequency be at least twice the
highest frequency contained in the signal.
● Quantization: Quantization is the process of
mapping continuous infinite values to a smaller set
of discrete finite values. The quantization step size
is the smallest possible difference in amplitude
between samples.
● Encoding: After quantization, each quantization
Figure 1: Analog-to-Digital Conversion
level is assigned a unique binary code.
27
Embedded Systems Lab Lab 03 ADC Programming of AVR
NED University of Engineering & Technology Electrical Engineering Department
𝑉𝑖𝑛
𝐷𝑜𝑢𝑡 =
𝑆𝑡𝑒𝑝 − 𝑠𝑖𝑧𝑒 Figure 2: 8-bit ADC Representation
28
Embedded Systems Lab Lab 03 ADC Programming of AVR
NED University of Engineering & Technology Electrical Engineering Department
29
Embedded Systems Lab Lab 03 ADC Programming of AVR
NED University of Engineering & Technology Electrical Engineering Department
The name of register is written in capital letters. Each register is 8-bit wide. Indexing is done to show
different bits, for example XYZ [2:0] means the least significant 3 bits of the register XYZ (XYZ2, XYZ1
& XYZ0). XYZ[2:0] = 5 would mean (XYZ2 =1, XYZ1= 0 and XYZ0 =1 since 5 = 0b101).
1) ADC Data Register Low and High Byte
After the A/D conversion is complete, the result is stored in registers ADCL (A/D Result Low Byte) and
ACDH (A/D Result High Byte). For 10-bit ADC result, the eight bits sit in one 8-bit register and the
remaining two bits are provided in the other register, with six bits being unused. The result can be left or
right adjusted as shown below. If only eight bits of resolution are needed, the ADC value is left-justified
and the high-order byte are read through ADCH.
● Reference Selector Bits (REFS [1:0]) The ADMUX [7:6] bits select the voltage reference for the
ADC.
Table 3: Function of the reference selector bits
ADMUX[7:6] Reference High
Description
= REFS[1:0] Voltage Selection
00 AREF Voltage provided at AREF pin externally (Internal Vref turned OFF)
AVCC with external capacitor at AREF pin. Note: Arduino already has
01 AVCC
capacitor placed on line
Internal 1.1 V reference fixed regardless of VCC. Note: Arduino already
11 Internal 1.1V
has capacitor placed on line
30
Embedded Systems Lab Lab 03 ADC Programming of AVR
NED University of Engineering & Technology Electrical Engineering Department
● Analog Channel Selection (MUX[3:0]) The 4 bits ADMUX[3:0] serve as selector for the
multiplexer that selects one of the 6 analog input channels to be connected to ADC.
Table 5: Input Channel Selection for ADC
MUX [3:0] Input Channel
0000 ADC0
0001 ADC1
0010 ADC2
0011 ADC3
0100 ADC4
0101 ADC5
1000 Temperature Measurement
Interesting Fact: The Atmega328P has an internal temperature sensor. Refer to the datasheet and read
about it. The output of the temperature sensor can be selected as one of the inputs for ADC module as
shown in the description of ADMUX Channel Selection bits.
3) ADCSRA (ADC Control and Status Register A)
31
Embedded Systems Lab Lab 03 ADC Programming of AVR
NED University of Engineering & Technology Electrical Engineering Department
5) ADCSRB
This is not needed for now. It has 2 important fields: (ACME-Analog Comparator Multiplexer Enable
and ADTS[2:0]- Auto Trigger Source Selection).
NOTE: The ADC has two different operating modes. In single conversion mode, each conversion will
be initiated by the user. In free running mode, the ADC is constantly sampling and updating the ADC
Data Registers. When a conversion is complete, the result is written to the ADC data registers, and ADIF
is set. In single conversion mode, ADSC is cleared simultaneously. The software may then set ADSC
again to start a new conversion. In free running mode, a new conversion will be started immediately after
32
Embedded Systems Lab Lab 03 ADC Programming of AVR
NED University of Engineering & Technology Electrical Engineering Department
the conversion completes while ADSC remains high. For further description, refer to the ATmega328P
datasheet section Analog to Digital Converter.
Example # 1: Reading an Analog Voltage Set by a Potentiometer
In this example, we are taking analog input through a potentiometer. The analog input voltage can vary
from 0 to 5V. This is given at ADC0 input channel. The digital 8-bit output is taken through PORTD pins
by reading the ADCH register. An LED is used to indicate each bit of the digital output. For a reference
voltage of 5V, using 8-bit ADC, each level corresponds to 19.53 mV.
Figure 6: Code for Example 1- Reading Analog Input from ADC0 Channel
33
Embedded Systems Lab Lab 03 ADC Programming of AVR
NED University of Engineering & Technology Electrical Engineering Department
LAB TASKS
TASK 1: To test the Example 1 on ATmega328P and verify working of ADC using an
external D/A Converter
1. Create a new AVR project and build the code given in the Example 1. Test the obtained digital output
by varying the output from potentiometer. Observe the on / off status of LEDs (used as indicators for
digital output) and verify the digital voltage by calculation for 8-bit ADC at given reference voltage.
Note that the ATmega328P has an ADC module but not a built-in DAC module so it cannot provide an
analog output through any of its pins.
2. Now, remove the LEDs and provide the 8-bit digital output to an external DAC circuit i.e., convert
the digital output to analog for verification. You can use a simple R-2R circuit of Figure 8 or use
DAC0808 IC. For DAC0808 IC, refer to its datasheet for more information. The pin diagram and
DAC circuit using this is shown in Figure 9 and 10.
3. Measure the analog input given through potentiometer and the analog output reproduced by the DAC.
Compare both and verify the ADC and DAC. This is shown in Figure 11 using R-2R circuit.
34
Embedded Systems Lab Lab 03 ADC Programming of AVR
NED University of Engineering & Technology Electrical Engineering Department
Note: Pay attention to the data type of variables when you calculate the input analog voltage using
the step-size and ADC result.
35
Embedded Systems Lab Lab 04 Serial Port Programming of AVR
NED University of Engineering & Technology Electrical Engineering Department
LAB SESSION 04
OBJECTIVE:
To utilize the USART (Universal Synchronous / Asynchronous Receiver /Transmitter) of ATmega328P for
transmitting and receiving data though asynchronous serial communication with PC
LAB OUTCOMES:
By the end of this lab, you should be able to:
1) Recognize the basics of serial communication protocol; baud-rate, stop bit, data bits, parity etc. and
the importance of required connectors (RS-232)
2) Identify the AVR ATmega328P pins associated with the USART
3) Identify the purpose of different fields of USART registers
4) Program ATmega328P for initializing the USART with given baud-rate
5) Program ATmega328P in C-language to establish serial communication with PC
6) Test and verify data (character, string, integer and float) transmission and reception for given
conditions using a Serial Terminal Emulator like TeraTerm
“The single biggest problem in communication is the illusion that it has taken place.”
– George Bernard Shaw
BACKGROUND:
Microcontrollers are provided with ability to communicate with external devices like computer, other
micro-controllers and peripherals. This communication is done through different protocols to allow
microcontrollers to send and receive data. ATmega328P is provided with USART (Universal
Synchronous/Asynchronous Transmitter/Receiver). In this lab, we will be exploring Asynchronous
Transmitter and Receiver (UART). It is not only used as a communications link to external device but
also as a debugging port to send status messages. This is one of the 3 communication options that can be
established with ATmga328P. The other two are SPI and I2C which will be explored later. Before
discussing the working of relevant pins and registers, we first need to understand the different types and
basics of communication protocols.
36
Embedded Systems Lab Lab 04 Serial Port Programming of AVR
NED University of Engineering & Technology Electrical Engineering Department
Figure 3: Framing ASCII ‘A’ (41H) with a stop-bit (1) and a start bit (0)
37
Embedded Systems Lab Lab 04 Serial Port Programming of AVR
NED University of Engineering & Technology Electrical Engineering Department
Parity Bit: UART chips allow programming of the parity bit for odd-, even-, and no-parity options. It is a
single bit added to the data frame to maintain data integrity.
Figure 4: Connection of ATmega328P RXD and TXD pins with Arduino UNO for UART
Figure 5: Placement of RX and TX pins and corresponding LEDs with ATmega328P and ATmega16 on
Arduino UNO board
To establish communication between microcontroller (USART pins) with PC, the PC must have a
communication port to support serial data transfer. These are called COM ports. A COM port is simply an
I/O interface that enables the connection of a serial device to a computer. COM ports are also referred to as
serial ports. They are asynchronous interfaces that can transmit one bit of data at a time when connected to
a serial device.
38
Embedded Systems Lab Lab 04 Serial Port Programming of AVR
NED University of Engineering & Technology Electrical Engineering Department
data transmission. In the absence of a COM port, a COM-to-USB converter module is needed. You can
read more about it here.
Luckily, the Atmega16U2 incorporated on the UNO (R3) board acts as a USB-to-serial converter for serial
communication using USB com drivers. On PC, a software applications is used with it to send data to or
display the received data from the board.
39
Embedded Systems Lab Lab 04 Serial Port Programming of AVR
NED University of Engineering & Technology Electrical Engineering Department
40
Embedded Systems Lab Lab 04 Serial Port Programming of AVR
NED University of Engineering & Technology Electrical Engineering Department
UBRR[15:12] The 4 bits, reserved, are set to 0. The remaining 12 bits UBRR[11:0] contain the USART0
baud rate (pre-scalar). The UBRR0H contains the four most significant bits, and the UBRR0L contains the
eight least significant bits of the USART0 baud rate.
For required baud rate ‘BAUD’, and oscillator frequency fosc, the value for UBRR0 is calculated by;
𝑓𝑂𝑆𝐶
𝑈𝐵𝑅𝑅0 = −1
16 × 𝐵𝐴𝑈𝐷
For a 16MHz clock, the required values of UBRR0 register are given in the Table below for different baud-
rates. Note: U2X0 is set 0 here. The baud-rates can be doubled by setting U2X0 high for same UBRR0
values. The formula can be applied for verification.
Table 1: UBRR0 Values for Different Baud Rates
Baud Rate (bps) UBRR0
2400 416 = 0x01A0
4800 207 = 0x00CF
9600 103= 0x0067
14400 68 = 0x0044
19200 51 =0x0033
Serial Terminal Emulator – TeraTerm
COM Port (communication port) is the original, yet still common, name of the serial port interface on PC-
compatible computers. It can refer not only to physical ports, but also to emulated ports.
Serial terminal emulators are software applications that replicate physical COM ports. The virtual serial
ports are fully compatible with operating systems and applications and are treated in the same way as a real
port. These are used for the serial communication between the host computer and an embedded system
41
Embedded Systems Lab Lab 04 Serial Port Programming of AVR
NED University of Engineering & Technology Electrical Engineering Department
(Target). It is mainly used as a user interface for debugging embedded system. It is also used for sending
commands, displaying result, loading firmware, logging result, etc.
Tera Term and PuTTY are famous terminal emulator applications. In this lab, we can use Tera Term. It is
an open-source, free, software implemented terminal emulator (communications) program.
1) Download Tera-Term using: https://filehippo.com/download_tera-term/
2) Type Tera Term in Windows search to open it. You will be able to select Serial once you connect
your device to PC USB port (connect Arduino UNO). The Serial and Port options will be enabled.
42
Embedded Systems Lab Lab 04 Serial Port Programming of AVR
NED University of Engineering & Technology Electrical Engineering Department
The initialization process consists of the following steps. Relevant Register Values (example) & C-Code
To program the USART as Transmitter, follow the steps: Relevant Register Values or C-Code
To program the USART as Receiver, follow the steps: Relevant Register Values or C-Code
EXAMPLES
The tested asynchronous communication is polling based and not interrupt based.
Example # 1: Transmitting a Character from ATmega328P to PC through UART
The following code transmits ‘A’ repeatedly with a delay of 1 sec. Note that only one character is sent at a
time. The following example uses usart_init( ) and usart_putChar( ) from the listed 3 sub-routines therefore,
these sub-routines must be defined in the main.c file.
44
Embedded Systems Lab Lab 04 Serial Port Programming of AVR
NED University of Engineering & Technology Electrical Engineering Department
The example code given here shows transmission of strings, float and integers by utilizing the subroutines
and functions discussed above. You can observe that a string is received from PC to AVR too.
45
Embedded Systems Lab Lab 04 Serial Port Programming of AVR
NED University of Engineering & Technology Electrical Engineering Department
Figure 11: Code for Example 2-Transmitting Strings, Float and Integer Data Types
Header File usart.h
For ease, you can include the header and source files (usart.h and usart.c) provided with the manual. Utilize
its simple functions for transmitting and receiving data or use the sub-routines discussed above in your code
to complete the given lab tasks.
LAB TASKS
TASK 1: To test Example 1 for transmitting a character serially at baud-rate of 9600 with 1
stop bit using ATmega328P USART
Test the Example 1 code using Arduino UNO. After building the given code, program the ATmega328P.
Now, disconnect and reconnect Arduino UNO with PC port. Open Serial Terminal Emulator (Tera Term).
Make connection with the required settings and observe the serial terminal. You should see the data
transmitted by AVR (received by the PC) on serial terminal.
Is there any impact if you select a different baud rate in Tera Term without changing the baud rate
initialized in the ATmega328P code? Are you able to correctly transmit the characters when
microcontroller and PC work at different baud rate?
________________________________________
Add two more lines to the code and comment on the result.
usart_putChar(65)
usart_putChar(‘65’)
46
Embedded Systems Lab Lab 04 Serial Port Programming of AVR
NED University of Engineering & Technology Electrical Engineering Department
TASK 2: To program ATmega328P for controlling the status of LED based on the received
character
Modify the previous code to make the microcontroller receive a character sent by PC. If the received
character is ‘A’, turn on the on board LED otherwise turn it off. The data should be received at baud-rate
of 14400 with 1 stop bit.
TASK 3: To transmit the analog voltage across a potentiometer read by the ATmega328P
ADC to PC
Extend the Task 2 of Lab 03 where you used ADC module to measure the voltage across potentiometer.
Send (transmit) the following through USART of the microcontroller to the PC serial terminal.
1) The 10-bit ADC output (in range of 0 to 1023)
2) The analog voltage across potentiometer in Volts
Pay attention to the data-type. You may use any suitable baud rate of your choice.
Vary the voltage and observe the values. Verify the analog voltage reading by ADC module and
transmission through the USART by comparing voltmeter reading and values displayed by Tera Term.
Sample Output:
**********10-bit ADC************
**********5V Reference Voltage****
*****Voltage across Potentiometer***
47
Embedded Systems Lab Lab 05 LCD Interfacing
NED University of Engineering & Technology Electrical Engineering Department
LAB SESSION 05
OBJECTIVE:
To interface an LCD (Liquid Crystal Display) screen with ATmega328P by sending required commands
and data
LAB OUTCOMES:
By the end of this lab, you would be able to:
1) Identify the pins and commands for controlling a 16x2 LCD
2) Interface a 16x2 LCD screen with ATmega328P and display different messages
“I don't care what it is, when it has an LCD screen, it makes it better.” — Kevin Rose
INTRODUCTION:
Display units like LEDs, 7-segment LED displays, LCD screens etc. play an important part in establishing
a good communication between the users and machines, and therefore, are vital for embedded systems.
Through display screens, the user gets a feeling of knowing the system’s working status. Consider the
examples of ATM machine, automatic washing machine or microwave ovens. They allow us to give input
through keypad or knobs or touch screens, and display useful messages on screens which guide us or show
the status of process. LCD screens are now seen everywhere due to their declining prices, ease of
programming due to an internal controller, and ability to display characters and graphics.
For learning purpose, we are interfacing our ATmega32P microcontroller with a standard 16x2 LCD screen.
16×2 LCD is named so because; it has 16 Columns and 2 Rows. Such dot-matrix LCDs are available in
different packages like 8x1, 8x2, 16x1, and 20x4.
48
Embedded Systems Lab Lab 05 LCD Interfacing
NED University of Engineering & Technology Electrical Engineering Department
LCD Pinout
Figure 1 shows the 16 pins of a 16x2 LCD and their names. Most of the LCDs have these 16 pins that are
used for connection according to their functionality. Let’s discuss the function of each pin one-by-one.
49
Embedded Systems Lab Lab 05 LCD Interfacing
NED University of Engineering & Technology Electrical Engineering Department
In this lab, we are interfacing the LCD with ATmega328P directly (parallel interface) and sending data
in 8-bit mode. Note that the 8-bit data interfacing is easier to program but uses 4 more pins.
LCD Commands
The following table hex code for the commands that are sent to LCD instruction register for the specified
functions.
Table 1: Hex code for Commands
Hex Code for
Function
Command to LCD
0E Display on, cursor on
01 Clear display screen
02 Return home
04 Decrement cursor (shift cursor to left
06 Increment cursor (shift cursor to right)
05 Shift display right
07 Shift display left
0F Display on, cursor blinking
80 Force cursor to beginning of first line
C0 Force cursor to beginning of 2nd line
38 Function Set: 2 lines and 5 × 8 matrix (D0–D7, 8-bit mode)
08 Display off, cursor off
18 Shift the entire display to the left
1C Shift the entire display to the right
Interfacing LCD with ATmega328P and C-Programming
The Figure 2 shows required connections for LCD 16 pins with ATmega328P in 8-bit data mode. The
R/W pin can be directly connected to ground instead of utilizing an I/O pin (as we are performing write
operation only).
50
Embedded Systems Lab Lab 05 LCD Interfacing
NED University of Engineering & Technology Electrical Engineering Department
For controlling the LCD and sending commands and data, the following steps are needed. Remember, the
digital I/O pins connected with the LCD must be configured as output pins using DDRx registers as per
your connections.
To initialize the LCD for 2-line and 8-bit operation, the following sequence of commands should be sent
to the LCD. Next we will show how to send a command to the LCD. After power-up you should wait
about 15ms before sending initializing commands to the LCD. If the LCD initializer function is not the
first function in your code you can omit this delay.
4) lcd_print: This takes a complete string to be printed and passes one character at a time by lcdData.
52
Embedded Systems Lab Lab 05 LCD Interfacing
NED University of Engineering & Technology Electrical Engineering Department
Figure 4: Sample Code for Example 1 - LCD Interfacing (8-bit Mode) with ATmega328P
LAB TASKS
TASK 1: To test Example 1 using ATmega328P and 16x2 LCD
Program ATmega328P with the given code. Make connections to interface the LCD and test the results.
TASK 2: To test different commands for modifying LCD display
Modify the code and test different commands to make the display interesting.
On line 1, display: <Your Name> (You can have more than 16 characters in the string).
On line 2, display: <Roll # …… >
Make the text moving (scrolling) continuously from left to right by using shift display commands.
53
Embedded Systems Lab Lab 05 LCD Interfacing
NED University of Engineering & Technology Electrical Engineering Department
Go-to Subroutine
Following is an interesting subroutine that allows you to move cursor at any specified location (y, x).
Where x is the line number (1 or 2) and y is character position (1 to 16).
54
Embedded Systems Lab Lab 06 SPI Protocol and Max6675 Interfacing
NED University of Engineering & Technology Electrical Engineering Department
LAB SESSION 06
OBJECTIVE:
To utilize SPI (Serial Peripheral Interface) protocol for interfacing the max6675 module with ATmega328P
and develop temperature measurement system based on the K-type thermocouple
LAB OUTCOMES:
By the end of this lab, you will be able to:
1) Recognize the difference between synchronous and asynchronous transmission
2) Identify the AVR ATmega328P pins associated with SPI communication
3) Identify the purpose of different fields of SPI registers
4) Program ATmega328P for SPI communication in master and slave modes for single-byte and
multiple-byte burst read/write
5) Interface SPI protocol-based module (Max6675) as slave with ATmega328P in master mode
6) Develop the complete system for temperature measurement and transmit result through USART to
PC
INTRODUCTION:
In Lab 04, we discussed briefly about serial and parallel data transmission. USART was utilized for
asynchronous transmission and reception, which is one of the types of serial communication. In this lab,
we will explore Serial Peripheral Interface communication protocol which is synchronous. The SPI (serial
peripheral interface) is a bus interface connection incorporated into many devices. The SPI bus was
originally started by Motorola Corp. (now Freescale), but in recent years has become a widely used standard
adapted by many semiconductor chip companies as it’s faster, compact and results in reduced power
consumption. Let’s first understand the features of Serial Peripheral Protocol.
Serial Peripheral Interface Bus Protocol
SPI has a Master/Slave configuration. It has only one master device but can have multiple slaves. A master,
that initiates communication, is usually a microcontroller and the slaves can be a microcontroller, sensors,
ADC, DAC, LCD etc.
SPI is 4-wire protocol.
SPI devices use only 2 pins for data transfer that are; SDI and SDO,
also called MISO (Master-In Slave-Out) and MOSI (Master-Out
Slave-In).
The SPI bus has the SCLK or SCK (shift clock) pin to synchronize the
data transfer between two chips.
The last pin is CE chip enable, also called SS Slave Select, which is
used to initiate and terminate the data transfer. It determines which
Figure 1: 4-wire SPI Bus
device the master is currently communicating with. Representation
55
Embedded Systems Lab Lab 06 SPI Protocol and Max6675 Interfacing
NED University of Engineering & Technology Electrical Engineering Department
Working of SPI
The system consists of two 8-bit wide shift registers, and a master clock generator. The SPI master initiates
the communication cycle when pulling low the slave select ̅̅̅ 𝑆𝑆. Master and slave prepare the data to be sent
in their respective shift registers, and the master generates the required clock pulses on the SCK line to
interchange data (one-bit at a time in each clock cycle). In SPI, the shift registers are 8 bits long. It means
that after 8 clock pulses, the contents of the two shift registers are interchanged. Data is always shifted from
master to slave on the MOSI, line, and from slave to master on the master MISO, line. After each data
packet, the master will synchronize the Slave by pulling high the slave select, ̅̅̅𝑆𝑆 line. It must be noted that
SPI is full duplex, meaning that it sends and receives data at the same time.
Figure 4: Pin Configuration of ATmega328P for SPI Interface and Associated Arduino UNO
pinout
Master-In MISO For sending data from Slave devices to Master device. Input – For Master
Slave-Out Output – For Slave
Master-Out MOSI For sending data from Master device to Slave devices. Input – For Slave
Slave-In Output – For Master
Serial SCK For clock pulses to synchronize data transmission from Input – For Slave
Clock Master devices. Output – For Master
57
Embedded Systems Lab Lab 06 SPI Protocol and Max6675 Interfacing
NED University of Engineering & Technology Electrical Engineering Department
The SPI Data Register is a read/write register. To write into SPI shift register, data must be written to SPDR.
To read from the SPI shift register, you should read from SPDR. Writing to the SPDR register initiates data
transmission.
58
Embedded Systems Lab Lab 06 SPI Protocol and Max6675 Interfacing
NED University of Engineering & Technology Electrical Engineering Department
59
Embedded Systems Lab Lab 06 SPI Protocol and Max6675 Interfacing
NED University of Engineering & Technology Electrical Engineering Department
codes or subroutines are given here as sample for reference. In this lab, we will be operating our
microcontroller in the master mode only.
60
Embedded Systems Lab Lab 06 SPI Protocol and Max6675 Interfacing
NED University of Engineering & Technology Electrical Engineering Department
3) Wait till transmission is complete i.e., poll SPIF flag to become high.
4) Make SS high to deselect slave.
61
Embedded Systems Lab Lab 06 SPI Protocol and Max6675 Interfacing
NED University of Engineering & Technology Electrical Engineering Department
junction diode measurement with the amplified thermocouple voltage and reads out the 12-bit result onto
the SO pin. A sequence of all zeros means the thermocouple reading is 0°C. A sequence of all ones means
the thermocouple reading is +1023.75°C.
63
Embedded Systems Lab Lab 06 SPI Protocol and Max6675 Interfacing
NED University of Engineering & Technology Electrical Engineering Department
64
Embedded Systems Lab Lab 06 SPI Protocol and Max6675 Interfacing
NED University of Engineering & Technology Electrical Engineering Department
65