我正在尝试在改变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);
}
答案 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
}