Страница 5 из 9

Re: Вопрос по программированию задержки внутри прерывания

Добавлено: Вс янв 26, 2025 11:35:22
shonty
[uquote="Starichok51",url="/forum/viewtopic.php?p=4670367#p4670367"]во, к примеру, как у меня сделана подстановка адреса возврата в прерывании для таймера1:

Код: Выделить всё

;--- Таймер1 ---
ldi R16, low(RAMEND)
out SPL, R16 
ldi R16, low(main)
push R16
ldi R16, high(main)
push R16
reti
перезаписываю вершину стека и пишу в стек адрес возврата.[/uquote]
Постепенно осознаю полезность приёма. :)))

В прерываниях конечно не везде зайдёт, а вот для использования какого-нибудь общего сценария без последующей проверки флагов самый раз.

Накидал дэмку для примера:
Спойлер

Код: Выделить всё

label_0:
ldi R16, low(RAMEND)
out SPL, R16
ldi R16, low(label_2)
push R16
ldi R16, high(label_2)
push R16
rjmp procedure

label_1:
ldi R16, low(RAMEND)
out SPL, R16
ldi R16, low(label_0)
push R16
ldi R16, high(label_0)
push R16
rjmp procedure

label_2:
ldi R16, low(RAMEND)
out SPL, R16
ldi R16, low(label_1)
push R16
ldi R16, high(label_1)
push R16
rjmp procedure

procedure:
nop
ret
То есть мы сразу обозначаем, куда нам нужно перейти после выполнения)
:beer:

Добавлено after 7 minutes:
Ну или так:
Спойлер

Код: Выделить всё

label_0:
tst R0
breq pc+6

ldi R16, low(label_1)
push R16
ldi R16, high(label_1)
push R16
rjmp procedure

ldi R16, low(label_2)
push R16
ldi R16, high(label_2)
push R16
rjmp procedure

label_1:
rjmp pc

label_2:
rjmp pc

procedure:
nop
ret
Добавлено after 41 minute 48 seconds:
А для тех, кто говорит, что на асм-е то ли много, то ли сложно писать :))) :
Спойлер

Код: Выделить всё

.equ after =0
.MACRO first				
ldi R16, low(@2)
push R16
ldi R16, high(@2)
push R16
rjmp @0
.ENDMACRO

Код: Выделить всё

; сначала в процедуру, потом на метку:
first PROCEDURE, after, LABEL_2
но это изврат) я так не делаю))

Добавлено after 3 minutes 5 seconds:
shonty писал(а):я так не делаю))
потому что нельзя совсем абстрагироваться от кода))

Re: Вопрос по программированию задержки внутри прерывания

Добавлено: Вс янв 26, 2025 11:57:27
Starichok51
ну, и где видно, когда твоё макро перейдет на метку LABEL_2?

Re: Вопрос по программированию задержки внутри прерывания

Добавлено: Вс янв 26, 2025 13:03:01
shonty
Starichok51 писал(а):ну, и где видно, когда твоё макро перейдет на метку LABEL_2?

Код: Выделить всё

.equ after =0
.MACRO first				
ldi R16, low(@2)
push R16
ldi R16, high(@2)
push R16
rjmp @0
.ENDMACRO
; -----------------------------

first PROCEDURE, after, LABEL_2

label_1:
rjmp pc

label_2:
rjmp pc

procedure:
nop
ret
Добавлено after 35 minutes 52 seconds:
redirect PROCEDURE, LABEL_2
- так более вменяемо будет..
но тогда макрос придётся немного переделать.

Re: Вопрос по программированию задержки внутри прерывания

Добавлено: Вс янв 26, 2025 14:41:41
Starichok51
а не проще вместо rjmp @0 сразу написать ret?

Re: Вопрос по программированию задержки внутри прерывания

Добавлено: Вс янв 26, 2025 15:20:34
shonty
ret написать проще, но работать не будет :)))

как тогда передать, что перед меткой_2 сначала нужно посетить процедуру?

Re: Вопрос по программированию задержки внутри прерывания

Добавлено: Вс янв 26, 2025 16:05:44
Starichok51
тогда понятно. а то я "клюнул" на то, что процедура у тебя пустая.

Re: Вопрос по программированию задержки внутри прерывания

Добавлено: Вс янв 26, 2025 16:19:34
shonty
тут вообще можно извратиться, передать в стёк несколько адресов, и получится по одному rjmp-у конвеерные переходы :)))

типа:
cruise label_1, label_3, label_10, label_7, label_1, label_4,...

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

Re: Вопрос по программированию задержки внутри прерывания

Добавлено: Вс янв 26, 2025 16:46:18
Starichok51
ну да, конвейер - это уже извращение.

Re: Вопрос по программированию задержки внутри прерывания

Добавлено: Вс янв 26, 2025 17:49:15
ДядяВован
Подход с манипуляцией стека с для условного возврата, в принципе, штука интересная. Хотя IMHO удобнее ICALL / IJMP.
Но зачем нам многократная переустановка указателя стека?
ldi R16, low(RAMEND)
out SPL, R16
Особенно в большом проекте, где стек обычно отнюдь не пустой.
Ну пришли в подпрограмму, хотим вернуться не туда откуда вызвали. Достанем адрес возврата посредством POP, запихнем новый адрес PUSH. Cтек на ramend единожды при старте настроить и хватит.

Re: Вопрос по программированию задержки внутри прерывания

Добавлено: Вс янв 26, 2025 19:15:56
Starichok51
ДядяВован, в данном случае мне НЕ НУЖЕН адрес возврата, поэтому я восстановил вершину стека и запихнул адрес начала цикла.
а shonty взялся придумывать, где еще можно применять этот прием.

Re: Вопрос по программированию задержки внутри прерывания

Добавлено: Вс янв 26, 2025 19:56:01
ДядяВован
Понятно.

Re: Вопрос по программированию задержки внутри прерывания

Добавлено: Пн фев 03, 2025 16:46:08
shonty
Кстати вспомнил по теме..
В обработчик прерывания же вообще можно не заходить и не обрабатывать. А вести опрос флага преывания в цикле.

На асме для 328-й для примера:
Спойлер

Код: Выделить всё

; init INT0 (PD2):	
	cli
	ldi R16,(1<<ISC01)		; прерывание INT0 по ниспадающему фронту
	sts EICRA, R16
	; ldi R16,(1<<INT0)		; разрешение внешнего прерывания INT0   НЕ ИСПОЛЬЗУЕМ
	; out EIMSK, R16
	ldi r16, (1<<INTF0)		; очистить флаг прерывания
	out EIFR, r16
	sei
Проверка в цикле:

Код: Выделить всё

	in R16, EIFR
	sbrc R16, INTF0
	rjmp КУДА_НИБУДЬ
И уже в подпрограмме чистим флаг:

Код: Выделить всё

ГДЕ_НИБУДЬ:
........
........
	ldi r16, (1<<INTF0)		; очистить флаг прерывания
	out EIFR, r16

Re: Вопрос по программированию задержки внутри прерывания

Добавлено: Пн фев 03, 2025 19:19:37
Starichok51
вот только запаздывание обработки в цикле относительно срабатывания прерывания может оказаться недопустимым.

Re: Вопрос по программированию задержки внутри прерывания

Добавлено: Пн фев 03, 2025 19:25:54
shonty
Согласен.. Но топикстартеру как раз это не критично было.
А мне тоже, просто чтобы импульс прерывания с Si4735 зафиксировался, не обязательно подрываться))

Код: Выделить всё

STC_wait:
	in R16, EIFR
	sbrs R16, INTF0
	rjmp PC-2
	out EIFR, r16
типа spi_wait или i2c_wait..

Re: Вопрос по программированию задержки внутри прерывания

Добавлено: Пн фев 03, 2025 19:55:37
BOB51
Для обработчика кнопок/ низкоскоростных процессов запаздывание в пределах до 0,014 секунды не критично.
:roll:

Re: Вопрос по программированию задержки внутри прерывания

Добавлено: Вт фев 04, 2025 03:55:08
akl
Замечу. Для m48...m328, да и не только справедливо такое.

Код: Выделить всё

STC_wait:
   SBIS EIFR,INTF0
   RJMP PC-1
   SBI EIFR,INTF0

Re: Вопрос по программированию задержки внутри прерывания

Добавлено: Вт фев 04, 2025 06:00:10
shonty
akl писал(а):Замечу. Для m48...m328, да и не только справедливо такое.
Спасибо. Полезный совет :beer:

Re: Вопрос по программированию задержки внутри прерывания

Добавлено: Вт фев 04, 2025 07:55:03
COKPOWEHEU
[uquote="akl",url="/forum/viewtopic.php?p=4678956#p4678956"]RJMP PC-1[/uquote]
Плохая идея. У вас же и так метка есть

Код: Выделить всё

STC_wait:
  SBIS EIFR,INTF0
    RJMP STC_wait
  SBI EIFR,INTF0

Re: Вопрос по программированию задержки внутри прерывания

Добавлено: Вт фев 04, 2025 08:12:18
shonty
COKPOWEHEU писал(а):Плохая идея. У вас же и так метка есть
Использование PC более универсально, да и привычнее мне.
А конечный результат в данном случае в макросе оформлен будет.
С метками порой конфликты случаются, когда много своих "библиотек" подключаешь.

Re: Вопрос по программированию задержки внутри прерывания

Добавлено: Вт фев 04, 2025 09:16:41
Starichok51
shonty, ты что, вручную вычисляешь смещения для РС?
а если нужно сделать прыжок на много адресов, то тоже руками вычисляешь смещение?
а универсально - это использование метки - пусть компилятор вычисляет смещение.