Engr2105 Lab3

Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 8

Title

LCD Stop Clock

Abstract

The Atmel ATiny2313/4313 microcontroller was used to program a 7-segment display as a stop
clock. This helped to better familiarize with the I/O interfacing capabilities of the Atmel
ATtiny2313/4313 microcontroller. This also gave the opportunity to understand timing in
assembly and C programming and multiplexing digital signals

Introduction

There are many programming languages used to design and implement digital circuits. Two of
such programming languages used are assembly (more outdated) and C (more popular). These
codes can be programmed on a microcontroller. A microcontroller (MCU) is a compact
integrated circuit designed to govern a specific operation in an embedded system.
Microcontrollers come in many shapes and sizes depending on its need. For example: for a small
operation like designing a stop clock, an Atmel ATiny2313/4313 can be used; or for a bigger
operation like automated robot., which requires more I/O ports and memory to implement.

The purpose of the study is to:

 To become familiar with timing and digital multiplexing using assembly and C
 To write assembly and C code for implementing the 7-segemt stop clock.
 To become familiar with the I/O interfacing capabilities of the Atmel ATtiny2313/4313
microcontroller
 To program the MCU to run the 7-segment stop clock

Materials and method

The materials used in this experiment was:


 A computer with the Microchip Studio Software.
 The Pololu USB AVR Programmer to program the MCU.
 A working breadboard circuit with the necessary components

These materials will be used to

 Build the circuit to be programmed using the components needed.


 Design a code for an one-digit segment stop clock using assembly and C. Then design a
code for a two-digit segment stop clock using C.
 Run and test the code

Results

ASSEMBLY CODE ONE DIGIT

.ORG 0
LDI R16, 0xFF
OUT DDRB, R16
OUT DDRD, R17

LDI R16, LOW(RAMEND)


OUT SPL, R16

START: SBIC PinD, 2


RJMP START

Main: RCALL zero


RCALL PAUSE
RCALL DELAY
RCALL one
RCALL PAUSE
RCALL DELAY
RCALL two
RCALL PAUSE
RCALL DELAY
RCALL three
RCALL PAUSE
RCALL DELAY
RCALL four
RCALL PAUSE
RCALL DELAY
RCALL five
RCALL PAUSE
RCALL DELAY
RCALL six
RCALL PAUSE
RCALL DELAY
RCALL seven
RCALL PAUSE
RCALL DELAY
RCALL eight
RCALL PAUSE
RCALL DELAY
RCALL nine
RCALL PAUSE
RCALL DELAY
RJMP Main

zero: LDI R16, 0x3F


OUT PORTB, R16
RET

one: LDI R16, 0x06


OUT PORTB, R16
RET

two: LDI R16, 0x5B


OUT PORTB, R16
RET

three: LDI R16, 0x4F


OUT PORTB, R16
RET

four: LDI R16, 0x66


OUT PORTB, R16
RET

five: LDI R16, 0x6D


OUT PORTB, R16
RET

six: LDI R16, 0x7D


OUT PORTB, R16
RET

seven: LDI R16, 0x07


OUT PORTB, R16
RET

eight: LDI R16, 0x7F


OUT PORTB, R16
RET
nine: LDI R16, 0x6F
OUT PORTB, R16
RET

DELAY: LDI R17, 255


L1: LDI R18, 255
L2: NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
DEC R18
BRNE L2
DEC R17
BRNE L1
RET

PAUSE: SBIS PinD,2


RCALL M
RET

M: RCALL DELAY
SBIC PinD,2
RJMP M
RET

1 DIGIT SEGMENT C CODE


#define F_CPU 1000000UL
#include <avr/io.h>
#include <inttypes.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
#include <stdio.h>
#include <stdlib.h>
#include <util/delay.h>
#include <math.h>

volatile int count=0;

ISR (INT0_vect){
if (!(PIND & (1<<2)))
{
count++;
if (count==2)
count=0;
_delay_ms(20);

int main()
{

int i, y, j,z, cnt2=0;


unsigned int num[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
DDRB=0xFF;
DDRD = 0xFF;
PORTD |= (1<<2);
GIMSK |= (1<<INT0);
MCUCR |= 0x02;
sei();

PORTB = 0x3F;

while (1){

for (i=cnt2;i<10;i++){

cnt2=i;

if (count==1){
PORTB = num[i];
_delay_ms(1000);

}
else
break;

if (count==0){

_delay_ms(1000);

}
if (i==10)
{cnt2=0;}

}
return 0;
}

2 DIGIT SEGMENT C CODE


#define F_CPU 1000000UL
#include <avr/io.h>
#include <inttypes.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
#include <stdio.h>
#include <stdlib.h>
#include <util/delay.h>
#include <math.h>

volatile int count=0;

ISR (INT0_vect){

if (!(PIND & (1<<2)))


{
count++;
if (count==2)
count=0;
_delay_ms(20);

int main()
{

int i, y, j,z, cnt2=0;


unsigned int num[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
DDRB=0xFF;
DDRD = 0xFF;
PORTD |= (1<<2);
GIMSK |= (1<<INT0);
MCUCR |= 0x02;
sei();
PORTD &= ~(1<<4);
PORTD&= ~(1<<5);
PORTB = 0x3F;
// Write your code here

while (1){

for (i=cnt2;i<100;i++){

cnt2=i;
if (count==1){
for (y=0;y<50;y++) {
_delay_ms(10);
j=i/10;
PORTD &= ~(1<<4);
PORTD |= (1<<5);
PORTB=num[j];

_delay_ms(10);
z=i%10;
PORTD |= (1<<4);
PORTD &= ~(1<<5);
PORTB=num[z];
}

}
else
break;

if (count==0){

PORTD &= ~(1<<4);


PORTD |= (1<<5);
PORTB=num[j];
_delay_ms(10);

PORTD |= (1<<4);
PORTD &= ~(1<<5);
PORTB=num[z];
_delay_ms(10);

}
if (i==100)
{cnt2=0;}

return 0;
}

Discussion
The MCU used a operation called polling to check whether the button was pressed or not. While
polling, the CPU constantly inspects the status of the system to find whether it meets the
requirements. In the case of the button, it keeps running the while loops to check if the button
was pressed; this results in a waste of CPU cycles. In other to mitigate that, interrupts can be
used. When using interrupts, the system informs the CPU that it met the requirement without
constantly checking. In the case of the button, as it is pressed, the interrupt is instantly triggered
and fetched before the next completes.

Literature cited

No literature cited.

You might also like