C++ 在子程序延迟之前卡住
我的任务是编程两个定时器,在LCD显示屏上显示一些东西。我有一个矩阵键盘,我可以用这个代码输入一些基本的东西,比如数字和字母:C++ 在子程序延迟之前卡住,c++,timer,arduino,interrupt,C++,Timer,Arduino,Interrupt,我的任务是编程两个定时器,在LCD显示屏上显示一些东西。我有一个矩阵键盘,我可以用这个代码输入一些基本的东西,比如数字和字母: void keyboard_read() { digitalWrite(s1, LOW); digitalWrite(s2, HIGH); digitalWrite(s3, HIGH); digitalWrite(s4, HIGH); if(digitalRead(r1) == LOW){lcd.print("1"); delay(200)
void keyboard_read()
{
digitalWrite(s1, LOW);
digitalWrite(s2, HIGH);
digitalWrite(s3, HIGH);
digitalWrite(s4, HIGH);
if(digitalRead(r1) == LOW){lcd.print("1"); delay(200);k++;feld[k]=1;}
if(digitalRead(r2) == LOW){lcd.print("4"); delay(200);k++;feld[k]=4;}
if(digitalRead(r3) == LOW){lcd.print("7"); delay(200);k++;feld[k]=7;}
if(digitalRead(r4) == LOW){lcd.print("A"); delay(200);k++;feld[k]='A';}
digitalWrite(s1, HIGH);
digitalWrite(s2, LOW);
digitalWrite(s3, HIGH);
digitalWrite(s4, HIGH);
if(digitalRead(r1) == LOW){lcd.print("2"); delay(200);k++;feld[k]=2;}
if(digitalRead(r2) == LOW){lcd.print("5"); delay(200);k++;feld[k]=5;}
if(digitalRead(r3) == LOW){lcd.print("8"); delay(200);k++;feld[k]=8;}
if(digitalRead(r4) == LOW){lcd.print("0"); delay(200);k++;feld[k]=0;}
digitalWrite(s1, HIGH);
digitalWrite(s2, HIGH);
digitalWrite(s3, LOW);
digitalWrite(s4, HIGH);
if(digitalRead(r1) == LOW){lcd.print("3"); delay(200);k++;feld[k]=3;}
if(digitalRead(r2) == LOW){lcd.print("6"); delay(200);k++;feld[k]=6;}
if(digitalRead(r3) == LOW){lcd.print("9"); delay(200);k++;feld[k]=9;}
if(digitalRead(r4) == LOW){lcd.print("B"); delay(200);k++;feld[k]='B';}
digitalWrite(s1, HIGH);
digitalWrite(s2, HIGH);
digitalWrite(s3, HIGH);
digitalWrite(s4, LOW);
if(digitalRead(r1) == LOW){lcd.print("F"); delay(200);k++;feld[k]='F';}
if(digitalRead(r2) == LOW){lcd.print("E"); delay(200);k++;feld[k]='E';}
if(digitalRead(r3) == LOW){lcd.print("D"); delay(200);k++;feld[k]='D';}
if(digitalRead(r4) == LOW){lcd.print("C"); delay(200);k++;feld[k]='C';}
}
当我输入第一个定时器(Timer0)时,键盘_read()工作正常,但当我进入第二个定时器(Timer2)时,键盘_read()在delay命令处停止。当我尝试将键盘_read()放入循环()时,它仍然在延迟命令处停止(目前循环中没有此命令)
计时器0的代码:
ISR(TIMER0_COMPA_vect) //Durchlaufendes Menü
{
cnt0++;
//Tastatureingabe_______________________________________________________________
keyboard_read();
if(feld[k]=='A') //Abfrage nach AutoStart
{
lcd.clear(); lcd.setCursor(0,0); lcd.print("AutoStart");
TCCR0B = 0x00; //Timer0 ausschalten
TCCR2B = 0x07; //Timer2 einschalten
}
else if(feld[k]=='E') //Abfrage nach Einstellungen
{
lcd.clear(); lcd.setCursor(0,0); lcd.print("Einstellungen");
TCCR0B = 0x00; //Timer0 ausschalten
//TCCR1B = 0x00; //Timer1 einschalten (not declared yet)
k=0;
}
else if((feld[k]!=NULL)) //Falsche Eingabe Abfrage
{
lcd.clear(); lcd.setCursor(0,0); lcd.print("Falsche Eingabe");
} //other things are not necessary
计时器2的代码:
ISR(TIMER2_COMPA_vect) //Ausgabe der Parameter
{
cnt2++;
loop();
//Tastatureingabe_________________________________________________________
keyboard_read();
if(feld[k]=='B') //Abfrage nach AutoStart
{
lcd.clear(); lcd.setCursor(0,0); lcd.print("Zuruek");
TCCR0B = 0x0D; //Timer0 einschalten
TCCR2B = 0x00; //Timer2 ausschalten
}
else if((feld[k]!=NULL))
{
lcd.clear(); lcd.setCursor(0,0); lcd.print("Falsche Eingabe");
}
我是否必须更改键盘读取()子程序或计时器中的某些内容才能使其正常工作
提前感谢您的帮助。您可以阅读Nick Gammon撰写的关于中断:关于Arduino SE的长篇文章 简言之:
- 中断必须尽可能短。若你们需要延迟,你们是做错了,你们可以稍后在循环中处理它。只需设置一些标志(或者您可以直接使用COMPA overflow标志而不中断它,您只需检查该标志并通过将逻辑1写入该标志来清除它)
- 您不能使用Arduinos
,因为它需要运行计时器/计数器0溢出中断。所有中断都会在ISR处理程序中自动阻止。所以你在等待永远不会发生的改变delay
- 此外,您不能使用任何其他依赖于另一个中断的内容。例如,Serial.write/print会一直工作,直到发送缓冲区被填满,然后出现死锁
- 为什么要调用
?它将在处理程序完成作业后立即返回中断的代码loop()