私は 8051 マイクロコントローラーでプログラミングを行っていましたが、割り込みを処理しているときに奇妙なことに気づきました。割り込みが発生したとします。その割り込みの処理中に、優先度の高い別の割り込みが発生しています。コントローラーは、優先度の高い割り込みの処理に飛び込んでから、優先度の低い割り込みに戻るべきではありませんか?
以下は私の質問を示しています。キーパッドは、外部割り込み 1 (優先度が低い) をトリガーするように配線されており、タイマー 0 割り込み (優先度が高い) が有効になっています。
// With this snippet, the LED-s are blinking as expected.
#include <8051.h>
#include <stdint.h>
#include <stdbool.h>
__xdata __at (0x9000) uint8_t KEYPAD;
__xdata __at (0xA000) uint8_t LED;
uint8_t LedState = 0x00;
bool Running = false;
void StopperIsr() __interrupt TF0_VECTOR
{
LedState = ~LedState;
LED = LedState;
TR0 = 0; // Prevent the timer restating right away.
Running = false;
}
void StopperStart()
{
TL0 = 0;
TH0 = 0;
TR0 = 1; // Start timer 0
Running = true;
}
void main()
{
ET0 = 1; // Enable timer 0 interrupt.
EA = 1; // Enable global interrupts.
TMOD = T0_M0; // Set timer 0 to 16-bit mode.
while(1) {
if (false == Running) {
StopperStart();
}
}
}
// The stopper is used inside external interrupt 1 ISR and since timer 0 has
// higher priority, the LED-s should be blinking just like in the previous snippet.
// This is not the case. Instead, on keypress, the ISR is called (LED gets 0xFF),
// but timer 0 ISR is never entered.
#include <8051.h>
#include <stdint.h>
#include <stdbool.h>
__xdata __at (0x9000) uint8_t KEYPAD;
__xdata __at (0xA000) uint8_t LED;
uint8_t LedState = 0x00;
bool Running = false;
void StopperStart()
{
TL0 = 0;
TH0 = 0;
TR0 = 1; // Start timer 0.
Running = true;
}
void StopperIsr() __interrupt TF0_VECTOR
{
LedState = ~LedState;
LED = LedState;
TR0 = 0; // Stop the timer.
Running = false;
}
void KeypadIsr() __interrupt IE1_VECTOR
{
LedState = 0xFF;
LED = LedState;
while(1) {
if (!Running) {
StopperStart();
}
}
}
void main()
{
EX1 = 1; // Enable keypad interrupt on external interrupt 1.
ET0 = 1; // Enable timer 0 interrupt.
TMOD = T0_M0; // Set timer 0 to 16-bit mode.
EA = 1; // Enable global interrupts.
KEYPAD = 0; // Reset the keypad to its initial state.
}