ตัวอย่างต่อไปนี้มาจากซอร์สโค้ดของ TimerOne :
// 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();
}
คำถาม: หากตัวจับเวลากำลังทำงานอยู่และการเรียกโปรแกรมหลักattachInterrupt()
ตัวจับเวลาจะเกิดขึ้นที่นั่นระหว่างการกำหนดฟังก์ชั่นตัวชี้isrCallback = isr;
? จากนั้นด้วยเวลาที่โชคดีTimer1.isrCallback();
ตัวชี้ฟังก์ชั่นจะประกอบด้วยบางส่วนของที่อยู่เก่าและส่วนหนึ่งของที่อยู่ใหม่ทำให้ ISR กระโดดไปที่ตำแหน่งปลอมหรือไม่
ฉันคิดว่านี่อาจเป็นเพราะตัวชี้ฟังก์ชั่นนั้นกว้างกว่า 1 ไบต์และการเข้าถึงข้อมูล> 1 ไบต์ไม่ใช่อะตอม วิธีแก้ไขที่เป็นไปได้อาจเป็น:
- โทรทุกครั้ง
detachInterrupt()
เพื่อให้แน่ใจว่าตัวจับเวลาไม่ทำงานก่อนที่จะโทรattachInterrupt()
เช่นทำให้เอกสาร Timer1 ชัดเจน - หรือแก้ไข Timer1 ปิดการใช้งานตัวจับเวลา overflow ขัดจังหวะชั่วคราวก่อนหน้านี้
isrCallback = isr;
สิ่งนี้สมเหตุสมผลหรือมีบางสิ่งในTimer1
แหล่งที่มาหรือการกำหนดตัวชี้ฟังก์ชันที่ฉันพลาดไปหรือไม่