2

我正在编写一个小型测试程序,该程序尝试serial.write()在 ISR 中执行随后的 serial.read()。该代码最终将用于提示外部 GSM 屏蔽定期发送 SMS。

ISR(TIMER2_OVF_vect) {

    Serial.println("AT+CMGS=\"0123456789\"");     // Tell Sim900 To prepare sms to number 01...
    while(Serial.read()!='>');                    // Wait for Sim900 to respond
    Serial.print("A text message");               // the SMS body
    Serial.write(0x1A);                           //Confirm send instruction
    Serial.write(0x0D);
    Serial.write(0x0A); 
  }
}

经过大量测试后,我发现在Serial.read()ISR 中无法读取实时串行提示符,而是只会读取在触发 ISR 之前缓冲的任何输入。

有没有办法解决?

我找到的唯一解决方案是将此代码放在 mainloop()中。但我想使用定时器中断发送短信。

谢谢

4

3 回答 3

1

您需要将代码放入loop()但使用 IF:

float toBeSent = interval;

loop() {
    if (millis() > toBeSent) {
        Send();
        toBeSent = milli() + interval;
    }
}

间隔是您的发送间隔,以毫秒为单位。

于 2013-04-29T16:50:26.097 回答
0

不久前我遇到了类似的问题,我设法通过使用 Arduino SoftwareSerial库而不是基于硬件的Serial.read.

使用 SoftwareSerial 会产生一些开销,而且您一次只能读取一个端口,所以我让那些对 Arduino 平台有更好理解的人来告诉您这是否是一个好主意,但好处之一这个库的最大特点是您可以在 ISR 中使用它。

要使用 SoftwareSerial 库,请在您的草图顶部添加以下两行代码,记住使用您要使用的相应引脚值重新设置 rx_pin 和 tx_pin:

#include <SoftwareSerial.h>
SoftwareSerial mySerial(rx_pin, tx_pin);

然后用(或您选择给 SoftwareSerial 实例的任何名称)替换Serial整个草图中的关键字。mySerial

使用 SoftwareSerial 时要记住的重要一点是,您只能在 Arduino 上使用某些引脚,因此请先阅读文档

于 2013-04-29T21:03:24.183 回答
0

如果您想危险地生活,您可以在 ISR 中启用中断并使用标志来防止重新进入。

int flag=0;

ISR(TIMER2_OVF_vect) {
flag = 1
if (flag){return;}
sei();
Serial.println("AT+CMGS=\"0123456789\"");     // Tell Sim900 To prepare sms to number 01...
while(Serial.read()!='>');                    // Wait for Sim900 to respond
  Serial.print("A text message");               // the SMS body
  Serial.write(0x1A);                           //Confirm send instruction
  Serial.write(0x0D);
  Serial.write(0x0A); 
  }
  flag = 0;
}
于 2016-09-29T21:15:59.520 回答