Форум программистов, компьютерный форум, киберфорум
Микроконтроллеры ATmega AVR
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.91/98: Рейтинг темы: голосов - 98, средняя оценка - 4.91
0 / 0 / 0
Регистрация: 11.08.2011
Сообщений: 466
1

Atmega 162, два USART, одновременный приход/отправка байта

28.08.2011, 22:42. Показов 18639. Ответов 43
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Доброе время суток.
Есть Atmega 162 в которой два USORT.
Для каждого обрабатывается прерывание на получение/отправку байта.
Вопрос вот в чем.
Предположим пришел символ на USORT0, вошли в прерывание и выставили cli().
В это время приходит/уходит символ на втором USORT1 (а у нас режим запрета глобальных прерываний).
Отработал обработчик вызванного прерывания USORT0, выставили sei().
Что произойдет дальше? Вызовется ли прерывание на USORT1, или будет выставлен флаг прерывания в регистре UCSRA1 но без прерывания, и функцию обработки надо вызывать вручную?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
28.08.2011, 22:42
Ответы с готовыми решениями:

Не программируется ATmega 162
Я недавно начал осваивать мк AVR, в частности мегу 162. Пишу в кодвижене простую программку...

ATMEGA 162 16AU 1027H
Парни здравствуйте! А можно ли считать ATMEGA 162 16AU 1027H без потери данных. Я в этом деле...

Отправка UDP пакета - два лишних байта
Народ проблема с формирование буфера для отправики через udp socket! Сформировал буфер для...

ATMega 162 помогите разобраться с UART
Добрый вечер! Помогите разобраться с UART0 на ATMiko162. Нашел пример работы на прерываниях, и...

ATmega 162 не могу вывести данные в PORTB в Proteus
Здравствуйте! Решил отлаживать устройство в Proteus, использую ATMiko 162 Столкнулся с тем, что...

43
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
Если второе прерывание разрешено, то оно случится. Программа кинется в его обработчик.
Ага, то есть если для USORT1 разрешены прерывания, то после отработки прерывания USORT0, при получении команды sei, прервется обработчик прерывания USORT0 и управление перейдет на обработчик прерывания для USORT1? Соответственно при обработке прерывания USORT1 в стеке будут два адреса возврата. Ниже адрес в теле обработчика прерывания для USORT0, следующая команда после sei, а выше адрес возврата из прерывания USORT0. Я правильно понимаю?
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
Это если выход делать по правилам, через reti. Если в первом прерывании разрешать прерывания, то вызов второго прервет вызов первого.
Я пишу на C, поэтому не могу непосредственно влиять на то, как компилятор реализует выход из прерывания, но если ситуация как в выделенной Вашей цитате. То есть предположим, что в ассемблерном коде sei будет стоять перед reti. Тогда прерывание второго порта прервет прерывание первого до возврата из него. Соответственно когда выполнится второе прерывание, то возврат будет идти по обратной цепочке. Сначала вернемся на reti первого прерывания, затем на прерванный участок программы. Так? Вроде я где то читал, что в 162 меге порт буферизирован: порт может начать принимать байт данных еще до того как предыдущий байт будет считан из буферного регистра приемника. То есть время вроде есть.

