ATMEGA8 için Timer1 kullanarak PWM ile servo kontrolü [Çeviri]

Başlatan XX_CİHAN_XX, 09 Mayıs 2010, 00:28:42

XX_CİHAN_XX

Arkadaşlar aşağıdaki çeviri bana aittir.
Çevirisini yaptığım link :
http://mil.ufl.edu/~achamber/servoPWMfaq.html
Ufak tefek çeviri hataları olabilir şimdiden affola diyelim ve birçok arkadaşımıza faydalı olması dileğiyle yazımızı yayınlayalım.

ATMEGA8 için Timer1 kullanarak PWM ile servo kontrolü

Servoların 3 girişi vardır.
Kırmızı = Vcc (Standart servo beslemesi 4.8V ile 6V arasındadır)
Siyah = Gnd
Beyaz = PWM girişi
Standart Servolar 50Hz lik bir pwm ile sürülmelidir. Yani servoya uygulanacak sinyalin periyodu
1/50 Hz = 20 ms olmalıdır.
Standart servolar 1ms ile 2ms aralığında bir duty cycle ile sürülür.
1.0ms = tam sola döner
1.5ms = orta konumdadır
2.0ms = tam sağa döner
Bu değerler servodan servoya üç aşağı beş yukarı değişim göstermektedir.
Phase and Frequency Correct mode:
Doğru faz modunda timer sayıcısı sıfırdan saymaya başlar, kullanıcının tanımladığı değere ulaşılınca ICRn(burada n, hangi timer kullanılıyorsa onun numarasıdır. Örneğin timer1 için ICR1 registeri kullanılır). Timer, tanımlanan değere ulaşınca tepe değerine gelmiş olur ve buradan sıfıra doğru inişe geçer. Servo kontrolü için timer ın yükselip inme süresi 20mS olmalıdır.
ICR1 değerini belirlemek için iki şey bilmelisiniz.
•   Sistem clock hızı
•   Timer clock hızı
Sistem clock hızı kullanacağımız kristal frekansı olmaktadır.
Timer clock hızı ise ön bölücülerden ayarlanmaktadır. Önbölücüler, TCCRn registerindeki CSn[2:0] (n burada timer numarasıdır) bitlerinden ayarlanmaktadır. Örneğin, Timer in hızı TCCR1B registerindeki CS1 bitlerinden ayarlanır.
Bu resim atmega8 datasheetinden alınmıştır




clkIO sizin sistem clock unuzdur. İstenen frekansın nasıl hesaplanacağı aşağıdaki formülde gösterilmiştir.

Buradaki N: Seçtiğimiz ön bölücü değeridir. (1, 8, 64, 256 veya 1024)
fclk_I/O: sistem clock frekansıdır.
fOCnxPFCPWM: PWM çıkışı frekansıdır
Sistem clock frekansımız 16Mhz iken 50Hz lik PWM üretmek için seçilen önbelen değerine göre TEPE(ICR1) değerleri aşağıdaki gibi olmalıdır.

Önbölücü N = 1 ise TOP(ICR1) = 160000 olmalıdır.
Önbölücü N = 8 ise TOP(ICR1) = 20000 olmalıdır.
Önbölücü N = 64 ise TOP(ICR1) = 2500 olmalıdır.
Önbölücü N = 256 ise TOP(ICR1) = 625 olmalıdır.
Önbölücü N = 1024 ise TOP(ICR1) = 156.25 olmalıdır.
Not: 16MHz de 50Hz lik PWM üretmek için önbölen değerini 1 yada 1024 veremezsiniz.
Çünkü bu değerler Timer1 (TCR1) in alabileceği değerler değildir. (timer1 16 bitlik bir sayıcıdır.)
Ben önbölen değerini 8 ve ICR1 değerinide 20000 olarak seçtim çünkü bu OCR1A regine 1000 ile 2000 arasında değer verebilmemizi sağlayacak. Bu da 1-2mS arasında high seviyede pals verebilmemizi sağlayacaktır.

