2 pici haberleştirmek

Başlatan ranadilara, 20 Nisan 2008, 00:28:07

ranadilara

merhaba,
rs232 seri iletişim hakkında bilgi edinmeye çalışıyorum, öncelikle işe 2pici birbirine bağlamakla başladım, ancak anlamadığım bazı noktalar var. örneğin şöyle gayet basit bir kod yazdım

************verici kısmı*********************************

#include<16F877A.h>
#fuses XT,NOWDT,NOPROTECT
#use delay(clock=4000000)
#use rs232(baud=9600,xmit=PIN_C6,rcv=PIN_C7)

int a=1;
void main()
{
while(1)
{
printf("%d",a);
delay_ms(500);
}
}


*******************alıcı kısmı***********************
#include<16F877A.h>
#fuses XT,NOWDT,NOPROTECT
#use delay(clock=4000000)
#use rs232(baud=9600,xmit=PIN_C7,rcv=PIN_C6)

int a;
void main()
{
while(1)
{
a=getc();
if(a==0)
{delay_ms(500);
 output_high(PIN_C1);
 delay_ms(500);
 output_low(PIN_C1);}
}
}


kod bu haliyle çalışıyor ancak anlamadığım nokta ben verici kısmında a=1 yaptım ancak alıcıda if(a==1) olduğunda çalışmıyor if(a==0) olduğunda çalışıyor :S bunun sebebi ne olabilir. ayrıca a verisini gönderdikten sonra başka bir b verisi göndermek ve bu veri alınınca başka bir ledi yaktırmak istedim ancak başarılı olamadım. aslında yapmak istediklerim çok daha kompleks şeyler ancak henüz basit işlemlerdeyim 2 pici seri haberleştirme konusunda forumu da aradım bir kaç örnek dışında birşey bulamadım kaynak önerebilirseniz sevinirim.

ete

Gördüğüm kadarı ile alıcı kısmında yalnızca a=0 ise C1 pinini çalıştırıyorsunuz . Sebep bu.
Yapılacak iş yalnızca
IF A==0  şartını oradan çıkarmak. ve pin_C1=a şeklinde bir komut vermek olur sanırım. Böylece vericiden a=0 gelirse pinde bir şey göremeyeceksiniz, a=1 olursa c1 pinide 1 olacaktır.

Veya başka bir pini daha kullanarak örneğin C2 pini,
a=0 ise c1 =1 olsun, c2=0 olsun
a=1 ise c2 =1 , c1=0 olsun şeklinde komut dizisi verirseniz sonucu daha iyi görebilirsiniz.

Ete
Bilgi hazinedir paylaştıkça büyür.            http://etepic.com

parda

merhaba ;

printf komutu ile siz asci karakter gonderiyorsunuz.

yani "1" gonderdiğinizde aslında siz 49 gondermis oluyorsunuz .

Bu durumu dikkate alınız

Kolaylıklar
Bildiğim tek şey, hiç bir şey bilmediğimdir.

ranadilara

peki integer göndermek için hangi komutu kullanmalıyım putc(a) komutunu denedim yine de çalıştıramadım ayrıca "a","b" gibi karakterler gönderdiğimde de çalıştıramadım

ete söylediğiniz gibi 2 ayrı pine işlem yaptırdım yine bir sonuç alamadım
yani kısacası hiçbir şekilde haberleştiremedim:) acaba problem rs232 ayarlarında mı gerçekten anlamadım, yardımcı olursanız sevinirim

ferdem

:) Karakterlerle ASCII karşılıkları biraz karışmış.
printf("%d",a); yazarak hatta 1 mi veriyorsunuz yoksa 1 in ASCII karşılığı 49 u mu? Bunu "printf" fonksiyonuna sormak lazım ki muhtemelen 49 u veriyor. Bu durumda siz bu 49 değerini karşı tarafta "integer" olarak alıyorsunuz ve "integer" 1 zannedip if(a==1) karşılaştırmasına tabi tutuyorsunuz ve sonuç ...istenilen değil.

if(a==1) yerine if(a==49) yazın bakalım istediğiniz gibi çalışıyor mu. Ve if(a==0) yerine 48 le karşılaştırınız.