И еще один вопросик. МК работает на 16Мгц. Предположим, что скорость передачи составляет 250 000 бод.
Если нам надо грубо оценить время в тактах, которое пройдет между передачей/получением байтов по USORT, то получается около 64 (без учета буферизации USORT, пусть это будет спасательным кругом если тормознули). То есть надо успеть обработать каждый принятый байт за это время деленное на 2 (два USORTA).
0
0 / 0 / 0
Регистрация: 12.07.2011
Сообщений: 2
29.08.2011, 01:33 6
Цитата Сообщение от Doimom78
Я пишу на C, поэтому не могу непосредственно влиять на то, как компилятор реализует выход из прерывания, но если ситуация как в выделенной Вашей цитате. То есть предположим, что в ассемблерном коде sei будет стоять перед reti.
Не будет:) При выходе по reti флаг глобального прерывания восстанавливается и ставить дополнительное разрешение не нужно. А значит сначала будет выход, а затем вызов следующего прерывания.
В общем случае, у авр вызовы прерываний не вложенные. Для их разрешения нужно руками ставить флаг I.
0
0 / 0 / 0
Регистрация: 11.08.2011
Сообщений: 466
29.08.2011, 12:10 7
Цитата Сообщение от PRS
Цитата Сообщение от Doimom78
Я пишу на C, поэтому не могу непосредственно влиять на то, как компилятор реализует выход из прерывания, но если ситуация как в выделенной Вашей цитате. То есть предположим, что в ассемблерном коде sei будет стоять перед reti.
Не будет:) При выходе по reti флаг глобального прерывания восстанавливается и ставить дополнительное разрешение не нужно. А значит сначала будет выход, а затем вызов следующего прерывания.
В общем случае, у авр вызовы прерываний не вложенные. Для их разрешения нужно руками ставить флаг 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
1. Итак, вошли в прерывание. Правильно ли я понимаю, что хоть мы и в прерывании, но флаг разрешен, и теоретически мы можем прервать обработчик прерывания?
Нет. При входе в прерывание флаг I сбрасывается, и устанавливается после выхода из него. Всё это происходит автоматически.
4.Исполняем sei(); Флаг глобальных прерываний подымается (то есть как в выделенной Вашей цитате я вручную взвел флаг), счетчик переходит на оператор return;
Если вы вручную разрешите прерывания внутри обработчика прерывания - получите вложенные прерывания, и вместе с ним геморрой на своё мягкое место.

Вложенные прерывания можно использовать, но при этом нужно контролировать ход выполнения программы вплоть до такта, и любая ошибка может взорвать мозг при её поиске. Даже не могу представить задачи, где они пригодились бы...
0
0 / 0 / 0
Регистрация: 11.08.2011
Сообщений: 466
29.08.2011, 12:25 9
[QUOTE="ptoop"][QUOTE="Цитата:[/QUOTE]
1. Итак, вошли в прерывание. Правильно ли я понимаю, что хоть мы и в прерывании, но флаг разрешен, и теоретически мы можем прервать обработчик прерывания?
Нет. При входе в прерывание флаг I сбрасывается, и устанавливается после выхода из него. Всё это происходит автоматически.
4.Исполняем sei(); Флаг глобальных прерываний подымается (то есть как в выделенной Вашей цитате я вручную взвел флаг), счетчик переходит на оператор return;
Если вы вручную разрешите прерывания внутри обработчика прерывания - получите вложенные прерывания, и вместе с ним геморрой на своё мягкое место.

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

То есть 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
Цитата Сообщение от инкер
Флаг нельзя запретить/разрешить, это аппаратная штучка и срабатывает автоматически по определенному событию. Сброшенный флаг в следующем такте может опять взвестись.
Речь идет о флаге глобальных прерываний, который реагирует на cli/sei. То есть везде, где я говорю флаг, с которым мы совершаем действия, я имею ввиду флаг глобальных прерываний.

Аппаратные флаги, сигнализирующие о каких либо событиях я тут рассматриваю, только в разрезе того, что за время нашего прерывания, случились другие события которые взвели свои флаги прерываний и ждут, когда их обработают. Но мы с ними ни каких действий не совершаем.
0
0 / 0 / 0
Регистрация: 19.09.2010
Сообщений: 1,761
29.08.2011, 12:56 12
То есть cli() внутри прерывания сбрасывает уже сброшенный флаг? А команда sei() раньше времени подымает флаг, который итак встанет после выхода из прерывания?
Именно так. CLI и SEI должны использоваться вне прерываний, для глобального запрета их в случае необходимости (например, при записи в EEPROM).

Получается, что для исключения вложенных прерываний, надо один раз поднять флаг, а дальше каждое прерывание уже "само будет использовать" механизм cli/sei, чтобы не допустить своего прерывания, и разрешить его после окончания своей работы?
Угу. Это аппаратный механизм.

Пойду смотреть, как же компилятор реализует обработку прерывания на асме.
А что вы там увидите? Переход на вектор, потом на обработчик, и всё...

Аппаратные флаги, сигнализирующие о каких либо событиях я тут рассматриваю, только в разрезе того, что за время нашего прерывания, случились другие события которые взвели свои флаги прерываний и ждут, когда их обработают.
Ну он как-бы тоже аппаратный, только у локальных флагов своё аппаратное событие, при котором они устанавливаются/сбрасываются (счётчик досчитал, байт пришел и т.д.), а у этого только одно - вход/выход в прерывание.
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
Цитата Сообщение от инкер
Речь идет о флаге глобальных прерываний, который реагирует на cli/sei. То есть везде, где я говорю флаг, с которым мы совершаем действия, я имею ввиду флаг глобальных прерываний.

Аппаратные флаги, сигнализирующие о каких либо событиях я тут рассматриваю, только в разрезе того, что за время нашего прерывания, случились другие события которые взвели свои флаги прерываний и ждут, когда их обработают. Но мы с ними ни каких действий не совершаем.
Флага глобального прерывания не существует, команда cli и вход в прерывание действуют как запрет на реагирование на флаги прерываний. Команда sei и reti - разрешают реакцию на флаги. Для удобства параллельно в прерывании запрещаются все прерывания и сбрасывается флаг конкретного обрабатываемого прерывания. Но это не исключает вход во вложенное прерывание за счет принудительного разрешения глобальных прерываний.
0
0 / 0 / 0
Регистрация: 28.09.2010
Сообщений: 4,283
29.08.2011, 13:29 16
Флага глобального прерывания не существует
- Папа, а правда, что флаг I в регистре SREG это глобальный флаг разрешения/запрещения прерываний?
- Нет сынок, это фантастика...
0
0 / 0 / 0
Регистрация: 19.09.2010
Сообщений: 1,761
29.08.2011, 13:38 17
команда cli и вход в прерывание действуют как запрет на реагирование на флаги прерываний.
И что должно произойти после этой команды? Ну просто, если логически подумать? Ядро должно обложить матом периферию со словами - "если, сука, в прерывание сунешься, спалю нах!!!"???
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
Цитата Сообщение от инкер
Флага глобального прерывания не существует, команда cli и вход в прерывание действуют как запрет на реагирование на флаги прерываний. Команда sei и reti - разрешают реакцию на флаги. Для удобства параллельно в прерывании запрещаются все прерывания и сбрасывается флаг конкретного обрабатываемого прерывания. Но это не исключает вход во вложенное прерывание за счет принудительного разрешения глобальных прерываний.
Ф%к мой мозг.

Тогда еще раз.
sei/cli разрешает/запрещает прерывания глобально. Это факт установленный, вроде вне сомнения.
Теперь у нас есть регистр состояния в котором есть бит номер 7, который реагирует на sei/cli. Как он правильно называется? Я думал что флаг разрешения/запрещения глобального прерывания.
Цитата Сообщение от инкер
Для удобства параллельно в прерывании запрещаются все прерывания и сбрасывается флаг конкретного обрабатываемого прерывания.
Как я понял из ответов, это реализуется аппаратно?
Цитата Сообщение от инкер
команда cli и вход в прерывание действуют как запрет на реагирование на флаги прерываний.
То есть их действие аналогично? Только вход это аппаратный аналог программного cli?

Епрст, пока строчил ответ, еще постов добавилось.
0
0 / 0 / 0
Регистрация: 28.10.2010
Сообщений: 893
29.08.2011, 13:46 20
[QUOTE="dsodir"][QUOTE="Цитата:[/QUOTE]
Флага глобального прерывания не существует
- Папа, а правда, что флаг I в регистре SREG это глобальный флаг разрешения/запрещения прерываний?
- Нет сынок, это фантастика...
Это не флаг, это бит разрешения. Там есть флаги переноса и т.д., но не I. Никакое событие периферии не способно прямо воздействовать на этот бит, значит это не флаг.
0
29.08.2011, 13:46
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
29.08.2011, 13:46
Помогаю со студенческими работами здесь

atmega 328p USART
Доброго времени суток и панигите люди добрые :) Общие оговорки: я любознателен, но не знаком с ...

Atmega 2560 проблема с USART
Всем доброго времени суток. Словил глюк и никак не могу понять в чем причина. За основу взял код...

USART на ATMega. Совмещённый регистр UBRRH\UCSRC
Всем привет! Господа, такой вопрос. Решил поработать с USORTом на ATMiko8, код пишу на C++ в IARe...

Задана запись с вариантами, имеющая два поля длиной два байта каждое
Здраствуйте, помогите пожалуйста дописать программу:есть запись с вариантами, имеющая два поля...

Отправка 2-х байт по USART
Здравствуйте! Помогите пожалста отправить данные по USORT. Код программы состоит из 2-х сишников....

Задана запись с вариантами, имеющая два поля длиной два байта (Integer) каждое. Получить их значения побайтно
Задана запись с вариантами, имеющая два поля длиной два байта (тип Integer) каждое. Получить...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru