Tek butonla 2 ayrı işlem yaptırmak

Başlatan protezdiyot, 31 Aralık 2014, 16:15:04

protezdiyot

Herkese merhaba; Bir deneme programı yazıyorum.Bir butonla 3 ayrı proses olarakta adlandırabilirsiniz. aşağıda örneğini verdiğim programda butona bir kere bastım ilk program çalışacak.Ama çalışmaya devam edecek sürekli.Ne zaman ikinci defa butona basarsam o zaman birinci program duracak 2. program çalışacak.3. defa basarsam da program komple duracak.nasıl yapabilirim?? Benim yazdığım aşağıdaki kodda ilk basışta çalışıyor ama ikinci 3. basışları algılamıyor? Düzeltebilir ve mantık hatamı söylerseniz sevinirim.


/******************************************************
Uygulama Adı : Yürüyen Işık
PIC PROG/DEKA : Port B jumper'ı LED konumunda olmalı
*******************************************************/
‪#‎include‬ <16f877.h> // Kullanılacak denetleyicinin başlık dosyası tanıtılıyor.
‪#‎fuses‬ XT,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOWRT,NODEBUG,NOCPD // Denetleyici konfigürasyon ayarları
‪#‎use‬ delay(clock=4000000) // Gecikme fonksiyonu için kullanılan osilatör frekansı belirtiliyor
int i,x,led; //i ve led isminde tam sayı tipinde 8 bitlik değişkenler tanıtılıyor.
/********* ANA PROGRAM FONKSİYONU********/
void main ()
{
setup_psp(PSP_DISABLED); // PSP birimi devre dışı
setup_timer_1(T1_DISABLED); // T1 zamanlayıcısı devre dışı
setup_timer_2(T2_DISABLED,0,1); // T2 zamanlayıcısı devre dışı
setup_adc_ports(NO_ANALOGS); // ANALOG giriş yok
setup_adc(ADC_OFF); // ADC birimi devre dışı
setup_CCP1(CCP_OFF); // CCP1 birimi devre dışı
setup_CCP2(CCP_OFF); // CCP2 birimi devre dışı
set_tris_b(0x00); // B portu tümüyle çıkış olarak yönlendiriliyor
output_b(0x00); // B portu çıkışları sıfırlanıyor
while(1)
{
x==0;
led=1;//led değişkeni değeri 1 oluyor
if (input (pin_a0))
{
delay_ms(25);
x++;
if (x==3)
{x=0;
}while(input(pin_a0))
{if (x==1)
{
for(i=0;i<=7;i++) // for döngüsü oluşturuluyor
{
output_b(led); // led değişkeni değeri B portuna gönder
led=led<<1; // led değişkeni değerini 1 bit sola kaydır
delay_ms(100); // 100 msn'lik gecikme veriliyor
}
led=0x80; //led değişkenine değer yükleniyor
output_b(led); //B portuna 0b10000000 bilgisi gönderiliyor
delay_ms(100); // 100 msn'lik gecikme veriliyor
for(i=0;i<=6;i++) // for döngüsü oluşturuluyor
{
led=led>>1; // led değişkeni değerini 1 bit sağa kaydır
output_b(led); // led değişkeni değeri B portuna gönder
delay_ms(100); // 100 msn'lik gecikme veriliyor
}}}
if(x=2)
{ for(i=0;i<=7;i++) // for döngüsü oluşturuluyor
{
output_b(led); // led değişkeni değeri B portuna gönder
led=led<<2; // led değişkeni değerini 1 bit sola kaydır
delay_ms(100); // 100 msn'lik gecikme veriliyor
}
led=0x80; //led değişkenine değer yükleniyor
output_b(led); //B portuna 0b10000000 bilgisi gönderiliyor
delay_ms(100); // 100 msn'lik gecikme veriliyor
for(i=0;i<=6;i++) // for döngüsü oluşturuluyor
{
led=led>>2; // led değişkeni değerini 1 bit sağa kaydır
output_b(led); // led değişkeni değeri B portuna gönder
delay_ms(100); // 100 msn'lik gecikme veriliyor
} }
}}}

Salih

#1
Gözüme takılan epey hata gördüm. Ve düzelttim. Sen karşılaştır artık.
Yalnız, döngüler de çok zaman geçeceği için kontrol butonunu
algılama zor olur. Döngülerdeki 100ms zamanı kesme yardımı ile
ana döngüde 100ms de bir lojik 1 olan bir değişken  tanımla
ve for döngüsü kullanmadan işlemi yapmaya çalış.

/******************************************************
Uygulama Adı : Yürüyen Işık
PIC PROG/DEKA : Port B jumper'ı LED konumunda olmalı
*******************************************************/
#include <16f877.h> // Kullanılacak denetleyicinin başlık dosyası tanıtılıyor.
#fuses XT,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOWRT,NODEBUG,NOCPD // Denetleyici konfigürasyon ayarları
#use delay(clock=4000000) // Gecikme fonksiyonu için kullanılan osilatör frekansı belirtiliyor
int i,x,led; //i ve led isminde tam sayı tipinde 8 bitlik değişkenler tanıtılıyor.
/********* ANA PROGRAM FONKSİYONU********/
void main ()
{
setup_psp(PSP_DISABLED); // PSP birimi devre dışı
setup_timer_1(T1_DISABLED); // T1 zamanlayıcısı devre dışı
setup_timer_2(T2_DISABLED,0,1); // T2 zamanlayıcısı devre dışı
setup_adc_ports(NO_ANALOGS); // ANALOG giriş yok
setup_adc(ADC_OFF); // ADC birimi devre dışı
setup_CCP1(CCP_OFF); // CCP1 birimi devre dışı
setup_CCP2(CCP_OFF); // CCP2 birimi devre dışı
set_tris_b(0x00); // B portu tümüyle çıkış olarak yönlendiriliyor
output_b(0x00); // B portu çıkışları sıfırlanıyor
while(true)
{ 
x=0;
led=1;//led değişkeni değeri 1 oluyor
   if (input (pin_a0))
      {
         delay_ms(25);
         x++;      
         if (x==3) x=0;
         while(input(pin_a0));
      }
            if (x==1)
            {
                  for(i=0;i<=7;i++) // for döngüsü oluşturuluyor
                  {
                     output_b(led); // led değişkeni değeri B portuna gönder
                     led=led<<1; // led değişkeni değerini 1 bit sola kaydır
                     delay_ms(100); // 100 msn'lik gecikme veriliyor
                  }
                        led=0x80; //led değişkenine değer yükleniyor
                        output_b(led); //B portuna 0b10000000 bilgisi gönderiliyor
                        delay_ms(100); // 100 msn'lik gecikme veriliyor
                  for(i=0;i<=6;i++) // for döngüsü oluşturuluyor
                  {
                     led=led>>1; // led değişkeni değerini 1 bit sağa kaydır
                     output_b(led); // led değişkeni değeri B portuna gönder
                     delay_ms(100); // 100 msn'lik gecikme veriliyor
                  }
           }
                        if(x==2)
                        { 
                              for(i=0;i<=7;i++) // for döngüsü oluşturuluyor
                              {
                                 output_b(led); // led değişkeni değeri B portuna gönder
                                 led=led<<2; // led değişkeni değerini 1 bit sola kaydır
                                 delay_ms(100); // 100 msn'lik gecikme veriliyor
                              }
                                    led=0x80; //led değişkenine değer yükleniyor
                                    output_b(led); //B portuna 0b10000000 bilgisi gönderiliyor
                                    delay_ms(100); // 100 msn'lik gecikme veriliyor
                              for(i=0;i<=6;i++) // for döngüsü oluşturuluyor
                                    {
                                       led=led>>2; // led değişkeni değerini 1 bit sağa kaydır
                                       output_b(led); // led değişkeni değeri B portuna gönder
                                       delay_ms(100); // 100 msn'lik gecikme veriliyor
                                    } 
                        }
}
}

protezdiyot

hocam çok teşekkür ederim lakin senin yazdığın programda butona basınca hiçbirşey çalışmıyor? Hata nerden kaynaklanıyor olabilir?Ben göremedim..

Salih

