在 C 中中断更新后,我的 while 循环没有中断
My while loop is not breaking after my interrupt updates in C
我正在实施 simon says 作为学校每周的一个小项目。使用 arduino Uno,我制作了 10 个关卡,每个关卡内部都有一个额外的模式。例如:1 级:[1],2 级:[1,2],等等……我的盾牌上有三个按钮。中断工作,一切都是 gucci。我的问题出在这个片段
bool readInput(uint8_t pattern[], uint8_t length)
{
sei();
uint8_t current = 0;
while (current < length)
{
btnPushed = false;
while (!btnPushed)
{
#ifdef DEBUG
_delay_ms(1);
#endif
}
printf("here");
cli();
_delay_ms(200);
if (currentPushed == pattern[current])
{
printf("correct, you pushed %d\n", currentPushed);
}
else
{
printf("incorrect, lets try again\n");
return false;
}
}
btnPushed = false;
return true;
}
所以基本上我将 buttonPushed 设置为 false,并开始侦听中断,一旦单击后为 true,我希望退出循环并检查输入,但是我的中断是正确的,并且我得到了带有指示灯的视觉反馈一旦我按下按钮,它就会亮起。
这是我的 ISR
ISR(PCINT1_vect)
{
uint8_t buttonCurr = currentButton();
if (buttonCurr != -1)
{
if (!btn1Pushed && buttonCurr == 0)
{
btn1Pushed = true;
}
currentPushed = buttonCurr;
blinkLed(currentPushed, 1);
btnPushed = true;
}
}
我的当前按钮 returns 0-2 代表被点击的按钮,-1 如果没有被点击。
这是我的其余代码,可以正常工作
int currentPushed = -1;
bool won;
bool btnPushed = false;
bool btn1Pushed = false;
ISR(PCINT1_vect)
{
uint8_t buttonCurr = currentButton();
if (buttonCurr != -1)
{
if (!btn1Pushed && buttonCurr == 0)
{
btn1Pushed = true;
}
currentPushed = buttonCurr;
blinkLed(currentPushed, 1);
btnPushed = true;
}
}
int main(void)
{
enableAllButtons();
enableAllLeds();
lightDownAllLeds();
prepareButtonsForInterrupt();
initUSART();
init();
play();
if (won)
{
printf("Simon says you win");
}
else
{
printf("simon says do better");
}
return 0;
}
void init(void)
{
printf("LETS PLAY SIMON SAYS\nPress button 1 to start!\n");
int seed = 0;
while (!btn1Pushed)
{
blinkLed(3, 4);
seed++;
}
srand(seed);
printf("Get ready!\n");
btnPushed = false;
cli();
}
void createRandomPattern(uint8_t array[], uint8_t length)
{
for (int i = 0; i < length; i++)
{
array[i] = rand() % 3;
}
}
void play(uint8_t pattern[])
{
uint8_t fullPattern[MAX_PATTERN_LENGTH];
createRandomPattern(fullPattern, MAX_PATTERN_LENGTH);
for (int i = 1; i <= MAX_PATTERN_LENGTH; i++)
{
printf("========LEVEL %d===========\n", i);
playPuzzle(fullPattern, i);
#ifdef DEBUG
printPuzzle(fullPattern, i);
#endif
readInput(fullPattern, i) ?: i--;
}
}
bool readInput(uint8_t pattern[], uint8_t length)
{
sei();
uint8_t current = 0;
while (current < length)
{
btnPushed = false;
while (!btnPushed)
{
}
cli();
if (currentPushed == pattern[current])
{
printf("correct, you pushed %d\n", currentPushed);
}
else
{
printf("incorrect, lets try again\n");
return false;
}
current++;
}
btnPushed = false;
return true;
}
void printPuzzle(uint8_t pattern[], uint8_t length)
{
printf("[ ");
for (int i = 0; i < length; i++)
{
printf("%d ", pattern[i]);
}
printf("]\n");
}
void playPuzzle(uint8_t pattern[], uint8_t length)
{
for (int i = 0; i < length; i++)
{
lightUpOneLed(pattern[i]);
_delay_ms(500);
lightDownOneLed(pattern[i]);
}
}
btnPushed 定义为 bool btnPushed = false;
.
所以当你写的时候:
while (!btnPushed)
{
#ifdef DEBUG
_delay_ms(1);
#endif
}
循环中的任何内容都不会更改 btnPushed
,因此编译器没有必要再次检查 btnPushed
。所以编译器看到的是这样的:
if (!btnPushed)
while(true)
{
#ifdef DEBUG
_delay_ms(1);
#endif
}
你必须告诉编译器当中断触发时 btnPushed
的值会意外改变:
volatile bool btnPushed = false;
我正在实施 simon says 作为学校每周的一个小项目。使用 arduino Uno,我制作了 10 个关卡,每个关卡内部都有一个额外的模式。例如:1 级:[1],2 级:[1,2],等等……我的盾牌上有三个按钮。中断工作,一切都是 gucci。我的问题出在这个片段
bool readInput(uint8_t pattern[], uint8_t length)
{
sei();
uint8_t current = 0;
while (current < length)
{
btnPushed = false;
while (!btnPushed)
{
#ifdef DEBUG
_delay_ms(1);
#endif
}
printf("here");
cli();
_delay_ms(200);
if (currentPushed == pattern[current])
{
printf("correct, you pushed %d\n", currentPushed);
}
else
{
printf("incorrect, lets try again\n");
return false;
}
}
btnPushed = false;
return true;
}
所以基本上我将 buttonPushed 设置为 false,并开始侦听中断,一旦单击后为 true,我希望退出循环并检查输入,但是我的中断是正确的,并且我得到了带有指示灯的视觉反馈一旦我按下按钮,它就会亮起。
这是我的 ISR
ISR(PCINT1_vect)
{
uint8_t buttonCurr = currentButton();
if (buttonCurr != -1)
{
if (!btn1Pushed && buttonCurr == 0)
{
btn1Pushed = true;
}
currentPushed = buttonCurr;
blinkLed(currentPushed, 1);
btnPushed = true;
}
}
我的当前按钮 returns 0-2 代表被点击的按钮,-1 如果没有被点击。
这是我的其余代码,可以正常工作
int currentPushed = -1;
bool won;
bool btnPushed = false;
bool btn1Pushed = false;
ISR(PCINT1_vect)
{
uint8_t buttonCurr = currentButton();
if (buttonCurr != -1)
{
if (!btn1Pushed && buttonCurr == 0)
{
btn1Pushed = true;
}
currentPushed = buttonCurr;
blinkLed(currentPushed, 1);
btnPushed = true;
}
}
int main(void)
{
enableAllButtons();
enableAllLeds();
lightDownAllLeds();
prepareButtonsForInterrupt();
initUSART();
init();
play();
if (won)
{
printf("Simon says you win");
}
else
{
printf("simon says do better");
}
return 0;
}
void init(void)
{
printf("LETS PLAY SIMON SAYS\nPress button 1 to start!\n");
int seed = 0;
while (!btn1Pushed)
{
blinkLed(3, 4);
seed++;
}
srand(seed);
printf("Get ready!\n");
btnPushed = false;
cli();
}
void createRandomPattern(uint8_t array[], uint8_t length)
{
for (int i = 0; i < length; i++)
{
array[i] = rand() % 3;
}
}
void play(uint8_t pattern[])
{
uint8_t fullPattern[MAX_PATTERN_LENGTH];
createRandomPattern(fullPattern, MAX_PATTERN_LENGTH);
for (int i = 1; i <= MAX_PATTERN_LENGTH; i++)
{
printf("========LEVEL %d===========\n", i);
playPuzzle(fullPattern, i);
#ifdef DEBUG
printPuzzle(fullPattern, i);
#endif
readInput(fullPattern, i) ?: i--;
}
}
bool readInput(uint8_t pattern[], uint8_t length)
{
sei();
uint8_t current = 0;
while (current < length)
{
btnPushed = false;
while (!btnPushed)
{
}
cli();
if (currentPushed == pattern[current])
{
printf("correct, you pushed %d\n", currentPushed);
}
else
{
printf("incorrect, lets try again\n");
return false;
}
current++;
}
btnPushed = false;
return true;
}
void printPuzzle(uint8_t pattern[], uint8_t length)
{
printf("[ ");
for (int i = 0; i < length; i++)
{
printf("%d ", pattern[i]);
}
printf("]\n");
}
void playPuzzle(uint8_t pattern[], uint8_t length)
{
for (int i = 0; i < length; i++)
{
lightUpOneLed(pattern[i]);
_delay_ms(500);
lightDownOneLed(pattern[i]);
}
}
btnPushed 定义为 bool btnPushed = false;
.
所以当你写的时候:
while (!btnPushed)
{
#ifdef DEBUG
_delay_ms(1);
#endif
}
循环中的任何内容都不会更改 btnPushed
,因此编译器没有必要再次检查 btnPushed
。所以编译器看到的是这样的:
if (!btnPushed)
while(true)
{
#ifdef DEBUG
_delay_ms(1);
#endif
}
你必须告诉编译器当中断触发时 btnPushed
的值会意外改变:
volatile bool btnPushed = false;