Arduino - 音质毫不拖延

时间:2015-10-10 07:31:51

标签: asynchronous arduino 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);
}

1 个答案:

答案 0 :(得分:2)

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

每X毫秒,定时器将复位并中断主循环。 ISR将运行并选择下一个音符并调用音调功能。退出ISR后,程序将从中断点开始继续。

我附上了我在其中一个项目中使用过的代码。定时器将每隔50ms(20 Hz)中断主循环,因此您必须将自己的数字放在OCR1A和预定标器中。请阅读更多关于arduino中的定时器中断的信息,以便您了解如何操作(例如:http://www.instructables.com/id/Arduino-Timer-Interrupts/step2/Structuring-Timer-Interrupts/)。您还可以在本页末尾(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
}