2016-11-14 7 views
1

私は私のLCDディスプレイに何かを表示する2つのタイマーをプログラムするタスクがあります。私はこのコードを数字といくつかの手紙のようないくつかの基本的な事柄を入力できマトリックスキーボードを持っている:サブプログラムの遅延の前にスタック

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';} 

} 

私が最初にタイマーを入力すると(タイマ0)keyboard_read()がうまく動作しますが、私が行くとき2番目のTimer(Timer2)に入ります。keyboard_read()はdelayコマンドで停止します。 keyboard_read()をloop()に入れようとしたとき、delayコマンドで停止しています(現時点ではループ内にこのコマンドはありません)。タイマ0のため

コード:タイマ2用

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 

コード:

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"); 
    } 

私はそれを動作させるためにkeyboard_read()サブプログラムまたはタイマーで何かを変更する必要がありますか?

ご協力いただきありがとうございます。

+0

できるだけ早くISRを終了する必要があります。つまり、遅延を使用しないでください(または時間のかかるもの)。 ISRの内部では、いくつかのフラグを設定してループ内で処理する必要があります。また、タイマ0は、遅延機能および他の時間保持機能によって使用される。 –

+1

また、Timer 2 ISRの中で 'loop();'を呼び出すこともできます。 –

答えて

1

あなたは割り込みの長い記事を読むことができます:ArduinoのSEにHow do interrupts work on the Arduino Uno and similar boards?をニック・ギャモン

によって、ショートで:

  • 割り込みはできるだけ短くする必要があります。遅延が必要な場合は間違っているので、後でループで処理できます。いくつかのフラグを設定するだけです(または、割り込みなしでCOMPAオーバーフローフラグを直接使用することができます。このフラグをチェックしてロジック1を書き込むことでクリアする必要があります)。
  • Arduinos delayはタイマー/カウンタ0オーバフロー割り込みが実行されています。すべての割り込みはISRハンドラで自動的にブロックされます。だから、決して起こらないミリ秒の変化を待っている。
  • また、別の割り込みに関連する他のものを使用することはできません。たとえば、Serial.write/printは送信バッファがいっぱいになるまで動作し、デッドロックが表示されます。
  • なぜloop()に電話しますか?ハンドラがジョブを終了した直後に、中断されたコードに戻ります。