Ассемблер (ASM) для AVR в вопросах и ответах

Обсуждаем контроллеры компании Atmel.
Аватара пользователя
BOB51
Друг Кота
Сообщения: 15556
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение BOB51 »

У АВРок внешнего разрешения счета нет... разве что использовать программный дубляж для управления по ICP/захвату в таймере С/Т1...
:roll:
Реклама
Аватара пользователя
Z_h_e
Собутыльник Кота
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение Z_h_e »

Если хорошая кнопка, то для подавления дребезга может быть достаточно конденсатора, я с таким уже встречался.

А режим захвата в AVR есть по фронту и спаду одновременно?
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Реклама
akl
Друг Кота
Сообщения: 4444
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение akl »

• Bit 6 – ICES1: Input Capture Edge Select
This bit selects which edge on the Input Capture pin (ICP1) that is used to trigger a capture
event. When the ICES1 bit is written to zero, a falling (negative) edge is used as trigger, and
when the ICES1 bit is written to one, a rising (positive) edge will trigger the capture.
When a capture is triggered according to the ICES1 setting, the counter value is copied into the
Input Capture Register (ICR1). The event will also set the Input Capture Flag (ICF1), and this
can be used to cause an Input Capture Interrupt, if this interrupt is enabled.
DS на ATtiny2313 утверждает, что нет.
Аватара пользователя
Z_h_e
Собутыльник Кота
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение Z_h_e »

Мне тоже помнится что нет. Хотя может на каких-то более продвинутых есть.
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
radio-fan
Родился
Сообщения: 8
Зарегистрирован: Чт май 18, 2017 11:57:03
Откуда: Барнаул

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение radio-fan »

[uquote="akl",url="/forum/viewtopic.php?p=3180822#p3180822"]В обработчике запустили таймер или сделали отсечку уже запущенного таймера. Ждете отпускания кнопки и в обработчике сделали следующую отсечку. Разница покажет длительность нажатия на кнопку.[/uquote]
Да, при коротком нажатии ловим сначала нажатие, фильтруем дребезг таймером, ловим отпускание, ещё раз фильтруем. А с длинным что делать? Надо чтобы длинное без отпускания ловил.
Реклама
Аватара пользователя
Z_h_e
Собутыльник Кота
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение Z_h_e »

radio-fan писал(а):Надо чтобы длинное без отпускания ловил.
После отсечки дребезга запускается таймер и останавливается при отпускании кнопки. При переполнении таймера, считается что кнопка достаточно долго нажата.
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Реклама
Аватара пользователя
BOB51
Друг Кота
Сообщения: 15556
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение BOB51 »

Делаем замер "самого длинного" делим на N частей (желателно кратно 2 дабы с математикой не заморачиваться) и делаем минимального "условного енота" с табличкой определений хотелок в УЕ (от 1 УЕ до максимум/УЕ +2УЕ). Это часть автокалибровки измерителя.
Измеренный интервал нарезаем интервалами "условного енота" с неким округлением и грузим количество тех интервалов в "счетчик УЕ, прошедших на вход".
Затем содержимое счетчика используем как указатель обработчика.
:wink:
Demiurg
Это не хвост, это антенна
Сообщения: 1480
Зарегистрирован: Ср июн 25, 2008 15:19:44
Контактная информация:

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение Demiurg »

Вы че тут понаписали про опрос кнопок? ТС-у требуется используя внешнее прерывание отловить короткие и длинные нажатия? Не вопрос. Пусть сработало внешнее прерывание. Как только оно сработало, отключаем внешнее прерывание и пин МК становится обычным входом. Отслеживаем его. Прошли дребезг? Засчитываем как нажатие, запускаем программный таймер длинного нажатия. Только нужно определиться, какое время считаем длинным нажатием? Секунда, пусть будет секунда. Три секунды? Пусть так. Отпустили кнопку раньше положенного? Считаем коротким нажатием. Снова настраиваем вход как внешнее прерывание. Сидим ждем следующее нажатие. Прошло заданное время? Значит длинное нажатие. А вот чтобы считать времянки, используем программные таймеры. Аппаратный таймер один. Программных можно сделать столько, насколько хватит ресурсов МК. Хоть десятки.
Аватара пользователя
BOB51
Друг Кота
Сообщения: 15556
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение BOB51 »

Я описал алгоритм замера и сортировки интервалов.
А кнопка то или чего иного - никакушной разницы, если базовым измерителем таймер с внешним разрешением счета выбран.
:wink:
akl
Друг Кота
Сообщения: 4444
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение akl »

[uquote="Demiurg",url="/forum/viewtopic.php?p=3182521#p3182521"]... Аппаратный таймер один...[/uquote]Вполне достаточно. Таймер(ы) для того и введён(ы), чтобы считать "времянки". Программе остается только анализ дребезга, короткого или длинного нажатия.
Demiurg
Это не хвост, это антенна
Сообщения: 1480
Зарегистрирован: Ср июн 25, 2008 15:19:44
Контактная информация:

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение Demiurg »

Речь идет о том, что аппаратных таймеров мало. И они нужны для других нужд. Поэтому, отводится один аппаратный таймер для программных таймеров, которых можно наделать сколько угодно, главное, чтобы хватило ресурсов МК.
Это распространенная проблема начинающих. Аппаратных таймеров мало, как отмерять времянки? Вот и ответ сразу - решение - программные таймеры.
Аватара пользователя
BOB51
Друг Кота
Сообщения: 15556
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение BOB51 »

Все зависит от терминологии...
Вобщем-то все проблемы снимает правильно скомпонованный генератор системной сетки частот.
Основа - 8/16 разрядный таймер с автоперезагрузкой (предпочтение 16-разрядному с вероятным предделителем), тактируемый от частоты системного генератора.
А при помощи чего дальнейшая обработка этого системного "тик" выполняться будет - зависит от творчества авторов.
Возможны добавочные счетчики с передаточными служебными флагами или чего другое...
Установка нескольких одновременно протекающих асинхронных процессов дело достаточно сложное из-за компоновки приоритетов прерываний. Да и не всегда дает желаемый результат по оперативному быстродействию.
:beer:
Аватара пользователя
radio-fan
Родился
Сообщения: 8
Зарегистрирован: Чт май 18, 2017 11:57:03
Откуда: Барнаул

Сообщение radio-fan »

И снова здравствуйте. Помогите пожалуйста.
Пытаюсь написать прогу переключения световых эффектов и их инверсии с помощью внешнего прерывания.
Проблема в том, что хреново отслеживается длинное нажатие (происходит незапланированная инверсия и\или увеличение счётчика нажатий (младшая тетрада Flag)). Надо чтобы при коротком мы инкрементировали счётчик, а при зажатии кнопки происходила инверсия, при последующем отпускании ничего не происходило и дальше снова ловим нажатие.
Код прилагаю ниже:

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

.include "c:\Program Files\Atmel\AVR Tools\AvrAssembler2\Appnotes\m8def.inc"
                   ;ATmega8 программируем
                   ;тактовая частота 8 МГц
.def Temp=R16      ;рабочая перемнная
.def Flag=R17      ;3-0 бит счётчик нажатий, 4 бит инверсии (1 инверсия), 5 бит нажатия отпускания (0 нажатие, 1 отпускание), 6 бит длинное короткое нажатие(0 короткое, 1 длинное)
.def Count=R18     ;счётчик эффектов
.def TimCount=R19  ;счётчик переполнений таймер 0
.def Temp1=R20
.def Temp2=R21
.def Temp3=R22

.cseg
.org 0

rjmp RESET         ;переход на обработку сброса
rjmp EXT_INT0      ;переход на обработку запроса IRQ0
reti;rjmp EXT_INT1      ;переход на обработку запроса IRQ1
reti;rjmp TIM2_COMP     ;переход на обработку сравнения Timer2
reti;rjmp TIM2_OVF      ;переход на обработку при переполнении Timer2
reti;rjmp TIM1_CAPT     ;переход на обработку при захвате фронта Timer1
rjmp TIM1_COMPA    ;переход на обработку при срабатывании компаратора A Timer1
reti;rjmp TIM1_COMPB    ;переход на обработку при срабатывании компаратора B Timer1
reti;rjmp TIM1_OVF      ;переход на обработку при переполнении Timer1
rjmp TIM0_OVF      ;переход на обработку при переполнении Timer0
reti;rjmp SPI_STC       ;переход на обработку при завершении передачи SPI
reti;rjmp USART_RXC     ;переход на обработку при завершении приёма УСАППО
reti;rjmp USART_UDRE    ;переход на обработку при освобождении регистра
reti;rjmp USART_TXC     ;переход на обработку при завершении передачи
reti;rjmp ACDC          ;переход на обработку при завершении приобразования АЦП
reti;rjmp EE_RDY        ;переход на обработку при готовности EEROM
reti;rjmp ANA_COMP      ;переход на обработку при срабатывании аналогового компаратора
reti;rjmp TWSI          ;двухпроводный последовательный интерфейс
reti;rjmp SPM_RDY       ;переход на обработку прерывания при готовности записи в память программ

;************************************************************************************************
;МАССИВ
;************************************************************************************************

ARRAY0:
.db 0b01001001, 0b10010010, 0b00100100, 0          ;Максимум 16 эффектов 

ARRAY1:
.db 0b00000001, 0b00000010, 0b00000100, 0b00001000 ;1 светодиод светится 1/8 с (125000мкс)
.db 0b00010000, 0b00100000, 0b01000000, 0b10000000 ;частота без предделиеля 8Мгц => 1 такт 0,125мкс
.db 0b01000000, 0b00100000, 0b00010000, 0b00001000 ;всего 65535 => 1 такт должен длиться 2мкс =>
.db 0b00000100, 0b00000010, 0, 0                   ;частота предделителя 8*10^6/32 гц (011) (1такт 4мкс)

ARRAY2:
.db 0b00011000, 0b00100100, 0b01000010, 0b10000001 ;125000/4=31250 (7A12)
.db 0b01000010, 0b00100100, 0, 0                   ;

ARRAY3:
.db 0b00000001, 0b00000010, 0b00000100, 0b00001000 ;
.db 0b00010000, 0b00100000, 0b01000000, 0b10000000 ;
.db 0, 0                                           ;

ARRAY4:
.db 0b10000000, 0b01000000, 0b00100000, 0b00010000 ;
.db 0b00001000, 0b00000100, 0b00000010, 0b00000001 ;
.db 0, 0                                           ;

ARRAY5:
.db 0b00011000, 0b00100100, 0b01000010, 0b10000001 ;
.db 0, 0                                           ;

ARRAY6:
.db 0b00000001, 0b00000011, 0b00000111, 0b00001111 ;
.db 0b00011111, 0b00111111, 0b01111111, 0b11111111 ;
.db 0b11111110, 0b11111100, 0b11111000, 0b11110000 ;
.db 0b11100000, 0b11000000, 0b10000000, 0          ;

ARRAY7:
.db 0b10000000, 0b11000000, 0b11100000, 0b11110000 ;
.db 0b11111000, 0b11111100, 0b11111110, 0b11111111 ;
.db 0b01111111, 0b00111111, 0b00011111, 0b00001111 ;
.db 0b00000111, 0b00000011, 0b00000001, 0          ;

ARRAY8:
.db 0b00011000, 0b00111100, 0b01111110, 0b11111111 ;
.db 0b01111110, 0b00111100, 0, 0                   ;

ARRAY9:
.db 0b00000001, 0b00000011, 0b00000111, 0b00001111 ;
.db 0b00011111, 0b00111111, 0b01111111, 0b11111111 ;
.db 0b01111111, 0b00111111, 0b00011111, 0b00001111 ;
.db 0b00000111, 0b00000011, 0, 0                   ;

ARRAY10:
.db 0b10000000, 0b11000000, 0b11100000, 0b11110000 ;
.db 0b11111000, 0b11111100, 0b11111110, 0b11111111 ;
.db 0b11111110, 0b11111100, 0b11111000, 0b11110000 ;
.db 0b11100000, 0b11000000, 0, 0                   ;

;################################################################################################
;ИНИЦИАЛИЗАЦИЯ
;################################################################################################

Reset: ldi Temp, high(RAMEND)      ;Инциализация стека
       out SPH, Temp               ;
	   ldi Temp, low(RAMEND)       ;
	   out SPL, Temp               ;

       ldi Temp, 0b11111111        ;Инициализация портов
	   out DDRB, Temp              ;
	   ldi Temp, 0b00000100        ;Подтягивающий резистор на INT0
	   out PORTD, Temp             ;

	   clr Flag                    ;
	   clr Count                   ;
	   clr TimCount                ;

       ldi Temp, 0b00000010        ;инициализируем INT0 по спаду
	   out MCUCR, Temp             ;

	   ldi Temp, 0b01000000        ;включаем прерывание int0
	   out GICR, Temp              ;
	   	   
	   ldi Temp, 0b00010001        ;настройка прерываний(разрешаем прерывание компаратора 1-ого таймера)
	   out TIMSK, Temp             ;вывод в TIMSK

       ldi Temp, high(31250)       ;Задаём число в компаратор
	   out OCR1AH, Temp            ;
	   ldi Temp, low(31250)        ;
	   out OCR1AL, Temp            ;

       ldi Temp, 0b00000011        ;настройка предделителя
	   out TCCR1B, Temp            ;вывод в TCCR1B

       clr Temp                    ;Обнуляем таймер
       out TCNT1H, Temp            ;
       out TCNT1L, Temp            ;


	   sei                         ;

