OBB
|
|
1 | |
Вызов подпрограммы из обработчика события28.03.2016, 15:01. Показов 14825. Ответов 53
Метки нет (Все метки)
Добрый день!
Пишу простенькую программу "мигающий светодиод". Реализовал с использованием таймера 0. Код
.def temp = r16 ;рабочая переменная .def counter = r17 ;счетчик .def max_counter_value = r18 ;счетчик .def currentValue = r19 ;результат ;============ прерывания ============ rjmp RESIT ;RESIT External Pin, Power-on Riset, Brown-out Riset, Watchdog Riset reti ;INT0 External Ymtirrupt Request 0 reti ;PCINT0 Pin Change Ymtirrupt Request 0 reti ;TIMER1_COMPA Timer/Counter1 Compare Match A reti ;TIMER1_OVF Timer/Counter1 Overflow rjmp TIMER0_OVF;TIMER0_OVF Timer/Counter0 Overflow reti ;EE_RDY EEPROM Ready reti ;ANA_COMP Analog Comparator reti ;ADC ADC Conversion Complete reti ;TIMER1_COMPB Timer/Counter1 Compare Match B reti ;TIMER0_COMPA Timer/Counter0 Compare Match A reti ;TIMER0_COMPB Timer/Counter0 Compare Match B reti ;WDT Watchdog Time-out reti ;USI_START USI START reti ;USI_OVF USI Overflow RESIT: ;начальная инициализация ldi temp,low(ROMEND) ;загрузка указателя стека out SPL,temp LDI currentValue, $00 ldi temp, $05 out TCCR0B,temp ldi max_counter_value, $33 CLR temp OUT SREG, temp LDI temp, $FF OUT DDRB, temp clr counter ;очищаем счетчик clr temp ldi temp,(1<<TOIE0) ;разр. прерывания Timer0 out TIMSK,temp sei ;разрешаем прерывания Gcykle: ;основной пустой цикл rjmp Gcykle TIMER0_OVF:;обработчик прерывания Timer0 yms counter ;в каждом прерывании увеличиваем на 1 CP counter, max_counter_value BRSH ChangeState ;некий код который надо выполнить даже в случае перехода на ChangeState reti ;конец обработки прерывания таймера ChangeState: LDI counter, $00 COM currentValue OUT PORTB, currentValue reti |
28.03.2016, 15:01 | |
Ответы с готовыми решениями:
53
Вызов обработчика события Вызов обработчика события. Ручной вызов обработчика события Косвенный вызов DoEvents() из обработчика события? |
0 / 0 / 0
Регистрация: 06.12.2016
Сообщений: 3,044
|
|
29.03.2016, 17:52 | 21 |
Сообщение от YTYOUT
Сообщение от YTYOUT
0
|
0 / 0 / 0
Регистрация: 02.10.2012
Сообщений: 1,946
|
|
29.03.2016, 22:56 | 22 |
Ну раз потоптался , давай исправляй код так , чтобы там совсем не было меток. :)) Что вполне себе возможно. Дашь пример для начинающих.
0
|
0 / 0 / 0
Регистрация: 06.12.2016
Сообщений: 3,044
|
|
29.03.2016, 23:15 | 23 |
Сообщение от YTYOUT
2 - А смысл? Если все уже перетерли. Пагранист показал пример с вызовом подпрограммы. Я показал пример с джампами. Сидеть, вникать, ужать пару тактов-байтов мне и лень и некогда, не до того. Обдумывал и твой предложенный вариант. Выполнить таинственный код до проверки. Но кто его знает, что там автору нужно? Примеров начинающему в этой теме дали достаточно, чтобы он продолжал дальше.
0
|
0 / 0 / 0
Регистрация: 02.10.2012
Сообщений: 1,946
|
|
30.03.2016, 01:52 | 24 |
Ну ты занудой стал :)) Я предлагал проабгрейдить только этот кусок
Код
CP counter, max_counter_value //Сравниваем BRSH ChangeState // Если больше или равно топаем на ChangeState reti //
0
|
1 / 1 / 0
Регистрация: 09.08.2014
Сообщений: 96
|
|
30.03.2016, 09:31 | 25 |
Сообщение от YTYOUT
BRSH ChangeState // Если больше или равно топаем на ChangeState reti // Ага ага, и то что вот на это завязано "CP counter, max_counter_value" тоже. Плюсовать counter и занимать под константу max_counter_value регистр не самое изящное решение.
0
|
0 / 0 / 0
Регистрация: 06.12.2016
Сообщений: 3,044
|
|
30.03.2016, 10:20 | 26 |
Сообщение от Пагранист
0
|
OBB
|
|
30.03.2016, 12:36 | 27 |
Спасибо за ответы и за обсуждение.
Раз важна задумка, то отвечу: это тестовый пример по обучению программированию. В свое время писал простенькие программки, но это было очень очень давно и были они довольно простые. Сейчас встала задача собрать с четырех датчиков сигналы в виде синусоиды частотой от 0 до 2.5кГц с пока не известной амплитудой (предположительно на низких частотах будет порядка десятков милливольт, а на высоких -до вольта-двух (но это только предположение), посчитать частоту, рассчитать среднюю. Задачка не сложная, плюс со старых времен осталась одна mega8 и пять tiny25. Вот и начал вспоминать и оценивать чего достаточно для решения. Надо собственно с входящим сигналом разбираться. Будут помехи, так что не уверен что компаратором получится обойтись. |
0 / 0 / 0
Регистрация: 02.10.2012
Сообщений: 1,946
|
|
30.03.2016, 12:58 | 28 |
Сообщение от dymyurk1978
CP заменить на CPSE
0
|
1 / 1 / 0
Регистрация: 09.08.2014
Сообщений: 96
|
|
30.03.2016, 14:11 | 29 |
Сообщение от YTYOUT
Сообщение от dymyurk1978
Дык ни кто и не против задумки автора. Просто я сильно возражаю против пустой траты целого регистра и лишней команды на сравнеие. Как делает автор Код
; заводит будильник clr r17 ; обнуляет счётчик ldi r18,$33 ; загружает для него максимальное значение ТРАТИТ РЕГИСТР ПОПУСТУ ; а тут он считает прерывания TIMER0_OVF:;обработчик прерывания Timer0 yms r17 ;в каждом прерывании увеличиваем на 1 CP counter, max_counter_value ; сравнивает ИМХО ЛИШНЯЯ КОМАНДА+ЛИШНИЙ РЕГИСТР BRSH ChangeState ; условие (больше или равно) хотя лучше бы просто BREQ для ясности ;некий код который надо выполнить даже в случае перехода на ChangeState reti ;конец обработки прерывания таймера Код
ldi r17,$33 ; зачем считать ДО, когдаможно считать ОТ ; на этом месте получил свободу прозябающий от безделия регистр ; а тут я считаю прерывания TIMER0_OVF:;обработчик прерывания Timer0 dec r17 ;в каждом прерывании мы отнимаем еденицу BREQ ChangeState; и с нетерпением ждём флага нуля не сравнивая счётчик ни с чем ;некий код который надо выполнить даже в случае перехода на ChangeState reti ;конец обработки прерывания таймера
0
|
OBB
|
|
31.03.2016, 10:24 | 30 |
"BREQ ChangeState; и с нетерпением ждём флага нуля не сравнивая счётчик ни с чем"
Спасибо, теперь понятно почему в одном примере видел уменьшение на единицу. Тогда не понял для чего обратный счет, а не прямой. |
0 / 0 / 0
Регистрация: 02.10.2012
Сообщений: 1,946
|
|
31.03.2016, 12:08 | 31 |
А ещё лучше привыкнуть использовать команду subi вместо dec.
К вопросу про cpse Код
;некий код который надо выполнить даже в случае перехода на ChangeState CPSE counter, max_counter_value //Сравниваем reti LDI counter, $00 COM currentValue OUT PORTB, currentValue reti
0
|
0 / 0 / 0
Регистрация: 28.06.2010
Сообщений: 211
|
|
04.04.2016, 00:00 | 32 |
Сообщение от oomomstir
Сообщение от dymyurk1978
Ведь он совсем не виноват». Как-то так схоже звучит в какой-то песенке. Думаю, проблема не в ассемблере, а в отсутствии хорошего описания, как писать на ассемблере. Отсюда начинающие пишут нехорошо. Можно взять плохо написанную начинающим программу на ЯВУ и утверждать: «ЯВУ сильно деформирует мышление».
Сообщение от OBB
Сообщение от dymyurk1978
У имеющих некоторый опыт - никакой лапши и путаницы, никакой «игры с кубиками», никаких сносов всей конструкции, никаких «тщательных отслеживаний срыва стека» и т.д. Все проще. Надо только соблюдать некоторые правила написания программы.
0
|
0 / 0 / 0
Регистрация: 06.12.2016
Сообщений: 3,044
|
|
04.04.2016, 17:55 | 33 |
Сообщение от Otixomdr_1
0
|
1 / 1 / 0
Регистрация: 09.08.2014
Сообщений: 96
|
|
05.04.2016, 00:19 | 34 |
Сообщение от Otixomdr_1
Т.е. в программах где интервал между прерываниями гарантировано длиннее времени вычисления того что требуется обсчитать, можно не торопится вылезать из прерывания. Тем более под прерывание пихают как раз тот код который требует большего приоритета по отношению к остальному коду.
0
|
0 / 0 / 0
Регистрация: 02.10.2012
Сообщений: 1,946
|
|
05.04.2016, 01:14 | 35 |
Увеличивается время реакции на внешние события всей системы. Флаг , вылез из прерывания , обрабатывай. Зато не пропустишь если возникнет прерывание с высшим приоритетом
0
|
0 / 0 / 0
Регистрация: 28.10.2010
Сообщений: 893
|
|
05.04.2016, 03:21 | 36 |
Однозначно не скажешь, может увеличивается, а как правило нет. До анализа флага еще дойти нужно. Про "пропуск" прерывания тоже не совсем точное выражение, особенно если речь идет о другом прерывании, а не повторном том же самом. Тут правильнее говорить о соблюдении приоритетности, причем не той аппаратной, заложенной конструкторами таблицы, а той котороя нужна конкретно тебе.
0
|
1 / 1 / 0
Регистрация: 09.08.2014
Сообщений: 96
|
|
05.04.2016, 08:40 | 37 |
0
|
0 / 0 / 0
Регистрация: 28.10.2010
Сообщений: 893
|
|
05.04.2016, 10:22 | 38 |
Приемов миллион, когда нет жестких требований по времени или памяти можно ограничиться десятком и все будет работать. Когда-то нужно было сэкономить драгоценные байты и пришлось сделать выход из нескольких прерываний не классически, а прыжком в хвост одного из них. В результате сэкономились десяток байт, которые тратились на POPы при возврате по стандартному варианту.
0
|
0 / 0 / 0
Регистрация: 02.10.2012
Сообщений: 1,946
|
|
05.04.2016, 10:24 | 39 |
0
|
0 / 0 / 0
Регистрация: 06.12.2016
Сообщений: 3,044
|
|
05.04.2016, 10:54 | 40 |
[QUOTE="YTYOUT"][QUOTE="Цитата:[/QUOTE]
Не факт. Не каждая итерация основного цикла выполняется строго определенное время. Сложились условия, выполнили быстро. Сложились другие условия, выполнились долгие задачи. А так да, анализируем выполнение каждой функции. Если времени вагон, от прерываний можно отказаться.
0
|
05.04.2016, 10:54 | |
05.04.2016, 10:54 | |
Помогаю со студенческими работами здесь
40
Вызов единственного обработчика события при переопределении Вызов обработчика события после вывода изображения на оси Вызов обработчика кнопки из другого обработчика. Создание объекта-события и обработчика события Выход из обработчика события Создание обработчика события Подключение обработчика события Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |