6

因此,中断似乎在事件发生时“中断”。我唯一的问题是我的中断会发生 2-3 次,一切都基本上停止了(串行输出,一切)。

我正在对电路板进行编程,以根据 HC-SR04 距离 IC 的输出串行输出计算出的距离。距离计算准确,但正如我之前所说,一切似乎都冻结了。下面是串行监视器的代码和图像。

在此处输入图像描述

#define TRIGPIN 4
#define ECHOPIN 3
#define RED 2
#define GREEN 13
#define INTNUM 1 //interrupt pin 1 is digital pin 3 on the duemilanove
#define PULSE 10 //microseconds 
#define CYCLETIME 50 //milliseconds

void ledWrite(int), trigPulse(), getTime();
int millisNow, millisPrev = 0;
int microsPrev;

boolean isHigh = false;


void setup() {
  Serial.begin (9600);

  pinMode(TRIGPIN, OUTPUT);
  pinMode(ECHOPIN, INPUT);
  pinMode(RED, OUTPUT);
  pinMode(GREEN, OUTPUT);

  attachInterrupt(INTNUM, getTime, CHANGE);
}

void loop() {
  trigPulse();
  // some other code while waiting on HC-SR04 to interrupt us when echo goes HIGH
}

void trigPulse(){
  if( (millisNow = millis()) - millisPrev >= CYCLETIME){ //sufficient cycle time 
    digitalWrite(TRIGPIN, HIGH);
    delayMicroseconds(PULSE);
    digitalWrite(TRIGPIN, LOW);
    millisPrev = millisNow; //reset clock 
  }
  return;  
}


void ledWrite(int dTime){
  int distance =  dTime/58.2;

  if (distance < 4) {  
    digitalWrite(RED,HIGH); 
    digitalWrite(GREEN,LOW);
  }
  else {
    digitalWrite(RED,LOW);
    digitalWrite(GREEN,HIGH);
  }

  if (distance >= 200 || distance <= 0){
    Serial.println("Out of range");
  }
  else {
    Serial.print(distance);
    Serial.println(" cm");
  }

}

void getTime(){
  int timeNow = micros(); 
  Serial.println("Interrupted");

  if(isHigh == false){
    microsPrev = timeNow; //get time now, pin LOW->HIGH
    isHigh = true;
    Serial.println("Returning ..");
    return;
      }

  else { //pin HIGH->lOW
    ledWrite(timeNow - microsPrev);
    isHigh = false;
    microsPrev = micros();
    Serial.println("Returning ..");
    return;
  } 

  return;
}
4

2 回答 2

14

我知道这是一个旧线程,但我只是遇到了自己的问题。这里的问题是您不能使用:

Serial.Print()

在中断服务程序中。Serial.Print()在 ISR 中不起作用的原因是它使用中断将字符拉出串行缓冲区,但在 ISR 中屏蔽了一定级别的中断。基本上发生的是,arduino 会抛出所有其他优先级较低的中断,这些中断属于 Serial.Read() 。

它记录在许多地方:link1link2link3

于 2014-06-11T16:44:05.757 回答
6

我认为您已经在处理中断时遇到了中断。您应该尝试在中断功能中立即禁用中断,并在返回前完成处理后再次重新启用它。因此,我建议只返回一次,这样您就不必重复启用中断的代码。还要确保您在中断代码中调用的函数不会重新启用中断。函数 micros() 或任何串行函数可能会重新启用中断。我建议不要直接在中断代码中调用函数,而是尝试使用一些标志并在中断中设置/重置,并在主循环中使用这些标志来调用您的常规函数​​。

于 2013-08-01T07:48:31.640 回答