Alıntı yapılan: protezdiyot - 01 Ocak 2015, 21:46:04
hocam çok teşekkür ederim lakin senin yazdığın programda butona basınca hiçbirşey çalışmıyor? Hata nerden kaynaklanıyor olabilir?Ben göremedim..
yeni fark ettim.
x=0 ifadesini while den önce yaz.
Led=1 ifadesini buton kontrolü içine yaz. Öyle dene.

protezdiyot

Alıntı yapılan: salih - 01 Ocak 2015, 22:03:13
yeni fark ettim.
x=0 ifadesini while den önce yaz.
Led=1 ifadesini buton kontrolü içine yaz. Öyle dene.

Maalesef değişen bir şey yok. Program hiçbir tepki vermiyor

Salih

Alıntı yapılan: protezdiyot - 01 Ocak 2015, 22:08:10
Maalesef değişen bir şey yok. Program hiçbir tepki vermiyor
Proteus da deniyorsan dosyayı da yollarmısın.


Salih

Şemayı düzelttim.
Kristal kullanmak hata değil fakat simülasyonda ihtiyaç duyulmuyor.
Buton bağlantın da hata varmış düzelttim.

http://www.dosya.tc/server37/SfeczW/Y_r_yenI__kUygulamas_.rar.html

protezdiyot

#8
Hocam çok teşekkürler.Program beklediğim gibi  çalıştı.Ancak benim istediğim bu değil.Ben basar basmaz program sonlansın ve ikinci programa geçsin.Ancak şuan görünen program yeniden ilk komut satırına çıkınca butona basınca ikinci işleme geçiyor.Eğer kesme kullanırsamda kesme sonrası program kaldığı yerden devam edecek.Yanlış mı düşünüyorum?Yani ikinci kez basarsam kesme uyguladığımda program, 2. program işlemi bitince, 1. program  tekrar kaldığı yerden devam edecek.En baştan başlamayacak. yanılıyor muyum?

Ayrıca Size şunu sorayım;
Ben PLC mantığıyla pic programlayamam mı?

mesaj birleştirme:: 01 Ocak 2015, 22:40:36

Bu illa tek buton olmak zorunda da değil.Ben PLC deki gibi sensörler kullanarak sensörlerden gelen bilgilere göre sistemi yönetmek istiyorum ama PİC de bu mantığı bir türlü oturtamadım.PLC gibi çalışmasını bekliyorum entegrenin.Ancak bu şekilde çalışmıyor sanırım

Salih

Alıntı yapılan: protezdiyot - 01 Ocak 2015, 22:35:25
Hocam çok teşekkürler.Program beklediğim gibi  çalıştı.Ancak benim istediğim bu değil.Ben basar basmaz program sonlansın ve ikinci programa geçsin.Ancak şuan görünen program yeniden ilk komut satırına çıkınca butona basınca ikinci işleme geçiyor.Eğer kesme kullanırsamda kesme sonrası program kaldığı yerden devam edecek.Yanlış mı düşünüyorum?Yani ikinci kez basarsam kesme uyguladığımda program, 2. program işlemi bitince, 1. program  tekrar kaldığı yerden devam edecek.En baştan başlamayacak. yanılıyor muyum?

Ayrıca Size şunu sorayım;
Ben PLC mantığıyla pic programlayamam mı?

Kesme kullan demem çalışma şeklini değiştirmek amaçlı değil.
Led lerin çalışma şeklini şu anda da değiştirebilirsin.
Kesme kullanarak butona bastığımızda, daha hızlı cevap verdirmesini sağlamak.
Şu anda butona basarak for döngüsünün bitmesini bekliyoruz, değişme olması için.
Kesmede bu tepki çabuk olur.
Ama buton tepkisi önemli değilse böylede çalışabilir.

PLC mantığı derken Ladder dilini kast ediyorsan. Bazı çok kısıtlı çalışmalar var ama yeterli değil.
pic için en uygunu C dili ile programlamak.
Pic le plc karşılaştırmak uygun olmaz.
Çünkü pic bir entegre, plc ise gelişmiş bir cihazdır.

protezdiyot

Şimdi ben PLC de  butona basar basmaz istediğim işlem çalıştırıyordum.Buton tepkisi anındaydı.Ve devam eden proses sonlandığında  ve yeniden başlatıldığında işlem her defasında en baştan ilk işlemlerden başlardı.Ben PİC de buton tepkisi için kesme uyguladığımda ,kesme prosesi sonlandığında ana programa geri döndüğünce işlemci kaldığı yerden devam ediyor en baştan başlamıyor.Bunu aslında kast ediyorum.Bunu nasıl çözebilirim?Yada çözümü var mı?

mufitsozen

Alıntı yapılan: protezdiyot - 01 Ocak 2015, 22:35:25

Ayrıca Size şunu sorayım;
Ben PLC mantığıyla pic programlayamam mı?

mesaj birleştirme:: 01 Ocak 2015, 22:40:36

Bu illa tek buton olmak zorunda da değil.Ben PLC deki gibi sensörler kullanarak sensörlerden gelen bilgilere göre sistemi yönetmek istiyorum ama PİC de bu mantığı bir türlü oturtamadım.PLC gibi çalışmasını bekliyorum entegrenin.Ancak bu şekilde çalışmıyor sanırım

Meliksah Universitesinden Prof.Dr.Murat Uzam'in yazdigi "Building a Programmable Logic Controller with a PIC16F648A" kitabindan faydalanarak PIC ile yapilmis bir PLCnin nasil calisabilecegini ogrenebilirsiniz.


http://www.meliksah.edu.tr/muzam/UZAM_PLC_with_PIC16F648A.htm
Aptalca bir soru yoktur ve hiç kimse soru sormayı bırakana kadar aptal olmaz.

Salih

Alıntı yapılan: protezdiyot - 01 Ocak 2015, 22:53:17
Şimdi ben PLC de  butona basar basmaz istediğim işlem çalıştırıyordum.Buton tepkisi anındaydı.Ve devam eden proses sonlandığında  ve yeniden başlatıldığında işlem her defasında en baştan ilk işlemlerden başlardı.Ben PİC de buton tepkisi için kesme uyguladığımda ,kesme prosesi sonlandığında ana programa geri döndüğünce işlemci kaldığı yerden devam ediyor en baştan başlamıyor.Bunu aslında kast ediyorum.Bunu nasıl çözebilirim?Yada çözümü var mı?

PLC de çalışanların pic de en çok aradığı ve bulamadığı en önemli fonksiyon timer elemanıdır.
PLC deki timer ın çalışması program döngüsünden bağımsızdır.
Pic de plc timer ı gibi komut olmamasına rağmen, çeşitli şekillerde timer benzeri işler
gerçekleştirilebilir.
En iyi yöntem ise pic de timer kesmeleri kullanmaktır.
Timer kesmeleri pic ana program döngüsünden bağımsız çalışırlar.
Ana döngüde while() ile bekleseniz bile timer kesmesi çalışır.

protezdiyot

#13
Murat hocayı biliyorum..
Sevgili ustalar, ben, bir butona bastım bir işlem yaptı ikinci butona BASAR BASMAZ! ikinci işlemi yaptırmak istiyorum.Sonra tekrar başla bir butona yada 1. butona bastım HEMEN! bastığım butona tanımlanmış işlemi yaptırmk istiyorum.Ve bu işlemler en baştan başlayacak.Bu picle mümkün mü? Bunu öğrenmek istiyorum.
Şimdiye kadar verdiğiniz yanıtlar için sonsuz teşekkürler bu arada...

Salih

Alıntı yapılan: protezdiyot - 01 Ocak 2015, 23:08:56
Murat hocayı biliyorum..
Sevgili ustalar, ben, bir butona bastım bir işlem yaptı ikinci butona BASAR BASMAZ! ikinci işlemi yaptırmak istiyorum.Sonra tekrar başla bir butona yada 1. butona bastım HEMEN! bastığım butona tanımlanmış işlemi yaptırmk istiyorum.Ve bu işlemler en baştan başlayacak.Bu picle mümkün mü? Bunu öğrenmek istiyorum.
Şimdiye kadar verdiğiniz yanıtlar için sonsuz teşekkürler bu arada...

Gerekli algoritmaları uygularsan hepsi mümkündür.
Pic de ne kadar karmaşık işleri profesyonelce yapmak istersen
o kadar tecrübe sahibi olman gerekir.
O da çok uğraşarak zamanla olur.
Sen başla bizler yardımcı oluruz.