Arama butonu
Bu konudaki kullanıcılar: 1 misafir
9
Cevap
1816
Tıklama
0
Öne Çıkarma
Pic Buton Sorunu
P
9 yıl
Yüzbaşı
Konu Sahibi

Arkadaşlar merhaba,

Bir projem için 16F628A pic ile devre yapmaya çalışıyorum, bu işlerde de yeniyim. Butona bastıkça modu değişecek bir devreyi programladım, proteus da sağlıklı şekilde çalışıyor. Pic'i programlayıp devreyi kurduğumuzda sadece 2 ve 3 nolu ledler yanıyor veya 2 nolu led yanıyor. Benim program ile alakası yok. Butona da cevap vermiyor, hiç bir tepki yok picte. Oysa ki simülasyonda gayet sağlıklı çalışıyor.

 


#include <16F628A.h>
#fuses XT, NOPROTECT
#use delay(clock=4000000)

#use fast_io(b)
#use fast_io(a)
#define buton pin_A2

int a=1;

void main()
{

set_tris_b(0x00);
output_b(0x00);
set_tris_a(0x00100);
basla:
while(1){

if(input(buton))
{
delay_us(10); //ark yaparak tekrar etmemesi için

if(a==3)

a=1;

else a++;

while(input(buton)){} //butonu bırakmadan geçmeyecek

delay_us(10); //ark olayı

}

if(a==1){
output_high(pin_b2);
delay_ms(20);
}
else if(a==2){

output_low(pin_b2);
delay_ms(50);
output_high(pin_b1);
delay_ms(50);
output_high(pin_b3);
delay_ms(50);
output_high(pin_b2);
delay_ms(50);
tekrar:
output_low(pin_b1);
delay_ms(50);
output_low(pin_b3);
delay_ms(50);
output_high(pin_b3);
delay_ms(50);
output_high(pin_b1);
delay_ms(50);
if(input(buton))
{
a==1;
output_low(pin_b1);
output_low(pin_b3);
goto basla;
}
goto tekrar;
}
}
}


Yukarıdaki kodu biraz daha değiştirerek kullanacağım ancak şuan da bu haliyle çalıştıramadım. Devrenin simülasyondaki ve gerçekteki görüntülerini de ekliyorum.

Teşekkürler..


< Resime gitmek için tıklayın >< Resime gitmek için tıklayın >



@slayer_ank Hocam bakabilir misiniz.

DH forumlarında vakit geçirmekten keyif alıyor gibisin ancak giriş yapmadığını görüyoruz.

Üye olduğunda özel mesaj gönderebilir, beğendiğin konuları favorilerine ekleyip takibe alabilir ve daha önce gezdiğin konulara hızlıca erişebilirsin.

Üye Ol Şimdi Değil



< Bu mesaj bir yönetici tarafından değiştirilmiştir >


Bu mesajda bahsedilenler: @slayer_ank
G
9 yıl
Yarbay

set_tris_a(0x00100); <-

Sayıyı 16 lık sistemde yazmışsın, 10 luktaki karşılığı 256 dır. Alt 8 bit 00 olduğu için A portu komple çıkış olur. Anladığım kadarıyla 2 numaralı pini giriş, diğerlerini çıkış yapmak istiyorsun. Öyleyse ya 4, ya 0x04, ya da 0b100 yazman gerekir.

Birde 10 us bekleme süresi ark ı önlemek için yeterli değil. En az 50 Ms (milisaniye) olmalı.


Bu mesaja 1 cevap geldi.
P
9 yıl
Yüzbaşı
Konu Sahibi

Sorunu dün gece çözdüm;

Sorun "#fuses xt" kısmındaymış. Ben dahili kristali kullanmak istiyordum, kullanma şekli #fuses INTRC olarak yazmak gerekiyormuş. Yardımlarınız için teşekkürler.



< Bu ileti mobil sürüm kullanılarak atıldı >
Bu mesaja 1 cevap geldi.

Bu mesajda bahsedilenler: @elektro_gadget
P
9 yıl
Yüzbaşı
Konu Sahibi

