在不中断操作的情况下切换Arduino Micro上的引脚

时间:2015-04-14 12:57:52

标签: arduino toggle microcontroller

我有一个代码,一旦它通过串行接收特定输入,它将2个引脚变为高电平,并等待中断发生并运行其代码。我尝试使用无限loop(while 1)但按下按钮时无法执行中断例程。

我希望输出LEDBEEP在收到'C'之后切换,直到中断发生。

// Declarations before

void loop() {
    while(Serial.available())
    { 
        char data = Serial.read();  
        if(data == 'C')
        {
            digitalWrite(BEEP, 1);
            digitalWrite(LED, 1);
            flag = true;
        }   
    }

// Interrupt routine

2 个答案:

答案 0 :(得分:0)

我刚在模拟器上试过这个:

#define ITR_PIN 3

volatile boolean start = false;

volatile boolean flag = false;

int LED= 4;

/**
 * This method is called on the interruption raised on the falling front of the PIN2
 * The start flag is used to avoid rebound front. Interruptions are disabled inside the 
 * interrupt vector method.
 * start is reset once it has been processed in the main loop() 
 */
void buttonPressed()
{
  if(flag)
  {
    if (!start)
    {
      start = true;
    }
  }
}

void setup()
{
  cli();
  pinMode(ITR_PIN, INPUT);
  pinMode(LED, OUTPUT);
  attachInterrupt(0, buttonPressed, FALLING); // Pin 3
  sei();
  Serial.begin(9600);  
}

void loop(){

  while(Serial.available())
  { 
    char data = Serial.read();   

    if(data == 'C')
    {
      digitalWrite(LED, 1);
      flag = true;
    } 
  }

  if(flag == true)
    if (start)
    {
      digitalWrite(LED, LOW);
      delay(50);
      start = false;
      flag=false;  
    }
}

(它只是你的缩小版本,我刚刚删除了步进器依赖项并将标记标记为易失性)。它适用于这个硬件:

arduino micro sample circuit

但是,我很确定你没有在你的赛道上添加上拉!

解决方案是:

  1. 在引脚3和+ 5V
  2. 之间添加一个电阻(例如10 kOhm)
  3. 启用内部上拉
  4. 解决方案2是首选方案:您只需要更改

    pinMode(ITR_PIN, INPUT);
    

    pinMode(ITR_PIN, INPUT_PULLUP);
    

    修改

    根据你的评论,我认为行为应该是不同的:

    • 一切都已关闭
    • 当您在串行接口上​​收到C时,指示灯开始“闪烁”
    • 当断言中断时,它会停止闪烁。

    我修改了代码来实现这个目标;我稍微减少了其余的代码(但你可以将它与前一个代码合并)

    #define ITR_PIN 3
    
    volatile boolean flag = false;
    
    const int blink_period_ms = 500; // Blink period in milliseconds
    
    unsigned long initialBlinkTime;
    
    int LED= 4;
    
    void buttonPressed()
    {
      flag = false;
    }
    
    void setup()
    {
      cli();
      pinMode(ITR_PIN, INPUT);
      pinMode(LED, OUTPUT);
      attachInterrupt(0, buttonPressed, FALLING); // Pin 3
      sei();
      Serial.begin(9600);  
    }
    
    void loop(){
    
      while(Serial.available())
      { 
        char data = Serial.read();   
    
        if(data == 'C')
        {
          if (!flag)
          {
            initialBlinkTime = millis();
            flag = true;
          }
        } 
      }
    
      if(flag)
      {
        int currentTime = millis() - initialBlinkTime;
        while (currentTime > blink_period_ms) currentTime -= blink_period_ms;
    
        digitalWrite(LED, currentTime < blink_period_ms/2);
        // Insert here the other instructions
        delay(50);
      }
    }
    

答案 1 :(得分:0)

当此代码从串行接收到'C'字符时,代码开始闪烁50毫秒并且50毫秒关闭,当产生中断ITR_PIN时,LED闪烁停止(将调用ISR buttonPressed函数! )

#define ITR_PIN 3

volatile bool start = false;
bool ledstatus = false;

int LED= 4;

/**
 * This method is called on the interruption raised on the falling front of the PIN2
 * The start flag is used to avoid rebound front. Interruptions are disabled inside the
 * interrupt vector method.
 * start is reset once it has been processed in the main loop()
 */
void buttonPressed()
{
    start=false;
}

void setup()
{
    cli();
    pinMode(ITR_PIN, INPUT);
    pinMode(LED, OUTPUT);
    attachInterrupt(0, buttonPressed, FALLING); // Pin 3
    sei();
    Serial.begin(9600);
}

void loop(){

    while(Serial.available())
    {
        char data = Serial.read();

        if(data == 'C')
        {
          start = true;
        }
    }

    if (start)
    {
        ledstatus=!ledstatus;
        digitalWrite(LED, (ledstatus)?HIGH:LOW);
        delay(50);
    } else {
        if (ledstatus) {
            ledstatus=false;
            digitalWrite(LED,LOW);
        }
    }        

}