while komutu farkli sonuclar verme

Başlatan selvi, 14 Ağustos 2013, 14:26:26

RaMu

#15
Alıntı yapılan: muhittin_kaplan - 14 Ağustos 2013, 22:10:37
selvi,
eğer devamlı kontroledeceksen butonları başka çaren yok
main()
{
    while (1)
     {
        while(buton1)
          {
              kodlar...()
              delay
           } 


        while(buton2)
          {
              kodlar...()
              delay
           } 

      }
}

şeklinde yapmalısın. Yok arkadaş böyle olmuyor diyorsan, interrupt ı incele.




Muhittin hocam bahsetmeyi gerekli görmedin sanırım ama
bu şekilde while(1) içinde birçok while(butonx) kontrolü yaparken
butona basılmasını kaçırma ihtimali oluşuyor,
bu yüzden while(butonx) rutinlerinde delay kullanmayıp
sadece while(1) sonunda delay kullanmak sorunu çözüyor,

https://www.picproje.org/index.php?topic=47905.0

bu konuda arkadaşın başına gelmişti daha detaylı açıklamışdım konuda,

ayrıca buton arkı ve çözümü konusundanda bahsetmiştim,
@selvi bence konuya bir gözatmalısın.

Ayrıca programını eklesen baksak daha güzel olur,
en azından problemli kısımları ekle,

while(1)
{
   while(input(pin_a4))
   {
   buton4 işlemi
   }

   while(input(pin_a5))
   {
   buton5 işlemi
   }

}


böyle yazılırsa ve misal buton4 e basılırsa buton arkından ötürü
buton4 işlemi yapıldıktan sonra buton arkı geçmeden buton4 ün kontrolüne tekrar gelinebilir ve
buton4 işlemi tekrarlanabilir,

while(1)
{
   while(input(pin_a4))
   {
   buton4 işlemi
   while(input(pin_a4));
   }

   while(input(pin_a5))
   {
   buton5 işlemi
   while(input(pin_a5));
   }

}


buton4 e basılırsa buton4 işlemi çok kısa sürede yapılır,
ve while(input(pin_a4)); kısmına gelindiğinde buton arkından ötürü buton bırakılmış gibi hissedilir
ve burada kalmak mümkün olmaz,
hatta yukarıdaki örnekdeki durum oluşur ve buton4 işlemi tekrarlanabilir,


while(1)
{
   while(input(pin_a4))
   {
   buton4 işlemi
   delay_ms(50);
   while(input(pin_a4));
   }

   while(input(pin_a5))
   {
   buton5 işlemi
   delay_ms(50);
   while(input(pin_a5));
   }

}


Burada ise buton4 e basılırsa buton4 işlemi yapılır tamam,
sonra delay_ms(50); ile buton arkının geçmesi beklenir güzel,
şu anda buton arkı yok ve    while(input(pin_a4)); kısmında program istediğimiz gibi butonun bırakılmasını bekliyor,
buradada sorun yok,
fakat buton4 bırakılırsa işler karışacak,
bırakıldığında yine buton arkı oluşacak ve while(input(pin_a4)) kısmına hemen dönülebilecek
bu yüzden butona tekrar basılmış gibi buton4 işlemi tekrarlanabilecek,
öyleyse;

while(1)
{
   while(input(pin_a4))
   {
   buton4 işlemi
   delay_ms(50);
   while(input(pin_a4));
   delay_ms(50);
   }

   while(input(pin_a5))
   {
   buton5 işlemi
   delay_ms(50);
   while(input(pin_a5));
   delay_ms(50);
   }

}


Bu en garantisi ama bundada ilk bahsettiğim olan olur,
insan için aynı anda (yani 1 msden kısa sürede gibi)
butonlara aynı anda basılırsa buton işlemleri gerçekleştirilemeyebilir,