Hocam o sorunu hallettik devreyi çiziyoruz tamam derken bir sorun daha çıktı. Şöyle ki; bu yan-sön olaylarını baya uzun tuttuk yani sadece 1 modda 160 satır var, yaklaşık olarak da aynı mod içinde 80 tane yan-sön var. Diğerleri ile birlikte 220 satır ve 120 tane yan-sön gerçekleşiyor. Bunları 16F628A ya atınca ROM değeri %28 e ulaştı ve hem simülasyonda hem de gerçek devrede pic sapıttı diyebilirim. Önceden butona bastıkça modu değiştirebiliyorken, şimdi butona 2 tane filtre yapmama rağmen modu çok zor değiştirebiliyorum. Butonun ve devrenin son halini aşağıya ekliyorum, kodlarda da değişiklik yaptım onu da ekleyim. Bu durumu nasıl aşabiliriz ?

@slayer_ank Hocam belki bu konuda sizin de bir fikriniz vardır

#include <16F628A.h> 

#fuses INTRC, NOPROTECT, NOMCLR

#use delay(clock=4000000)

#use fast_io(b)

#use fast_io(a)

#define buton pin_A2

int k=0;

void main()
{
set_tris_b(0x00);
output_b(0x00);
set_tris_a(0b00100);

tekrar:

while(1)

{

if(input(buton))

{

delay_ms(1);
if(k==3)

k=1;

else k++;
while(input(buton)){}
delay_ms(1);
}

if(k==1)

{


output_high(pin_b3);
delay_ms(100);
output_high(pin_b2);
delay_ms(100);
output_high(pin_b1);
delay_ms(500);
output_low(pin_b1);
delay_ms(100);
output_low(pin_b2);
delay_ms(100);
output_low(pin_b3);
delay_ms(100);
}

if(k==2)
{

output_high(pin_b2);
delay_ms(100);
output_low(pin_b2);
delay_ms(200);
output_high(pin_b2);
delay_ms(100);
output_low(pin_b2);
delay_ms(100);
output_high(pin_b2);
delay_ms(100);
output_low(pin_b2);
delay_ms(100);
output_high(pin_b3);
delay_ms(100);
output_low(pin_b3);
delay_ms(50);
output_high(pin_b2);
delay_ms(100);
output_low(pin_b2);
delay_ms(100);
output_high(pin_b2);
delay_ms(100);
output_low(pin_b2);
delay_ms(100);
output_high(pin_b2);
delay_ms(100);
output_low(pin_b2);
delay_ms(100);
output_high(pin_b3);
delay_ms(100);
output_low(pin_b3);
delay_ms(50);
output_high(pin_b2);
delay_ms(100);
output_low(pin_b2);
delay_ms(300);
output_high(pin_b3);
delay_ms(100);
output_low(pin_b3);
delay_ms(200);
output_high(pin_b3);
delay_ms(100);
output_low(pin_b3);
delay_ms(100);
output_high(pin_b3);
delay_ms(100);
output_low(pin_b3);
delay_ms(100);
output_high(pin_b1);
delay_ms(100);
output_low(pin_b1);
delay_ms(50);
output_high(pin_b3);
delay_ms(100);
output_low(pin_b3);
delay_ms(100);
output_high(pin_b3);
delay_ms(100);
output_low(pin_b3);
delay_ms(100);
output_high(pin_b3);
delay_ms(100);
output_low(pin_b3);
delay_ms(100);
output_high(pin_b1);
delay_ms(100);
output_low(pin_b1);
delay_ms(50);
output_high(pin_b3);
delay_ms(100);
output_low(pin_b3);
delay_ms(300);
output_high(pin_b1);
delay_ms(100);
output_low(pin_b1);
delay_ms(200);
output_high(pin_b1);
delay_ms(100);
output_low(pin_b1);
delay_ms(100);
output_high(pin_b1);
delay_ms(100);
output_low(pin_b1);
delay_ms(100);
output_high(pin_b2);
delay_ms(100);
output_low(pin_b2);
delay_ms(50);
output_high(pin_b1);
delay_ms(100);
output_low(pin_b1);
delay_ms(100);
output_high(pin_b1);
delay_ms(100);
output_low(pin_b1);
delay_ms(100);
output_high(pin_b1);
delay_ms(100);
output_low(pin_b1);
delay_ms(100);
output_high(pin_b2);
delay_ms(100);
output_low(pin_b2);
delay_ms(50);
output_high(pin_b1);
delay_ms(100);
output_low(pin_b1);
delay_ms(300);
}

if(k==3)
{
output_high(pin_b2);
}

if(k==4)
{

k=0;
goto tekrar;

}
}
}

