;*************************************************************************** ;* lnop ;*************************************************************************** ;* Typ : Macro, Öffentlich ;* Kurzbeschreibung : Quasi ein NOP-Befehl, der aber 2 Zyklen benötigt ;* Eingabe : keine ;* Ausgabe : keine ;* Benutzte Register : keine ;* Zyklen : 2 ;* PrgMem-Verbrauch : 1 Words ;*************************************************************************** ; Langer NOP ; Braucht 2 Zyklen zur Verarbeitung, aber nur ein Word Code. .macro lnop ; rjmp $ + 1 ; Für AvrTerse (Muss im listfile zu c000 kompiliert werden) rjmp PC + 1 ; Für AVRASM (Muss im listfile zu c000 kompiliert werden) .endmacro ;*************************************************************************** ;* delay_flex3Kern ;*************************************************************************** ;* Typ : Makro, Öffentlich ;* Kurzbeschreibung : FlexiWait mit 3 freiwählbaren Registern, ;* die mit der Verzögerungszeit initialisiert sein ;* müssen. Verzögerungsbereich: 10 - 167,7M Zyklen ;* Eingabe : @0: Lowbyte, @1: Midbyte, @2: Highbyte ;* @0-@2: Alles initialisierte Register ab R16 ;* Zugelassener 24-Bit-Wertebereich: ;* $1 - $ffffff ($0 entspr. $1000000) ;* Ausgabe : keine ;* Benutzte Register : Status, @0-@2 ;* Zyklen : 24-Bit-Wert * 10 ;*************************************************************************** ; Flexible Waitroutine zum abwarten von bel. Zyklenanzahlen ; Eingabe: 24-Bit in drei Registern aufgeteilt. ; Verzögerung: (24-Bit-Wert * 10) = Zyklen ; Variablen: @0 Low-Byte, @1 Mid-Byte, @2 High-Byte ; (alles Reg. oder Reg.Def's von R16-R31) ; Beispiel: ; ; Register mit Verzögerung initialisieren ; ; .set delayzyklen = 1000000 ; ; ldi r16, low(delayzyklen) ; 1 ; ldi r17, byte2(delayzyklen) ; 1 ; ldi r18, byte3(delayzyklen) ; 1 ; ; delay_flex3Kern r16, r17, 18 ; ; Gesammtverzögerung bis hier: 3 + 10*delayzyklen .macro delay_flex3Kern ; Schleifenkern: ; Großen Zähler decrementieren delay_f3K_W1: subi @0, 1 ; 1 sbci @1, 0 ; 1 sbci @2, 0 ; 1 lnop ; 2 (LNOP) nop ; 1 lnop ; 2 (LNOP) brne delay_f3K_W1 ; 2 (1) nop .endmacro ;*************************************************************************** ;* delay_superflex3kern ;*************************************************************************** ;* Typ : Makro, Öffentlich ;* Kurzbeschreibung : SuperflexWait mit 3 freiwählbaren Registern, ;* die mit der Verzögerungszeit initialisiert sein ;* müssen. ;* Eingabe : @0: Lowbyte, @1: Midbyte, @2: Highbyte ;* @0-@2: Alles initialisierte Register ab R16 ;* Achtung: Zugelassener 24-Bit-Wertebereich: ;* $8 - $ffffff (Verz. 16 - 16,7M Zyklen) ;* Ausgabe : keine ;* Benutzte Register : Status, @0-@2 ;* Zyklen : 24-Bit-Wert + 8 ;*************************************************************************** ; Minimaler 24-Bitwert: 8 (-> min. Verzoegerung: 16 Zyklen) ; Maximaler 24-Bitwert: $ffffff (-> max. Verzoegerung: 16.777.223 Zyklen) ; Verzögerung = 24-Bitwert + 8 ; Braucht genau 18 Instructions ; Beispiel: ; ; Register mit Verzögerung initialisieren ; ; .set delayzyklen = 1000000 ; .set calczyk = delayzyklen - 8 - 3 ; Assembler rechnet für uns... ; ldi r16, low(calczyk) ; 1 ; ldi r17, byte2(calczyk) ; 1 ; ldi r18, byte3(calczyk) ; 1 ; ; delay_superflex3kern r16, r17, 18 ; ; ; Gesammtverzögerung bis hier: genau delayzyklen! .macro delay_superflex3kern ; Dieser Teil verbät Offset + N Zyklen. N:[0..7], 3 niedrigste Bits von @0 ; Bit 2 verweilen (0 -> 3 Zyklen bis _E2, 1 -> 7 Zyklen bis _E2) sbrs @0, 2 rjmp delay_Sf3K_E2 lnop lnop nop delay_Sf3K_E2: ; Bit 1 verweilen (0 -> 3 Zyklen bis _E1, 1 -> 5 Zyklen bis _E1) sbrs @0, 1 rjmp delay_Sf3K_E1 lnop nop delay_Sf3K_E1: ; Bit 0 verweilen (0 -> 2 Zyklen bis _E0, 1 -> 3 Zyklen bis _E0) sbrc @0, 0 rjmp delay_Sf3K_E0 delay_Sf3K_E0: ; Die 3 untersten Bits ausblenden, da verarbeitet andi @0, 0b11111000 ; Bis hier 9 - 16 Zyklen (je nach Bits 0..2) ; Diese Schleife verbrät (([@2,@1,@0] * 8) - 1) Zyklen delay_Sf3K_W1: subi @0, 8 ; 1 ( Hier jetzt immer 8 subtra.! ) sbci @1, 0 ; 1 sbci @2, 0 ; 1 lnop ; 2 (LNOP) nop ; 1 ; lnop ; 2 (LNOP) brne delay_Sf3K_W1 ; 2 (1) ; nop .endmacro ;*************************************************************************** ;* delay_superflex2kern ;*************************************************************************** ;* Typ : Makro, Öffentlich ;* Kurzbeschreibung : SuperflexWait mit 2 freiwählbaren Registern, ;* die mit der Verzögerungszeit initialisiert sein ;* müssen. ;* Eingabe : @0: Lowbyte, @1: Highbyte ;* @0-@1: Alles initialisierte Register ab R16 ;* Achtung: Zugelassener 16-Bit-Wertebereich: ;* $4 - $ffff (Verz. 16 - 65,5k Zyklen) ;* Ausgabe : keine ;* Benutzte Register : Status, @0-@1 ;* Zyklen : 16-Bit-Wert + 5 ;*************************************************************************** ; Minimaler 16-Bitwert: 4 (-> min. Verzoegerung: 9 Zyklen) ; Maximaler 16-Bitwert: $ffff (-> max. Verzoegerung: 65.540 Zyklen) ; Verzögerung = 16-Bitwert + 5 ; Braucht genau 10 Instructions .macro delay_SuperFlex2kern ; Dieser Teil verbät Offset + N Zyklen. N:[0..3], 2 niedrigste Bits von @0 ; Bit 1 verweilen (0 -> 3 Zyklen bis _E1, 1 -> 5 Zyklen bis _E1) sbrs @0, 1 rjmp delay_Sf2K_E1 lnop nop delay_Sf2K_E1: ; Bit 0 verweilen (0 -> 2 Zyklen bis _E0, 1 -> 3 Zyklen bis _E0) sbrc @0, 0 rjmp delay_Sf2K_E0 delay_Sf2K_E0: ; Die 2 untersten Bits ausblenden, da verarbeitet andi @0, 0b11111100 ; Bis hier 6 - 9 Zyklen (je nach Bits 0..1) ; Diese Schleife verbrät (([@1,@0] * 4) - 1) Zyklen delay_Sf2K_W1: subi @0, 4 ; 1 ( Hier jetzt immer 4 subtra.! ) sbci @1, 0 ; 1 brne delay_Sf2K_W1 ; 2 (1) .endmacro