Aynı Anda Birden Fazla Led Yakmak

Başlatan vitruvius, 02 Mayıs 2011, 03:49:59

vitruvius

Merhaba öncelikle belirtmeliyim ki bu CCS C ile de PIC ile de ilk projem. Cevabınızı bunu hatırlayarak verirseniz sevinirim. Yapmak istediğim şey şu: C#\'a bir textbox koydum bununla led\'in yanıp sönme süresini kontrol etmek istiyorum. Textbox\'ta yazdığım şeyi lcd\'de görebiliyorum ancak bunu bir sabit gibi tanımlatıp delay_ms()\'in içine yazdıramadım.

C#\'ta yazdığım kod şu şekilde:

private void button1_Click(object sender, EventArgs e)
        {
            serialPort1.PortName = \"COM2\";
            serialPort1.BaudRate = 9600;
            serialPort1.DataBits = 8;
            serialPort1.Parity = Parity.None;
            serialPort1.StopBits = StopBits.One;

            serialPort1.Open();
            string x = textBox1.Text;
            serialPort1.WriteLine(x + (char)13);
            serialPort1.Close();
        }

CCS C\'de yazdığım kod ise şöyle:

#include <16f877.h>
#device ADC=10
#fuses XT,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOWRT,NODEBUG,NOCPD
#use delay (clock=4000000)
#define use_portb_lcd TRUE
#use fast_io(d)
#include <lcd.c>
#use rs232 (baud=9600,rcv=PIN_C7, xmit=PIN_C6, parity=N, stop=1) //rs 232 için

char x[20];

#int_rda
void kesme ()
{
disable_interrupts(int_rda);
gets(x);

return;
}