Bu yüzden uygulamaya yönelik kodu yazmak zorundayız,
tek buton kontrol edilecekse bu şekilde kullanılabilir,
uygun delay süresi belirlenebilir, kısaltılabilir,
yada daha iyi bir uygulama için buton arkı delaysız olarak stabil hale gelmesi kontrol edilebilir,
yani 1ms boyunca buton son durumu üzerinde herhangibir değişiklik olmadı,
o zaman buton son durumu budur denebilir,
while(input(pin_a4))
   {
   buton4 işlemi
   delay_ms(50);
   while(input(pin_a4));
   delay_ms(50);
   }




aynı rutinde birçok buton kontrol edilecekse,

while(1)
{
   while(input(pin_a4))
   {
   buton4 işlemi
   }

   while(input(pin_a5))
   {
   buton5 işlemi
   }

.
.   diğer buton kontrolleri-rutinleri
.





delay_ms(50);

}



bu şekilde kullanılabilir
Sorularınıza hızlı cevap alın: http://www.picproje.org/index.php/topic,57135.0.html

selvi

#16
  program asagidaki sekildedir:

/******************************************************
      PIC16F877 ile Tu? Taky'my' Uygulamasy'-1
      PIC PROG/DEKA     : Port B jumper'y' LED konumunda olmaly'
*******************************************************/
#include <16f628a.h>
#fuses INTRC,NOWDT,PUT,NOPROTECT,NOLVP,NOBROWNOUT
#use delay(clock=4000000)

#use fast_io(a)
#use fast_io(b)

#define use_portb_lcd TRUE

#include <lcd.c>

#define std  pin_a4

//#byte   portb=0x06   // B portu "tus" ismine e?itleniyor.
char harf,a1=0,a2=0,b1=0,bilgi,tus=0,deger=0,sayi=0,bs=0;
int1 st=0,satir2=0;

char port_goster()
{
    if(deger==1)     harf='a';
    if(deger==2)     harf='b';
    if(deger==3)     harf='c';
    if(deger==14)    harf='m';
    if(deger==17)    harf='o';
    if(deger==22)    harf='u';

       
    return harf;  // Fonksiyon "harf" de?eri ile geri döner
}

/********* ANA PROGRAM FONKSY'YONU********/

void main ( )
{
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);

   set_tris_a(0b00111111);
   set_tris_b(0x00);   // B portu komple çy'ky'?

   output_b(0x00); // Y'lk anda B portu çy'ky'?y' sy'fy'rlany'yor
   
   lcd_init();
   
   while(TRUE)  // Sonsuz döngü
   {
       tekrar:
       tus=input_a();
       tus&=0b00001111;
       
       if (tus==10){write_eeprom(0,0);write_eeprom(1,0);write_eeprom(2,0);write_eeprom(3,0);write_eeprom(4,0);
       write_eeprom(5,0);write_eeprom(6,0);write_eeprom(7,0);}
      
       if(tus==10) {tus=0;st=1;a1=0;b1=0;a2=0;bs=0;sayi=0;satir2=0;deger=0;}
     
       if(st==1 && tus!=0)
       {
          bs++;
          if (bs==1 && tus==12){while(input(std));goto git;  }
          if (bs==1){a1=tus;while(input(std));goto tekrar;}
          if (bs==2 && tus==12){b1=0;while(input(std));goto kontrol;} 
          if (bs==2 && tus!=11){a2=tus;b1=0;while(input(std));goto kontrol;} 
          if (bs==2 && tus==11){a1*=10;while(input(std));goto tekrar;}   //a2=0 eklenebilir   
          if (bs==3) {b1=tus;while(input(std));}  
          
          kontrol:
          deger=a1+b1;
          bilgi=port_goster();
          
          write_eeprom(sayi,bilgi);  // yazma iþlemi için bu yeterli ve daha az yer kaplar.
          
          sayi++; 
        
          git:
          if(tus==12) 
          {
            if(sayi==2 && tus==12){write_eeprom(2,0);write_eeprom(3,0);write_eeprom(4,0);write_eeprom(5,0); write_eeprom(6,0);write_eeprom(7,0);}
            if(sayi==3 && tus==12){write_eeprom(3,0);write_eeprom(4,0);write_eeprom(5,0); write_eeprom(6,0);write_eeprom(7,0);}
            if(sayi==4 && tus==12){write_eeprom(4,0);write_eeprom(5,0);write_eeprom(6,0);write_eeprom(7,0);}
            if(sayi==5 && tus==12){write_eeprom(5,0);write_eeprom(6,0);write_eeprom(7,0);}
            if(sayi==6 && tus==12){write_eeprom(6,0);write_eeprom(7,0);}
            if(sayi==7 && tus==12) write_eeprom(7,0);
            
            if (satir2==1)lcd_gotoxy(1,2); // Ýmleç 1.sütun, 2. satýrda
            
            printf(lcd_putc,"%c%c%c%c%c%c%c%c",read_eeprom(0),read_eeprom(1),read_eeprom(2),read_eeprom(3),
            read_eeprom(4),read_eeprom(5),read_eeprom(6),read_eeprom(7));
            sayi=0;a1=0;b1=0;deger=0;bs=0;satir2=1;tus=0;while(input(std));
          }
                                                                                                                                                                                                                                                                                
          if(a2!=0){a1=a2;a2=0;bs=1;goto tekrar;}
        
          tus=0;if(sayi==255)sayi=0;a1=0;b1=0;bs=0;
      }
   }
       
}

