2022-02-07

1. Delay subroutine

  • Review how a subroutine works in assembly and in operation. see day09.

Now notice that we are doing two loops that have the same form. Factor out so the outer loop calls another subroutine. Create a new subroutine DelayB which calls a (sub)subroutine DelayBShort:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
.equ INNER_COUNT = 0x03  ; 8b unsigned
.equ OUTER_COUNT = 0x02  ; 8b unsigned


Main:
    sbi PORTB, 3    ;set PB3 high
    rcall DelayB    ; and wait

    cbi PORTB, 3    ;set PB3 low
    rcall DelayB    ; and wait

    rjmp Main       ; only to do it again!

;
; Delay subroutines
;
DelayB:
    ldi r17, OUTER_COUNT

DelayB_LoopOuter:         ; ---+
    rcall DelayBShort     ; -+ |
    dec r17               ;    |
    brne DelayB_LoopOuter ; ---+
;
    ret     ; return from outer delay


DelayBShort:
    ldi r16, INNER_COUNT
DelayB_LoopInner:         ;-+
    dec r16               ; |
    brne DelayB_LoopInner ;-+
;
    ret     ; return from inner delay

What happens with the stack and stack pointer in this new set of subroutines?

2. Something useful

(an eye-of-the-beholder situation)

ECE 322, day15 had to do with state machines in the RIMS / zyBook style.

Use an interrupt to “tick” a state machine that blinks an LED.

Program this in assembly!

  • Use a byte in SRAM to store TimerFlag

  • Make TickFct_Blink() a subroutine

The timer Interrupt Service Routine simply does (in C): TimerFlag = 1. How does the correct code execute when the interrupt fires?

The main while(1) loop waits for the value of this variable to be set, then immediately clears it, hence implementing a delay between state transitions.