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

Обсуждаем контроллеры компании Atmel.
Ответить
Друг Кота
Аватара пользователя
Сообщения: 20093
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

Сообщение Gudd-Head »

Land писал(а):На картинке видно
Не видно.
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Реклама
Прорезались зубы
Сообщения: 217
Зарегистрирован: Ср янв 11, 2012 11:55:51

Сообщение Land »

akl писал(а):1. Думаю, что стек Вы установили
2. При входе в прерывание I-флаг сбрасывается аппаратно, а выходите Вы RJMPом, естественно, зависая навсегда на PAUSE.
1. В смысле руками? Нет. Флаг устанавливается через некоторое количество циклов, не поленился, пощелкал в пошаговом режиме.
2. Можно другими словами, чуть доступнее? Я-то получается в прерывание не вхожу, т.к. перехода по вектору не происходит. Флаг выставился, меня должно сбросить на пятый вектор, а с него rjmp на дальнейшую обработку. Или я что-то недопонимаю?
Gudd-Head писал(а):Не видно.
флаг TOV0 -- разве не флаг переполнения?
Реклама
Друг Кота
Аватара пользователя
Сообщения: 20093
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

Сообщение Gudd-Head »

Land писал(а):1. В смысле руками? Нет. Флаг устанавливается через некоторое количество циклов, не поленился, пощелкал в пошаговом режиме.
2. Можно другими словами, чуть доступнее? Я-то получается в прерывание не вхожу, т.к. перехода по вектору не происходит. Флаг выставился, меня должно сбросить на пятый вектор, а с него rjmp на дальнейшую обработку. Или я что-то недопонимаю?
1. При чём тут флаг??? Вас про указатель стэка спрашивают.
2. Для выхода из прерывания надо использовать RETI.
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Модератор
Аватара пользователя
Сообщения: 13490
Зарегистрирован: Ср ноя 26, 2008 16:34:25
Откуда: Тамбовская обл.

Сообщение ploop »

Ссылка не работает, потому не видно.
Реклама
Эиком - электронные компоненты и радиодетали
Прорезались зубы
Сообщения: 217
Зарегистрирован: Ср янв 11, 2012 11:55:51

Сообщение Land »

ploop писал(а):Ссылка не работает, потому не видно.
ага. А куда положить (в смысле на какой фотохост) чтобы было видно?
Реклама
Друг Кота
Аватара пользователя
Сообщения: 3872
Зарегистрирован: Пт янв 29, 2010 10:27:40
Откуда: Москва

Сообщение Engineer_Keen »

Можно же прямо на форум картинку выложить, но не в ней дело... Исправьте выход из прерывания как вам сказали, и проверьте результат.
Последний раз редактировалось Engineer_Keen Пт май 18, 2012 12:24:40, всего редактировалось 1 раз.
Реклама
Прорезались зубы
Сообщения: 217
Зарегистрирован: Ср янв 11, 2012 11:55:51

Сообщение Land »

Gudd-Head писал(а): 1. При чём тут флаг??? Вас про указатель стэка спрашивают.
2. Для выхода из прерывания надо использовать RETI.
1.
ldi r16,HIGH(RAMEND) ;Загрузка в регистр r16 адреса верхней границы ОЗУ
out SPH,r16 ;Копирование значения из r16 в регистр указателя стека SPH
ldi r16,LOW(RAMEND) ;Загрузка в регистр r16 адреса верхней границы ОЗУ
out SPL,r16 ;Копирование значения из r16 в регистр указателя стека SPL
2. вот так?
.org OVF0addr ;Задание адреса прерывания по переполнению таймера 0
reti rjmp timer0_ovf ;Безусловный переход к метке timer0_ovf
Друг Кота
Аватара пользователя
Сообщения: 20093
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

Сообщение Gudd-Head »

