繁体   English   中英

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

[英]Toggle pin on Arduino Micro without disrupting operation

我有一个代码,一旦它通过串行接收到特定的输入,它将把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

我只是在模拟器上尝试过:

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

(这只是您的简化版本,我只是删除了步进器相关性,并将标记标记为volatile)。 它可以与此硬件一起使用:

arduino微型采样电路

但是,我很确定您尚未将上拉电路添加到电路中!

解决方案是:

  1. 在引脚3和+ 5V之间增加一个电阻(例如10 kOhm)
  2. 启用内部上拉

解决方案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);
  }
}

当此代码从序列中接收到“ C”字符时,该代码将启动LED闪烁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);
        }
    }        

}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM