Micros () belgeleri, dönüş değerinin her zaman 4'ün katı olacağını belirtir.
Tercihen 1 mikrosaniye seviyesine kadar daha yüksek çözünürlüklü bir mikrosaniye tıklaması elde etmenin herhangi bir yolu var mı?
AVR seviyesine düşmek kabul edilebilir.
Micros () belgeleri, dönüş değerinin her zaman 4'ün katı olacağını belirtir.
Tercihen 1 mikrosaniye seviyesine kadar daha yüksek çözünürlüklü bir mikrosaniye tıklaması elde etmenin herhangi bir yolu var mı?
AVR seviyesine düşmek kabul edilebilir.
Yanıtlar:
Evet, Arduino'nuzun temel saat hızına bağlı olarak. Örneğin, ATMega2560'ın sayaç zamanlayıcısı 2 ve 16MHz'lik temel bir saat hızı için ön ölçeklemeden sonraki sayaç zamanlayıcı giriş frekansları ve süreleri. Zamanlayıcı, bu tabloda gösterilen frekansı / periyodu belirleyen "ön ölçekleyici" değer seçeneklerine sahiptir:
TCCR2B bits 2-0 Prescaler Freq [KHz], Period [usec] after prescale
0x0 (TC stopped) -- --
0x1 1 16000. 0.0625
0x2 8 2000. 0.500
0x3 32 500. 2.000
0x4 64 250. 4.000
0x5 128 125. 8.000
0x6 256 62.5 16.000
0x7 1024 15.625 64.000
Daha iyi zamanlama çözünürlüğü için TCNT2 adlı bir değer kullanırsınız. Zamanlayıcı 8 bit olduğundan sayaçta 0 ile 255 arasında bir sayım vardır. Sayaç TCNT2 tarafından atanan değere ulaştığında bir kesmeyi tetikler. Bu kesintiye TIMER2_OVF_vect adı verilir.
bu bilgi göz önüne alındığında, elde edilen kesme hızı şöyle olur: 16MHz / (ön ölçekleyici * (255 - TCNT2))
Zamanlayıcının tam 16MHz'de (62.5nSec) çalışmasını sağlayabilirsiniz, ancak bu ihtiyacınız olandan daha hızlıdır; Başlangıç sayısı (255-2) olan 2MHz size 1MHz kesme hızı verir. Bunu ISR'nizde 2'ye bölün:
extern uint32_t MicroSecClock = 0;
ISR(TIMER2_OVF_vect) {// this is a built in function that gets called when the timer gets to the overflow counter number
static uint_8 count; // interrupt counter
if( (++count & 0x01) == 0 ) // bump the interrupt counter
++MicroSecClock; // & count uSec every other time.
digitalWrite(53,toggle);// pin 53 is arbitrary
TCNT2 = 253; // this tells the timer when to trigger the interrupt. when the counter gets to 253 out of 255(because the timer is 8 bit) the timmer will trigger an interrupt
TIFR2 = 0x00; // clear timer overflow flag
};
MCU'nuz için veri sayfası temel kaynaktır; bu makale size iyi bir başlangıç sağlayacaktır.
Mark, Arduino Atmega328 Timer2'yi temel alan ve taşma kesmelerini kullanarak 0,5us'a kadar hassasiyet elde etmek için yeni bir işlev seti yazmaya karar verdim. Kodum buradan indirilebilir ve kullanılabilir:
İşte kısa bir açıklama: "Bir" libary "yazdım" micros () "yerine koyma işlevinde 0,5us hassasiyet elde etmek, böylece 1us içinde bir PWM veya PPM sinyal okuma tekrarlanabilir sonuçlar elde edebilirsiniz. internet ve karşılaştırılabilir bir şey bulamadı (veya kullanımı kolaydı ve Arduino'nun Servo Libary aracılığıyla PWM sinyalleri yazma yeteneğini korudu), bu yüzden bu Arduino ve Radyo Kontrol dünyasına ilk büyük katkım olduğunu düşünüyorum. "
AVR Seviyesine düşmek kabul edilebilirse (sorunuzda belirtildiği gibi), bir zamanlayıcı ayarlayabilir ve hatta AVR saatinin saatlerini bile alabilirsiniz.
AVR'nizin veri sayfasına başvurmanız gerekir, çünkü farklı ATMegas ve ATTinys içinde farklılık gösterir. Ancak prosedür her zaman aynıdır. Yapmanız gereken:
TCCR
Bu şekilde zamanlayıcı kaydından kesin keneler alabilirsiniz, ancak taşmaları manuel olarak saymanız gerekir. Bu, teknoloji ile mümkün olduğunca hassastır.
Eski AT90S2313 için bazı örnek kod, ancak temel olarak ne yapmanız gerektiği konusunda iyi ipuçları verir:
/* uC: AT90S2313 */
#include <avr/io.h>
#include <avr/interrupt.h>
int main(void)
{
// set up timer 0
TCCR0 = (1<<CS01); // Prescaler 8
// enable overflow interrupt
TIMSK |= (1<<TOIE0);
// activate interrupts
sei();
while(1)
{
/* Do whatever you like */
}
}
ISR (TIMER0_OVF_vect)
{
/*
This gets called everytime there in an overflow in the timer register
*/
}
TIMSK
, TOIE0
vb (atmega328p bilgi formundan kopya zamanlayıcı ayarları). ISR () makrosunu kullanamazsınız, bunun yerine arduino.cc/en/Reference/AttachInterrupt kullanın .