0 / 0 / 0
Регистрация: 11.08.2011
Сообщений: 466
|
|
1 | |
Atmega 162, два USART, одновременный приход/отправка байта28.08.2011, 22:42. Показов 18639. Ответов 43
Метки нет (Все метки)
Доброе время суток.
Есть Atmega 162 в которой два USORT. Для каждого обрабатывается прерывание на получение/отправку байта. Вопрос вот в чем. Предположим пришел символ на USORT0, вошли в прерывание и выставили cli(). В это время приходит/уходит символ на втором USORT1 (а у нас режим запрета глобальных прерываний). Отработал обработчик вызванного прерывания USORT0, выставили sei(). Что произойдет дальше? Вызовется ли прерывание на USORT1, или будет выставлен флаг прерывания в регистре UCSRA1 но без прерывания, и функцию обработки надо вызывать вручную?
0
|
28.08.2011, 22:42 | |
Ответы с готовыми решениями:
43
Не программируется ATmega 162 ATMEGA 162 16AU 1027H Отправка UDP пакета - два лишних байта ATMega 162 помогите разобраться с UART ATmega 162 не могу вывести данные в PORTB в Proteus |
0 / 0 / 0
Регистрация: 28.09.2010
Сообщений: 4,283
|
|
28.08.2011, 22:51 | 2 |
Если второе прерывание разрешено, то оно случится. Программа кинется в его обработчик.
0
|
0 / 0 / 0
Регистрация: 11.08.2011
Сообщений: 466
|
|
28.08.2011, 23:00 | 3 |
Сообщение от dsodir
0
|
0 / 0 / 0
Регистрация: 12.07.2011
Сообщений: 2
|
|
28.08.2011, 23:19 | 4 |
Второе прерывание выполнится. Но если первое прерывание будет слишком долгим, то следующие пришедшие на второй порт символы могут быть потеряны.
Нет, не правильно. При выходе из первого прерывания и установленном флаге на второе вызов второго прерывания произойдет после выхода из первого. Это если выход делать по правилам, через reti. Если в первом прерывании разрешать прерывания, то вызов второго прервет вызов первого.
0
|
0 / 0 / 0
Регистрация: 11.08.2011
Сообщений: 466
|
|
28.08.2011, 23:27 | 5 |
Сообщение от PRS
И еще один вопросик. МК работает на 16Мгц. Предположим, что скорость передачи составляет 250 000 бод. Если нам надо грубо оценить время в тактах, которое пройдет между передачей/получением байтов по USORT, то получается около 64 (без учета буферизации USORT, пусть это будет спасательным кругом если тормознули). То есть надо успеть обработать каждый принятый байт за это время деленное на 2 (два USORTA).
0
|
0 / 0 / 0
Регистрация: 12.07.2011
Сообщений: 2
|
|
29.08.2011, 01:33 | 6 |
Сообщение от Doimom78
В общем случае, у авр вызовы прерываний не вложенные. Для их разрешения нужно руками ставить флаг I.
0
|
0 / 0 / 0
Регистрация: 11.08.2011
Сообщений: 466
|
|
29.08.2011, 12:10 | 7 |
Сообщение от PRS
В общем случае, у авр вызовы прерываний не вложенные. Для их разрешения нужно руками ставить флаг I. Извините, видимо у меня принципиальное недопонимание. Предположим есть что то вроде обработчика Код
void some_int_homdler () { cli(); //Суперкод sei(); return; // Исключительно для наглядности } Что то делаем; Устанавливаем флаг глобальных прерываний; Выходим (return я для наглядности вставил, в коде его нет, но в ассемблерном листинге будет один из вариантов возврата типа выталкивание из стека адреса возврата и переход на него, а может еще чего) 1. Итак, вошли в прерывание. Правильно ли я понимаю, что хоть мы и в прерывании, но флаг разрешен, и теоретически мы можем прервать обработчик прерывания? 2. Сняли Флаг прерываний. Все, теперь нас ни кто не прервет. Если разрешены другие прерывания и они случились, то они только взведут свои флаги. Кстати если за время нашего прерывания случится больше двух других прерываний, то начнется исполняться первым с наименьшим номером (читал об этом, но там спор шел так ли это или не так)? 3.Закончили обработку. Флаг прерывания сброшен. Доходим до ключевых операторов. Ситуация следующая. Глобальные прерывания запрещены, но у парочки флаги подняты, они на низком старте и ждут поднятия глобального флага прерываний. Счетчик команд указывает на sei(); 4.Исполняем sei(); Флаг глобальных прерываний подымается (то есть как в выделенной Вашей цитате я вручную взвел флаг), счетчик переходит на оператор return; И...... БАЦ, фиг Вам, младшее прерывание, как наиболее шустрое, забирает управление на себя. Что делает процессор. Запихивает в стек текущий указатель команд, для нас это будет Сишный return, и входит в другое прерывание. Прошу не пинать, но как я понял то, что Вы описали выше, выльется в другой сценарий. Доходим пункта 4. Исполняем sei, но процессор откладывает взведение флага прерываний до выхода из текущего прерывания. После того, как мы выполнили return, процессор вспоминает, что флаг то уже пора бы и поднять, и взводит флаг глобальных прерываний. Я правильно понимаю? Еще раз уточню, что пишу на "Cи", то есть не вижу что там замутил компилятор. То ли reti, то ли условно pop adres, jmp adres, то ли еще что.
0
|
0 / 0 / 0
Регистрация: 19.09.2010
Сообщений: 1,761
|
|
29.08.2011, 12:20 | 8 |
Вложенные прерывания можно использовать, но при этом нужно контролировать ход выполнения программы вплоть до такта, и любая ошибка может взорвать мозг при её поиске. Даже не могу представить задачи, где они пригодились бы...
0
|
0 / 0 / 0
Регистрация: 11.08.2011
Сообщений: 466
|
|
29.08.2011, 12:25 | 9 |
[QUOTE="ptoop"][QUOTE="Цитата:[/QUOTE]
Вложенные прерывания можно использовать, но при этом нужно контролировать ход выполнения программы вплоть до такта, и любая ошибка может взорвать мозг при её поиске. Даже не могу представить задачи, где они пригодились бы... То есть cli() внутри прерывания сбрасывает уже сброшенный флаг? А команда sei() раньше времени подымает флаг, который итак встанет после выхода из прерывания? Получается, что для исключения вложенных прерываний, надо один раз поднять флаг, а дальше каждое прерывание уже "само будет использовать" механизм cli/sei, чтобы не допустить своего прерывания, и разрешить его после окончания своей работы? Пойду смотреть, как же компилятор реализует обработку прерывания на асме.
0
|
0 / 0 / 0
Регистрация: 28.10.2010
Сообщений: 893
|
|
29.08.2011, 12:38 | 10 |
1. Итак, вошли в прерывание. Правильно ли я понимаю, что хоть мы и в прерывании, но флаг разрешен, и теоретически мы можем прервать обработчик прерывания?
2. Сняли Флаг прерываний. Все, теперь нас ни кто не прервет. Если разрешены другие прерывания и они случились, то они только взведут свои флаги. Кстати если за время нашего прерывания случится больше двух других прерываний, то начнется исполняться первым с наименьшим номером (читал об этом, но там спор шел так ли это или не так)? ---------------------------------------- Флаг нельзя запретить/разрешить, это аппаратная штучка и срабатывает автоматически по определенному событию. Сброшенный флаг в следующем такте может опять взвестись. По большому счету случиться может только взвод флага, А прерывания подчинены программе и происходят только при их разрешении и наличии взведенного флага.
0
|
0 / 0 / 0
Регистрация: 11.08.2011
Сообщений: 466
|
|
29.08.2011, 12:49 | 11 |
Сообщение от инкер
Аппаратные флаги, сигнализирующие о каких либо событиях я тут рассматриваю, только в разрезе того, что за время нашего прерывания, случились другие события которые взвели свои флаги прерываний и ждут, когда их обработают. Но мы с ними ни каких действий не совершаем.
0
|
0 / 0 / 0
Регистрация: 19.09.2010
Сообщений: 1,761
|
|
29.08.2011, 12:56 | 12 |
0
|
0 / 0 / 0
Регистрация: 12.07.2011
Сообщений: 2
|
|
29.08.2011, 13:02 | 13 |
1. Когда вызывается прерывание, то флаг I автоматически сбрасывается.
2. При выходе из прерывания по через reti, флаг I ставиться тоже автоматически. 3. Это все делается аппаратно и компилятор сам ничего не разрешает/запрещает. Единственное отличие, что для выхода из прерывания компилятор использует reti вместо ret.
0
|
0 / 0 / 0
Регистрация: 11.08.2011
Сообщений: 466
|
|
29.08.2011, 13:05 | 14 |
Огромное всем спасибо за разъяснение
0
|
0 / 0 / 0
Регистрация: 28.10.2010
Сообщений: 893
|
|
29.08.2011, 13:20 | 15 |
Сообщение от Doimom78
0
|
0 / 0 / 0
Регистрация: 28.09.2010
Сообщений: 4,283
|
|
29.08.2011, 13:29 | 16 |
- Нет сынок, это фантастика...
0
|
0 / 0 / 0
Регистрация: 19.09.2010
Сообщений: 1,761
|
|
29.08.2011, 13:38 | 17 |
0
|
0 / 0 / 0
Регистрация: 28.09.2010
Сообщений: 4,283
|
|
29.08.2011, 13:42 | 18 |
На самом деле, все до безобразия просто:
Если (установлен флаг I в SREG) и (установлен флаг разрешения прерывания) и (установлен флаг прерывания) то бежим в обработчик.
0
|
0 / 0 / 0
Регистрация: 11.08.2011
Сообщений: 466
|
|
29.08.2011, 13:43 | 19 |
Сообщение от инкер
Тогда еще раз. sei/cli разрешает/запрещает прерывания глобально. Это факт установленный, вроде вне сомнения. Теперь у нас есть регистр состояния в котором есть бит номер 7, который реагирует на sei/cli. Как он правильно называется? Я думал что флаг разрешения/запрещения глобального прерывания.
Сообщение от инкер
Сообщение от инкер
Епрст, пока строчил ответ, еще постов добавилось.
0
|
0 / 0 / 0
Регистрация: 28.10.2010
Сообщений: 893
|
|
29.08.2011, 13:46 | 20 |
[QUOTE="dsodir"][QUOTE="Цитата:[/QUOTE]
- Нет сынок, это фантастика... Это не флаг, это бит разрешения. Там есть флаги переноса и т.д., но не I. Никакое событие периферии не способно прямо воздействовать на этот бит, значит это не флаг.
0
|
29.08.2011, 13:46 | |
29.08.2011, 13:46 | |
Помогаю со студенческими работами здесь
20
atmega 328p USART Atmega 2560 проблема с USART USART на ATMega. Совмещённый регистр UBRRH\UCSRC Задана запись с вариантами, имеющая два поля длиной два байта каждое Отправка 2-х байт по USART Задана запись с вариантами, имеющая два поля длиной два байта (Integer) каждое. Получить их значения побайтно Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |