如stackoverflow-17135805中所述,如果中断被禁用,则millis()函数不会返回正确的时间,而Arduino必须检测到timer0的溢出。
我有一个时间关键程序,它使用许多必须禁用中断的函数。所以我的程序运行1:30,而它认为它只在1点运行。
我可以用另一个计时器来避免这个问题吗?
当我使用GSM模块时,它发生在我身上:
// startpoint
unsigned long t = 0;
unsigned long start = millis();
while ( (millis()-start) < 30000 ){
//read a chunk from the gprs module
for (int i=0;i<8;i++)
client.read();
//do this loop every 10ms
while( (millis()-start) < t*10 ){};
t++;
}
//endpoint
从起点到终点,它需要30秒。相反,它需要65秒。
答案 0 :(得分:2)
如果你必须经常禁用中断,那么最好的选择就是使用外部计时器。我强烈推荐DS3231。由于它具有内置晶体,因此比1307更容易设置,而且它也更加准确。
答案 1 :(得分:1)
跟踪时间。例如,莱昂纳多定时器1是一个16位定时器。
要直接设置它(这会消除代码可移植性),有几个步骤。
TCCR1A = 0;
这会使计时器进入&#34;正常&#34;模式,意味着它只运行到0xFFFF并回绕到0x0000。
TCCR3B = 0;
TCCR3B = _BV(CS11) | _BV(CS10);
启动定时器并将其设置为使用时钟/ 64预分频,相当于每4us 1个tic。
检查时间:
long time; // declared somewhere in scope.
time = TCNT1; // this reads the timer count register
time *= 4; // this multiplies time by 4 to give you us.
如前所述,TCNT1在0xFFFF = 65536处回绕。因此,如上所述设置了预缩放器,在程序需要将数据放入之前,这将为您提供大约65536 * 4E-6 = .262秒的计数一个更大的变量(假设你关心)。希望每秒轮询事物的次数超过4次并不是一个问题,这会让你远离中断。
一些arduino核心功能使用这些计时器,因此您需要验证您所需的核心功能并不依赖于您选择的计时器。例如,执行上述操作会破坏某些引脚上的analogWrite()。