Table of Contents

Delay Loops

  • Often we need to slow our programs down so that the user can see the results
  • Delay loops are used to burn clock cycles.
        ldi  r16, val
loop:
        dec  r16
        brne loop
  • The biggest number we can put in val is 255.
  • Our clock frequency is 16MHz, so the period is T = 1/f = 62.5 x 10-9 seconds per cycle.
  • We can determine the length of time required for the loop as follows:
                            # of times    # of clocks   Total clocks
        ldi  r16, val            1               1             1
loop:
        dec  r16                 val             1             val
        brne loop                val             2             2*val-1
  • The -1 on 2*val-1 is because the BRNE instruction only requires on clock cycle the last time it runs.
  • With val=255, this works out to 1+255+509 → 47.8 x 10-6 seconds.
  • This doesn't provide much of a delay… let's consider a nested loop:
                            # of times    # of clocks   Total clocks
        ldi  r17, val1           1               1             1
loop2:
        ldi  r16, val2           val1            1             val1
loop1:
        dec  r16                 val2*val1       1             val1*val2
        brne loop1               val2*val1       2             2*val1*val2
        dec  r17                 val1            1             val1
        brne loop2               val1            2             2*val1
  • To simplify things, we're ignoring assuming that the BRNE execution is 2 cycles all the time.
  • With val1=val2=255, this works out to 1+255+65025+130050+255+510 → 0.0123 seconds.
  • If you need a timing loop to provide a delay that is longer than 0.0123 seconds requires at least three nested loops.

The Stack

  • Is a memory structure located in SRAM
  • Typically we make the starting address for the stack at the last available SRAM location (0x85F or RAMEND).
  • ATmon actually uses the last 32 memory locations for it's stack, so we will initialize our stack to RAMEND-0x20.
  • There is a special pointer to the stack (called SP)
    • The stack pointer points to the “top” of the stack.
    • The SP is 16 bits wide since it contains an address.
    • Hence, it consists of two registers (SPH and SPL).
    • We initialize it like this:
      ldi  r16, HIGH(RAMEND-0x20)
      out  SPH, r16
      ldi  r16, LOW(RAMEND-0x20)
      out  SPL, r16
  • The stack may be used as a temporary storage area for data.
  • The PUSH instruction puts data onto the stack.
    • PUSH R0 does the following:
      • (SP) ← R0 (puts the value of R0 in the memory location that SP is pointing to)
      • SP ← SP - 1 (moves the stack pointer down one address)
  • Each PUSH should have a corresponding POP operation.
    • POP R0 does the following:
      • SP ← SP + 1 (moves the stack pointer up one address)
      • R0 ← (SP) (puts the value at the top of the stack into R0)
  • Recall that the stack is a Last In/First Out structure.
  • It can be used to save/restore the values in the registers before/after a call to a subroutine. E.g.,
      push r0
      push r1
      push r2
      ...
      push r31
      ; call some subroutine
      pop  r31
      ...
      pop  r2
      pop  r1
      pop  r0

Stack Example

.nolist
.include "m32def.inc"
.list

.cseg
.org 0
        rjmp start

.org 0x2a
start:
        ldi  r16, HIGH(RAMEND-0x20)  ; Initialize stack pointer
        out  SPH, r16
        ldi  r16, LOW(RAMEND-0x20)
        out  SPL, r16

        ldi  r20, 0x25               ; Initialize registers r20-r22
        ldi  r21, 0x50
        ldi  r22, 0x75

        push r20                     ; Save r20-r22 register values
        push r21                     ; by placing r20-r22 onto the stack
        push r22

        ; blah blah blah

        pop  r22                     ; Restore r20-r22 registers by
        pop  r21                     ; by popping their values off the stack
        pop  r20
forever:
        rjmp forever                 ; This loop is tight
ce2800/loopsandstack.txt · Last modified: 2010/03/09 20:55 (external edit)
 

This website is not owned or managed by the Milwaukee School of Engineering.

© 2003-2010 Dr. Christopher C. Taylor, et. al. • Office: L-343 • Phone: 277-7339 • npǝ˙ǝosɯ@ɹolʎɐʇ • -> RSS <-