Donanım zamanlayıcılarından birine bir ofset eklemesi gereken bir mikroişlemci kesmesi yazıyorum. Bununla birlikte, zamanlayıcı ön ayarlayıcının çalışma biçimi nedeniyle, naif yaklaşım, zamanlayıcı yürütme zamanına göre zamanlayıcı yürütme zamanlamasına bağlı olarak birebir hata verebilir.Önceden tanımlı bir donanım zamanlayıcısına bir offset eklerken bu tek tek hatadan nasıl kurtulabilirim?
Bunun için bir ATmega328P (= Arduino) zamanlayıcıyı 1 kullanıyorum. Normal modda bir/8 prescaler ile kurdum ve bunu tetiklemek için zamanlayıcı yakalama interruptını kullanıyorum; kesme işleminin amacı, giriş yakalamayı tetikleyen olaydan sonra tam olarak period
döngüsünü taşması için zamanlayıcıyı ayarlamaktır (başka bir kesme veya tetiklemenin devre dışı bırakıldığı başka bir durumda tetikleyici oluşması durumunda).
(PWM çıkışını, değişken bir AC faz ofsetinde iki şebeke optotriacını tetiklemek için, tüm CPU zamanını yakmak zorunda kalmadan kötüye kullanıyorum; kesinti, şebeke fazında sıfır geçiş detektörü tarafından tetiklenir.)
uint_16 period = 16667;
ISR(TIMER1_CAPT_vect){
TCNT1 = TCNT1 - ICR1 - period + (elapsed counter ticks during execution);
}
burada kritik aralık TCNT1
okunduğu zaman ve daha sonra tekrar yazıldığında arasındaki biridir: ISR için
kod böyle bir şey olurdu.
olarak bildiğim kadarıyla, doğrudan ön ölçekleme durumunu okumak için bir yolu yoktur, bu yüzden sadece uygulamak mümkün olduğunu sanmıyorum, farklı bir ISR zamanlama dayalı ofset.
ISR (GTCCR |= _BV(TSM); GTCCR |= _BV(PSRSYNC); GTCCR &= ~_BV(TSM);
) eşitlenmeden önce önekleyiciyi sıfırlayabilirim, ancak yine de ISR zamanlamasına bağlı olarak zamanlayıcıya rastgele bir uzaklık tanıtır.
ben düşünüyorum bir diğer yaklaşım, ön ölçekleme ile senkronize bir kesme oluşturmak için bir zamanlayıcı kullanmaktır. Zaten çıkış 1'i her iki çıkış karşılaştırması kullanıyorum, ancak zamanlayıcı 0, önekleyiciyi paylaşabileceği şekilde paylaşıyor. Ancak, zamanlayıcı kesme yürütmesi başka bir kesme veya 'cli' bloğu tarafından ertelenebilir, bu nedenle bu çalışma garantisi yoktur.
Bu hatayı önlemek için kesilmemi nasıl yazabilirim?
"TCNT1" hesaplamasının bir _always_ off (bir zamanlama 2?), Sadece _sometimes_ (zamanlama 1) olmadığını varsayalım? – chux
@chux evet, 'TCNT1' yalnızca bir bazen kapalıdır. Bunu kelimelerle nasıl açıklayacağımı gerçekten bilmiyorum ama içerdiğim zamanlama şeması bunun nasıl olduğunu gösteriyor. – AJMansfield
ISR rutin bir "clk_Tn" nabzını örneklemek ve kesin olarak algılamak için yeterince hızlı mı? Clk_Tn, ISR tarafından silinebilen bir bayrak ayarlayabilir mi? – chux