초기 질문
마이크로 컨트롤러의 인터럽트 처리에 대한 일반적인 질문이 있습니다. MSP430을 사용하고 있지만이 질문이 다른 uC로 확대 될 수 있다고 생각합니다. 코드를 따라 인터럽트를 자주 활성화 / 비활성화하는 것이 좋은 습관인지 아닌지 알고 싶습니다. 즉, 인터럽트에 민감하지 않은 코드 부분이 있거나 더 나쁜 경우 인터럽트를 수신해서는 안되는 코드가 있다면 다음과 같이하는 것이 좋습니다.
- 인터럽트를 전에 비활성화 한 다음 중요 섹션 후에 인터럽트를 다시 활성화하십시오.
- 각 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
들어 버튼 세트 (debouce 시스템 등)에서 오는 인터럽트에 민감하고 싶다고 가정 해 봅시다 . 누군가이 버튼 중 하나를 누르면 인터럽트가 생성되고 입력 포트와 관련된 플래그가 변수에 복사됩니다 buttonPressed
. 디 바운스가 어떤 식 으로든 (워치 독 타이머, 타이머, 카운터 등) 200ms로 설정되면 200ms buttonPressed
이전에 새로운 값으로 업데이트 할 수 없습니다. 이것이 내가 당신에게 요구하는 것입니다 (물론 :)
STATE_A
떠나기 전에 DO 활동에서 인터럽트를 활성화 하고 비활성화해야합니까?
/* 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 의 이전 값을 덮어 쓴 후속 인터럽트에서 오는 것이 아니라고 확신합니다. 필요합니다 (250ms가 경과해야하기 때문에 이것이 불가능합니다).