Merhabalar, Ben CCS C ile bir butona 3sn den kısa basılırsa kısa döngü, uzun basılırsa uzun döngüye sokacak şekilde komutlar atamak istiyorum. (Kısa Döngü = Led 2 defa 1sn yanıp sönsün, 2 defa 2sn yanıp sönsün. on1sn-off1sn-on1sn-off1sn-on2sn-off2sn-on2sn-off2sn-on1sn-off1sn...) (Uzun Döngü = Aynı Led 4 defa 1sn yanıp sönsün, 4 defa 2sn yanıp sönsün. on1sn-off1sn-on1sn-off1sn-on1sn-off1sn-on1sn-off1sn-on2sn-off2sn-on2sn-off2sn-on2snoff2sn-on2sn-off2sn-on1sn-off1sn...)
Butona bu döngüleri sokacak şekilde komutları vermeyi başardım ancak sıkıntı, eğer kısa döngü içinde ben butona uzun döngüyü çağıracak kadar basılı tuttuysam, kısa döngü bittikten sonra uzun döngüye girmesi gerektiğini ya da uzun döngü içindeyken kısa döngüyü çağırırsam uzun döngü bitince kısaya girmesi gerektiğini nasıl kodlayabilirim? Yardımcı olur musunuz ?
Benim yazdığım kod :
#include<main33.h> #Use Delay(clock=4000000) // 4MHz osscillator #define button pin_c0 // Define PORTC0 as button #define DEBOUNCE 0.1 // Define DEBOUNCE time as 100ms
void buttonCheck() { if (input(button)) // Check if button is pressed { count=0; // Reset count at first set_timer0(100); buttonState=1; while(input(button)) // While holding button { time=count*0.050176; } buttonState=0; } }
void longLoop () // Function of 4x(on1sec,off1sec) + 4x(on2sec,off2sec) { while(TRUE) // Initial infinite loop { for (int a=0;a<4;a++) { delay_ms(15); output_b(0x01); // Led ON delay_ms(250); output_b(0x00); // Led OFF delay_ms(250); } for ( a=0;a<4;a++ ) { delay_ms(15); output_b(0x01); // Led ON delay_ms(500); output_b(0x00); delay_ms(500); // Led OFF } if (buttonState==0 && time>DEBOUNCE && time<3) { break; // Call Function of shortLoop } } } void shortLoop () // Function of 2x(on1sec,off1sec) + 2x(on2sec,off2sec) { while(TRUE) // Initial infinite loop { for (int a=0;a<2;a++) { delay_ms(15); output_b(0x01); // Led ON delay_ms(1000); output_b(0x00); // Led OFF delay_ms(1000); } for (a=0;a<2;a++) { delay_ms(15); output_b(0x01); // Led ON delay_ms(2000); output_b(0x00); delay_ms(2000); // Led OFF } if (buttonState==0 && time>=3) { break; } } longLoop(); // Call Function of longLoop } #int_timer0 // Interrupts of timer0 void interrupts () {
setup_psp(PSP_DISABLED); // Disabled PSP Setup_spi(SPI_SS_DISABLED); // Disabled SPI_SS Setup_timer_0(RTCC_INTERNAL | RTCC_DIV_256); // Setting timer0 and Prescaler as 256 setup_timer_1(T1_DISABLED); // Disabled Timer1 setup_timer_2(T1_DISABLED,0,1); // Disabled Timer2 Setup_adc_ports(NO_ANALOGS); // No Analog Input Setup_adc(ADC_OFF); // Disabled ADC Unit Setup_CCP1(CCP_OFF); // Disabled CCP1 Unit Setup_CCP2(CCP_OFF); // Disabled CCP2 Unit Enable_Interrupts(INT_timer0); // Start interrupts Enable_Interrupts(GLOBAL); // Let interrupts active
Set_timer0(100); // Setting timer0's initial value as 100 set_tris_b(0x00); // Setting all PORTB as OUTPUT set_tris_c(0x01); // Setting PORTC0 as INPUT, rest of them as OUTPUT output_b(0x00); // Let all PORTB get logic 0 at the beginning output_c(0x00); // Let all PORTC get logic 0 at the beginning
While(True) // Infinite Loop { shortLoop(); //Starting with shortloop }
} Teşekkür ederim şimdiden.
void buttonCheck() buttonState=0;
olduğu için karışıklık var.
ben olsam ana döngüyü
While(True) // Infinite Loop { shortLoop(); //Starting with shortloop }
yerine sürekli butonu kontrol eden fonksiyona gönderirdim. void buttonCheck()
oradan shortloop veya longloop hangisine gideceğine karar verirdim. CCS C' de debugger varsa bu tür hataları kısa sürede çözebilirsiniz.
enrgrup
kullanıcısına yanıt
İlk başta o şekilde yaptım ancak, herhangi bir loop çağırıldığı vakit o loop bitmeden button'un basılıp basılmadığını kontrol etmede zorluk yaşıyorum. Mesela shortLoop() fonksiyonunda for içine girdikten sonra butona basılıp basılmadığını, basıldıysa eğer ne kadar basıldığını kontrol edip, ona göre döngü değişimi yapmam gerekiyor. Umarım anlatabilmişimdir çünkü durum çok karışık geliyor bana.
ertan010
kullanıcısına yanıt
for dögülerinin içine aşağıdakine benzer kod eklenirse butonun basılı olup olmadığı kontrol edilebilir.
if (button!=1) //butona basılı değil ise { break; }
enrgrup
kullanıcısına yanıt
Aslına bakarsan onu da düşündüm ama sıkıntı delay komutlarında, simulasyonda denediğim zaman delay komutları yüzünden buton basma durumuna geçmiyor, ya da geçse bile 1 sn ya da 2 sn delay yüzünden döngü değişiminde istediğim zamanda basılmasını elde edemiyorum. Sanırım bunun için ayrı bir fonksiyon var.
ertan010
kullanıcısına yanıt
o zaman algoritmayı external interrupt (harici kesme) üzerinden tekrar kurmanız gerekiyor.
enrgrup
kullanıcısına yanıt
Biraz daha detaylı bilgi verebilir misiniz acaba ?
ertan010
kullanıcısına yanıt
öncelikle kullanacağınız pic mikronun datasheet'inde external interrupt bölümünü iyice okuyun.
external interrupt oluştuğunda interrupt fonksiyonu içinde sayım gerçekleştirin. çıkan sonuca göre shortloop veya longloop fonksiyonlarını çağırın. sayım timer kullanarak yapılabilir yani 2 interrupt kaynağı aynı anda çalışır mı emin değilim denemek lazım. manuel belki şöyle yapılabilir..
unsigned int count;
sayac_kontrol() { if (count<=3000) shortloop(); else longloop(); //
}
void interrupts () { count++; delay_ms(1); //1 ms de 1 arttır
}
void main() { . . . . sayac_kontrol();
}
count değeri bir yerlerde sıfırlanmalı şu an deneme imkanım olmadığı için yanlış yönlendirmek istemiyorum.
enrgrup
kullanıcısına yanıt
Öncelikle çok teşekkür ederim. Ben de siz external interrupt ile internal beraber ayrı ayrı çalışıyor mu diye araştırma yapmaya çalıştım, siz externaldan bahsedince ancak deneyecek fırsatım olmamıştı şu an deneyeceğim. Umarım sonuç olumlu olur. Tekrardan ilginiz için teşekkürler. :-)
yeni mesaja git
Yeni mesajları sizin için sürekli kontrol ediyoruz, bir mesaj yazılırsa otomatik yükleyeceğiz.Bir Daha Gösterme