TİMER kesmesi hakkında bilgi

Herkese iyi günler. Timer kesmesini kullanırken ben 1 Hz lik bi kesme elde edebilmek için neden böleni 1024 alıyorum ? örnek programları incelerken herkes 1024 almıs farklı bi deger alınıp ctc modunda daha farklı bi deger verebilir miyim? yada bu bölen olayını neye göre ayarlayabiliyorum bilgi verirseniz cok memnun olurum,zira cok yazı okudum ama anlayamadım lütfen acıklayıcı yazın herkese tesekkürler iyi çalışmalar ufak bi kod örnegi : define LED 22 define LED2 23 bool durum0 = false, durum1 = false; void setup() { pinMode(LED, OUTPUT); pinMode(LED2, OUTPUT); cli(); //interreptlar durduruluyor Serial.begin(9600); //-------------------------- //timer1 1Hz’ e ayarlanıyor //registerler sıfırlanır TCCR1A = 0;// TCCR1A register 0’lanıyor TCCR1B = 0;// TCCR1B register 0’lanıyor TCNT1 = 0;//sayac değeri 0’la // OCRxA karşılaştırma registeri 1Hz değer için ayarlanıyor //16 MHz osilatör,1Hz timer1 ın çalışma frekansı,1024 prescalar OCR1A = 15624;// = (16*10^6) / (1*1024) - 1 (değer 65536 dan küçük) // CTC mod açılıyor. TCCR1B |= (1 << WGM12); // CS10 ve CS12 bitleri 1024 prescaler için ayarlanıyor TCCR1B |= (1 << CS12) | (1 << CS10); // timer karşılaştırma interruptı aktifleştiriliyor TIMSK1 |= (1 << OCIE1A); //------------------------ //timer3 0.5 Hz’ eayarlanıyor TCCR3A = 0;// TCCR3A register 0’lanıyor TCCR3B = 0;// TCCR3B register 0’lanıyor TCNT3 = 0;//sayac değeri 0’la // OCR3A karşılaştırma registeri 1Hz değer için ayarlanıyor //16 MHz osilatör,0.5Hz timer3 ın çalışma frekansı,1024 prescalar OCR3A = 15624;// = (16*10^6) / (0.5*1024) - 1 (değer 65536 dan küçük) // CTC mod açılıyor. TCCR3B |= (1 << WGM32); // CS30 ve CS32 bitleri 1024 prescaler için ayarlanıyor TCCR3B |= (1 << CS32) | (1 << CS30); // timer karşılaştırma interruptı aktifleştiriliyor TIMSK3 |= (1 << OCIE3A); //interreuptlar aktif sei(); } ISR(TIMER1_COMPA_vect){ //timer1 interrupt ı 1Hz de tetikleniyor. if (durum0){ digitalWrite(LED,HIGH); durum0 = 0; } else{ digitalWrite(LED,LOW); durum0 = 1; } } ISR(TIMER3_COMPA_vect){//timer3 interrupt 0.5 1Hz de tetikleniyor. if (durum1){ digitalWrite(LED2,HIGH); durum1 = 0; } else{ digitalWrite(LED2,LOW); durum1 = 1; } } void loop() { }

Buradaki 1024 değeri Prescaler değeridir yani ön bölücü, Bir nevi işlemicinin osilatörünün orjinaliyle değilde sanki belli bir sayı ile çarpılmış/bölünmüş değerleriyle işlem yapmayı sağlar. Neden 1024 aldığın sorusuna ise şöyle yanıt vereyim, 1024 alma zorunluluğun yok. Buradaki asıl amaç sayacağın sayıyı tutturmakta. Örneğin senin yazılımında sayacağın sayı OCR3A = 15624;// = (16*10^6) / (0.5*1024) - 1 (değer 65536 dan küçük) satırındaki 15624 sayısı. işlemcinin osilatör değeri 16Mhz bunu dışarıdan osilatör eklemedikçe değiştiremezsin. O yüzden oynayabileceğin prescaler değeri var. Biraz daha detaylı anlatmak gerekirse işlemcin 16Mhz yani senin 1 cycle lık satırın örneğin ; i=0; bu satırın işlemci tarafından işlenme süresi 1/16Mhz yani 62.5nS (nanosaniye) yani sen prescaleri ellemeden 1HZ ( 1/1Hz = 1Sn ) lik bir timer kurmaya kalktığın zaman 1Sn/62.5nS = 16000000 ( 16milyon ) OCR3A = 16000000 ; yazman lazım. Peki bunu yazabilir misin ? Yazamazsın çünkü işlemci 16bit yazabileceğin maksimum sayı 16 bit te 65535 dir. Demekki orjinal osilatörle 1HZlik bir timer kurulamazmış. Prescaleri 1/8 alırsak olurmu peki ? Deneyelim Sub osilatör = 16Mhz /8 =2Mhz ( İşlemcin sanki 2MHZ miş gibi davranacak ) bir satırın ( cycle ) işlemci tarafından işlenme süresi 1/2Mhz = 0.5uS ( mikro saniye) 1HZ ( 1/1Hz = 1Sn ) lik bir timer kurmaya kalktığın zaman 1Sn / 0.5 uS = 2000000 ( 2milyon ) OCR3A = 2000000 ; yazman lazım. Peki bunu yazabilir misin ? Yazamazsın çünkü işlemci 16bit yazabileceğin maksimum sayı 16 bit te 65535 dir. Demekki 1/8 presclalerlede 1HZlik bir timer kurulamazmış. Prescaleri 1/256 alırsak olurmu peki ? Deneyelim Sub osilatör = 16Mhz /256 =62.5Khz ( İşlemcin sanki 62.5Khz miş gibi davranacak ) bir satırın ( cycle ) işlemci tarafından işlenme süresi 1/62.5Khz = 16uS ( mikro saniye) 1HZ ( 1/1Hz = 1Sn ) lik bir timer kurmaya kalktığın zaman 1Sn / 16 uS = 62500 OCR3A = 62500; yazman lazım. Peki bunu yazabilir misin ? Evet yazabilirsin çünkü 62500 sayısı bizim yazabileceğimiz maksimum sayı olan 65535 sayısından küçük. Özetle ; Kuracağın Timerın frekansı ( periyodu ) na göre prescaler seçilir. Ve belirlenen bir frekans farklı prescalerler ilede gerçekleştirilebilir. Örneğin 1Hz timer; OCR3A = 62500; yazıp prescaleri 256 alırsan da doğru sayar OCR3A = 15624; yazıp prescaleri 1024alırsan da doğru sayar Prescaler değerinide; TCCR1B |= (1 << CS12) | (1 << CS10); //bu komut ile yapıyorsun CS10,CS11,CS12 nin durumlarına göre farklı prescalerler seçilebilir. Umaırm açıklayıcı olmuştur

Hocam ne diyim sana :slight_smile: Allah razı olsun simdi cok guzel bi sekilde oldu hic bi soru işareti kalmadı inş baska bakanlarda bu konuyu görürler…

Ben de okudum hepsini. Ben zaten kökten timer kesmesini anlamıyorum ama bişiler anladım okuyunca. :smiley:

const int inputPin= 2; const int inputPin2= 6; const int inputPin3= 8; void setup() { pinMode(inputPin, INPUT); pinMode(inputPin2, INPUT); pinMode(inputPin3, INPUT); pinMode(13, OUTPUT); } void loop() { int val = digitalRead(inputPin); int val2 = digitalRead(inputPin2); int val3 = digitalRead(inputPin3); if (val==HIGH && val2==HIGH&& val3==HIGH) if (val==HIGH && val2==HIGH&& val3==HIGH) { digitalWrite(13, HIGH); delay(1000); digitalWrite(13, LOW); delay(1000); digitalWrite(13, HIGH); delay(2000); digitalWrite(13, LOW); delay(2000); digitalWrite(13, HIGH); delay(3000); digitalWrite(13, LOW); delay(3000); digitalWrite(13, HIGH); delay(4000); digitalWrite(13, LOW); delay(4000); } for (int sayi=0;sayi<10;sayi++) /////////////////////////////10 defa tekrar { digitalWrite(13, HIGH); delay(1000); digitalWrite(13, LOW); delay(1000); digitalWrite(13, HIGH); delay(2000); digitalWrite(13, LOW); delay(2000); digitalWrite(13, HIGH); delay(3000); digitalWrite(13, LOW); delay(3000); digitalWrite(13, HIGH); delay(4000); digitalWrite(13, LOW); delay(4000); } ///////////////////////////////////// 10 defa tekrardan sonra burayi işler ( bu kısmı 20 tekrar olsun istiyorum ykardaki for döngüsünü 20 yaparsam kullancagım projede olmuyor) üstdeki 10 tekrarı fordaki sayıyla oynamadan 20 tekrardan sonra buraya nasıl bi kod işlemeliyimki altdaki kodu calıştırabileyim ? digitalWrite(13, HIGH); delay(4000); digitalWrite(13, LOW); delay(4000); } hocam bir nevi timer gibi calışıyor işlem ama benim timer kodlarına baya bi uzagım ve ayri ayri zamanlar oldugundan beni cok yoracak yukarıdaki kodlar temsili kodlar yukarıda bahseddigim gibi bi işlemi nasıl yapabilirim bi yardımcı olurmusnuz? şimdiden teşekkür ederim

O işi şöyle çözerssin, Timer kuracağın sayıların OKEK ( Ortak Katların En Küçüğü )ini alırsın. Örneğin 1Sn, 2Sn, 5Sn ve 10Snlik timerler kurmak istiyorsan. OKEK(1,2,5,10) =10 Asıl timeri 10Sn ye ye kurarsın.( Yukarda hesabı yapılan timer işlemi ) Daha sonrada; if(Timer%1==0) { 1Snlik timer bölümü } if(Timer%2 ==0 ) { 2snlik timer bölümü } if(Timer%5 ==0) { 5Snlik timer bölümü } if(Timer%10 ==0 ) { 10Snlik timer bölümü oluşmuş olur. }

hocam timer siz baska bi çözümü yokmu :S

Bir kodun herhangi bir yerinde bekleme olacak ise ( Örneğin led 3 sn yan 5 sn sön gibi ) Bunu ya Timer ile ya da Delay komutuyla yapabilirsin. Delay komutu programın akışını bozacağı için Timer önerilir. Benim tavsiyem bu.Sen istediğini yapabilirsin

başka yolu yoksa timer ögrencez yapacak bişey yok demekki .. Çok teşkkür ederim hocam … yine arada rahatsız edicem sizi :smiley:

et ama arada :slight_smile:

define LED 5 define LED2 6 bool durum0 = false, durum1 = false; void setup() { pinMode(LED, OUTPUT); pinMode(LED2, OUTPUT); cli(); //interreptlar durduruluyor Serial.begin(9600); //-------------------------- //timer1 1Hz’ e ayarlanıyor //registerler sıfırlanır TCCR1A = 0;// TCCR1A register 0’lanıyor TCCR1B = 0;// TCCR1B register 0’lanıyor TCNT1 = 0;//sayac değeri 0’la // OCRxA karşılaştırma registeri 1Hz değer için ayarlanıyor //16 MHz osilatör,1Hz timer1 ın çalışma frekansı,1024 prescalar OCR1A = 15624;// = (16*10^6) / (1*1024) - 1 (değer 65536 dan küçük) // CTC mod açılıyor. TCCR1B |= (1 << WGM12); // CS10 ve CS12 bitleri 1024 prescaler için ayarlanıyor TCCR1B |= (1 << CS12) | (1 << CS10); // timer karşılaştırma interruptı aktifleştiriliyor TIMSK1 |= (1 << OCIE1A); //------------------------ //timer3 0.5 Hz’ eayarlanıyor TCCR3A = 0;// TCCR3A register 0’lanıyor TCCR3B = 0;// TCCR3B register 0’lanıyor TCNT3 = 0;//sayac değeri 0’la // OCR3A karşılaştırma registeri 1Hz değer için ayarlanıyor //16 MHz osilatör,0.5Hz timer3 ın çalışma frekansı,1024 prescalar OCR3A = 31249;// = (16*10^6) / (0.5*1024) - 1 (değer 65536 dan küçük) // CTC mod açılıyor. TCCR3B |= (1 << WGM32); // CS30 ve CS32 bitleri 1024 prescaler için ayarlanıyor TCCR3B |= (1 << CS32) | (1 << CS30); // timer karşılaştırma interruptı aktifleştiriliyor TIMSK3 |= (1 << OCIE3A); //interreuptlar aktif sei(); } ISR(TIMER1_COMPA_vect){ //timer1 interrupt ı 1Hz de tetikleniyor. if (durum0){ digitalWrite(LED,HIGH); durum0 = 0; } else{ digitalWrite(LED,LOW); durum0 = 1; } } ISR(TIMER3_COMPA_vect){//timer3 interrupt 0.5 1Hz de tetikleniyor. if (durum1){ digitalWrite(LED2,HIGH); durum1 = 0; } else{ digitalWrite(LED2,LOW); durum1 = 1; } } void loop() { } hocam böyle bi kaynak buldum buraya buton eklemeye calıştıgımda hata oluyor biraz erken rahatsız ettim ama :smiley: bu timere buton basılı iken calışı nasıl yapabilirim birde bu timer neresini degiştirisem cogaltabilirim milsa 10 tane kullanmak istiyorum 10 buton icin yane şimdiden teşkkürler

Kanki sen yanlış anladın mevzuyu. Timer butona basınca say bırakınca dur gibi birşey değil. Bir kere sayacağı sayıyı ayarlarsın, sonra başla komutu verince o arka planda sürekli sayar. Sen butona bassanda basmasanda sayar. Sen biraz daha araştır timer konusunu

butona basılarakta işlem yapılabilir @ekmekci hocam buton durumuna göre sei() cli() komutları devreye sokulabilir.

Dostum Timer kesmesi deyince aklına ne geliyor ? Bir açıklarmısın

çok şey geliyor , butona bağlı da timer kesmesini çalıştırabileceğim geliyor mesala aklıma , harici kesme ile de timer saydırabileceğim geliyor.harici kesme gelince tcn registeri 0layıp tekrar aktif edip saydırabilirim

işlemcinin arka planında çalışcak , ama bunu kontrol edilebilir halde de çalıştırılabilir bu durum .

Dostum C gibi dillerde bir işi yapmak için çok alakasız şeylerden yardım alınarak ta yapılabilir. Ama o işi yaptın diye doğru yapmış sayılmazsın. İf fonksiyonları kullanılarak bir for yapısı kurulabilir. Ama o yapıyı kurdun diye doğru yapmış sayılmazsın. Bilmem anlatabiliyor muyum. Timer Kesmesinin mantığı, ayarladığın belirli periyodlardan haberin olmasıdır. Bu kadar ! Ben işlemcideki her 15ms aralığı bilmek istiyorum dersen bu Timer kesmesidir. Kurarsın 15ms ye sonra kollarını bağlayıp arkana yaslanırsın ve yapısı gereği Timer kesmesi sana her 15ms yi haber verir. Sen bunu butonla başlatmışsın, potla başlatmıisın veya ıslık çalarak başlatmışsın birşey değiştirmez. Yapı mantığındna çıkarak istediğini yapabilirsin. Ama asıl yapı budur. Hala aksini iddia edeceksen. Tamam kardeşim senin dediğin olsun ben yanlış biliyorum :slight_smile: Haklısın…

siz tek düze klasik düşünüyorsunuz , kalıplara alıştığınız için bu durum normal :slight_smile: , geliştirmeye açık düşünürseniz kesmeleri de daha yararlı düşünebilirsiniz.Zaten psikoloji de şu olayın bir tanımı vardır , hala inat ediyorsan hala yapıyorsan ben yokum , ben bilmem lafının.Bence biraz daha güzel düşünün ,

elmalar armutlar hep karışmış

butonla timer yalan oldu bizim sanırım bu kavga arasında gitti :smiley: