Merhaba, aşağıdaki kod 1'er saniye arayla kesmeye giriyor ve syc değişkeni 1 artıyor, amacım bu değişken 5'e ulaştığında kesmeyi 3 saniyeliğine durdurup tekrar devam ettirmek fakat noInterrupts(); çağrınca bir daha aktifleştiremiyorum... bunun için nasıl bir yol izlemem gerekiyor?
Not: delay komutu timer0 kullanıyor, buradaki kesme fonksiyonu timer1 ile yapılmıştır
int syc = 0;
void setup()
{
setupTimer1();
Serial.begin(115200);
}
void setupTimer1()
{
noInterrupts();
// Clear registers
TCCR1A = 0;
TCCR1B = 0;
TCNT1 = 0;
// 1 Hz (16000000/((15624+1)*1024))
OCR1A = 15624;
// CTC
TCCR1B |= (1 << WGM12);
// Prescaler 1024
TCCR1B |= (1 << CS12) | (1 << CS10);
// Output Compare Match A Interrupt Enable
TIMSK1 |= (1 << OCIE1A);
interrupts();
}
void loop()
{
if (syc >= 5)
{
noInterrupts();
delay(3000);
setupTimer1();
}
}
ISR(TIMER1_COMPA_vect)
{
syc++;
Serial.println(syc);
}
Bence Timerı açıp kapatarak zaman kaybetmeyin. Bir flag ile kontrolünüzü sağlayabiliriniz. Mesela değişkeniniz 5 olunca flag 1 olucak, Daha sonra timer 3 saniye sayıp süre sonunda flagı 0 yapıcak ve değişkeniniz artıcak
Kesme içine o kadar kod yığma.
Sadece bir değişkene bir bayrak oluştur. Zamanlayıcıya 1 saniyelik kesme olacak şekilde ayarla. Zamanlayıcıyı çalıştır ve bayrağı kontrol et.
Ana çevrim (loop) içinde bayrağı kontrol et. bayrak istenen değerde ise bir sayıcıyı 1 artır. Artık sayıcı değerini kontrol etmesini biliyorsun.
Eğer karşılaştırılacak sayılar belirli ve sabit ise , toplam işlemi bu sayıların toplamı kadar yaparsın.
örneğindeki gibi 5+3 toplama sayacın olduğunda sıfırlarsın.
sayac=0 değerinde 1. aşamayı başlatırsın,
sayac=5 değerinde 2. aşamayı, ve sayac=8 olduğunda sayacı sıfırla...
Aslında temel saat işlemi gibi düşünülebilir.
Loop içinde kesme kontrolleri daha kolay gerçekleştirilebilir.
Hatta bu şekilde millis() fonksiyonunuda kullanabilirsin.
Bunun için hazır milis fonksiyonu var.
https://www.arduino.cc/reference/en/language/functions/time/millis/
Alıntı yapılan: Kabil ATICI - 24 Kasım 2022, 22:31:58Kesme içine o kadar kod yığma.
Sadece bir değişkene bir bayrak oluştur. Zamanlayıcıya 1 saniyelik kesme olacak şekilde ayarla. Zamanlayıcıyı çalıştır ve bayrağı kontrol et.
Ana çevrim (loop) içinde bayrağı kontrol et. bayrak istenen değerde ise bir sayıcıyı 1 artır. Artık sayıcı değerini kontrol etmesini biliyorsun.
Eğer karşılaştırılacak sayılar belirli ve sabit ise , toplam işlemi bu sayıların toplamı kadar yaparsın.
örneğindeki gibi 5+3 toplama sayacın olduğunda sıfırlarsın.
sayac=0 değerinde 1. aşamayı başlatırsın,
sayac=5 değerinde 2. aşamayı, ve sayac=8 olduğunda sayacı sıfırla...
Aslında temel saat işlemi gibi düşünülebilir.
Loop içinde kesme kontrolleri daha kolay gerçekleştirilebilir.
Hatta bu şekilde millis() fonksiyonunuda kullanabilirsin.
oluşturacağınız bayrak değişkeninin volatile olarak oluşturulması gerektiğini ekleyelim.
cevaplar için teşekkür ederim, şu an öğrenmek istediğim konu interrupt işlemini kestikten sonra neden tekrar başlatamıyorum?
noInterrupts();
delay(3000);
setupTimer1();
noInterrupts();
delay(3000);
syc=0;
setupTimer1();
Birde böyle denermisin
timer in 1 sn de bir çalışıyorsa;
timer içinde bir sayaç çalıştırsan ve bu sayaç 8 e ulaştığında sıfırlasan, sayaç değerin 5 ten büyük 8 den küçük olduğu sürece hiç bir işlem yaptırmasan, ama timerini sürekli çalışsa olmaz mı?
mesela;
ISR(TIMER1_COMPA_vect)
{
syc++;
if(syc <=5){
//yapmak istediklerini yap
}
if(syc >=8) syc =0;
Serial.println(syc);
}
bu şekilde çalışıyor sorun çözüldü...
int syc = 0;
void setupTimer1()
{
noInterrupts();
// Clear registers
TCCR1A = 0;
TCCR1B = 0;
TCNT1 = 0;
// 1 Hz (16000000/((15624+1)*1024))
OCR1A = 15624;
// CTC
TCCR1B |= (1 << WGM12);
// Prescaler 1024
TCCR1B |= (1 << CS12) | (1 << CS10);
// Output Compare Match A Interrupt Enable
TIMSK1 |= (1 << OCIE1A);
interrupts();
}
void setup()
{
Serial.begin(115200);
setupTimer1();
}
void loop()
{
if (syc == 3)
{
TIMSK1 &= ~(1 << OCIE1A); // Timer İnterrupt Kapat
delay(3000);
setupTimer1();
}
}
ISR(TIMER1_COMPA_vect)
{
syc++;
Serial.println(syc);
}