Lab No 2 ES
Lab No 2 ES
Reg No B20F0169EE08
Department Electrical and Computer Engineering
Lab Engr Sir Rafi-ullah
Course Title Introduction to Embedded System Lab
LAB NO:2
Introduction to AVR Microcontroller & Assembly Language
OBJECTIVE:
The main objective of this lab is :
Tools/Equipment Used:
• Arduino IDE
• Atmel studio 7.0
• Arduino Board
• Oscilloscope
INTRODUCTION:
The AVR is a modified Harvard architecture machine, where program and data are stored in
separate physical memory systems that appear in different address spaces, but having the
ability to read data items from program memory using special instructions.
AVR Atmega32 is a 40 pin integrated chip in which 32 pins are input/output pins in the form
of four ports; PORTA, PORTB, PORTC & PORTD and other are voltage supply, ground, analog
reference, crystal & reset pins.
TASK NO:1
a) Compile the given file (lab.ino) and upload the code to the Arduino Uno board
available in the lab. Show the output on an oscilloscope by connecting any pin of
port b to the probe of oscilloscope. Note down the time period and frequency of the
generated signal. Understand the code and calculate the time period and frequency.
Square Wave Generation:
Initially, we wrote the assembly code for the generation of square wave in which , portB is
declared as output. Firstly we set all the bits of portB high i.e. 0xFF ,then after 1’s
complement the value of portB becomes low i.e. 0x00(the value of portB keeps on
toggling).In this way square wave is generated .
For checking the frequency of square wave on oscilloscope, we connect probe to any pin of
PORTB and connect ground pin to ground pin of Arduino.
Calculation:
𝑓𝑟𝑒𝑞𝑜𝑓𝑥𝑡𝑟𝑎𝑙 = 16𝑀𝐻𝑧
𝑛𝑜𝑜𝑓𝑐𝑦𝑐𝑙𝑒𝑠 = 10
Total frequency generated by square wave is
𝑓𝑟𝑒𝑞𝑜𝑓𝑥𝑡𝑟𝑎𝑙
𝑡𝑜𝑡𝑎𝑙𝑓𝑟𝑒𝑞 =
𝑛𝑜𝑜𝑓𝑐𝑦𝑐𝑙𝑒𝑠
16𝑀
𝑡𝑜𝑡𝑎𝑙𝑓𝑟𝑒𝑞 =
10
𝒕𝒐𝒕𝒂𝒍𝒇𝒓𝒆𝒒 = 𝟏. 𝟔𝑴𝒉𝒛
CODE:
#include "avr/io.h"
;------------------------
.global mysetup
.global myloop
;------------------------
mysetup:
LDI R16,0xFF
OUT DDRB,R16
.org 0x200
COM R16
JMP L1
void myloop();
void setup() {
mysetup();} void
loop() {
myloop();} OUTPUT:
Frequency generated by assembly code is 1.6MHz which is greater than the build in function
of Arduino.
b)You are provided another Arduino project file (lab00.ino). Compile this file as well and
upload the code to the Arduino Uno board. Compare the output with a) and give your
comments.
CODE:
void setup() {
// put your setup code here, to run once:
pinMode(12, OUTPUT);
}
void loop() {
// put your main code here, to run repeatedly: digitalWrite(12,
HIGH);
// turn the LED on (HIGH is the voltage level) digitalWrite(12,
LOW); // turn the LED off by making the voltage LOW
}
#define __SFR_OFFSET 0x00
#include "avr/io.h"
;------------------------
.global mysetup
.global myloop
;------------------------
mysetup:
LDI R16,0xFF
OUT DDRB,R16
RET ;return to setup() function
;---------------------------------------------------------------------------
myloop:
.org 0x200
L1: OUT PORTB,R16
COM R16
JMP L1
RET ;return to loop() function
Circuit Diagram:
OUTPUT:
c) What is the maximum frequency of square wave (50% duty cycle) you can generate using
i) assembly code ii) Arduino Programming language?
CODE:
#define __SFR_OFFSET 0x00
#include "avr/io.h"
;------------------------
.global mysetup
.global myloop
;------------------------
mysetup:
LDI R16,0xFF
OUT DDRB,R16
RET ;return to setup() function
myloop:
.org 0x200
L1: OUT PORTB,R16
COM R16
RJMP L1
RET ;return to loop() function
extern "C"
{
void mysetup();
void myloop();
}
void setup() {
// put your setup code here, to run once: mysetup();
}
void loop() {
// put your main code here, to run repeatedly: myloop();
}
Circuit Diagram:
OUTPUT:
For the maximum generation of frequency , maintaining duty cycle 50%, we use RJMP
instruction which take less execution cycle. Maximum generated frequency is 2MHz
TASK NO:2
Refer to the datasheet of ATMEGA328P, and
a) Write the addresses of the following registers:
Register Address I/O Address
DDRB 0x04 (0x24) 0x 17
DDRC 0x07 (0x27) 0 x 14
DDRD 0x0A (0x2A) 0 x 11
PORTB 0x05 (0x25) 0 x 18
PORTC 0x08 (0x28) 0 x 15
PORTD 0x0B (0x2B) 0 x 12
PINB 0x03 (0x23) 0x 16
PINC 0x06 (0x26) 0 x 13
PIND 0x09 (0x29) 0 x 10
b) Mention the group of instructions that does not affect the SREG register.
SNO MNEMONIC DESCRIPTION
1 Break break
2 NOP No operation
3 Sleep sleep
4 WDR Watchdog reset
5 Swap Swap nibbles
6 SBI Set bit in i/o register
7 CBI Clear bit in i/o register
8 Push Push register on stack
9 Pop Pop register from stack
10 LAC Load and clear
11 LAT Load and toggle
TASK NO:3
Write an assembly language code to generate two square waves (50% duty cycle) of 1Hz and
0.5Hz. Write subroutines for the purpose. Provide a switch on pin 3 of PORTB (or any other
pin of your choice) to select between the two waves to be generated on pin 4 of PORTB (or
any other pin of your choice) and show on oscilloscope. Show your implementation to the
lab instructor. CODE: extern "C"
{
void mysetup();
void myloop();
}
void setup() {
// put your setup code here, to run once: mysetup();
}
void loop() {
// put your main code here, to run repeatedly: myloop();
}
brne loop1
RET
mydelay2:
ldi r25, 20 loop_1:
ldi r26, 210 loop_2:
ldi r27, 250 loop_3:
dec r27 brne
loop_3 dec r26
brne loop_2 dec
r25 brne loop_1
RET
RET;return to loop() function OUTPUT:
TASK NO:4
The trainer board provided in the lab has 7-segment led displays with built-in BCD to 7-segment
decoder. Using the delay in subroutines written in Lab Task 3, can you build a simple 1-digit and 2-
digit counter?
CODE:
ldi r25, 0x00 ; bcd counter initial value, r25 = our bcd counter
ldi r26, 0x0A ; maximum value of bcd counter + 1 ldi r27,
0x00 ; bcd counter initial value, r25 = our bcd counter ldi r28,
0x0A ; maximum value of bcd counter + ldi r29,0x00 ;
register for moving reset 0 value ldi r30, 0xFF ldi r31, 0X09
ldi r16, 0xff
out ddrb, r16 ; Declaring outputs
ldi r17, 0xff
out ddrd, r17 ldi r16, 0x00 out
ddrc, r16 ; Inputs declaring
input:
in r16, pinc sbis
pinc, 1
rjmp here
rcall here0 here:
inc r25 ; increment bcd counter cp r25, r26 ; compare bcd counter value with
10, not that cp does not change registers' values brne here2 ; if (bcd counter
is not equal to 10) goto here2
ldi r25, 0
brne here2 ; give 0 to the 7 segment here2: out
portb, r25 cpse r25,r29 ; if r25=0 then increment
r27 skip delay rjmp delaycall inc r27 cp r27,r28 ; if
r27 equal to 10 brne here3 ; until go to here3 and
print 1 to 9 ldi r27,0 ; if 0 then
brne L6 rjmp input mydelay2: ; this part is executed when 'PIN 0' of 'PORT
C' is set (equal to 1) ldi r22, 50
L3:ldi r20, 150
L2: ldi r21, 150
L1: dec r21
brne L1 dec
r20 brne L2
dec r22 brne
L3 rjmp input
ret delaycall: