Начальный вопрос
У меня есть общий вопрос об обработке прерываний в микроконтроллерах. Я использую MSP430, но я думаю, что вопрос может быть распространен на другие СК. Я хотел бы знать, является ли хорошей практикой частое включение / отключение прерываний по всему коду. Я имею в виду, если у меня есть часть кода, которая не будет чувствительна к прерываниям (или, что еще хуже, не должна слушать прерывания по любой причине), лучше:
- Отключите прерывания до, а затем снова включите их после критического раздела.
- Поместите флаг внутри соответствующего ISR и (вместо отключения прерывания) установите флаг в значение false перед критическим разделом и сбросьте его в значение true, сразу после. Для предотвращения выполнения кода ISR.
- Ни один из двух, поэтому предложения приветствуются!
Обновление: прерывания и графики состояния
Я предоставлю конкретную ситуацию. Предположим, мы хотим реализовать диаграмму состояний, которая состоит из 4 блоков:
- Переходы / Эффект.
- Условия выхода.
- Вступительная деятельность.
- Заниматься деятельностью.
Это то, чему нас учил профессор в университете. Вероятно, не лучший способ сделать это, следуя этой схеме:
while(true) {
/* Transitions/Effects */
//----------------------------------------------------------------------
next_state = current_state;
switch (current_state)
{
case STATE_A:
if(EVENT1) {next_state = STATE_C}
if(d == THRESHOLD) {next_state = STATE_D; a++}
break;
case STATE_B:
// transitions and effects
break;
(...)
}
/* Exit activity -> only performed if I leave the state for a new one */
//----------------------------------------------------------------------
if (next_state != current_state)
{
switch(current_state)
{
case STATE_A:
// Exit activity of STATE_A
break;
case STATE_B:
// Exit activity of STATE_B
break;
(...)
}
}
/* Entry activity -> only performed the 1st time I enter a state */
//----------------------------------------------------------------------
if (next_state != current_state)
{
switch(next_state)
{
case STATE_A:
// Entry activity of STATE_A
break;
case STATE_B:
// Entry activity of STATE_B
break;
(...)
}
}
current_state = next_state;
/* Do activity */
//----------------------------------------------------------------------
switch (current_state)
{
case STATE_A:
// Do activity of STATE_A
break;
case STATE_B:
// Do activity of STATE_B
break;
(...)
}
}
Давайте также предположим, что, скажем STATE_A
, я хочу быть чувствительным к прерыванию, исходящему от набора кнопок (с дебоус-системой и т. Д. И т. Д.). Когда кто-то нажимает одну из этих кнопок, генерируется прерывание, и флаг, связанный с портом ввода, копируется в переменную buttonPressed
. Если debounce каким-либо образом установлен на 200 мс (сторожевой таймер, таймер, счетчик, ...), мы уверены, что buttonPressed
его нельзя обновить новым значением до 200 мс. Это то, что я прошу вас (и себя :), конечно)
Нужно ли включать прерывание в операции DO STATE_A
и отключать перед уходом?
/* Do activity */
//-------------------------------------
switch (current_state)
{
case STATE_A:
// Do activity of STATE_A
Enable_ButtonsInterrupt(); // and clear flags before it
// Do fancy stuff and ...
// ... wait until a button is pressed (e.g. LPM3 of the MSP430)
// Here I have my buttonPressed flag ready!
Disable_ButtonsInterrupt();
break;
case STATE_B:
// Do activity of STATE_B
break;
(...)
}
Таким образом, я уверен, что в следующий раз, когда я выполню блок 1 (переход / эффекты) на следующей итерации, я уверен, что условия, проверенные вдоль переходов, не происходят из последующего прерывания, которое перезаписало предыдущее значение buttonPressed
этого I нужно (хотя это невозможно, потому что должно пройти 250 мс).