当变量发生变化时,如何打破if

时间:2017-05-23 23:47:48

标签: c pic

我需要帮助我有这个基本的基本程序,根据我推动的开关,按顺序使用LED,我想知道的是:如何中断一个(或停止它)并运行另一个顺序,当我切换其他开关并运行新的顺序而不是之前的顺序时,我想知道其他需要中止操作的程序是如何做的,因为它将处于延迟和填充的“循环”中,我想这是一个如果每个引导和关闭的线之间都会这样做,但我不认为这是正确/有效的方式..谢谢!

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

2 个答案:

答案 0 :(得分: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循环跳转到下一个循环,以便在适当的时候改变顺序。

答案 1 :(得分:1)

您可以设置一个触发每毫秒的计时器,然后将代码重写为状态机。这样你就不会在延迟例程中浪费cpu周期,并且你能够立即响应按钮按下,至少在一毫秒内响应,这对用户来说是即时的。

状态机跟踪变量。数字表示它所处的状态。每次执行状态时,状态可能会改变。更改的状态在下次定时器触发时执行。每个触发器还会检查按钮/去抖等。

确保您的代码在计时器周期内运行,因此请不要使用任何延迟,而是使用状态机执行延迟,或者如果您需要不同的分辨率/时间,请使用其他计时器。

我将由你来设置定时器和中断寄存器。

  /* 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;
     }
  }