Seri iletişimde yığın ı çözme

Başlatan Chausonline, 14 Ocak 2005, 20:00:51

Chausonline

Pc ve pic arasında seri iletişim kuran bi devrem var. Pc den veriler hızlı gönderildiği için yığın haline geliyor yani pic in tek tek işleye bileceği "85, 42, 15," gibi sayılar "85-42-15-" şeklinte tek olarak iletiliyor. Her sayı arkasında - işareti var. Acaba diziyi - den ayırıp bi döngü kurmam mümkünmü? Böylede her sayıyı tek tek işleyebilir ve yığın oluşmadan işlemi gerçeklerştirmem mümkün olur. Pbp de diziyi bölme konusunda yardımcı olabilirmisiniz? (pic16f84 kullanıyorum. kristal 4Mhz. Protokol rs232 "Serin2")

optech

Zannediyorum program icinde alinan veri disari verilirken her bytetan sonra "-" karakteri konulmus. Orda cikan "-" isaretinin nedeninin bu oldugunu dusunuyorum. Sorun bu mu bilmiyorum ama sorun kodlardansa cozumde ona gore olacaktir. Bir de iletim hiziniz ne kadar hizli olursa olsun arada problem olabilecek sey "asenkronizasyon" yani alicinin "baud rate"iyle vericinin "baud rate"i aynı olmamasindan kaynaklanan anlasma problemidir. Bu durumda anlamsiz veriler gorursunuz. Bunun yaninda  benim karsilastigim bir durum olarak FIFO'ya(USART'li PIClerde bulunan bir cesit ara bellek benim kullandigim 16F628de 2 byte idi.) bosaltilmadan asiri yuklenme ile PIC'in sonsuz bir dongude veri yollamasi! (Bosaltmadan 3 byte yuklenince son byte sonsuz donude disari veriliyor)

axanc

merhaba arkadaşlar,

ayrıca bilenler bilir ki şöyle bir sorun vardır, bilgiler bilgisayara parça parça gelirler yani "Merhaba nasilsin" bilgisini gönderirken, "merh" "aba " "nası" "lsın" şeklinde felan parçalanmalar olur. aslında böyle bir parçalanmanın hiç olmaması gereklidir. bunun çözümünü bir hocamdan öğrendim, uzun bir metni serial olarak göndrirken bütün timer'ları ve kesmeleri durdurmanız sorunu çözecektir.

en azından bu konu altında bu ipucunu da vermiş olduk.
Uzmanlık: Bilgisayar Müh. öğrenci Derleyici: PicBasic Pro Compiler Ver. 2.45 Program: Proteus 6.2.5 ve MCSP

Chausonline

Sanırım iyi anlatamadım, İletişimde sorun yok.  - leri diziyi ayıklayabilmek için ben koydum. Pc klavyeden basılan yön yuşlarını pic'e seri porttan gönderiyor. Bir tuş her basıldığında bir kez gönderiliyor bundada sorun yok. Fakat tuş seri olarak basılıp bırakıldığında yığın oluşuyor ve veri (0-1-0-1-) gibi birleşik iletiliyor ve pic sadece baştaki 0 ı işliyor gerisi yok muş gibi işleme konmuyor. Bunu program üzerinden tek tek 0 1 0 1 gibi - lerden ayırıp iletirsem işlem çok yavaşlıyor çünkü komutlar arasına gecikme koymam gerekiyor. Bu yüzden diziyi pic te ayıklamam gerekiyor. Pbp de split tarzı bi komut yada benzer bişey varmı? yani bana gereken birleşik gelen diziyi ayıklayıp bi döngü oluşturmak ve gelen veriyi doğru yere göndermek. Kısacası Split tarzı bi işlem gerekiyor. (baud rate: 2400,N,8,1)

optech

Chausonline, yardim etmek istiyorum. Yalniz senin anlattigin seyler kafamda bir durum olusturmadi. Ben PC'den girilen sayilari Displayde gosteren ve iletisimi seri olarak yapan bir devre gerceklestirdim.  Bak bir kac sey sorayim...
* Yigin dedigin nedir? Benim bildigim yigin(stack) denilen sey mikrokontrolorler icinde bulunan ve alt program adreslerini tutan bir cesit hafizadir. Senin burda yigin olusuyor derken kasdettigin seyi anlamadim.
* Diziyi ayirmak icin de neden "-" koydugunu anlamadim. Bunu koyarken amacin bir diziyi ayirmak mi yoksa her byte-ı ayirmak mi? Yoksa baska bir sey mi?
* Bir de yapmaya calistigin devrenin amaci onu da soylersen sanrim daha yi olur.
Ozetle eger sorununu daha ayrintili anlatabilirsen ben de yardimci olmaya calisirim.

Chausonline