;#################################################################################################
;ООСНОВНОЙ ЦИКЛ
;#################################################################################################

Do:			sbrs Flag, 6           ;
			rjmp Do                ;
			ldi Temp3, 0x12        ;загружаем число 124F80 задержка 0,75с
			ldi Temp2, 0x48        ;6000000/5=1200000
			ldi Temp1, 0x80        ;750000/0,125=6000000
Delay:      subi Temp1, 1          ;задержка
			sbci Temp2, 0          ;
			sbci Temp3, 0          ;
			brcc Delay             ;
			cli                    ;запрещаем прерывания
			cbr Flag, 0b01000000   ;устанавливаем короткое нажатие
			sbrs Flag, 4           ;инверсия эффектов
			rjmp Invers            ;
			cbr Flag, 0b00010000   ;
			rjmp End               ;
Invers:     sbr Flag, 0b00010000   ;
End:        ldi Temp, 0b00000010   ;инициализируем INT0 по спаду
	   		out MCUCR, Temp        ;
			ldi Temp, 0b00000011   ;настройка предделителя
	   		out TCCR1B, Temp       ;вывод в TCCR1B
			sei                    ;разрешаем прерывния
			rjmp Do                ;

;#################################################################################################
;ПРЕРЫВАНИЕ КОМПАРАТОРА
;#################################################################################################

TIM1_COMPA: in Temp, SREG          ;сохраняем флаги в стек
			push Temp              ;
            clr Temp               ;Обнуляем таймер
			out TCNT1H, Temp       ;
			out TCNT1L, Temp       ;			

Test0:      mov Temp, Flag         ;Проверка кнопки
            andi Temp, 0b00001111  ;
            cpi Temp, 0            ;
			brne Test1             ;
            ldi ZH, High(ARRAY0*2) ;
			ldi ZL, Low(ARRAY0*2)  ;
			rjmp Readarray         ;

Test1:      cpi Temp, 1            ;
			brne Test2             ;
            ldi ZH, High(ARRAY1*2) ;
			ldi ZL, Low(ARRAY1*2)  ;
			rjmp Readarray         ;

Test2:      cpi Temp, 2            ;(10)
			brne Test3             ;
            ldi ZH, High(ARRAY2*2) ;
			ldi ZL, Low(ARRAY2*2)  ;
			rjmp Readarray         ;

Test3:      cpi Temp, 3            ;(11)
			brne Test4             ;
            ldi ZH, High(ARRAY3*2) ;
			ldi ZL, Low(ARRAY3*2)  ;
			rjmp Readarray         ;

Test4:      cpi Temp, 4            ;(100)
			brne Test5             ;
            ldi ZH, High(ARRAY4*2) ;
			ldi ZL, Low(ARRAY4*2)  ;
			rjmp Readarray         ;

Test5:      cpi Temp, 5            ;(101)
			brne Test6             ;
            ldi ZH, High(ARRAY5*2) ;
			ldi ZL, Low(ARRAY5*2)  ;
			rjmp Readarray         ;

Test6:      cpi Temp, 6            ;(110)
			brne Test7             ;
            ldi ZH, High(ARRAY6*2) ;
			ldi ZL, Low(ARRAY6*2)  ;
			rjmp Readarray         ;

Test7:      cpi Temp, 7            ;(111)
			brne Test8             ;
            ldi ZH, High(ARRAY7*2) ;
			ldi ZL, Low(ARRAY7*2)  ;
			rjmp Readarray         ;

Test8:      cpi Temp, 8            ;(1000)
			brne Test9             ;
            ldi ZH, High(ARRAY8*2) ;
			ldi ZL, Low(ARRAY8*2)  ;
			rjmp Readarray         ;

Test9:      cpi Temp, 9            ;(1001)
			brne Test10            ;
            ldi ZH, High(ARRAY9*2) ;
			ldi ZL, Low(ARRAY9*2)  ;
			rjmp Readarray         ;

Test10:     cpi Temp, 10            ;(1010,A)
            ldi ZH, High(ARRAY10*2) ;
			ldi ZL, Low(ARRAY10*2)  ;

