ECE 412 Lab 4

You might also like

Download as doc, pdf, or txt
Download as doc, pdf, or txt
You are on page 1of 9

ECE 412 Lab 4

Introduction to Interrupt Systems

Due on: 10/07/2008

Submitted on: 10/02/2008

Performed on: 9/29, 10/01

Chris McDowell

Patrick Riley

Title: Familiarization with Interrupt System using IRQ’


Program Objective: The purpose of this experiment is to familiarize ourselves with
dealing with hardware-induced interrupts with our Assembly program. In this
experiment, we were to first develop a background task that would allow for a
debounced push button to activate the IRQ’ pin interrupt on the breadboard. In
turn, our application would need to be constructed in a way that would perform a
specific task during the interrupt and then return to normal operation.

Explanation of Program: The background task of the application takes the input of
the logic switches as two BCD numbers. Once the application recognizes the input,
specific actions are to be taken in order to complete the run of the application.

The first set of instructions to be done include verifying that the input number is
valid BCD. In order to verify that validity of the input we needed to take the 8 bit
used as the input and then proceed to mask both the upper and lower nibbles so
that the values can be compared to the value 9 in order to ensure that the number
is valid BCD. When masking the upper nibble, the resultant value cannot be greater
than 9. When masking the lower nibble, the resultant value cannot be greater than
90. Once verified to be valid BCD, the entire 8 bits were to be compared to 90
again to ensure that the value does not exceed 90 as per the criteria for the
experiment. Each nibble is stored separately for recall later in the application. An
algorithm, albeit a short one, to transform the upper nibble into a form to be used
later involved perform a Logic Shift Right 4 times in order to get the correct decimal
place. Once completed, we were to output to the 7-segment display, starting at
what the BCD number minus the value of the upper nibble would be and counting
up to the value of the BCD number plus the lower nibble. An interrupt can occur
during this portion.

Once an interrupt is recognized, the background application would enter a


subroutine specifically for the interrupt. Whatever number was currently being
displayed on the display at the time of the interrupt would be stored to memory for
recall later. Then the subroutine would count down from the value of the BCD
number plus the lower nibble to the value of the BCD number minus the upper
nibble. Once the countdown is complete, the application would restore the previous
number displayed on the display before the interrupt request occurred and
continue.

The background task would perform the incrementation a total of four times before
restarting the application and reading in the value from the logic switches.

Pseudo Code:

Start program

Read input from logic switches

Store in memory location


Mask upper nibble and compare value to 9, branch to subroutine if higher

Store value in memory location

Mask lower nibble and compare value to 90, branch to subroutine if higher

Store value in memory location

Compare input to value 90 and branch if higher

Perform arithmetic on upper nibble to transform it to be in lower nibble


position by using LSR

Store value in memory location

Subtract the value of the upper nibble from the input and store in memory to
be used for lower bound

Add the value of the lower nibble to the input and store in memory to be used
for upper bound

Enter loop to be run 4 times before going back to the start of the program

Display lower bound on 7-segment display and increment by 1 until the upper
bound is reached or an interrupt occurs.

Interrupt Routine:

Store current value on the 7 segment display to memory for recall

Display the upper bound number on the display and decrement until the
lower bound is reached

Once the lower bound is reached, restore the value on the display of the
number from before the interrupt routine was entered. Program
resumes normal operation at this point

Observations and Comments: One of the issues we originally ran into was when a
number would cross a value of 10; i.e. when 42 is used. When our algorithms were
performed to get the upper and lower bounds for counting, we would get invalid
data that wasn’t valid BCD. This was because we were attempting to subtract the
upper nibble from the real BCD number. The DAA command apparently doesn’t
function after a SUBX procedure is performed. We had to modify our code at this
point to instead subtract whatever the upper nibble was from the value 99 in order
to decrement the original BCD correctly by adding said value to the BCD number. In
order to decrement BCD by a single number, you simply add 99 to it. To subtract by
two you would add 98 to the BCD number and so on. Once this was discovered our
application appeared to run without a problem.
Conclusion: The application seemed fairly simple to implement and didn’t require a
large amount of time to figure out. We did have a few subroutines and probably
could have modularized it a little bit more especially with the comparing functions.
This might not necessarily have made it more efficient but the flow of the actual
code may have been easier to read and traverse. Implementation of the interrupt
using the IRQ’ pin was fairly simple due to most of the lab work just requiring coding
instead of a lot of wiring. The implementation of the interrupt was pretty straight
forward and self explanatory.

Program Listing:

*********************************************************
* LEDS: S1 -> PC7, S8 -> PC0
*********************************************************
*********************************************************
* Port addresses and assignments
*********************************************************
DPB EQU $1000 ; Deboucned Push Button
LEDS EQU $1004 ; 7-segment display(LED Port B)
INPUT EQU $1003 ; logic switches(INPUT)