Baştan anlatim. Şimbi benim bi devrem var. Pc klavyeden basılan yön tuşlarını rs232 seri porttan pic e gönderiyor. Tuş kısa bir süre basıldığında örn: "38-" şeklinde tuş numarası pic e iletiliyor (38 = yukarı ok tuşu). tuş her basılışta kodu bikere pice gönderiliyor. Buraya kadar herşer normal. Tuş seri olarak basılıp bırakıldığında tuş kodları arka arkaya sıralanıyor yani dizi oluşuyor. örn: "38-38b-38-38b-" (38b = tuş bırakıldı) pic sadece baştaki 38- i kale alıyor ve tuşun bırakıldığını anlamıyor. Bu durumda gelen veriyi - lerden ayırıp döngü ile tek tek işlemek gerekiyor. Fakat ben - lerden nasıl ayıracağımı bilmiyorum. Dahada ayrıntılı anlatmak için sanırım programı ve hazırladığım visaul basic kodlarını buraya paste etmem gerekcek :) Henüz pic konusunda oldukça acemiyim bu yüzden bazı terimleri yanlış yerlerde kullanmaı mazur görmenizi rica ediyorum.

Digimensch

Istersen su kadu incele.
Senin sanirim sorunun Pic icine yazdigin kodda.Bir döngü ile PC'den gelen karekterleri toplayip bunu LCD'de Line icine yazdirman gerekiyor.
Yani gelen veri arka arkaya tutulup kelime olusacak. Degilmi??
Bu kod senin Klavyeden gönderdigin karekterleri yigilma olmadan alir LCD ekraninda gösterir.
include "modedefs.bas"

Define LCD_DREG PORTA 
Define LCD_DBIT 0 
Define LCD_RSREG PORTA 
Define LCD_RSBIT 4 
Define LCD_EREG PORTB 
Define LCD_EBIT 3 
Define LCD_LINES 2 
Define LCD_BITS 4 


Line1 con $80
Line2 con $C0
MaxCol con 16 ' 2 line * 16 char LCD

BAUD CON 16780  ' Hyper Terminaldede 2400 secilmeli 

Col  var byte 
SI   VAR PORTB.2 
VERI VAR BYTE 

TRISA = 0
PORTA = 0
TRISB = %00000100
PORTB = 0 

PAUSE 200
LCDOUT $FE, 1 ' LCD'yi temizle
LCDOUT $FE, Line1, "Veri bekleniyor.",$FE, Line2, "................"

Col = MaxCol * 2

LOOP: 
    SERIN2 SI,BAUD,[VERI] 
    LCDOUT $FE, $0F   ' Imlec yanip sönüyor
    Select Case Col
    Case MaxCol * 1 
    LCDOUT $FE, Line2 ' Line2'ye gec
    Case MaxCol * 2
    LCDOUT $FE, 1 ' LCD'yi sil ve Line1'e gec
    Col = 0
    end select 
    if VERI = 13 then ' Entere basilinca diger Line'ye gec
    if Col < 16 then   ' Karekter sayisi 16 olunca diger Line'ye gec
    Col = 16 
    LCDOUT $FE, Line2 ' Line2'ye gec
    endif
    else    
    LCDOUT VERI  ' LCD ekraninda gelen veriyi göster
    Col = Col + 1   ' Gelen verileri arka arkaya ekle
    endif
    GOTO LOOP 
END


PC'den Klavyeye bastiginda Veriyi Serial Porta gönderecek yazilim kodu da söyle:
Ben C++ Builder ile yazdim sanirim VB kodlarida hemen hemen aynidir.Cünkü  bende C++ Builderde bu isi MSComm kompenenti kullanarak yaptim.
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "MSCommLib_OCX"
#pragma resource "*.dfm"
TForm1 *Form1;