Bu gibi uygulamalarda "char" mı, "integer" mi karışıklığına yol açmamak için seri iletişimin doğasına daha uygun olarak karakter gönderme karakter alma yapabilirsiniz. Yani verici taraf:
char x,y;
x='A';
y='B';
putc(x) veya putc(y); [veya hiç değişken tanımlamadan putc('A') gibi]

alıcı tarafta ise:
if(getc()=='A') ve if(getc()=='B') gibi kontrollerle istediğiniz gibi bir uygulama yapabilirsiniz. İyi çalışmalar.

ranadilara

****verici****
#include<16F877A.h>
#fuses XT,NOWDT,NOPROTECT
#use delay(clock=4000000)
#use rs232(baud=9600,xmit=PIN_C6,rcv=PIN_C7)

void main()
{
while(1)
{
putc('a');
delay_ms(500);

putc('b');
delay_ms(500);
}
}

***alıcı****
#include<16F877A.h>
#fuses XT,NOWDT,NOPROTECT
#use delay(clock=4000000)
#use rs232(baud=9600,xmit=PIN_C7,rcv=PIN_C6)

void main()
{
while(1)
{

if(getc()=='a')
{delay_ms(500);
output_high(PIN_C1);
delay_ms(500);
output_low(PIN_C1);}

if(getc()=='b')
{delay_ms(500);
output_high(PIN_C2);
delay_ms(500);
output_low(PIN_C2);}
}
}


bu şekilde yazdım sonunda çalıştırabildim:)) cevap yazan bütün arkadaşlara çok teşekkürler.
şimdi de alıcıda alınan karaktere göre lcdye yazdırma işlemini gerçekleştirmek istiyorum verici kodunu aynı bıraktım alıcıda şöyle bir yazdım

#include<16F877A.h>
#fuses XT,NOWDT,NOPROTECT
#use delay(clock=4000000)
#use rs232(baud=9600,xmit=PIN_C7,rcv=PIN_C6)
#include<lcd.c>

void main()
{
lcd_init();

while(1)
{

if(getc()=='a')
{delay_ms(500);
 printf(lcd_putc,"\f a");
 delay_ms(500);}

if(getc()=='b')
{delay_ms(500);
 printf(lcd_putc,"\f a");
 delay_ms(500);}
}
}
lcdde herhangi bir karakter göremedim, printf(lcd_putc,"\f a"); printf(lcd_putc,"\f a"); yerine led yaktırmayı denedim önce denediğim gibi bu sefer ledler de yanmadı tek değişen #include<lcd.c> ve lcd_init(); eklenmesiydi bunun sebebi ne olabilir acaba

kadirbas

Öncelikle, aklıma daha önceki sorununuzla alakalı bir seçenek (ya da daha doğrusu printf kullanımıyla alakalı bir bilgi) geldi ve bunu belirtmek istiyorum.

printf("%d",a);  

yerine

printf("%c",a);

yazarsanız, printf fonksiyonu a değerinin kendisini gönderecektir.

İkinci konuyla (yani son sorduğunuz soruyla) alakalı ise sorununuz temel olarak iki şeye dayandığını düşünüyorum. Biri senkronizasyon, diğeri ve daha önemlisi (ve hatta senkronizaston problemi gibi birşeyle karşılaşmamanızı sağlayacak olan durum) ise koddaki mantık ya da uygulama hatası.

while(1)
{

if(getc()=='a')
{delay_ms(500);
printf(lcd_putc,"\f a");
delay_ms(500);}

if(getc()=='b')
{delay_ms(500);
printf(lcd_putc,"\f a");
delay_ms(500);}
}


Yazdığınız alıcı kısımda kullandığınız "getc" fonksiyonu, denetleyiciyi karakter alımına kadar kilitler ve başka bir işlem yapamamanızı sağlar. Burada, ilk olarak kullandığınız "getc" fonksiyonunda, 'a' karakterinin gelip gelmediğini sorguluyorsunuz. Şöyle bir durumun olduğunu düşünelim:

Gönderici modülünüzdeki denetleyici 'a' karakterini gönderdiğinde alıcı modülünüz henüz çalışmamıştı ya da başka bir nedenle bu 'a' karakterini kaçırdı. Bu durumda siz gönderici modülün gönderdiği ikinci karakter olan 'b' karakterini alacaksınız ve bu karşılaştırma (yani if(getc() == 'a')) yanlış sonuç verecektir. Sizin istediğiniz durum oluşmadığından LCD'de 'a' karakterini göremeyeceksiniz. ikinci "getc" fonksiyonunda ise gönderici 'a' karakterini gönderiyor olacak ve bu seferde siz 'b' karakterinin gelip gelmediğini kontrol ediyor olacaksınız.

Benim önerim ve kodun aslında istenen şekilde çalışmasını sağlayacak olan kod parşası ise şöyle:

void main()
{
char ch;

lcd_init();

while(1)
{

ch = getc();
if(ch == 'a')
{
printf(lcd_putc,"\f a");
}
else if(ch == 'b')
{
printf(lcd_putc,"\f a");
}
}
}


Tabi burada switch-case ifadesi kullanırsanız kodunuz daha fazla kontrol için daha hızlı çalışacaktır. Ben sizin bu kullanımı bilmeme ihtimalinize karşın kodu if-else if kullanarak yazdım...

Kolay gelsin...

apollaa

seri iletişimde herzaman karakter iletilir int veya başka veri tipi değil daha doğrusu göndereceğiniz karakterin ascıı kodunu dikkate almalısınız
Vatan Sizden Hizmet Bekler ( Her Alanda)

Veli B.

Böyle bir genelleme yapamazsınız ki yapsanız dahi bu bilgi yanlıştır. Bit bazlı iletim esastır ve bundan sonrası sizin terminalleriniz ve paket yapılandırmanız ile igilidir. 5 bit ile de haberleşebilirsiniz 32 bit ile de. ASCII derseniz bu otomatikman 7 veya 8 bite zorlama getirir ki olay bu değildir. ASCII iletim sadece bir alternatiftir. Standartları konulmuştur...

kadirbas

Alıntı yapılan: "apollaa"seri iletişimde herzaman karakter iletilir int veya başka veri tipi değil daha doğrusu göndereceğiniz karakterin ascıı kodunu dikkate almalısınız