Pekiiii OCRxn nedir?
Eğer ATMega datasheetinde pwm üretimi ile ilgili kısmı okuduysanız, OCRxn in ne olduğu konusunda ve ICRn ile arasındaki farkın ne olduğu konusunda şaşırmış olabilirsiniz. OCRxn registerinde, x timer numarasını belirtir ve n de hangi servoyu kontrol edeceğini gösterir. Timerlarla en fazla 2 servo kontrol edilebilir. Örneğin; Timer 1 ile OCR1A ve OCR1B yi kurabiliriz ve bazende OCR1C yi...


OCRxn ve ICRn için basit bir açıklama:

ICRn, servo için 50Hz lik PWM sinyali oluşturur.
OCRxn, servonun fiili manevralarını kontrol eder.
Birkez ICRn(Timer1 için ICR1) registerini kurduktan sonra bi daha değiştirmeye gerek yoktur.
Ancak OCRxn(Timer ve A servosu için OCR1A) registeri servonun pozisyonu için sürekli değiştirilecektir.
Buradaki diyagram ATMega8 datasheetinden alınmıştır ve OCRxn değerinin kontrol sinyalinin uzunluğunu nasıl değiştirdiğini göstermektedir.


(ATMega8 data sheet i sayfa 94)

TCNT1 (Timer Counter 1)  registeri Timer1 in sayaç değerini taşır. Timer sayıcısı sıfırdan başlar ICR1 (Input Compare Register 1) değerine kadar yükselir ve sonra tekrar sıfıra iner.
TCNT1, OCR1A (Output Compare Register 1A) registerine eşit değere geldiğinde, çıkış pini OC1A (Output Compare 1A) set olur.
•   TCNT1, aşağı doğru sayarken OCR1A ya eşit olduğunda, çıkış pini OC1A ise sıfıra düşer
•   Yani bir başka deyişle her TCNT1 = OCR1A durumu oluştuğunda OC1A çıkışı konum değiştirir.
Durumu özetlersek:
TCNT1 = Timer1 sayıcısının değeri
ICR1 = Timer1 in üst limitini belirler (50Hz sinyal oluşturmamız için gereken değer buraya girilir)
OCR1A = PWM sinyali (Duty cyckle uzunluğu) değiştirileceği zaman bu register kullanılır.
OC1A = PWM sinyalinin çıktığı pindir. Datasheet ten hangi pin olduğuna bakınız.
Servonun pozisyonunu değiştirmek isterseniz OCR1A registerine 1000 ile 2000 arasında değer girilir.
Örnek C kodu:
OCR1A = 1500;

Umarım ATMega serisi ile servo kontrolü konusunda yardımcı olabilmişimdir.

Kaynak:
http://mil.ufl.edu/~achamber/servoPWMfaq.html


Yakın bir süre sonra uygulamalı örnek kodda ekliyeceğim inşallah. İşlerimin yoğunluğundan dolayı şimdilik bukadar.
İyi çalışmalar.
Yirmi yaşındaki bir insan, dünyayı değiştirmek ister . Yetmiş yaşına gelince , yine dünyayı değiştirmek ister, ama yapamayacağını bilir.

XX_CİHAN_XX

void rgbPwmInit (void)
{	//fast pwm modu ile 3 kanal pwm kuruldu
	TCCR0A = 0b10100011;    //no prescaler, 8bit, fast pwm mode
	TCCR0B = 0b00000001; 
	TCCR1A = 0b10000001; 
	TCCR1B = 0b00001001;
	OCR0A = 0;
	OCR0B = 0;
	OCR1A = 0;
	TCNT0 = 0;          
	TCNT1 = 0;         
}
Yirmi yaşındaki bir insan, dünyayı değiştirmek ister . Yetmiş yaşına gelince , yine dünyayı değiştirmek ister, ama yapamayacağını bilir.

klutch


omerdedemli

slm...öncelikle paylaşım için çok tşkler...
bu durumu atmega8, 4 mhz kristal için avr assembly ile nasıl yapabilirim...
ben atmega8 ile bir proje üzerinde çalışıyorum ve 3 servo sürmeliyim...
servo_1 sadece 0 derece,90 derece ve 180 derecelik açılarla hareket ederken
diğer ikisi ileri ve geri olarak bir birinden bagımsız hareket edebilmeliler...
   bu konuyla ilgili örnek çalışmada varsa ekler misiniz?