//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button1Click(TObject *Sender)
{
AnsiString Veri;
Veri=Edit1->Text;
if (Edit1->Text=="")
{
ShowMessage("Lütfen göndermek istediginiz Mesaji giriniz");
return;
}
else
{
MSComm1->Output=Veri;
}
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Edit1KeyPress(TObject *Sender, char &Key)
{
MSComm1->Output=AnsiString(Key);
if (Key==VK_ESCAPE)
Edit1->Text="";

}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
if (MSComm1->PortOpen==false)
{
MSComm1->Settings= "2400,N,8,1";
MSComm1->PortOpen=true;
}
else
{
ShowMessage("Com1 su an zaten acik");
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
MSComm1->Output=AnsiString(Char(27));
Edit1->Text="";
}
//---------------------------------------------------------------------------

optech

Benim anladigim kadariyla zannediyorum bir tur DC motor kontrolu yapmak istiyorsun. Yon tuslarina basildiginda o yonde hareket eden birakildiginda da duran bir sey yapmak istiyorsun.? mu acaba? Eger yanlis anladiysam DAHA ayrintili bir aciklama yapman gerekebilir.
Ama yapmak istedigin seyi soylesen sanirim daha net cozumler onerebilecegiz.
Veriyi "-"lerden nasil ayiracagin konusu da anladigim kadariyla tabi soyle.. VB'den veri gonderirken ya da PIC veriyi aldiktan sonra eklenen bir isaret muhtemelen bu. Bunu cikarmak icin ya VB'den veri gonderme kismina ya da PIC icinde veri gonderme yerine bakip ordan bu isareti kaldirman lazim.
Bir de su durum var ;
Alıntı Yap- leri diziyi ayıklayabilmek için ben koydum.
demistin. Simdi koydugun yerden kaldirabilmen lazim. Sorun ne anlamadim?

Chausonline

evet yön tuşlarına göre hareket eden bi motor olacak. Şöyleki bir adet araba sağ sola dönebiliyor bunun üstünde rf alıcından gelen verileri işleyip aracı hareket ettircek pic16f84 ile yapılmış bi devre olacak. vericide bilgisayarın seri portundan bilgi toplayan 16f84 e bağlı olacak. bİLgirayardan ileri oka bastığımda araç ileri gidecek geri bastığımda geri.  VB Klavyeden tuşa basılı tutulduğunda çok seri bi şekilde tuş kodlarını seri porttan pice gönderiyor. Bunu kısıtlayarak tuş basılı tutulsa bile sadede kodunun bir kes gönderilecek şekilde kısıtladım. Devrenin çalılşması için şimdilik çıkışlara sadece röle bağladım. İleri bastığımda ileri rölesi çekiyor bıraktığımda bırakıyor. Fakat tuşu çok hızlı basıp bıraktığımda röle çewkiyor ve bırakmıyor yanı bıraktı veri ile bastı verisi "10" şeklinde birleşip gidiyor. Pic programını yazim buraya.
Include "Modedefs.Bas" 
SEND var PORTB.0 

SI VAR PORTB.1   
LED VAR PORTB.2  
VERI VAR WORD 
Mesaj VAR Word
BAUD CON 16780
Define OSC 4 
TRISB.0 = 1
PORTB = 0 

HIGH Portb.2
Mesaj = "0101"

LOOP: 

SERIN2 SI,BAUD,Islemler,[VERI]

Islemler: 

SEROUT2 SEND,BAUD,10,[Mesaj,13]

SELECT CASE VERI 

CASE "1" 
 HIGH Portb.2
  SEROUT2 SEND,BAUD,10,["Geri",13]

CASE "2" 
 HIGH Portb.3
 SEROUT2 SEND,BAUD,10,["ILeri 1",13]

CASE "3" 
 HIGH Portb.4
 SEROUT2 SEND,BAUD,10,["ILeri 2",13]

CASE "4" 
 HIGH Portb.5
 SEROUT2 SEND,BAUD,10,["Sag",13]

CASE "5" 
 HIGH Portb.6
 SEROUT2 SEND,BAUD,10,["Sol",13]

CASE "0" 
 LOW Portb.2
 LOW Portb.3
 LOW Portb.4
 LOW Portb.5
 LOW Portb.6
 SEROUT2 SEND,BAUD,10,["Durdu",13]

END SELECT    
goto loop 

end


Vb içinde standart Mscomm nesnesi kullandım.

Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)
'40 geri
'38 ileri
'39 sag
'37 sol

If KeyCode = 40 And Not dgeri = 1 Then
'40 geri
dgeri = 1
MSComm1.Output = "1"
End If

If KeyCode = 38 And Not dileri1 = 1 Then
'38 ileri
dileri1 = 1
MSComm1.Output = "2"
End If

If KeyCode = 39 And Not dsag = 1 Then
'39 sag
dsag = 1
MSComm1.Output = "4"
End If

If KeyCode = 37 And Not dsol = 1 Then
'37 sol
dsol = 1
MSComm1.Output = "5"
End If

End Sub

Private Sub Form_KeyUp(KeyCode As Integer, Shift As Integer)
'40 geri
'38 ileri
'39 sag
'37 sol

If KeyCode = 40 Then
'40 geri
dgeri = 0
MSComm1.Output = "0"
End If

If KeyCode = 38 Then
'38 ileri
dileri1 = 0
MSComm1.Output = "0"
End If

If KeyCode = 39 Then
'39 sag
dsag = 0
MSComm1.Output = "0"
End If

If KeyCode = 37 Then
'37 sol
dsol = 0
MSComm1.Output = "0"
End If

End Sub

optech

Programlarin gordugum kadariyla guzel olmuş. Bana gore bu kodlarin calismasi lazim. Burdaki sorun bana gore rolenin algilamasiyla ilgili. Yani mesela, led surerken belli bir frekanstan sonra gozun yanip sonmeyi algilamadigi gibi belli bir zaman araliginda role de bu sinyalin kesildigini anlamiyordur. Ordaki gercek sinyali gormenin en iyi yolu osiloskop. Boyle bir imkanin yoksa kullanmak istedigin motoru ya da ona benzeyen bir motor kullanip deneyebilirsin. Ornegin oyuncak arabalardaki motor olabilir. Ama bana gore dedigim gibi bu kodlar cok guzel calisir.

Sonuc olarak veride herhangi bir karisma ya da birlesme olmuyor. Sorun tamamen algilamayla alakali.

Kolay gelsin...