;Delay:
;Cnt - cycles number (17 minimum)
; ldi Cnt,Cycles ;1
; rcall Delay ;3
Delay: subi Cnt,13 ;1
lsr Cnt ;1 Cnt / 2
brcs de1 ;2(1)
de1: lsr Cnt ;1 Cnt / 2
brcs de2 ;2(1)
de2: brcs de3 ;2(1)
de3: dec Cnt ;1
nop ;1
brne de3 ;2(1)
ret ;4
#include <inavr.h>
#define mks 16 //частота кварца в МГц
void main (void)
{
...
__delay_cycles (100*mks); //задержка 100 мкс
...
__delay_cycles (1000*mks); //задержка 1 мс
...
//и т.д.
}
; ldi Cnt,Cycles ;1
; rcall Delay ;3
;Delay:
;Cnt - cycles number (15 minimum)
Delay: subi Cnt,15 ;1
lsr Cnt ;1 Cnt / 2
brcs de1 ;2(1)
de1: lsr Cnt ;1 Cnt / 2
brcc de2 ;2(1)
nop ;1
rjmp de2 ;2
de3: dec Cnt ;1
nop ;1
de2: brne de3 ;2(1)
ret ;4
.macro delay_ZL_cycles ;; 11 <= ZL <= 255
ldi ZH,high(noptab) ;; ZH = NOP table start address MSB
subi ZL,10 ;; Compensate for a macro execution time
neg ZL ;; ZL = compensated # of NOPs to execute
icall ;; Enter a calculated # of NOPs sequence
.endm
ldi ZL,11 ; Test code (try any value from 11 to 255)
delay_ZL_cycles ; Cycle counter will show 1 cycle more due to the ldi ZL line above
nop ; Test breakpoint placeholder
.org (PC & 0xFF00)+256 ; Align to a 256 code words boundary
noptab: ; Place at the end of a code segment for convenience
.dq 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; 32 x dq 0 = 128 NOPs
.dq 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; 32 x dq 0 = 128 NOPs
ret
// Добавка из-за длинных команд и других обработчиков,
// которая уже воспринимается как "авария"
#define MAX_JITTER
// Меньше этого быть не может (сумма тактов ухода на вектор, jmp оттуда
// и тактов обработчика до точки in ZL, TCNT0
#define MIN_DELAY
#define MAX_DELAY (MIN_DELAY+MAX_JITTER)
TIMER0_OVF_vect:
push ZL
in ZL, SREG
push ZL
push ZH
in ZL, TCNT0
cpi ZL, MAX_DELAY
brsh too_high_delay ; на ветвь обработчика ошибки (мало
; заказали MAX_JITTER)
clr ZH
subi ZL, low( - (pm(t0_jtable) - MIN_DELAY ) )
sbci ZH, high( - (pm(t0_jtable) - MIN_DELAY ) )
ijmp
t0_jtable:
.rept MAX_DELAY - MIN_DELAY
nop
.endr
; тут выровнялись и пошли работать
pop ZH
pop ZL
out SREG, ZL
pop ZL
reti