Haberler:

Forum kuralları güncellendi LÜTFEN  okuyunuz:  https://bit.ly/2IjR3ME

Ana Menü

seri iletişim kesme problemi

Başlatan modernherakles, 23 Mayıs 2009, 03:31:23

modernherakles

arkadaşlar,ustalar  bir kodun içinden cıkamadım ve sizinle paylaşayım dedim.tamaının vermiyorum çünkü ilgili altprogramlar var sadece
Senaryo şu pc ile seri iletişen bir picimiz var ölçüm neticesinde engel var ise stop diyor.Ben de pcden onu geri alma rutinine koşturmak istiyorum ]ancak seri kesme bile burda if döngüsünü kıramıyor:( daha doğrusu olması gereken kesme ile gelen veri olduğu vakit hemen picimizin ona koşturması gerkmiyor mu?oysa bu durduktan sonra veri gönderince programı baştan başlıtıyor bu nasıl iş anlayamadım gitti.
Sorum şu:Bu mesafe aynı kaldığı müddettçe pic  PC nin sözünü dinlemeyecek mi yani ?
Pice burda nasıl veri beklemesini söyleyebiliriz döngü devam ediyorken?
ana kod:
 while(true) // 
   {
   enable_interrupts(int_rda);
   output_low(pin_c0);
   olcum_al();
  
   if(mesafe<40){
   Stop();
   printf("\n\r engel var veri beklesin");
   break;
  }
If we hear, we forget; if we see, we remember; if we do, we understand – Confucius

ferdem

Seri veri kesmesini kurduysanız PIC daha öncelikli bir interruptta olmadığı sürece seri veri kesme altrutinine dallanır.

if(mesafe<40){
   Stop();
   printf("\n\r engel var veri beklesin");
   break;
  }


Burdaki "break;" ne için konuldu? Bu break; programı while(true) döngüsünden çıkarıyor. while döngüsünden çıkınca PIC nerelere gider, neler yapar bilemiyorum. Bu "break" i kaldırın.

En basit haliyle seri veri kesmesi kullanımını ben yine de buraya ekleyeyim:
//picproje.org
//CCS C seri veri kesmesi örnek kullanımı
#include <16F628A.h>
#fuses NOPROTECT, NOMCLR, NOWDT, NOLVP, INTRC_IO
#use delay(clock=4M)
#use rs232(baud=9600, xmit=PIN_b2, rcv=PIN_b1)

unsigned int veri=0;
void main(){
enable_interrupts(global);
enable_interrupts(int_rda);

   while(1){
      output_high(pin_b4);
      delay_ms(1000);
      output_low(pin_b4);
      delay_ms(1000);
   }

}

#int_rda
void seri_veri_geldi(){
veri=getc();
output_toggle(pin_b0);
}


"break;" i kaldırıp deneyiniz, kolay gelsin.

modernherakles

ilginiz için teşekkür ediyorum ferdem bey,dosdoğru anlayıp cevap yazdığınız için.Şimdi break i koymaktaki amaç hala engel orda durmaya devam ettiği halde döngüden kurtulup Pc nin dediği yöne gitmek şu şekilde tekrar deniyorum.Bu arada seri  kesme veya iletişim if döngüsüne girmeden problemsiz çalışıyor.Yani buradaki hedefim bir kere döngü dönüp dursun ne yaapacagını kullanıcıya sorsun döngüyü
bunu ilave ettim ama çıkamıyor döngüden hala engel var mesajı geldiği için
if(mesafe<40){
   Stop();
   printf("\n\rOnde engel var veri bekliyor"); 
   if(kbhit())break;
                }




oysa ben kesmeye dallanmasını ve orda kalmasını istiyorum?
If we hear, we forget; if we see, we remember; if we do, we understand – Confucius

ferdem

Öncelikle "break" i unutalım. "break" komutunun "if" le bir alakası yok. "break" sadece "do, for, switch, while" gibi döngülerden çıkmaya yarar. "break" sizin istediğiniz işi("if"ten çıkma) yapmaz burda. "if" bloğu içindeki komutlar koşul doğruysa çalışır değilse çalışmaz, "break" ile çıkılmaz.

Sizin o "if" in içine "break" yazmanız burdaki kodda PIC i while dan çıkarıyor, PIC ipini koparıp gidiyor. CCS C durumu anlayıp PIC i sleep moda mı sokuyor yoksa program bir yerlerde takılıp kalıyor mu bilmiyorum. Proteusta bakıyorum yeni veri geldiği zaman reset atıyor.

Kesmeye dallanıp orda kalma işi ise olmaz, kesmede kalırsak başka kesme alamayız, geri dönmek şart. Asıl çakılı kalma durumu kesmede kalmak olur. PIC daha kimsenin sözünü dinlemez:)

Burdan bakarak bu meseleye çözüm önerisinde bulunabilmem zor, kafamda birkaç senaryo var ama sizinki hangisi!

Programınızı küçük parçalar halinde deneyin, emin olduğunuz bazı kısımlar düşündüğünüz gibi çalışmıyor olabilir.

"break" i kaldırıp denediğinizde sorun ne oldu? Belki bu şekilde daha kolay çözebiliriz. Kolay gelsin.

modernherakles

evet ferdem bey madem break komutu için öyle dediğiniz için if li olan kısmı while yapmayı denedim.Snuç yine umduğum gibi olmadı ve ekrana devamlı yazıyı basmaya başladı çünkü gene döngüden kurtulamıyordu.Bu anlamda break in tam olarak işlevini anlayamadığımı söyleyebilirim.
ondan sonra çözümü şu şekilde buldum:araya biraz zaman koyarak.1sn kadar döngüde beklerken seri kesmeye izin veriyor böylece duvardan kaçmak için kullanıcıya fırsat doğuyor.TAbi bu arada ekran 1snde bir engel var kaçınız diye mesaj geliyor.Bu bir çözüm oldu şimdilik benim için daha iyi bir tavsiyeniz varsa onnuda dinleyebilirim neticede hala döngüden kurtulamadım ama ona boyun egerek böyle bir çözüm buldum yinede çok  teşekkürler.
if(mesafe<40){
   Do_Stop();printf("\n\r engel var veri beklesin"); output_high(pin_c0);delay_ms(1000);output_low(pin_c0);


Veri geldiği anda if ten cıkmak nası olurdu acaba???
If we hear, we forget; if we see, we remember; if we do, we understand – Confucius

kadirbas

Selamlar modernherakles.

Öcelikle "if" deyimi bir döngü değildir. "if" bir koşul deyimidir ve işlevi, kendisinden sonra gelen parantez içindeki koşul doğru ise, takip eden blok ya da blok yoksa ifadenin işletilmesini sağlamaktır. Örnek olarak sizin ilk kodunuzdaki if değimli kısıma

if(mesafe<40)
{
   Stop();
   printf("\n\r engel var veri beklesin");
   break;
  }


açıklama getirmeye çalışırsam, ilk olarak mesafe değişkeninin değeri kontrol edilecek, sorasında karşılaştırma doğru ise, '{' ve '}' arasındaki işlemler gerçekleştirilecek. Gerçekleştirilen işlemlerden ilki sanırım cihazın durmasını sağlıyor. İkincisi ekran çıktısı için kullanılan "printf" işlevi, sonuncusu ise döngülerden ve koşul komutu olan "switch" değiminden herhangi bir yerde çıkmaya yarayan "break" komutu. Dolayısıyla, ilk verdiğiniz örnekten beklenen, "break" komutunun "while" döngüsünü kırması.

Burada "if" değimini "while" değimiyle değiştirmeyi istemezsiniz sanırım. Çünkü bunun "break" deyimini kaldırmaktan farklı bir tarafı olmayacaktır.

Bunun dışında, programınızda "while" döngüsü içinde sürekli olarak,

enable_interrupts(int_rda);
output_low(pin_c0);


işlemleri yapılıyor, ki bence hem gereksiz, hem de sürekli olarak ilgili saklayıcıların değiştirilmeye çalışılması sorunlara yol açabilir..

Yazdıklarınızdan, yapmaya çalıştığınızı doğru anlayıp anlayamadığımı bilemiyorum ama anladığım kadarıyla bir öneride bulunmaya çalışayım.

Öncelikle

enable_interrupts(int_rda);
output_low(pin_c0);


kısımlarını döngünün dışına almanızı tavsiye ederim. Programın, PC'den gelen verileri beklemesini istiyorsanız, PC'den gelinceye kadar yapılmasını istemediğiniz işleri bu ana döngü içerisinde bir "if" değimi içerisine koyabilirsiniz. "if" değiminin koşulu olarak da, son işlemlerden sonra geçerli bir verinin gelip gelmediğini tutan bir bayrağın testini kullanabilirsiniz..

Toparlamak için, ilk yazdığınız koda alternatif olarak şöyle birşey önerebilirim:

  enable_interrupts(int_rda);
   output_low(pin_c0);
   GecerliVeriyiBekle = 0;

while(true) 
{
       // Yapılması gereken diğer işlemleri if'den önce koyabilirsiniz...

       if( !GecerliVeriyiBekle )
       {
               olcum_al();
       
              if(mesafe<40)
               {
                     Stop();
                     GecerliVeriyiBekle = 1;
                     printf("\n\r engel var veri beklesin");
               }
       }

       // Yapılması gereken diğer işlemleri buraya da koyabilirsiniz...

}


Tabii ki, seri port veri alma kesmesinde de "GecerliVeriyiBekle" adlı değişkeni, geçerli veri geldiği taktirde sıfırlamanız gerekir...

Koşulu, ilk söylediğimden farklı kullandım fakat; bu anlamsal olarak daha uygun ve anlaşılır gibi gözüktü..

İşinize yara umarım...
Kolay gelsin

modernherakles

herseyden önce kadirbas bey ilgilendiğiniz ve tümünü okuduğunuz için çok teşekkür ederim.Bu if döngüsünden (hala döngü diyorum)deyiminden kurtulmanın yolunun diğer bir if deyimi(gelenveribekle)komutuyla yapılması cok mantıklı ve denedim çalışıyor.
Benim tesadüfende olsa calışan süre koymam burda benim daha cok işime geliyor çünkü sizin dedğiniz gibi yaparsam evet döngüden çıkıyor ama hala engel varken seri porttan komut alıp kaçmasına izin vermediği için suvardan kaçacak süreyi tanımıyor.Bunun  dışında if ten çıkmasına yaradığı için sorumun cevabı olmuş oluyor.
Alıntı Yap
enable_interrupts(int_rda);
output_low(pin_c0);
işlemleri yapılıyor, ki bence hem gereksiz, hem de sürekli olarak ilgili saklayıcıların değiştirilmeye çalışılması sorunlara yol açabilir..
haklısınız bunlar sonsuz döngünün önüne alıyorum hemen.


Alıntı YapBurada "if" değimini "while" değimiyle değiştirmeyi istemezsiniz sanırım. Çünkü bunun "break" deyimini kaldırmaktan farklı bir tarafı olmayacaktır.
evet bunuda denedim seri kesmeden dönmesini bekledim ozaman whileyi kırıp neden olmadığını biraz açarmısınız?
If we hear, we forget; if we see, we remember; if we do, we understand – Confucius

kadirbas

Son sorunuza cevap olarak; if yerine while kullanmak durumunu incelersek, bu değişiklik sonunda kodunuz şöyle olacaktı:

while(true) //
   {
   enable_interrupts(int_rda);
   output_low(pin_c0);
   olcum_al();
 
   while(mesafe<40){
   Stop();
   printf("\n\r engel var veri beklesin");
   break;
  }


Bu durumda ikinci ( ya da içteki ) while döngüsü, döngü gibi çalışamayacak. Çünkü mesafenin 40 değerinden küçük olduğu durumda döngünün içine girmesine karşın, bir kere stop işlemini yapıp, bir kere printf işlemini yapıp, break komutuyla çıkıyor. Tabi bu da bir döngüden çok, ikinci while yerine if koymuşsunuz, break deyimini de kaldırmışsınız gibi oluyor.. Bunun yanında, bu işlemleri bir kere de yapmıyor. Çünkü kod, ana döngünün içinden tekrar bu kısıma gelerek, döngü vazifesi görmeyen bu while bloğunun içini bir kez daha çalıştırıyor. Tabi bu durumu, ölçümünüzün sürekli aynı sonucu verdiğini düşünerek söylüyorum...

Bunun dışında, daha önceki mesajımda anlatmaya çalıştığım yapının, yanlış düşünmüyorsam, veri almayı engellememesi gerekiyor.. Fakat kodunuzun tamamını göremediğimiz ve ilerlemek için nasıl bir algoritma kullandığınızı bilemediğimiz için, bu kısım hakkında doğru bir yorumda bulunamamış olabilirim.. Tahminen, burada stop fonksiyonunu kullanmanıza rağmen, başka bir yerlerde ilerle diyorsunuz ve bu da ilerlemenizi engellemiyor gibi...

Sonuç olarak, algoritmanızı gözden geçirmenizi öneriyorum. Algoritmayı gözden geçirmenin yollarından birisi de, diyagramını çıkartıp incelemektir.

Tekrar kolay gelsin..

modernherakles

Tamam while-break olayı anlaşılmıştır:D
Alıntı YapBunun dışında, daha önceki mesajımda anlatmaya çalıştığım yapının, yanlış düşünmüyorsam, veri almayı engellememesi gerekiyor..
evet kadirbas bey veri engellenmesi sözkonusu değil ancak mesafe şartı(if de)hala saglandığı için; (pcden ne komutu alınırsa alınsın)kesmeden hemen geri dönüp stoplamaya devam ediyor ki gayet makul ve beklenen de odur.

Alıntı YapFakat kodunuzun tamamını göremediğimiz ve ilerlemek için nasıl bir algoritma kullandığınızı bilemediğimiz için, bu kısım hakkında doğru bir yorumda bulunamamış olabilirim.. Tahminen, burada stop fonksiyonunu kullanmanıza rağmen, başka bir yerlerde ilerle diyorsunuz ve bu da ilerlemenizi engellemiyor gibi...
Yok yok başka bi yerde ilerle komutu düşündüğünüz gibi ilerle komutu,programının kalanındada alt programlar(stop,ilerle  vs.) ve kesme rutinleri dışında hiç birşey olmadığı için uzun tutmamak için yazmadım.isteginiz dahilinde yazabilirim.

ilginiz için tekrar teşekkürü bir borç bilirim.saygılar
If we hear, we forget; if we see, we remember; if we do, we understand – Confucius