Отправлено Леонид Иванович 29 апреля 2008 г. 02:52
 
Так делает микропаузы IAR
__delay_cycles(1);
NOP

__delay_cycles(2);
RJMP $+2

__delay_cycles(3);
RJMP $+2
NOP

__delay_cycles(4);
RJMP $+2
RJMP $+2

а начиная с 9 примерно так:

__delay_cycles(9);
LDI R16, 3
DEC R16
BRNE $-2

 

 

http://telesys.ru/wwwboards/mcontrol/2014/messages/485771.shtml

А это довольно интересное упражнение, сделать задержку в циклах, задаваемую переменной.

Вот один из примеров:

Отправлено Леонид Иванович 29 апреля 2008 г. 03:08
 
;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

 

 

IAR Я делаю так:

Отправлено DC 29 апреля 2008 г. 14:33
 

#include <inavr.h>

#define mks 16             //частота кварца в МГц

void main (void)
{
...
__delay_cycles (100*mks);  //задержка 100 мкс

...
__delay_cycles (1000*mks);  //задержка 1 мс
...
//и т.д.
}

 

 

 

 

Лёгким движением руки это превращается в минимум 15

Отправлено ReAl 01 мая 2008 г. 17:17
В ответ на: Вот мой пример: отправлено Леонид Иванович 01 мая 2008 г. 13:51

;	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

 

Вот мой quick and dirty вариант для 11..255 тактов(+)

Отправлено MBedder 01 мая 2008 г. 15:57
В ответ на: Как сделать программную задержку на ATMega16 с дискретностью в один такт контроллера? отправлено tivocr 01 мая 2008 г. 13:22
 
.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

 

 

Тоже на скорую руку - именно устранение джиттера входа в прерывание,
вплоть до нулевого. Ну если я ни где не ошибся.

Отправлено ReAl 01 мая 2008 г. 17:34
В ответ на: Как сделать программную задержку на ATMega16 с дискретностью в один такт контроллера? отправлено tivocr 01 мая 2008 г. 13:22
// Добавка из-за длинных команд и других обработчиков,
// которая уже воспринимается как "авария"
#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