我在面包板上制作了一个带有Arduino Uno和梯形电阻梯的基本波形发生器。我使用loop
函数和micros()
根据需要更改电压电平,以在每次电压变化之间进行延迟。它并不完美,但它适用于压电。
我的问题是我在我的代码中设置信号频率,我希望能够使用例如一个锅来改变它。但是只要我在代码中放置analogRead
(所有代码都在loop()
函数中),输出信号就会改变。我发现analogRead
函数运行时间可能长达100μs,并且大于每次电压变化之间的延迟,因此实际信号周期不正确:
unsigned long now, next;
int freq;
void loop(){
//if I put analogRead() here it takes to much time
now = micros();
if(now >= next){
//Here I change the output analog value using a R-2R ladder
//then I change the value of next
}
}
我尝试了一些解决方案,包括使用开关而不是使用开关,但digitalRead
结合if语句似乎效率更高。我也尝试过使用中断的开关,但结果与digitalRead
相同。
有人知道另一种解决方案吗?
谢谢!
答案 0 :(得分:2)
analogRead
等待转换完成,所以如果你想做其他事情,你必须以不同的方式处理它。
您可以使用ADC中断和自由运行模式。或者您可以通过多个来源触发ADC转换周期,例如定时器比较。
或者你可以通过“基于事件”的方法来做 - 通过检查ADC转换完成并通过将逻辑1写入该标志来重置它。
// in setup:
ADCSRA |= _BV(ADATE); // enable auto trigger mode
ADCSRB = 0; // free running mode for the auto trigger
// and in the loop:
if (ADCSRA & _BV(ADIF)) {
value = ADC; // get ADC value
ADCSRA |= _BV(ADIF); // reset flag by writing logic one into it
// whatever you want with the current value
// or ADCSRA |= _BV(ADSC); // start another conversion if you don't want free running mode
}
顺便说一句:宏_BV(BIT)
被替换为1<<(BIT)
(如果你想知道我为什么要使用它)