*********************************************************
* Variable declaration
*********************************************************
BCDF EQU $0000 ; BCD flag: 0 = !BCD, 1 = BCD
BCDN EQU $0001 ; Place to store entire BCD from INPUT
BCDN1 EQU $0002 ; Stores the upper nibble of N
BCDN2 EQU $0003 ; Stores the lower nibble of N
N1 EQU $0004 ; N1 = N - BCDN1
N2 EQU $0005 ; N2 = N + BCDN2
IDSPVAL EQU $0006 ; value on display before Interrupt

*********************************************************
*********************************************************
* Main Program
*********************************************************
ORG $D000 ; start of program

*********************************************************
* Initialization
*********************************************************
START LDS #$01FF ; loads stack pointer
CLR BCDF ; clear BCD flag

LDAA INPUT ; load BCD number to ACCA


STAA BCDN ; store the input in mem loc
TAB ; transfer ACCA to ACCB
ANDA #$0F ; mask upper nibble of ACCA
STAA BCDN2 ; and store the value in BCDN2
CMPA #$09 ; compare ACCA with 9
BHI NOTBCD ; and branch to NOTBCD if higher
BCD0 ANDB #$F0 ; otherwise, mask lower nibble of ACCB
STAB BCDN1 ; and store ACCB in BCDN2
CMPB #$90 ; compare ACCB to 90
BHI NOTBCD ; and branch to NOTBCD if higher
; at this point, the number is at least
; valid BCD but now need to check to
; see if 0 < N <= 90 is true
BCD1 INC BCDF ; sets flag to verify that
; the input is valid BCD
NLT90 LDAA BCDN
CMPA #$90
BHI NOTBCD

*********************************************************
* Conversion of BCD to Binary
* Purpose if to get the upper nibble to transfer to
* lower nibble form: xxxx0000 -> 0000xxxx
*********************************************************
LSRB ; performs logic shift right on
LSRB ; upper nibble to transform it
LSRB ; to a valid lower nibble value
LSRB
STAB BCDN1 ; stores result in BCDN1
LDAB #$99 ; loads ACCB with 99 then
SUBB BCDN1 ; subtracts BCDN1 and adds 1 to
ADDB #$01 ; ACCB then adds B to A
ABA ; to get lower bound number
DAA
STAA N1 ; stores result as N1
LDAA BCDN ; loads ACCA with the BCD number
ADDA BCDN2 ; and adds the lower nibble to it
DAA ; to get upper bound number
STAA N2 ; and stores result as N2

*********************************************************
* Count from N1 to N2 on Display 4 times
* before pausing, then rereading the logic switches
*********************************************************
LDAB #$05 ; loads ACCB with 5 for looping
CLI ; enables interrupts
LOOP LDAA N1 ; loads ACCA with lower bound num
DECB ; decrements the loop counter
CMPB #$00 ; and verifies that it hasnt
BEQ NOTBCD ; looped 4 times and branches if
; it has

DISPLAY STAA LEDS ; stores ACCA in the LEDS


JSR DELAY; delay allowing number to be seen
ADDA #$01 ; then increments by 1
DAA ; performs DAA to get valid bcd
CMPA N2 ; compares it to upper bound
BHI LOOP ; and branches if it is higher
BRA DISPLAY ; otherwise repeats counting
*********************************************************
* End of Main Program
*********************************************************
*********************************************************

*********************************************************
* Interrupt routine "VldBCD"
* Purpose: Checks to see if input from PORTC(logic
* switches) was valid BCD
*********************************************************
VldBCD LDAB DPB ;load accumulator B with PORTA value (3 if pressed, 0
if not)
BITB #$01 ;OR B with 0000 00001
BNE VldBCD ;branch if not equal to zero

LDAA LEDS ; stores value of LEDS before


STAA IDSPVAL ; interrupt and stores in IDSPVAL
LDAA BCDF ; loads the BCD flag
BEQ NOTBCD ; and branches if previous was
; not valid BCD

*********************************************************
* Count down from N2 to N1 in BCD, display
*********************************************************
LDAA N2 ; loads upper bound number
DISPC STAA LEDS ; displays ACCA in LEDS
JSR DELAY ; jumps to delay sr
CMPA N1 ; compares ACCA to N1
BEQ CDONE ; and branches when they are eq
ADDA #$99 ; otherwise, subtracts 1 from A
DAA ; performs DAA to get BCD
BRA DISPC ; branches to repeat

*********************************************************
* Count is completed, restore value and return
*********************************************************
CDONE LDAA IDSPVAL ; loads ACCA with previous LED
STAA LEDS ; displays ACCA in LEDs
RTI ; returns execution to main
; application

*********************************************************
* Subroutine for when input value is not valid BCD
*********************************************************
NOTBCD LDAA #$00 ; loads ACCA with value 00
STAA LEDS ; and displays it to the LEDS
JSR DELAY ; performs delay routine so it
JSR START ; can be seen then restarts app

*********************************************************
* Delay subroutine
*********************************************************
DELAYLDY #$0010
DELAY1 LDX #$8000
DELAY2 DEX
BNE DELAY2
DEY
BNE DELAY1
RTS
ORG $FFF2 ; Interrupt vector
FDB VldBCD ; IRQ Pin Interrupt

ORG $FFFE ; Reset vector


FDB START

You might also like