我正在尝试在Atmega 2560上每50毫秒定期执行一次循环。使用简单的延迟功能将不起作用,因为总循环时间最终是执行其他函数所花费的时间。循环,加上你的延迟时间。如果您的函数调用需要可变时间,这通常会更好。
为了解决这个问题,我实现了一个简单的计时器类:
volatile unsigned long timer0_ms_tick;
timer::timer()
{
// Set timer0 registers
TCCR0A = 0b00000000; // Nothing here
TCCR0B = 0b00000000; // Timer stopped, begin function start by setting last three bits to 011 for prescaler of 64
TIMSK0 = 0b00000001; // Last bit to 1 to enable timer0 OFV interrupt enable
sei(); // Enable global interrupts
}
void timer::start()
{
timer0_ms_tick = 0;
// Set timer value for 1ms tick (2500000 ticks/sec)*(1 OFV/250 ticks) = 1000OVF/sec
// 256ticks - 250ticks - 6 ticks, but starting at 0 means setting to 5
TCNT0 = 5;
// Set prescaler and start timer
TCCR0B = 0b00000011;
}
unsigned long timer::now_ms()
{
return timer0_ms_tick;
}
ISR(TIMER0_OVF_vect)
{
timer0_ms_tick+=1;
TCNT0 = 5;
}
主循环使用它如下:
unsigned long startTime, now;
while(true)
{
startTime = startup_timer.now_ms();
/* Loop Functions */
// Wait time step
now = startup_timer.now_ms();
while(now-startTime < 50)
{
now = startup_timer.now_ms();
}
Serial0.print(ltoa(now,time_string, 10));
Serial0.writeChar('-');
Serial0.print(ltoa(startTime,time_string, 10));
Serial0.writeChar('=');
Serial0.println(ltoa(now-startTime,time_string, 10));
}
我的输出如下:
11600-11550=50
11652-11602=50
11704-11654=50
11756-11706=50
12031-11758=273
11828-11778=50
11880-11830=50
11932-11882=50
11984-11934=50
12036-11986=50
12088-12038=50
12140-12090=50
12192-12142=50
12244-12194=50
12296-12246=50
12348-12298=50
12400-12350=50
12452-12402=50
12504-12454=50
12556-12506=50
12608-12558=50
12660-12610=50
12712-12662=50
12764-12714=50
12816-12766=50
12868-12818=50
12920-12870=50
12972-12922=50
13024-12974=50
13076-13026=50
13128-13078=50
13180-13130=50
13232-13182=50
13284-13234=50
13336-13286=50
13388-13338=50
13440-13390=50
13492-13442=50
13544-13494=50
13823-13546=277
13620-13570=50
它似乎在大部分时间都能正常工作,但每隔一段时间,时间值就会发生奇怪的事情。我认为这与中断有关,但我不确定是什么。任何帮助将不胜感激。