Aşağıdaki snippet'ler TimerOne kitaplığı kaynak kodundandır :
// TimerOne.h:
void (*isrCallback)();
// TimerOne.cpp:
ISR(TIMER1_OVF_vect) // interrupt service routine that wraps a user defined function supplied by attachInterrupt
{
Timer1.isrCallback();
}
// TimerOne.cpp:
void TimerOne::attachInterrupt(void (*isr)(), long microseconds)
{
if(microseconds > 0) setPeriod(microseconds);
isrCallback = isr; // register the user's callback with the real ISR
TIMSK1 = _BV(TOIE1); // sets the timer overflow interrupt enable bit
resume();
}
Soru: Zamanlayıcı zaten çalışıyorsa ve ana program çağırıyorsa attachInterrupt()
, zamanlayıcı kesintisi fonksiyon işaretçisi ataması sırasında orada olabilir isrCallback = isr;
mi? Sonra, şanslı zamanlama ile, Timer1.isrCallback();
fonksiyon işaretçisi kısmen eski ve kısmen yeni adreslerden oluşarak ISR'nin sahte bir yere atlamasına neden olur mu?
İşlev işaretçileri kesinlikle 1 bayttan daha geniş olduğundan ve> 1 bayt verilerine erişmek atomik olmadığından, durum böyle olabilir. Olası geçici çözümler şunlar olabilir:
- Aramadan
detachInterrupt()
önce zamanlayıcının çalışmadığından emin olmak için her zaman arayınattachInterrupt()
, yani Zamanlayıcı1 belgelerini netleştirin. - Veya Zamanlayıcı1'i değiştirin, zamanlayıcı taşması devre dışı bırakıldığında,
isrCallback = isr;
Bu mantıklı mı, yoksa Timer1
kaynaklarda veya işlev işaretçisi atamalarında kaçırdığım bir şey var mı?