Arduino - 音调毫不拖延

Arduino - Tone without delay

我试图在改变 LCD 显示器上的内容时播放音调。我四处搜索并尝试了 protothreads,但似乎延迟仍然阻止了程序。我也试过完全消除延迟,但它跳过了除最后一个音符之外的所有内容。有没有办法在不使用延迟的情况下播放音调? (也许是毫秒?)

示例音序列:

//Beats per Minute
#define BPM 250

//Constants, try not to touch, touch anyways.
#define Q 60000/BPM   //Quarter note
#define W 4*Q         //Whole note
#define H 2*Q         //Half note
#define E Q/2         //Eigth note
#define S Q/4         //Sixteenth note

void toneFunction()
{
      tone(tonePin,C5,Q);
      delay(1+W);
      tone(tonePin,C5,Q);
      delay(1+W);
      tone(tonePin,C5,Q);
      delay(1+W);
      tone(tonePin,C6,W);
}

您可以设置一个计时器并将音符更改逻辑放入中断服务程序 (ISR)。

每隔 X 毫秒,计时器将重置并中断您的主循环。 ISR 将 运行 并选择下一个音符并调用音调函数。退出 ISR 后,程序从中断点继续。

我附上了我在我的一个项目中使用的代码。定时器将每 50 毫秒(20 赫兹)中断一次主循环,因此您必须将自己的数字放入 OCR1A 和预分频器中。请阅读有关 arduino 中定时器中断的更多信息,以便您了解如何执行此操作(例如此处:http://www.instructables.com/id/Arduino-Timer-Interrupts/step2/Structuring-Timer-Interrupts/). You can also see the example at the end of this page (http://playground.arduino.cc/Code/Timer1)以获得更用户友好的方式。

setup() {

  ....

  /* Set timer1 interrupt to 20Hz */
  cli();//stop interrupts
  TCCR1A = 0;// set entire TCCR1A register to 0
  TCCR1B = 0;// same for TCCR1B
  TCNT1  = 0;//initialize counter value to 0
  OCR1A = 781; // approximately 20Hz
  TCCR1B |= (1 << WGM12);// turn on CTC mode
  TCCR1B |= (1 << CS12) | (1 << CS10);  // 1024 presxaler
  TIMSK1 |= (1 << OCIE1A); // enable timer compare interrupt
  sei();//allow interrupts
} 

...

ISR(TIMER1_COMPA_vect){
  // pick next note
}