void main()
{
setup_psp(PSP_DISABLED);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_CCP1(CCP_OFF);
setup_CCP2(CCP_OFF);

set_tris_d(0x00);
output_d(0x00);

lcd_init();


enable_interrupts(GLOBAL);
enable_interrupts(int_rda);

while(1)
{
output_high(pin_d7); //Kırmızı Işık Yandı
delay_ms(500);
output_low(pin_d7); //Kırmızı Işık Söndü
delay_ms(500);
kesme ();
printf(lcd_putc,\"\\f%s\",x);  //LCD\'yi temizle ve x string ifadesini LCD\'de göster
}
}

Bu x\'i delay_ms(x) şeklinde yazdırmak istiyorum yani, ama dizi şeklinde olmasından kaynaklanıyor sanırım sorunum. Yardımlarınızı bekliyorum, teşekkürler.

ogoculu

bir karakterden 0x30 çıkarırsan o sayının ondalık karşılığını bulursun. 10 lar basamağını 10 la yüzler basamağını 100 le çarpıp toplarsan gelen gönderdiğin sayıya ulaşırsın.

vitruvius

Merhaba, kodlarımı biraz değiştirdim. Textbox\'tan girdiğim sayıyı lcd\'de görebiliyorum. Ancak delay_ms()\'in içine yerleştiremedim. Örneğin textbox\'tan 100 giriyorum, aldığım datayı kodda göreceksiniz 10 ile çarpıp s1 değişkenine atıyorum. Bu s1 değişkenini de delay_ms()\'in içine koyuyorum. Burada örnek 1000 oluyor, yani 1 saniyelik yanıp sönmeler olması lazım ama daha hızlı oluyor. Sorun nerede acaba? Teşekkürler.

CCS C\'deki kodum:

#include <16F877.h>
#fuses XT,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOWRT,NODEBUG,NOCPD
#use delay(clock=4000000)
#define use_portb_lcd TRUE
#include <lcd.c>
#use rs232(baud=9600, xmit=PIN_C6, rcv=pin_C7,uart1)
#use fast_io (a)
#use fast_io (d)
#byte INTCON=0x0B
#byte PIE1=0x8C

unsigned int s1; //sürelerimiz
unsigned int dt; //kesme ile gelen data
unsigned int veri;

void main()
{
INTCON=0b11000000; //global ve peripheral kesmeler aktifmiş
PIE1=0b00100000; //uart kesmesi ayarlanmış
set_tris_c(0b10000000);
set_tris_d(0x00); //tümüyle çıkış olsun
output_d(0x00); //Sıfırlayalım
lcd_init();

while(1)
{     

printf(lcd_putc,\"\\f%u\",veri);
delay_ms(10);
      output_high(pin_d0);
      delay_ms(s1);
      output_low(pin_d0);
      delay_ms(s1);     
}
}

#INT_RDA
void data()
{
dt=getc();
veri=(unsigned int)dt;
s1=10*veri;

}

ASPGraphic

s1 için atadığınız değiken 8bit lik bir değilken olduğundan 0-255 arası bir rakam tutabilir. Siz 255 in üstünde ne yazarsanız yazın 255 ms çıkış görürsünuz.
unsigned long s1;
usdigned int16 s1;
unsigned int32 s1;
yukarıdaki örnekler gibi 16 bit ve üstü değişkenler ile daha yüksek rakamları saklayabilirsiniz.
Yapacağınız örnekte unsigned long s1; değikeni sizin işinizi görecektir.
İnsan hayalleriyle yaşar. www.32bit-core.com

vitruvius

#4
Merhaba, çok teşekkür ediyorum. Günlerdir delirdim delirttim şu iş için. unsigned long tanımlaması ile sorunumu çözdüm. Şimdi bir sonraki sıkıntım için bir şey sormak istiyorum:

Birden fazla trafik direğinin ışıklarının yanma süresini kontrol etmeye çalışıyorum proje olarak. Başlarda seri iletişimsiz denemiştim projemi. O zaman bir sorunla karşılaşmıştım: Led sayımı arttırdığımda while içinde her led\'in yanıp sönme komutlarını yazdığım zaman program yukarıdan aşağıya işliyordu. Yani iki led\'i aynı anda yakamıyorum. Şu var; trafik lambası yapacağımdan C# simulasyonunda 3\'lü 3\'lü (direk direk) gruplayıp öyle kodluyorum. if\'lerle de on-off durumunu kontrol ettiğim zaman bütün if blokları birbirinden bağımsız zamanda çalıştığı için hem aynı anda birden fazla ışık yanıyor, hem de bir direğin durumunu on yada off yaptığım zaman anında tepki alıyorum. CCS C\'de ise program yukarıdan aşağıya işliyor yani bir led sönmeden diğeri yanmıyor. C#\'ta yaptığım gibi 3\'lü 3\'lü olarak birbirlerinden bağımsız zamanlı gruplayıp nasıl kodlayabilirim?

Çok teşekkür ederim.

ASPGraphic

#5
Hmm.. Her lambanın yanma süreleri için birer değişken tanımlayabilirsiniz.
Örneğin: Birinci lambanın kırmızısının gecikmesi için K1, Sarı için S1, yeşili için ise Y1 gibi değişken tanımlayabilirsiniz. İkinci ve üçüncü lambalar içinde aynı şekil K2 ve K3 gibi devam eder. Lambaların durumlarınıda aynı şekilde yapabilirsin.
Birde durum değişkeni atrsanız. Bu değişken yazılımı programlama modu ve devam modu olarak ikiye ayrılır. Atıyorum, durum değişkeni 1 ise bilgisayardan gelen bilgiler girilir. Durum değişkeni 0 ise program aldığı yeni bilgilerle programı baştan başlatır. Bilgisayar yazılımına birde başlat butonu koyarsanız. Lambaların bekleme değerlerini değişkenlere kaydettikten sonra başlat butonuna basarak durum değişkenini 0 yaparsınız ve program yeni değerler ile devam eder.
Bu aslında yazılım bilmekten çok program mantığıyla alakalıdır. Sizin hayal gücünüze göre farklı methotlarla da yapılabilir. Buna benzer bir trafik projesini yakın zamanda bir meslek okulu için yapmıştım. Oda birbirinden bağımsız 2 trafik lambasının kablosuz senkronisazyonunu kapsayan bir proje idi. http://www.mcu-turkey.com/?p=2502
Kod olarak yazmıyorum çünkü hem zaman alıyor hemde görerek değil yaparak bir şeyler elde edersiniz. Anlam veremediğiniz yerlerde ben sizi aydınlatırım.
İnsan hayalleriyle yaşar. www.32bit-core.com

vitruvius

Merhaba öncelikle daha basit olarak seri iletişim kurmadan denemek istedim devreyi. 2 adet değişken atayıp bunlara if\'lerle baktım. Direkleri {} ile ayırdım ki birbirlerinin içine girmesinler. 2 direk ( 6 led) için şöyle bir kod yazıyorum, aynı mantıkta kodu C#\'ta da yazıyorum orada da simulasyon olarak göstersin diye. Orada çalışıyor CCS C\'de yukarıdan aşağı işliyor. Yani C#\'ta aynı anda iki ışık yakabiliyorum ama CCS C\'de hepsi program sırasına göre gidiyor.

#include <16f877.h>
#fuses XT,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOWRT,NODEBUG,NOCPD
#use delay(clock=4000000)
#use fast_io(a)
#use fast_io(b)
#use fast_io(c)
#use fast_io(d)
int i=1, k=1;
void main ()
{
setup_psp(PSP_DISABLED);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_adc_ports(NO_ANALOGS);
setup_CCP1(CCP_OFF);
setup_CCP2(CCP_OFF);

set_tris_a(0x00);
set_tris_b(0x00);
set_tris_c(0x00);
set_tris_d(0x00);

output_a(0x00);
output_b(0x00);
output_c(0x00);
output_d(0x00);

//1. Direk
{if (i==1)
{
output_high(pin_b0); //Kırmızı Işık Yandı
delay_ms(500);
output_low(pin_b0); //Kırmızı Işık Söndü
delay_ms(500);
output_high(pin_b1); //Sarı Işık Yandı
delay_ms(500);
output_low(pin_b1); // Sarı Işık Söndü
delay_ms(500);
output_high(pin_b2); // Yeşil Işık Yandu
delay_ms(500);
output_low(pin_b2); //Yeşil Işık Söndü
delay_ms(500);
}}
// 2. Direk
{if(k==1)
{
output_high(pin_b3); //Kırmızı Işık Yandı
delay_ms(500);
output_low(pin_b3); //Kırmızı Işık Söndü
delay_ms(500);
output_high(pin_b4); //Sarı Işık Yandı
delay_ms(500);
output_low(pin_b4); // Sarı Işık Söndü
delay_ms(500);
output_high(pin_b5); // Yeşil Işık Yandı
delay_ms(500);
output_low(pin_b5); //Yeşil Işık Söndü
delay_ms(500);
}
}}

Teşekkürler.

ASPGraphic

Gecikme süreleri sabit kalacak ise tek fonksiyonda hepsini birleştirebilirsiniz.

Örneğin:
#include <16f877.h>
#fuses XT,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOWRT,NODEBUG,NOCPD
#use delay(clock=4000000)
#use fast_io(a)
#use fast_io(b)
#use fast_io(c)
#use fast_io(d)

void main ()
{
setup_psp(PSP_DISABLED);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_adc_ports(NO_ANALOGS);
setup_CCP1(CCP_OFF);
setup_CCP2(CCP_OFF);

set_tris_a(0x00);
set_tris_b(0x00);
set_tris_c(0x00);
set_tris_d(0x00);

output_a(0x00);
output_b(0x00);
output_c(0x00);
output_d(0x00);

while(TRUE)
{
output_high(pin_b0); //Kırmızı Işık Yandı
output_high(pin_b3); //Kırmızı Işık Yandı
delay_ms(500);
output_low(pin_b0); //Kırmızı Işık Söndü
output_low(pin_b3); //Kırmızı Işık Söndü
delay_ms(500);
output_high(pin_b1); //Sarı Işık Yandı
output_high(pin_b4); //Sarı Işık Yandı
delay_ms(500);
output_low(pin_b1); // Sarı Işık Söndü
output_low(pin_b4); // Sarı Işık Söndü
delay_ms(500);
output_high(pin_b2); // Yeşil Işık Yandı
output_high(pin_b5); // Yeşil Işık Yandı
delay_ms(500);
output_low(pin_b2); //Yeşil Işık Söndü
output_low(pin_b5); //Yeşil Işık Söndü
delay_ms(500);
}
}

veya aynı gecikme ile lambaların birbirine zıt yanması gibi;

#include <16f877.h>
#fuses XT,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOWRT,NODEBUG,NOCPD
#use delay(clock=4000000)
#use fast_io(a)
#use fast_io(b)
#use fast_io(c)
#use fast_io(d)

void main ()
{
setup_psp(PSP_DISABLED);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_adc_ports(NO_ANALOGS);
setup_CCP1(CCP_OFF);
setup_CCP2(CCP_OFF);

set_tris_a(0x00);
set_tris_b(0x00);
set_tris_c(0x00);
set_tris_d(0x00);

output_a(0x00);
output_b(0x00);
output_c(0x00);
output_d(0x00);

while(TRUE)
{
output_high(pin_b0); //Kırmızı Işık Yandı
output_low(pin_b3); //Kırmızı Işık Sondu
delay_ms(500);
output_low(pin_b0); //Kırmızı Işık Söndü
output_highpin_b3); //Kırmızı Işık Yandi
delay_ms(500);
output_high(pin_b1); //Sarı Işık Yandı
output_low(pin_b4); //Sarı Işık Sondu
delay_ms(500);
output_low(pin_b1); // Sarı Işık Söndü
output_high(pin_b4); // Sarı Işık Yandi
delay_ms(500);
output_high(pin_b2); // Yeşil Işık Yandı
output_hlow(pin_b5); // Yeşil Işık Sondu
delay_ms(500);
output_low(pin_b2); //Yeşil Işık Söndü
output_high(pin_b5); //Yeşil Işık Yandi
delay_ms(500);
}
}
İnsan hayalleriyle yaşar. www.32bit-core.com

vitruvius

Merhaba, gecikme süreleri her direğin her bir ışığı için bilgisayardan girilecek. O yüzden direkleri birbirlerinden bağımsız şekilde grup grup kodlamaya çalışıyorum. Hatta bilgisayardan her direk için on/off yapan checkbox koydum. İşaretli ve işaretli olmadığı zamanlar x ve y sayısı gibi byte yollayıp bende bunları iflerle kontrol edip ona göre ledleri yakacağım. Tek direk için sorun yok ama birden fazla direk olunca çözüm bulamadım. Tek direk için şöyle bir şey kodladım:

#include <16F877.h>
#fuses XT,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOWRT,NODEBUG,NOCPD
#use delay(clock=4000000)
#define use_portb_lcd TRUE
#include <lcd.c>
#use rs232(baud=9600, xmit=PIN_C6, rcv=pin_C7,uart1)
#use fast_io (a)
#use fast_io (d)
#byte INTCON=0x0B
#byte PIE1=0x8C

unsigned long s1,s2,s3; //sürelerimiz
unsigned int dt; //kesme ile gelen data
int led;

void main()
{
INTCON=0b11000000; //global ve peripheral kesmeler aktifmiş
PIE1=0b00100000; //uart kesmesi ayarlanmış
set_tris_c(0b10000000);
set_tris_d(0x00); //tümüyle çıkış olsun
output_d(0x00); //Sıfırlayalım
lcd_init();

while(1)
{     

printf(lcd_putc,\"\\f%u\",dt);
delay_ms(10);

      output_high(pin_d0);
      delay_ms(s1);
      output_low(pin_d0);         
      output_high(pin_d1);
      delay_ms(s2);
      output_low(pin_d1);     
      output_high(pin_d2);
      delay_ms(s3);
      output_low(pin_d2);           

}
}

#INT_RDA
void data()
{
dt=getc();
if(dt==200)
{
led=1;
}
if(dt==201)
{
led=2;
}
if(dt==202)
{
led=3;
}
if(dt==203) // Direk\'in off moduna girdiğini belirten byte gelirse
{led=4;}
if(dt<200 && led!=4) // Off durumunda değilse
{
if(led==1)
{s1=1000*dt;}
if(led==2)
{s2=1000*dt;}
if(led==3)
{s3=1000*dt;}
}
else if(led==4) // Off durumunda ise o direğin tüm ışıkları sönsün
{output_low(pin_d0);
output_low(pin_d1);
output_low(pin_d2);
}
}

Teşekkürler.

vitruvius

Yani derdim iki {} parantez içindeki fonksiyonları eş zamanlı çalıştırmak..

vitruvius

Biraz daha basitleştirdim devreyi seri iletişimi kaldırıp. Ancak CCS C\'nin yukardan aşağı çalışma sorununu çözemedim hala.

Tekrar bir özet geçersem her bir direğe ait kodları {} arasına alıyorum ancak bir direğin işlemleri bitmeden bir sonraki direğe sıra gelmiyor. Her bir direğin her bir ışığı için değerler tek tek bilgisayardan girileceğinden bu bir sorun oluşturuyor. Yoksa 3 tane delay_ms() ile çözerdim.  {}\'ler arasına yazdığım kodların aynı anda çalışmasını nasıl sağlayabilirim? Yani kodlardaki 1. direk ile 2. direğin aynı anda çalışmasını istiyorum. Teşekkürler.

Çalıştığım devrenin basit halinin kodları:

#include <16F877.h>
#fuses XT,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOWRT,NODEBUG,NOCPD
#use delay(clock=4000000)
#use fast_io (b)
#use fast_io (c)

unsigned long k1=1000;
unsigned long s1=200;
unsigned long y1=800;

unsigned long k2=900;
unsigned long s2=300;
unsigned long y2=600;

void main()
{
setup_psp(PSP_DISABLED);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_adc_ports(NO_ANALOGS);
setup_CCP1(CCP_OFF);
setup_CCP2(CCP_OFF);

set_tris_b(0x00); //tümüyle çıkış olsun
set_tris_c(0x00); //tümüyle çıkış olsun
output_b(0x00); //Sıfırlayalım
output_c(0x00); //Sıfırlayalım

//Direk 1
{
output_high(pin_b0);
delay_ms(k1);
output_low(pin_b0);
output_high(pin_b1);
delay_ms(s1);
output_low(pin_b1);
output_high(pin_b2);
delay_ms(y1);
output_low(pin_b2);
}

//Direk 2
{
output_high(pin_c0);
delay_ms(k2);
output_low(pin_c0);
output_high(pin_c1);
delay_ms(s2);
output_low(pin_c1);
output_high(pin_c2);
delay_ms(y2);
output_low(pin_c2);
}

}


yazici67

bu sorun için sahte multitasking kullanılabilir.Ancak ben sıralı işlemi öneririm.
Sıralı işlem şöyle olabilir : (Beklemesi daha kısa olan işlem önce yapılır (ben 1.\'yi kısa kabul ettim))
    -> 1.Direk -> 1.İşlem
    -> 1. Bekleme
    -> 2.Direk -> 1.İşlem
    -> 2.Bekleme ile 1.Beklemenin farkı kadar bekleme
   
    -> 1.Direk -> 2.İşlem
    ...
diye devam eder.
Kendi bulduğum(u zannettiğim) bir mantıktır.
Oldukçada karışıktır.  :D
Anlatabildiysem bir dene.

zaferk1028

sonsuz bir döngü tanımla ve bu dongu icinde bir sayac bulundur istenilen islemlerin suresini bu sayaca gore yaptir
 örnek:
int i=0;
int direk1_sure,direk2_sure,direk3_sure;
while(1)
{
if(i==direk1_sure)
{
//direk 1 icin istenilen sureye ulasilinca yapilacak islemler
}
if(i==direk2_sure)
{
//direk 2 icin istenilen sureye ulasilinca yapilacak islemler
}
if(i==direk3_sure)
{
//direk 3 icin istenilen sureye ulasilinca yapilacak islemler
}

delay_ms(1);
i++;
if(i==100)
i=0;
}

Hızlı Yanıt

Not: Bu konu bir moderatör tarafından onaylanmadan görüntülenmeyecektir.

Adı:
E-Posta:
Doğrulama:
Lütfen bu kutuyu boş bırakın:
IRFP250 Nedir:
kısayollar: göndermek için alt+s veya önizleme yapmak için alt+p'ye basın