Bu mesaja eklenen görseller:

< Resime gitmek için tıklayın >


@elektro_gadget



< Bu mesaj bir yönetici tarafından değiştirilmiştir >
Bu mesaja 1 cevap geldi.

Bu mesajda bahsedilenler: @slayer_ank , @elektro_gadget
G
9 yıl
Yarbay

Gayet açık değil mi? Buton kontrolünü ledlerin yanıp sönmesi bittiği zaman yapıyorsun. k==1 ise toplam 1 saniye delay var orada, bunun anlamı 1 saniye boyunca buton algılanmayacak demek. k==2 ise daha da uzun süre.

Eğer ledler yanıp sönerken de buton algılansın istiyorsan kesme kullanacaksın. Baktım kullandığın denetleyicide 1 tane harici kesme varmış o da RB0 pini, onu kullanacaksın.


Bu mesaja 1 cevap geldi.
P
9 yıl
Yüzbaşı
Konu Sahibi

Hocam Merhabalar;

İlk baştaki if içinde bulunan k==1 den mi bahsediyoruz. Ben döngü oluşturmak için onu kullanmıştım yani k ya bastıkça değer yükselecek 1 olduğunda içindeki konfigürasyonu gerçekleştirecek. Bulunduğumuz devreye kesme işlemini nasıl ekleyebilirim ? Her bir mod için içine kesme mi eklemem gerek.



< Bu ileti mobil sürüm kullanılarak atıldı >
Bu mesaja 1 cevap geldi.

Bu mesajda bahsedilenler: @elektro_gadget
G
9 yıl
Yarbay

... 

int mod;

#INT_EXT
void butona_basildi()
{
++mod;
// Butona basılınca yapılacak diğer işlemler
}

void main()
{
ext_int_edge(H_TO_L);
enable_interrupts(INT_EXT);
enable_interrupts(GLOBAL);

while(1) {
switch(mod) {
case 0:
// mod 0 işlemleri
break;
case 1:
// mod 1 işlemleri
break;
case 2:
// mod 2 işlemleri
break;
// case 4:
...
}
}
}


Bu şablonla yapabilirsin. "butona_basildi" fonksiyonuna buton basılınca gerçekleşecek işlemleri yazarsın. switch içindeki case lerde o an mod değişkeninin değeri neyse ona uygun işlemleri yapılır. 256 farklı işlem tanımlayabilirsin.

Yapacağın işleri direkt switch içine yazmak yerine her bir mod için ayrı fonksiyon yazmalısın ki kod karman çorman olmasın. Senin kod kabus gibi benden söylemesi. Bekleme süreleri ve pin değişimleri düzenli olsaydı kodunu çok kısa şekilde yazabilirdik ama bu haliyle kısaltmak zor.


Bu mesaja 1 cevap geldi.
P
9 yıl
Yüzbaşı
Konu Sahibi

Hocam öncelikle bıkmadan, üşenmeden cevapladığınız için teşekkür ediyorum. Dediğiniz gibi üstünde de biraz oynayarak yaptım ancak;
quote:

void butona_basildi
kısmını kullanırsam hiç bir şekilde modlara geçmiyor, pic de hiç bir hareket yok. Onun yerine aşağıda yazdığım kod gibi switch'in öncesine butona basılırsa modu artır şeklinde konfigüre edersem kesinlikle verimsiz olsa da modlar arasında geçiş yapılabiliyor. Sanırım dediğiniz kısımı kullanamadım, internetteki interrupt örneklerini de uyguladım ancak bir türlü başarılı sonuç alamadım. Birde modların içerisine yazdığım yan-sön'ler biraz uzun olacak, bunların uzun veya kısa olması problem yaratır mı bana; interrupt'ı doğru şekilde kullanırsam bile ? Sizin dediğiniz şekilde yazdım; mod1' de sadece 1. led, mod2' de sadece 2. led, mod3' de sadece 3. led 1 kez yanacak-sönecek şekilde sağlıklı bir sonuç alamadım başlayınca 2 yanıyor, butona defalarca basınca 3 e geçiyor, bir daha basınca herşey gidiyor.