Bu güne kadar kendini sınırlayan böyle bir yaklaşımı hiç duymadığımı söylemek istiyorum. Seri iletişimde ya da herhangi bir iletişim tipinde ilettiğiniz şey sadece sayıdır. Siz onu karakter olarak algılamak isterseniz karakter karşılığına bakarsınız, sayı olarak algılamak isterseniz sayı olarak kullanırsınız, iletişimde gönderdiğiniz toplu bilginin tamamını farklı herhangi bir tür (kendi oluşturduğunuz yapılar gibi n byte'lık nesneler de dahil) olarak algılamak isterseniz aldığınız veriyi o türden nesneyle kullanırsınız, vs...  

Dolayısıyla "apollaa" arkadaşımın söylediklerine katılmıyorum ve kendinizi, ufkunuzu sınırlayacak düşüncelerden uzak durmanızı tavsiye ediyorum.

Sayın "apollaa". Sizin söylediklerinizi yanlış da anlamış olabilirim. Bir yanlışlık varsa şimdiden özür dilerim. Ama benim anlatmak istediğim hususun gayet açık olduğunu düşünüyorum.

İyi çalışmalar...

Veli B.

Sayın Kadirbaş, bir konuda düzeltme ihtiyacı hissettim. Gönderdiğimiz sayıdır tabiri, olayı decimal tabana taşır ki bu da tam olarak doğru değildir. 3 bit ilede haberleşebilirsiniz ki bu octale taşır durumu, 4 bit ile taşırsınız hex nibble olur...

kadirbas

Alıntı yapılan: "katana"Sayın Kadirbaş, bir konuda düzeltme ihtiyacı hissettim. Gönderdiğimiz sayıdır tabiri, olayı decimal tabana taşır ki bu da tam olarak doğru değildir. 3 bit ilede haberleşebilirsiniz ki bu octale taşır durumu, 4 bit ile taşırsınız hex nibble olur...

Söylediklerinize katılıyorum. Ben sadece olayın fiziksel iletiminden sonraki algılama kısmıyla alakalı yorum yapmak istedim. Dediğiniz gibi iletimin de tam olarak bitsel bir standartta (8 bit gibi) olması gerekmiyor...

can_tasan

Arkadaşlar pic programlamada yeniyim. Bilgisayarın seri portundan gönderilecek olan sayıları pic'in programında tanımladığım integer'lara atayarak bu du değerlere göre işlemler yaptırmak istiyorum.

Şöyle düşündüm:

x=getc();
delay_ms(500);    //bu gecikmeyi karakter gönderme gecikmesinden kısa tutucam
y=getc();

şeklinde yazarsam gönderilen normal decimal sayıları x ve y ye atayabilir miyim? ASCII değerleri kafamı karıştırdı. sadece sayı istiyorum çünkü. Bir de seri porttan bu değerleri nasıl yollayacağım visual basic ile yazılmış bir arayüz kullanacağım.

kadirbas

Alıntı yapılan: "can_tasan"Arkadaşlar pic programlamada yeniyim. Bilgisayarın seri portundan gönderilecek olan sayıları pic'in programında tanımladığım integer'lara atayarak bu du değerlere göre işlemler yaptırmak istiyorum.

Şöyle düşündüm:

x=getc();
delay_ms(500);    //bu gecikmeyi karakter gönderme gecikmesinden kısa tutucam
y=getc();

şeklinde yazarsam gönderilen normal decimal sayıları x ve y ye atayabilir miyim? ASCII değerleri kafamı karıştırdı. sadece sayı istiyorum çünkü. Bir de seri porttan bu değerleri nasıl yollayacağım visual basic ile yazılmış bir arayüz kullanacağım.

Öncelikle "getc" fonksiyonuyla alacağınız sayının bir BYTE olacağını hatırlatmak istiyorum. Dolayısıyla bir kerede sadece 0-255 arası değerleri gönderebilirsiniz (Tabii 8bit gönderim yaparsanız).

Yazdığınız fonksiyonda da delay kullanmanıza gerk yok esasında. Çünkü "getc" fonksiyonu çağırıldığında, programınız, seri porttan bilgi gelene kadar o satırda bekleyecektir. Dolayısıyla

x=getc();
y=getc();

yazdığınızda da aynı sonucu alacaksınız. Bu konuda tavsiyem, bir an önce kesme kullanımını da öğrenmeniz (ki CCS gibi derleyiciler sayesinde bu çok kolay). Bu sayede programınız getc gibi fonksiyonlar ile kesintiye uğramaz.

Bu arada, PC tarafında deneme amaçlı windows'un HyperTerminal programını, CCS'in seri port arayüz aracını ya da internetteki mutelif diğer küçük programları kullanabilirsiniz. Arayüz konusunda da, yapacağınız arayüz çok karmaşık değils,  VB hızlı ve kolay bir çözüm sağlamanız için iyi bir tercih.

İyi çalışmalar...

aydertunca

Selam arkadşlar bende c# ta yazığı bir arayüzle pc de çalan müziğin adını seri portta gönderip pi16f877a'ya bağlı lcd de göstermesini yapyorum ama bir türlü beceremedim yani lcd de hiç bi yazı göremedim...SERDAR ÇİÇEK HOCANIN CCS C İLE PIC PROGRAMLAMA KİTABNDAKİ SAYFA 344 DEKİ SERİ PORT ÖRNEĞİ PROTEUSTA SİMİLASYON YAPINCA ÇALIŞOY AMA GERÇEKTE B ÇALIŞMOYO...DAHA ÖNCE BUNU İNCELEYEN ARKADAŞLAR VARSA SORUNU NASIL ÇÖZDÜLER LÜTFEN YAZSINLAR...
BEN KİTAPTAKİNİ KENDİ PROJEME UYARLADIM..AMA ÇALIŞMIYO MERET..