Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Прерывания UART MSP430F5437
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > MSP430
1921
Джентльмены! Помогите чайнику в освоении, пжалста!
Суть вкратце такова. USCI_A имеет один адрес в таблице векторов прерываний на приём и передачу, поэтому при срабатывании прерывания мы сначала влетаем в обработчик, а потом разбираемся, "кто звонил". Прерывание срабатывает только при разрешении локально и GIE, флаги устанавливаются и так. Вектор IV и флаг IFG сбрасываются сразу при входе в прерывание (точнее, при первом чтении IV, которое обычно в примерах анализируется с помощью switch). Ситуация: Сначала по UART передаётся с помощью прерывания 5 байт, после передачи последнего локальные прерывания на передачу запрещаются и разрешаются прерывания на приём. Далее следует приём, скажем, 6 байт. НО! Влетая в обработчик по приёму, программа нормально отрабатывает switch - case:2, после этого заходит в case:4 (передача, хотя она запрещена локально. Флаг, конечно, стоит, куда же он денется.) и передаёт лишний байт. Итог: Передаётся 5 байт, потом ещё 6 при приёме. Откуда это,а? Нет, я понял, что если после каждого case ставить break, то всё будет нормально. Но почему всё-таки? Ведь не должен он попадать внутрь case 4, даже если 2 флага стоят. Прерывания-то по передаче запрещены, и IV просто не должен генериться. smile3046.gif
MrYuran
Цитата(1921 @ Oct 6 2010, 10:47) *
Нет, я понял, что если после каждого case ставить break, то всё будет нормально. Но почему всё-таки?

То есть что почему?
Если вы не поставили break; то ваша программа продолжается дальше, case - это всего лишь метка.

И главное, какой резон не ставить break?
1921
Цитата(MrYuran @ Oct 6 2010, 10:55) *
То есть что почему?
Если вы не поставили break; то ваша программа продолжается дальше, case - это всего лишь метка.

И главное, какой резон не ставить break?


Ну да, продолжается. Но IV не может быть равен 4, если при входе он был равен 2. Соответственно, тело case 4: {} выполняться не должно. Так почему же программа заходит в тело и передаёт байт?
MrYuran
Цитата(1921 @ Oct 6 2010, 11:04) *
Ну да, продолжается. Но IV не может быть равен 4, если при входе он был равен 2. Соответственно, тело case 4: {} выполняться не должно. Так почему же программа заходит в тело и передаёт байт?

Код
label_1: DoSomething();
Label_2: DoSomethingElse();

Программе глубоко наплевать, чему равен ваш IV.
Она попадает на метку и выполняет от и до.
оператор break выкидывает программу из тела цикла или switch.
Если его нет, программа идет дальше.

Учите матчасть.
1921
И ещё вопрос: что означает switch (__even_in_range(UCA1IV,4)). Вроде ограничение возможного значения UCA1IV? А зачем? Во всех примерах написано именно так. Е ещё вопрос: если стоит сразу 2 флага в IFG, то правильно ли я понимаю, что IV сгачала примет значение 2, отработает прерывание на приём, сбросит флаг на приём, выйдет, прыгнет снова в обработчик со значением IV=4, и отработает передачу и сбросит флаг передачи.
MrYuran
Цитата(1921 @ Oct 6 2010, 11:11) *
И ещё вопрос: что означает switch (__even_in_range(UCA1IV,4)). Вроде ограничение возможного значения UCA1IV? А зачем?

Это оптимизирующая фича ИАРа.
Строит оптимальную таблицу переходов.
Этот макрос даёт понять компилятору, что все значения чётные и расположены по порядку вплоть до указанного значения.
Оптимизирует так, что на ассемблере красивее не напишешь.
1921
Цитата(MrYuran @ Oct 6 2010, 11:09) *
Код
label_1: DoSomething();
Label_2: DoSomethingElse();

Программе глубоко наплевать, чему равен ваш IV.
Она попадает на метку и выполняет от и до.
оператор break выкидывает программу из тела цикла или switch.
Если его нет, программа идет дальше.

Учите матчасть.


ВАХ! А я думе\ал, что switch отрабатывается аналогично
if (IV==4) {}
if (IV==2) {}
А вишь оно как! Чудны дела твои господи! Спасибо, буду теперь знать! Для меня это правда неожиданность!!!
MrYuran
Цитата(1921 @ Oct 6 2010, 11:17) *
ВАХ! А я думе\ал, что switch отрабатывается аналогично
if (IV==4) {}
if (IV==2) {}
А вишь оно как! Чудны дела твои господи! Спасибо, буду теперь знать! Для меня это правда неожиданность!!!

Скорее, так:
if() goto L1;
if() goto L2;
...
L1: f1();
l2: f2();
...
Это если без оптимизации.
С оптимизацией бывает интереснее.
В вашем случае это будет что-то типа:

goto &(PC + IV);
ниже - вплотную таблица переходов

Чуете разницу?
Одной командой вы переноситесь в нужный обработчик, без перебора вариантов.
Быстро и компактно.
Кстати, именно так и рекомендуют обрабатывать IV сами техасовцы в своих юзер-гуайдах
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.