Readarray:  ldi Temp, 0            ;загружаем элемент массива
            add ZL, Count          ;
			adc ZH, Temp           ;
			lpm                    ;
			mov Temp, R0           ;
			cpi Temp, 0            ;
			breq Go                ;
			inc Count              ;
			rjmp Output            ;

Go:         clr Count              ;
            rjmp Test0             ;

Output:     sbrc Flag, 4           ;проверка на бегущую тень
            com Temp               ;
			out PortB, Temp        ;вывод в порты
			pop Temp               ;
			out SREG, Temp         ;
			reti                   ;

;#############################################################################################
;ПРЕРЫВАНИЕ ПО КНОПКЕ
;#############################################################################################

EXT_INT0:   in Temp, SREG          ;сохраняем флаги в стек
			push Temp              ;
            clr Temp               ;
            out GICR, Temp         ;запрещаем прерывание по кнопке
	        out TCCR1B, Temp       ;останавливаем компаратор
			out TCCR0, Temp        ;останавливаем таймер 0
			out TCNT0, Temp        ;очищаем регистр 0 таймера
			cbr Flag, 0b01000000   ;длинного нажатия нет

            sbrs Flag, 5           ;если 0 то было нажатие, если 1 то отпускание
			rjmp PushCycl          ;
			clr Count              ;
			ldi Temp, 0b00000011   ;настройка предделителя
	        out TCCR1B, Temp       ;вывод в TCCR1B
			mov Temp, Flag         ;сравниваем счётчик нажатий
			andi Temp, 0b00001111  ;
			cpi Temp, 11           ;
			brne GO1               ;
			andi Flag, 0b11110000  ;
			rjmp GO2               ;
GO1:        inc Flag               ;
GO2:        cbr Flag, 0b00100000   ;
            ldi TimCount, 195      ;пауза 0,05 с
            ldi Temp, 0b00000001   ;запускаем таймер 0
			out TCCR0, Temp        ;частота 1/8
			clr count              ;
			pop Temp               ;извлекаем флаги из стека
			out SREG, Temp         ;
			reti

PushCycl:   sbr Flag, 0b00100000   ;
            ldi TimCount, 146      ;пауза 0,25 с
            ldi Temp, 0b00000011   ;частота 1/32
			out TCCR0, Temp        ;
			pop Temp               ;извлекаем флаги из стека
			out SREG, Temp         ;
			sei                    ;
			rjmp Do                ;конец прерывания

;#############################################################################################
;ПРЕРЫВАНИЕ ПО ПЕРЕПОЛНЕНИЮ ТАЙМЕРА 0
;#############################################################################################

TIM0_OVF:   in Temp, SREG          ;сохраняем флаги в стек
			push Temp              ;
            dec TimCount           ;
            breq Timer             ;
			pop Temp               ;извлекаем флаги из стека
			out SREG, Temp         ;
			reti                   ;

Timer:      clr Temp               ;останавливаем таймер 0
			out TCCR0, Temp        ;
			sbrs Flag, 5           ;
            rjmp GO3               ;
			ldi Temp, 0b00000011   ;инициализируем INT0 по фронту
	        out MCUCR, Temp        ;
			sbr Flag, 0b01000000   ;
			ldi Temp, 0b01000000   ;включаем прерывание int0
	        out GICR, Temp         ;
			ldi Temp, 0b00000011   ;настройка предделителя
	        out TCCR1B, Temp       ;вывод в TCCR1B
			pop Temp               ;извлекаем флаги из стека
			out SREG, Temp         ;
			reti

GO3:        ldi Temp, 0b00000010   ;инициализируем INT0 по спаду
	   		out MCUCR, Temp        ;
			ldi Temp, 0b01000000   ;включаем прерывание int0
	        out GICR, Temp         ;
			pop Temp               ;извлекаем флаги из стека
			out SREG, Temp         ;
			sei                    ;
			rjmp Do                ;конец прерывания
P.S.Ещё один баг нашёл. Вообще не понимаю почему так происходит. Если перебирать эффекты, то он меняет местами 3,4 массивы и 9,10 массивы. Как это исправить?
Demiurg
Это не хвост, это антенна
Сообщения: 1480
Зарегистрирован: Ср июн 25, 2008 15:19:44
Контактная информация:

Re:

Сообщение Demiurg »

Ассемблер ничем не отличается от других языков в плане абстракций. Проектирование сверху вниз. Забудьте о регистрах, байтах и тактах. Устройство, блоки устройства, блоки блоков. Алгоритмы. Берете бумажку и составляете ТЗ. Рисуйте алгоритмы. Когда это у вас будет, тогда будут и программы. По сути, программы будут писаться по нарисованным алгоритмам. Пишите программы на ассемблере так, как будто вы пишете на языке высокого уровня.
Ссылки на цикл статей я вам давал. Читайте, там все разжевано и даже картинки есть. Вам осталось написать программу по этим картинкам.
akl
Друг Кота
Сообщения: 4444
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Re:

Сообщение akl »

[uquote="radio-fan",url="/forum/viewtopic.php?p=3189945#p3189945"]

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

;#############################################################################################
;ПРЕРЫВАНИЕ ПО КНОПКЕ
;#############################################################################################

EXT_INT0:   in Temp, SREG          ;сохраняем флаги в стек
			push Temp              ;
            clr Temp               ;
            out GICR, Temp         ;запрещаем прерывание по кнопке
	        out TCCR1B, Temp       ;останавливаем компаратор
			out TCCR0, Temp        ;останавливаем таймер 0
			out TCNT0, Temp        ;очищаем регистр 0 таймера
			cbr Flag, 0b01000000   ;длинного нажатия нет

            sbrs Flag, 5           ;если 0 то было нажатие, если 1 то отпускание
			rjmp PushCycl          ;
			clr Count              ;
			ldi Temp, 0b00000011   ;настройка предделителя
	        out TCCR1B, Temp       ;вывод в TCCR1B
			mov Temp, Flag         ;сравниваем счётчик нажатий
			andi Temp, 0b00001111  ;
			cpi Temp, 11           ;
			brne GO1               ;
			andi Flag, 0b11110000  ;
			rjmp GO2               ;
GO1:        inc Flag               ;
GO2:        cbr Flag, 0b00100000   ;
            ldi TimCount, 195      ;пауза 0,05 с
            ldi Temp, 0b00000001   ;запускаем таймер 0
			out TCCR0, Temp        ;частота 1/8
			clr count              ;
			pop Temp               ;извлекаем флаги из стека
			out SREG, Temp         ;
			reti

PushCycl:   sbr Flag, 0b00100000   ;
            ldi TimCount, 146      ;пауза 0,25 с
            ldi Temp, 0b00000011   ;частота 1/32
			out TCCR0, Temp        ;
			pop Temp               ;извлекаем флаги из стека
			out SREG, Temp         ;
			sei                    ;
			rjmp Do                ;конец прерывания[/uquote]Здесь будет срыв стека, т.к. выход из прерывания по RJMP
Аватара пользователя
radio-fan
Родился
Сообщения: 8
Зарегистрирован: Чт май 18, 2017 11:57:03
Откуда: Барнаул

Сообщение radio-fan »

Если прерывание int0 произойдёт во время отсчёта задержки, то командой reti мы вернёмся обратно в задержку, а после прерывания она нам уже будет не нужна.
Только вот что, а если из прерывания выходить не через reti, то в стеке будет оставаться адрес?
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение ARV »

radio-fan писал(а): если из прерывания выходить не через reti, то в стеке будет оставаться адрес?
ясен пень, куда ж ему деваться-то?
не смотря на то, что ассемблер позволяет делать, что угодно, все-таки хорошей практикой следует признать выход из прерывания туда, откуда был вход. собственно, как и из любой другой подпрограммы.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
BOB51
Друг Кота
Сообщения: 15556
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение BOB51 »

RETI всего лишь сбрасывает блокировку прерываний
(восстанавливает флаг "глобального разрешения" I в регистре статуса SREG после того, как он будет АВТМАТИЧЕСКИ СБРОШЕН при входе в прерывание)
По обработке стека и RET и RETI
ОДНО И ТО ЖЕ.
8)
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение ARV »

BOB51 писал(а):По обработке стека и RET и RETI
ОДНО И ТО ЖЕ
только речь про
akl писал(а):rjmp Do ;конец прерывания
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
akl
Друг Кота
Сообщения: 4444
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Re:

Сообщение akl »

[uquote="radio-fan",url="/forum/viewtopic.php?p=3191470#p3191470"]...если из прерывания выходить не через reti, то в стеке будет оставаться адрес?[/uquote]Да, но указатель стека SP будет смещен и следующие прерывания с таким же условием будут его смещать и смещать. В итоге зависон обеспечен.
Ответить

Вернуться в «AVR»