Yaşam anlamlandırıldıkça kutsaldır....

selvi

#17
 r4 pinini osiloskopta denedim.tusa basili oldugu surece lojik 1  tus birakildiginda lojik 0 oluyor.

while(input(std)){delay_ms(50);while(input(std));delay_ms(50);}


yukardaki sekilde kodlari ekledim ayni sorun devam ediyor.

mesaj birleştirme:: 15 Ağustos 2013, 08:47:55

sema asagidaki linkteki gibidir.
http://imageshack.us/photo/my-images/607/3jef.png/
Yaşam anlamlandırıldıkça kutsaldır....

selvi

  while komutunu gelen mesajlara gore duzenledim herhangi bir gelisme yok.
  while komutunu kaldirip rb0 kesmesini kullandim sorun cozuldu.
Yaşam anlamlandırıldıkça kutsaldır....

Gökhan BEKEN

Örnek kod verirseniz, daha sonra sorun yaşayanlarda yararlanabilir.
Özel mesaj okumuyorum, lütfen göndermeyin.

selvi

   normalde kodluk bir durum yok.cm8870 islemcisinin 15 nlu pini(std) ucunu 16f628 islemcisinin rb0 pinine baglaniyor.herhangi bir tusa basildiginda std ucu lojik 1 oluyor.tus birakildiginda std uu lojik 0 oluyor.bu degisikligi programla denetlemek icin while komutu kullanmistim.yani tusa basili oldugu surece (yani lojik 1) odugunda "(while(input(rb0))" bu komutla donguye giriyor.tus birakildiginda bu donguden cikararak yeni tus bilgisini bekliyor.bahsettigim gibi while komutu bu tarz davranmiyordu.
  yukarda bahsettigim isleri yapmasi icin rb0 kesmesini kullandim.sorun cozuldu.yani herhangi bir tusa basilmadiginda rb0 lojik 0 dir.tusa basildiginda rb0 lojik 1 oluyor.yyukselen kenar tetiklemesinde rb0 kesmesini kullanarak bu sorunu cozdum.

  rb0 kesmesine iliskin kisimlari parca parca asagidaki sekildedir
#define std  pin_b0
#int_ext
void ext_kesmesi ()
{
   rb=1;
}

  .
  .
  .
  ext_int_edge(L_TO_H);
   
   enable_interrupts(INT_EXT);
   enable_interrupts(GLOBAL);
   .
   .
   .
while(1)
{
        if (rb==1)
       {
       rb=0;
       tus=input_a();
       tus&=0b00001111;
       .
       .
       .
       
Yaşam anlamlandırıldıkça kutsaldır....