Не видно.Land писал(а):На картинке видно
Ассемблер (ASM) для AVR в вопросах и ответах
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
- Реклама
- Сообщения: 217
- Зарегистрирован: Ср янв 11, 2012 11:55:51
1. В смысле руками? Нет. Флаг устанавливается через некоторое количество циклов, не поленился, пощелкал в пошаговом режиме.akl писал(а):1. Думаю, что стек Вы установили
2. При входе в прерывание I-флаг сбрасывается аппаратно, а выходите Вы RJMPом, естественно, зависая навсегда на PAUSE.
2. Можно другими словами, чуть доступнее? Я-то получается в прерывание не вхожу, т.к. перехода по вектору не происходит. Флаг выставился, меня должно сбросить на пятый вектор, а с него rjmp на дальнейшую обработку. Или я что-то недопонимаю?
флаг TOV0 -- разве не флаг переполнения?Gudd-Head писал(а):Не видно.
1. При чём тут флаг??? Вас про указатель стэка спрашивают.Land писал(а):1. В смысле руками? Нет. Флаг устанавливается через некоторое количество циклов, не поленился, пощелкал в пошаговом режиме.
2. Можно другими словами, чуть доступнее? Я-то получается в прерывание не вхожу, т.к. перехода по вектору не происходит. Флаг выставился, меня должно сбросить на пятый вектор, а с него rjmp на дальнейшую обработку. Или я что-то недопонимаю?
2. Для выхода из прерывания надо использовать RETI.
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
- Сообщения: 217
- Зарегистрирован: Ср янв 11, 2012 11:55:51
ага. А куда положить (в смысле на какой фотохост) чтобы было видно?ploop писал(а):Ссылка не работает, потому не видно.
- Реклама
Можно же прямо на форум картинку выложить, но не в ней дело... Исправьте выход из прерывания как вам сказали, и проверьте результат.
Последний раз редактировалось Engineer_Keen Пт май 18, 2012 12:24:40, всего редактировалось 1 раз.
- Сообщения: 217
- Зарегистрирован: Ср янв 11, 2012 11:55:51
1.Gudd-Head писал(а): 1. При чём тут флаг??? Вас про указатель стэка спрашивают.
2. Для выхода из прерывания надо использовать RETI.
2. вот так?ldi r16,HIGH(RAMEND) ;Загрузка в регистр r16 адреса верхней границы ОЗУ
out SPH,r16 ;Копирование значения из r16 в регистр указателя стека SPH
ldi r16,LOW(RAMEND) ;Загрузка в регистр r16 адреса верхней границы ОЗУ
out SPL,r16 ;Копирование значения из r16 в регистр указателя стека SPL
.org OVF0addr ;Задание адреса прерывания по переполнению таймера 0
reti rjmp timer0_ovf ;Безусловный переход к метке timer0_ovf
Land писал(а):reti rjmp timer0_ovf ;Безусловный переход к метке timer0_ovf
Вы знаете что такое и где находится выход из прерывания?
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Тогда при возникновении прерывания будет сразу возврат из него, какой смысл? Это вместо BRNE pause надо писать, только изменить немного выход из цикла.Land писал(а):2. вот так?
- Сообщения: 217
- Зарегистрирован: Ср янв 11, 2012 11:55:51
а почему из прерывания компаратора по rjmp уходит? Вернее тут же дело не в том, как с прерывания уходит. Проблема в том, что на прерывание не уходит.Engineer_Keen писал(а):Можно же прямо на форум картинку выложить, но не в ней дело... Исправьте выход из прерывания как вам сказали, и проверьте результат.
ну видимо нет. Пойду еще раз читать. Я так понимаю, просить поделиться сокровенным знанием не стоит?Land писал(а):
reti rjmp timer0_ovf ;Безусловный переход к метке timer0_ovf
Вы знаете что такое и где находится выход из прерывания?
Честно признаюсь -- не понял.Тогда при возникновении прерывания будет сразу возврат из него, какой смысл? Это вместо RJMP pause надо писать
Почему же? При возникновении прерывания флаг I сбрасывается (чтобы другое прерывание не помешало, если оно вдруг произойдёт в это время), и "МК прыгает" (на самом деле в счётчик команд подгружается) в начало памяти программ на таблицу векторов прерывания. Там ставят команды RJMP на область кода, где расположен обработчик прерывания. И в конце этого обработчика ставят команду RETI, которая выставляет обратно флаг I и "возвращает МК" на то место, где его застало прерывание.Land писал(а):Я так понимаю, просить поделиться сокровенным знанием не стоит?
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
- Сообщения: 217
- Зарегистрирован: Ср янв 11, 2012 11:55:51
Все. Кажется сообразил. После срабатывания компаратора не происходит установки флага I. И следовательно прерывание таймера запрещено. Я был уверен, что элементарщину не догоняю!
UPD: УРА!!! Заработало!!! Всем огромное спасибо!!!
Угу. Только про Правила Форума не забываем. Особенно пп. 2.2 и 2.7.
Gudd-Head
UPD: УРА!!! Заработало!!! Всем огромное спасибо!!!
Угу. Только про Правила Форума не забываем. Особенно пп. 2.2 и 2.7.
Gudd-Head
Лучше ввести переменную-признак, которую в прерывании от таймера обнулить. а в программе проверять признак, а не ждать когда таймер закончится. Ведь в вашем случае, когда не произойдет вызов возврата из прерывания в стеке будет находится лишний адрес возврата, ну 20-30 раз прерывание сработает... и все, стек переполнится и затрет важные переменные.
Впрочем, при большой необходимости стек можно освободить принудительно и разрешить прерывания сразу после метки "tmr_clr". Но к этому лучше не привыкать.
А вообще тут даже интересно применить команду SLEEP или аналогичную - контроллер "уснет" до тех пор пока не возникнет прерывание - вот тебе и пауза.
Впрочем, при большой необходимости стек можно освободить принудительно и разрешить прерывания сразу после метки "tmr_clr". Но к этому лучше не привыкать.
А вообще тут даже интересно применить команду SLEEP или аналогичную - контроллер "уснет" до тех пор пока не возникнет прерывание - вот тебе и пауза.
- Сообщения: 217
- Зарегистрирован: Ср янв 11, 2012 11:55:51
ну у меня одного переполнения не хватает на всю выдержку, надо считать количество переполнений. Видимо Sleep выигрыша не даст никакого (энергопотребление не важно в принципе)Alexeyslav писал(а):Лучше ввести переменную-признак, которую в прерывании от таймера обнулить. а в программе проверять признак, а не ждать когда таймер закончится.
А вообще тут даже интересно применить команду SLEEP или аналогичную - контроллер "уснет" до тех пор пока не возникнет прерывание - вот тебе и пауза.
ну я так и сделал. А чем потенциально плох такой вариант?Впрочем, при большой необходимости стек можно освободить принудительно и разрешить прерывания сразу после метки "tmr_clr". Но к этому лучше не привыкать.
Отсутсвием контроля за ветвлением программы. управление туда может перейти не только когда это нужно...
Надо подождать несколько прерываний? организуешь цикл внутри которого ждешь одно прерывание. И делов-то.
Надо подождать несколько прерываний? организуешь цикл внутри которого ждешь одно прерывание. И делов-то.
- Сообщения: 58
- Зарегистрирован: Вс май 29, 2011 19:59:19
Кто-нибудь может пояснить, как настроить порты на xmega (256A3)...? На assembler естественно.. На мегах разобрался, всё понятно, а на xmega по ДШ не понял...
Да и вообще информации мало по assembler и xmega на русском.. Ну искал я , честно 
- Сообщения: 217
- Зарегистрирован: Ср янв 11, 2012 11:55:51
ну разумеется так и делаю. Вот только после sleep у меня почему-то переходит на следующую строку не дожидаясь пока таймер натикает. Что-то опять не догоняю.Alexeyslav писал(а): Надо подождать несколько прерываний? организуешь цикл внутри которого ждешь одно прерывание. И делов-то.
сон заканчивается по любому прерыванию, не только от таймера. если есть возможность, надо запретить остальные прерывания и оставить только таймер если хочешь быть уверенным что SLEEP закончится только после отсчета таймера. Если прерывания другие запрещать нельзя, тогда остается только проверять признак. Кстати, не обязательно для этого заводить какую-то переменную. Достаточно запретить прерывание от таймера и проверять бит переполнения таймера, обнуляя его когда он устанавливается в активное состояние и в начале цикла.
- Сообщения: 217
- Зарегистрирован: Ср янв 11, 2012 11:55:51
нет, как раз это не мешает, я все равно после выхода из паузы проверяю не было ли за это время еще сработки компаратора, так что если из сна по прерыванию компаратора выйдет -- не беда, надо только корректно это обработать. Тут другая ошибка проявилась. В sleep я вхожу, но почему-то в его состоянии таймер не считаетAlexeyslav писал(а):сон заканчивается по любому прерыванию, не только от таймера.
Кстати, а можно ли этоsei
ldi r16,(1<<CS02)|(1<<CS00) ;Загрузка двух "1", смещенных на CS00 и CS02
out TCCR0B,r16 ;Копирование значения из регистра r16 в регистр TCCR0B
ldi r16,(1<<SE)
out MCUCR,r16
sleep
; Цикл ожидания переполнения таймера 0
timer0_ovf: dec r18 ; счет кол-ва циклов переполнения таймера
cpi r18,0
breq stop
reti
более компактно прописать?ldi r16,(1<<SE)
out MCUCR,r16
не прокатывает почему-то.sbi MCUCR,SE
Не прокатывает потому что SBI работает только с нижней частью портов. увы.
Но ничто не мешает вам прописать ту конструкцию как макрос и вызывать одной короткой строчкой.
Где-то тут я уже видел универсальные макросы с условной компиляцией, которые используют SBI к младшим регистрам и более сложную конструкцию для старших портов.
Но его несложно самому написать, в хелпе прочитать про директиву .macro и директивы условной компиляции.
Ага, таймер останавливается потому что микроконтроллер переходит в глубокий сон с остановкой тактового генератора, я точно не помню но атмеловске контроллеры имеют несколько режимов сна и они как-то настраиваются. Среди них есть такие режимы которые не останавливают переферию и тактовый генератор, например режим сна для минимизации шумов на время измерения АЦП который останавливает только ядро.
Регистр MCUCR биты SM2..0 определяют режим сна. Тебе поидее нужен режим 000 - Idle.
Но ничто не мешает вам прописать ту конструкцию как макрос и вызывать одной короткой строчкой.
Где-то тут я уже видел универсальные макросы с условной компиляцией, которые используют SBI к младшим регистрам и более сложную конструкцию для старших портов.
Но его несложно самому написать, в хелпе прочитать про директиву .macro и директивы условной компиляции.
Ага, таймер останавливается потому что микроконтроллер переходит в глубокий сон с остановкой тактового генератора, я точно не помню но атмеловске контроллеры имеют несколько режимов сна и они как-то настраиваются. Среди них есть такие режимы которые не останавливают переферию и тактовый генератор, например режим сна для минимизации шумов на время измерения АЦП который останавливает только ядро.
Регистр MCUCR биты SM2..0 определяют режим сна. Тебе поидее нужен режим 000 - Idle.


