#ifndef __DELAY_INC_ASM_INCLUDED__ #define __DELAY_INC_ASM_INCLUDED__ .equ TAKTE_PRO_MS = (F_CPU / 1000) .equ TAKTE_PRO_NS = (F_CPU / 1000000) .equ TAKTE_PRO_SCHLEIFE = 6 .equ SCHLEIFEN_PRO_MS = (TAKTE_PRO_MS / TAKTE_PRO_SCHLEIFE) .equ SCHLEIFEN_PRO_NS = (TAKTE_PRO_NS / TAKTE_PRO_SCHLEIFE) .if (SCHLEIFEN_PRO_MS>0xffff) .error "Aktuelle Taktfrequenz ergibt mehr als 0xffff Schleifendurchläufe/ms!" .endif .macro M_DELAY_MICROSECOND_IN_LOOP ; ein Schleifendurchlauf braucht 3 Takte. ; Bei 3 MHz erzeugt dieses Makro nichts. .if (F_CPU > 3000000) nop ; Bei 4 MHz einen NOP .endif .if (F_CPU > 4000000) nop ; bei 5 MHz zwei NOPs .endif .if (F_CPU > 5000000) nop ; usw.. .endif .if (F_CPU > 6000000) nop .endif .if (F_CPU > 7000000) nop .endif .if (F_CPU > 8000000) nop .endif .if (F_CPU > 9000000) nop .endif .if (F_CPU > 10000000) nop .endif .if (F_CPU > 11000000) nop .endif .if (F_CPU > 12000000) nop .endif .if (F_CPU > 13000000) nop .endif .if (F_CPU > 14000000) nop .endif .if (F_CPU > 15000000) nop .endif .if (F_CPU > 16000000) nop .endif .if (F_CPU > 17000000) nop .endif .if (F_CPU > 18000000) nop .endif .if (F_CPU > 19000000) nop .endif .endm .macro M_DELAY_MICROSECOND nop .if (F_CPU > 1000000) nop .endif .if (F_CPU > 2000000) nop .endif .if (F_CPU > 3000000) nop .endif .if (F_CPU > 4000000) nop .endif .if (F_CPU > 5000000) nop .endif .if (F_CPU > 6000000) nop .endif .if (F_CPU > 7000000) nop .endif .if (F_CPU > 8000000) nop .endif .if (F_CPU > 9000000) nop .endif .if (F_CPU > 10000000) nop .endif .if (F_CPU > 11000000) nop .endif .if (F_CPU > 12000000) nop .endif .if (F_CPU > 13000000) nop .endif .if (F_CPU > 14000000) nop .endif .if (F_CPU > 15000000) nop .endif .if (F_CPU > 16000000) nop .endif .if (F_CPU > 17000000) nop .endif .if (F_CPU > 18000000) nop .endif .if (F_CPU > 19000000) nop .endif .endm #ifdef USE_DELAY_US Delay_us: ; wartet r16 µs lang ; Zusätliche Takte, die abgezogen werden müssen: ; 3 (rcall) + 4 (ret) + 8 (push und pop) 2 (in und out) + 1 (subi) + 1 (brne ohne branch) ; => 17 Takte .equ Takte_pro_us = F_CPU/1000000 .equ DelayMicrosecondsAbzug = (17 / Takte_pro_us) push r16 ; 2 Takte push r17 ; 2 Takte in r17,SREG subi r16, DelayMicrosecondsAbzug ; 1 Takt DelayMicrosecondsLoop: M_DELAY_MICROSECOND_IN_LOOP dec r16 brne DelayMicrosecondsLoop ; 1 Takt out SREG, r17 pop r17 ; 2 Takte pop r16 ; 2 Takte ret ; 4 Takte #endif #if (defined(USE_DELAY_MS) || defined(USE_DELAY_10MS) || defined(USE_DELAY_100MS) || defined(USE_DELAY_1S)) Delay_ms: push r16 push r17 push r18 push r19 push r20 ldi r19,0 ldi r20,1 Delay_ms_S_ms: ldi r17,LOW(SCHLEIFEN_PRO_MS) ldi r18,HIGH(SCHLEIFEN_PRO_MS) Delay_ms_S: sub r17,r20 ; 1 Takt sbc r18,r19 ; 1 Takt cp r17,r19 ; 1 Takt cpc r18,r19 ; 1 Takt brne Delay_ms_S ; 2 Takte dec r16 brne Delay_ms_S_ms pop r20 pop r19 pop r18 pop r17 pop r16 ret #endif #ifdef USE_DELAY_10MS Delay_10ms: push r16 ldi r16,10 rcall Delay_ms pop r16 #endif #ifdef USE_DELAY_100MS Delay_100ms: push r16 ldi r16,100 rcall Delay_ms pop r16 #endif #ifdef USE_DELAY_1S Delay_1s: push r16 ldi r16,200 rcall Delay_ms rcall Delay_ms rcall Delay_ms rcall Delay_ms rcall Delay_ms pop r16 #endif /* Alte Version: Delay_us: push r16 push r17 push r18 push r19 push r20 ldi r19,0 ldi r20,1 Delay_us_S_us: ldi r17,LOW(SCHLEIFEN_PRO_NS) ldi r18,HIGH(SCHLEIFEN_PRO_NS) Delay_us_S: sub r17,r20 ; 1 Takt sbc r18,r19 ; 1 Takt cp r17,r19 ; 1 Takt cpc r18,r19 ; 1 Takt brne Delay_us_S ; 2 Takte dec r16 brne Delay_us_S_us pop r20 pop r19 pop r18 pop r17 pop r16 ret */ #endif ; #ifndef __DELAY_INC_ASM_INCLUDED__