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 }
İ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.
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.
ö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.
Ö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. :-)
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
int1 buttonState;
int8 count=0; // Assigning count
float time=0.0; // Assigning time
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 ()
{
set_timer0(100); // Setting timer0 initial 60
count++; // Increasing count
buttonCheck();
}
void main()
{
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.