; CE-2800 DelayLoop.asm ; Purpose: Demonstrate how to implement a delay loop .NOLIST .INCLUDE "m32def.inc" ; contains .EQU's for DDRB, PORTB, and a lot more .LIST .EQU start = 0x2a ; define a symbol to represent address 0x3a in program memory .CSEG ; this means further directives are for the Code Segment .ORG 0x0 rjmp start ; initialize Reset Vector .ORG start ; define the beginning of the program - where the Assembler places further program instructions .DEF ddr_ctrl = R24 ; another alias for a register containing DDRB control bits .DEF counter1 = R16 ; loop counters for delay loop .DEF counter2 = R17 .DEF counter3 = R18 .DEF Bounce = R20 ; ldi ddr_ctrl, 0xff ; set all bits to 1 out DDRB, ddr_ctrl ; tell DDRB to configure pins as output or input (0xff means all output) reset: sbr Bounce, 0x80 ; set leftmost bit repeat: out PORTB, Bounce ; output bits to light LEDs .EQU C1=50 ; define some loop counter constants .EQU C2=50 .EQU C3=50 ; start of delay loop; uses 3 nested loops ; Cycles for initialization: 1 ; Cycles for inner loop: C3*C2*C1*3 - C1*C2 ; Cycles for middle loop: C2*C1*4 - C1 ; Cycles for outer loop: C1*4 - 1 ; Total cycles: 1 + C3*C2*C1*3 - C1*C2 + C2*C1*4 - C1 + C1*4 - 1 ; = C3*C2*C1*3 + C2*C1*3 + C1*3 ; = 3*C1(C3*C2 + C2 + 1) sbr counter1, C1 ; init outermost loop counter to C1 loop1a: ; this loop executes C1 times sbr counter2, C2 ; init middle loop counter to C2 loop2a: ; this loop executes C1*C2 times sbr counter3, C3 ; init innermost loop counter to C3 loop3a: ; this loop executes C1*C2*C3 times dec counter3 brne loop3a ; takes 2 CPU cycles if true; 1 if false dec counter2 brne loop2a dec counter1 brne loop1a ; end of delay loop; takes 14.625 microseconds at 8MHz for C1=C2=C3=3 lsr Bounce ; shift bits right brne repeat ; and keep repeating if the bit is still in the register breq reset ; otherwise, reset if the bit "rolled off" the edge