#include <16F628A.h> 
#fuses INTRC, NOPROTECT, NOMCLR
#use delay(clock=4000000)
#use fast_io(b)
#INT_EXT
#define buton pin_B0
int mod=0;





void main()
{
set_tris_b(0x01);
output_b(0x00);


ext_int_edge(H_TO_L);
enable_interrupts(INT_EXT);
enable_interrupts(GLOBAL);




while(1)

{
if(input(pin_B0))
{
mod++;
}

switch(mod)
{

case 1:


{


output_high(pin_b2);
delay_ms(100);
output_low(pin_b2);
delay_ms(200);
output_high(pin_b2);
delay_ms(100);
output_low(pin_b2);
delay_ms(100);
output_high(pin_b2);
delay_ms(100);
output_low(pin_b2);
delay_ms(100);
output_high(pin_b3);
delay_ms(100);
output_low(pin_b3);
delay_ms(50);
output_high(pin_b2);
delay_ms(100);
output_low(pin_b2);
delay_ms(100);



}
break;

case 2:
{


output_high(pin_b3);
delay_ms(100);
output_high(pin_b2);
delay_ms(100);
output_high(pin_b1);
delay_ms(500);
output_low(pin_b1);
delay_ms(100);
output_low(pin_b2);
delay_ms(100);
output_low(pin_b3);
delay_ms(100);

}
break;

case 3:
{


output_high(pin_b3);
delay_ms(50);
output_low(pin_b3);
delay_ms(50);

}


}
}
}


Bu mesaja 1 cevap geldi.

Bu mesajda bahsedilenler: @elektro_gadget
G
9 yıl
Yarbay

PB0 ı giriş olarak ayarlamayı unutmuşuz (set_tris_b(0x01);) Sen ayarlamışsın ama bu sefer de kesme sistemini bozmuşsun. #INT_EXT in altına hangi fonksiyon gelirse kesme fonksiyonu odur. Sen main'i koymuşsun, yanlış.

Birde kesmeyi ayarladıktan sonra pini okumanın bir mantığı yok. Sen butona basınca zaten otomatik olarak #INT_EXT direktifinin altındaki fonksiyon çalışacak. Ancak unuttuğumuz birşey daha var.
ext_int_edge(H_TO_L); <-
Burada dedik ki kesmeyi 1'den 0'a düşerken algıla. Yani bunun çalışması için PB0'ı 10k civarı bir dirençle +5V a bağlaman gerekir. Butonu da 0V a bağlayacaksın. Butona basınca High to Low durumu oluşacak.

Elimde kullanmadığım pic ler var ama programlayıcı yok, o yüzden deneyemiyorum. Ha birde zorunlu değilsen pic kullanmamanı tavsiye ederim. Devir Atmel devri. 16f628a ile aynı fiyata atmega328p alınıyor. Arada uçurumlar kadar fark var.


Bu mesaja 1 cevap geldi.
P
9 yıl
Yüzbaşı
Konu Sahibi

Hocam merhaba,

Yaptığım hatayı fark ettim sonradan değiştirdim ancak durum değişmedi. Başında da anlamıştım buton ve direnç kısmını, dediğiniz gibi oluşturdum ancak sonuç yine aynı. Kısa programlar yazdığımızda aralarında geçiş yapılabiliyorken uzun bir program yazarsam geçiş olmuyor. Uzun olana gelip kalıyor orada. 16F628A kullanmamın sebebi ucuz ve küçük olması. Birde bendeki programlayıcı ile programlayabiliyorum, ATMEL'i bendeki programlayıcı ile programlayabilir miyim fikrim yok. Acaba programın uzun olması, programdan çıkmama sebebi olabilir mi ? Geriye bir tek bu kalıyor benim mevcut bilgim ile




Bu mesajda bahsedilenler: @elektro_gadget
DH Mobil uygulaması ile devam edin. Mobil tarayıcınız ile mümkün olanların yanı sıra, birçok yeni ve faydalı özelliğe erişin. Gizle ve güncelleme çıkana kadar tekrar gösterme.