2017-05-23 17 views
0

私はこの基本的な基本的なプログラムを順番に再生するために、どのスイッチを押しますか、私は他のスイッチをトグルして新しいシーケンシングを実行しますが、前のものは実行していないときに、他のシーケンスを実行すると、アクションを中止する必要のある他のプログラムが "loop"遅延や物事では、私はそれぞれの間に行間を置くことは、それを行うだろうと思うが、私はそれが正しい/効率的な方法だとは思わない..ありがとう!変数が変更されたときにどのようにブレークすることができますか?

#include <16f876.h> 
#use delay(clock=4M) 
#fuses XT,NOWDT 
#use standard_io(A) 
#use standard_io(B) 

int16 t0=2000; 
int16 t1=1000; 
int16 t2=1000; 
int16 t3=500; 

void main(){ 
    output_b(0b00000000); 
    while(TRUE){ 
     if(input(PIN_A0)==0){ 
     output_b(0b00000000); 
     output_b(0b00011000); 
     delay_ms(t0); 
     output_b(0b00100100); 
     delay_ms(t0); 
     output_b(0b01000010); 
     delay_ms(t0); 
     output_b(0b10000001); 
     delay_ms(t0); 
     } 
     if(input(PIN_A1)==0){ 
     output_b(0b00000000); 
     output_b(0b00000001); 
     delay_ms(t1); 
     output_b(0b00000011); 
     delay_ms(t1); 
     output_b(0b00000111); 
     delay_ms(t1); 
     output_b(0b00001111); 
     delay_ms(t1); 
     output_b(0b00011111); 
     delay_ms(t1); 
     output_b(0b00111111); 
     delay_ms(t1); 
     output_b(0b01111111); 
     delay_ms(t1); 
     output_b(0b11111111); 
     delay_ms(t1); 
     } 
     if(input(PIN_A2)==0){ 
     output_b(0b10000000); 
     delay_ms(t2); 
     output_b(0b11000000); 
     delay_ms(t2); 
     output_b(0b11100000); 
     delay_ms(t2); 
     output_b(0b11110000); 
     delay_ms(t2); 
     output_b(0b11111000); 
     delay_ms(t2); 
     output_b(0b11111100); 
     delay_ms(t2); 
     output_b(0b11111110); 
     delay_ms(t2); 
     output_b(0b11111111); 
     delay_ms(t2); 
     } 
     if(input(PIN_A3)==0){ 
     output_b(0b00000000); 
     output_b(0b00000001); 
     delay_ms(t3); 
     output_b(0b00000000); 
     delay_ms(t3); 
     output_b(0b00000011); 
     delay_ms(t3); 
     output_b(0b00000000); 
     delay_ms(t3); 
     output_b(0b00000111); 
     delay_ms(t3); 
     output_b(0b00000000); 
     delay_ms(t3); 
     output_b(0b00001111); 
     delay_ms(t3); 
     output_b(0b00000000); 
     delay_ms(t3); 
     output_b(0b00011111); 
     delay_ms(t3); 
     output_b(0b00000000); 
     delay_ms(t3); 
     output_b(0b00111111); 
     delay_ms(t3); 
     output_b(0b00000000); 
     delay_ms(t3); 
     output_b(0b01111111); 
     delay_ms(t3); 
     output_b(0b00000000); 
     delay_ms(t3); 
     output_b(0b11111111); 
     delay_ms(t3); 
     } 
    } 
} 
+0

同時に複数のライトを点灯することができますか? 3 if文を使用する代わりに、if/elseブランチを使用するとどうなりますか? –

+0

これは一度に1つです。 –

答えて

1

独自delay_msはこのような何かを書くことができます機能:

bool my_delay_ms(int mstime) { 
    int current = 0; 
    while (current < mstime) { 
     delay_ms(10); 
     current += 10; 
     if (something?) { 
      return true; 
     } 
    } 
    return false; 
} 

その後if (my_delay_ms(t0)) continue;ですべてのdelay_msを交換してください。

10を頻繁に変更して割り込み信号をポーリングすることができます。状態が割り込み信号を検出すると、continueは、whileループが次のサイクルにジャンプして、必要に応じてシーケンスを変更できるようにします。

+0

こんにちは、お返事ありがとう、私は質問があります、 "if(my_delay_ms(t0))続行;私はそれを設定した時間を実際に待つか、それとも正確な瞬間に真か偽かをチェックして次の行に行きますか?私はその疑問を持っています。 –

+0

関数を終了する前に関数全体を評価します。割り込みフラグが決して真でない場合、関数は全期間実行され、早期に終了するとcontinue文がトリガされます。 –

+1

シンプルで機能しました!ブール値の代わりにintを使用しなければなりませんでしたが(ブールはここには存在せず、1と0を返します)、t0、t1、t2、t3、mstimeに対してはint16(理由は同じですが、理由はintですが、int16とintは技術的に同じですが...) –

1

ミリ秒ごとにトリガーするタイマーをセットアップしてから、コードをステートマシンとして書き直すことができます。そうすれば、遅延ルーチンでCPUサイクルを無駄にすることなく、即座に少なくとも1ミリ秒以内にボタンプレスに即座に対応することができます。

ステートマシンは変数を追跡します。番号は、その状態を表します。状態が実行されるたびに、状態が変わることがあります。変更された状態は、次にタイマがトリガされたときに実行されます。各トリガは、ボタン/デバウンスなどもチェックします。

コードがタイマー期間内に実行されるようにしてください。遅延を使用しないでください。ただし、ステートマシンを使用して遅延を行うか、タイミング。

タイマーと割り込みレジスタをセットアップすることは任せます。

/* global variables */ 
    int state = 0; 
    unsigned char delaycnt = 0; 
    char millisecond_flag = 0; 

    void DoStateMachine() 
    {  
    switch(state) 
    { 
     case 100: 
      output_b(0b00000000); 
      output_b(0b00011000); 
      state++; 
      delaycnt = 10; 
      break; 
     case 101: 
      delaycnt--; 
      if(delaycnt == 0) state = 102; 
      break; 
      case 200: 
      output_b(0b00000000); 
      output_b(0b00000001); 
      state++; 
      delaycnt = 10; 
      break; 
     case 201: 
      delaycnt--; 
      if(delaycnt == 0) state = 202; 
      break; 
     default: 
      state = 0; // do nothing 
      break; 
     } 
    } 

    void CheckButtons() 
    { 
    // Do button debounce here 
    if(BUTTON1 == 1) 
     state = 100; 
    if(BUTTON2 == 1) 
     state = 200; 
    } 

    void main() 
    { 
    //Setup timer here 

    while(1) 
    { 
     if(millisecond_flag == 1) 
     { 
      CheckButtons(); 
      DoStateMachine(); 
      millisecond_flag = 0; 
     } 
     //sleep device? 
    } 
    } 

    // Handle interrupt 
    void interrupt ISR() 
    { 
    if(TMR1IF == 1) 
    { 
     millisecond_flag = 1; 
     TMR1IF = 0; 
    } 
    } 
関連する問題