Land писал(а):reti rjmp timer0_ovf ;Безусловный переход к метке timer0_ovf
:facepalm:
Вы знаете что такое и где находится выход из прерывания?
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Друг Кота
Аватара пользователя
Сообщения: 3872
Зарегистрирован: Пт янв 29, 2010 10:27:40
Откуда: Москва

Сообщение Engineer_Keen »

Land писал(а):2. вот так?
Тогда при возникновении прерывания будет сразу возврат из него, какой смысл? Это вместо BRNE pause надо писать, только изменить немного выход из цикла.
Прорезались зубы
Сообщения: 217
Зарегистрирован: Ср янв 11, 2012 11:55:51

Сообщение Land »

Engineer_Keen писал(а):Можно же прямо на форум картинку выложить, но не в ней дело... Исправьте выход из прерывания как вам сказали, и проверьте результат.
а почему из прерывания компаратора по rjmp уходит? Вернее тут же дело не в том, как с прерывания уходит. Проблема в том, что на прерывание не уходит.
Land писал(а):
reti rjmp timer0_ovf ;Безусловный переход к метке timer0_ovf


Вы знаете что такое и где находится выход из прерывания?
ну видимо нет. Пойду еще раз читать. Я так понимаю, просить поделиться сокровенным знанием не стоит?
Тогда при возникновении прерывания будет сразу возврат из него, какой смысл? Это вместо RJMP pause надо писать
Честно признаюсь -- не понял.
Друг Кота
Аватара пользователя
Сообщения: 20093
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

Сообщение Gudd-Head »

Land писал(а):Я так понимаю, просить поделиться сокровенным знанием не стоит?
Почему же? При возникновении прерывания флаг I сбрасывается (чтобы другое прерывание не помешало, если оно вдруг произойдёт в это время), и "МК прыгает" (на самом деле в счётчик команд подгружается) в начало памяти программ на таблицу векторов прерывания. Там ставят команды RJMP на область кода, где расположен обработчик прерывания. И в конце этого обработчика ставят команду RETI, которая выставляет обратно флаг I и "возвращает МК" на то место, где его застало прерывание.
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Прорезались зубы
Сообщения: 217
Зарегистрирован: Ср янв 11, 2012 11:55:51

Сообщение Land »

Все. Кажется сообразил. После срабатывания компаратора не происходит установки флага I. И следовательно прерывание таймера запрещено. Я был уверен, что элементарщину не догоняю!

UPD: УРА!!! Заработало!!! Всем огромное спасибо!!! :beer:

Угу. Только про Правила Форума не забываем. Особенно пп. 2.2 и 2.7.
Gudd-Head
Друг Кота
Сообщения: 4550
Зарегистрирован: Чт май 05, 2011 21:26:34
Откуда: Украина, Славутич

Сообщение Alexeyslav »

Лучше ввести переменную-признак, которую в прерывании от таймера обнулить. а в программе проверять признак, а не ждать когда таймер закончится. Ведь в вашем случае, когда не произойдет вызов возврата из прерывания в стеке будет находится лишний адрес возврата, ну 20-30 раз прерывание сработает... и все, стек переполнится и затрет важные переменные.

Впрочем, при большой необходимости стек можно освободить принудительно и разрешить прерывания сразу после метки "tmr_clr". Но к этому лучше не привыкать.

А вообще тут даже интересно применить команду SLEEP или аналогичную - контроллер "уснет" до тех пор пока не возникнет прерывание - вот тебе и пауза.
Контактная информация:
Прорезались зубы
Сообщения: 217
Зарегистрирован: Ср янв 11, 2012 11:55:51

Сообщение Land »

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

А вообще тут даже интересно применить команду SLEEP или аналогичную - контроллер "уснет" до тех пор пока не возникнет прерывание - вот тебе и пауза.
ну у меня одного переполнения не хватает на всю выдержку, надо считать количество переполнений. Видимо Sleep выигрыша не даст никакого (энергопотребление не важно в принципе)
Впрочем, при большой необходимости стек можно освободить принудительно и разрешить прерывания сразу после метки "tmr_clr". Но к этому лучше не привыкать.
ну я так и сделал. А чем потенциально плох такой вариант?
Друг Кота
Сообщения: 4550
Зарегистрирован: Чт май 05, 2011 21:26:34
Откуда: Украина, Славутич

Сообщение Alexeyslav »

Отсутсвием контроля за ветвлением программы. управление туда может перейти не только когда это нужно...

Надо подождать несколько прерываний? организуешь цикл внутри которого ждешь одно прерывание. И делов-то.
Контактная информация:
Открыл глаза
Сообщения: 58
Зарегистрирован: Вс май 29, 2011 19:59:19

Сообщение neurofunk »

Кто-нибудь может пояснить, как настроить порты на xmega (256A3)...? На assembler естественно.. На мегах разобрался, всё понятно, а на xmega по ДШ не понял... :cry: Да и вообще информации мало по assembler и xmega на русском.. Ну искал я , честно :?
Прорезались зубы
Сообщения: 217
Зарегистрирован: Ср янв 11, 2012 11:55:51

Сообщение Land »

Alexeyslav писал(а): Надо подождать несколько прерываний? организуешь цикл внутри которого ждешь одно прерывание. И делов-то.
ну разумеется так и делаю. Вот только после sleep у меня почему-то переходит на следующую строку не дожидаясь пока таймер натикает. Что-то опять не догоняю.
Друг Кота
Сообщения: 4550
Зарегистрирован: Чт май 05, 2011 21:26:34
Откуда: Украина, Славутич

Сообщение Alexeyslav »

сон заканчивается по любому прерыванию, не только от таймера. если есть возможность, надо запретить остальные прерывания и оставить только таймер если хочешь быть уверенным что SLEEP закончится только после отсчета таймера. Если прерывания другие запрещать нельзя, тогда остается только проверять признак. Кстати, не обязательно для этого заводить какую-то переменную. Достаточно запретить прерывание от таймера и проверять бит переполнения таймера, обнуляя его когда он устанавливается в активное состояние и в начале цикла.
Контактная информация:
Прорезались зубы
Сообщения: 217
Зарегистрирован: Ср янв 11, 2012 11:55:51

Сообщение Land »

Alexeyslav писал(а):сон заканчивается по любому прерыванию, не только от таймера.
нет, как раз это не мешает, я все равно после выхода из паузы проверяю не было ли за это время еще сработки компаратора, так что если из сна по прерыванию компаратора выйдет -- не беда, надо только корректно это обработать. Тут другая ошибка проявилась. В sleep я вхожу, но почему-то в его состоянии таймер не считает :shock: Хотя запущен:
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
не прокатывает почему-то.
Друг Кота
Сообщения: 4550
Зарегистрирован: Чт май 05, 2011 21:26:34
Откуда: Украина, Славутич

Сообщение Alexeyslav »

Не прокатывает потому что SBI работает только с нижней частью портов. увы.

Но ничто не мешает вам прописать ту конструкцию как макрос и вызывать одной короткой строчкой.

Где-то тут я уже видел универсальные макросы с условной компиляцией, которые используют SBI к младшим регистрам и более сложную конструкцию для старших портов.

Но его несложно самому написать, в хелпе прочитать про директиву .macro и директивы условной компиляции.

Ага, таймер останавливается потому что микроконтроллер переходит в глубокий сон с остановкой тактового генератора, я точно не помню но атмеловске контроллеры имеют несколько режимов сна и они как-то настраиваются. Среди них есть такие режимы которые не останавливают переферию и тактовый генератор, например режим сна для минимизации шумов на время измерения АЦП который останавливает только ядро.

Регистр MCUCR биты SM2..0 определяют режим сна. Тебе поидее нужен режим 000 - Idle.
Контактная информация:
Ответить

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