Seri iletişim yardım lütfen

Başlatan Canermyn, 19 Haziran 2016, 01:13:55

Canermyn

Merhabalar pc den bir seri port terminal ile gönderdiğim bilgiyi( karakter ve sayı) max 16 karaktere kadar rx den alıp aynı picin tx den rf ile gönderen bir programa ihtiyacım var.ne kadar denediysem olmadı.
Hserin komutu veya serin komutunun wait olmadan bi kullanımı nasıl yapabiliriz.
16f877a ile 4 mhz osc kullanıyorum.
Waitle yapamam çünkü pc den gelen bilgi değişken lütfen yardım edin... teşekkürler.

Burak

#1
PC tarafından gelen verinin string formatını bilmemiz gerek .. Formattan kastım string olarak örneğin : "SICAKLIK=24,5" ifadesi gibi ... Bizim için gelen veririnin dinamik yada sabit olması gerekmiyor .. Her türlü string'i hserin ile yakalayabilirsin ve WAIT gibi bir giriş modifiyecisi kullanmak zorunda değilsin .. Önemli olan string sekans'ını bilmek ve işlemek .. Ayrıca iletişim hızı gibi bilgilere ihtiyaç var .. WAIT parametresi yerine 16 adet veri gelecekse HSERIN [str x\16] ile 16 adet x array değişkenine gelecek her bir karakter bu komutla yerleştirilir , geriye ise sadece string'i bir for döngüsü ile arayıp gerekli parçayı bulmaya kalır .. Dediğim gibi bir format ver ki yardımcı olabilelim ..

Burak
Ω Gens Una Sumus Ω

deepdiver

#2
Bilgisayardan gelecek verinin herhangi bir formatı yoksa veriyi yakalamak için 2 yol daha var aslında.

1. USART kesmesini kullanmak. Kesme oluşunca Rx bufferı  (1 byte) okuyup Tx pininden gönderirsin. Yazılım gelen vernin ne olduğuna bakmaz. Her gelen byte'ı alır ve Tx hattından gönderir. (Ben bu yöntemi tercih ederim.)

2. Rx pininin port change kesmesini aktif hale getirirsin. Port change olduğunda start biti gelmiştir. yine byteı okuyup gönderirsin. Ama kullanım amacına uygun değil. Sorun yaşanabilir. En güzeli 1. yöntem.

Bu şekilde bir proje yapmıştırm sanırım  (Areste yaptım). İstersen Tx verisinin Baud rate'ni Rx'ten farklı yapabilirsin. Böylece örneğin veriyi bilgisayardan 9600 baud ile alıp, 19200 baud ile RF vericiye gönderebilirsin.

HSEROUT komutunu herhangi bir karakter beklemeden kullanmak için
HSEROUT [alınan_byte_değişkeni] yapman yeterlidir.
Tüm işlemciler aynı hızda bekler!

Burak

#3
Alıntı yapılan: deepdiver - 19 Haziran 2016, 02:26:40
Bilgisayardan gelecek verinin herhangi bir formatı yoksa veriyi yakalamak için 2 yol daha var aslında.

1. USART kesmesini kullanmak. Kesme oluşunca Rx bufferı  (1 byte) okuyup Tx pininden gönderirsin. Yazılım gelen vernin ne olduğuna bakmaz. Her gelen byte'ı alır ve Tx hattından gönderir. (Ben bu yöntemi tercih ederim.)

2. Rx pininin port change kesmesini aktif hale getirirsin. Port change olduğunda start biti gelmiştir. yine byteı okuyup gönderirsin. Ama kullanım amacına uygun değil. Sorun yaşanabilir. En güzeli 1. yöntem.

Bu şekilde bir proje yapmıştırm sanırım  (Areste yaptım). İstersen Tx verisinin Baud rate'ni Rx'ten farklı yapabilirsin. Böylece örneğin veriyi bilgisayardan 9600 baud ile alıp, 19200 baud ile RF vericiye gönderebilirsin.

1. yöntemde OERR hatası alma olasılığı çok yüksek , veri yollama hızı alma hızından yüksek bile olsa o arada 2 seviye FIFO'nun dolması ihtimali var buda çok mantıklı değil çünkü klasik RF modüller ile bir veri preamble sinyali dahil verinin kendisi ile birlikte onlarca kez gönderilmek zorunda olduğundan bu şekilde bir iletişim aksaklık demektir ve Ayrıca 19200 Baud ile çalışan RF modüller alıcı tarafta kolüzyon yaratacak dolayısıyla RF alıcı tarafı gürültüden dolayı sağlıklı bir alış gerçekleştiremeyecek (SPI modüller ile ancak mümkün) ..

Bu PIC modeli için yaklaşık yaklaşık 90 adet array değişkeni oluşturulabilir , o yüzden bütün veriler alınıp string filtrelenmediği sürece istenilen sağlıklı olarak elde edilemez .. OERR biti 3. byte'ın stop biti ile set oluyor .. ve maalesef buda bir sonraki CREN reset'ine kadar alıcının kilitlenmesi demektir ...

Burak
Ω Gens Una Sumus Ω

deepdiver

gelen verinin miktarı ve gönderilecek veriyi tam bilemiyoruz. Ancak kesme kullanımı yerine basit olarak,

HSERIN  [ALINAN]
HSEROUT [ALINAN]

kodları yeterli oluyor. Tabi başına birşeyler eklemeyeceksen. Basit RF modullerde başına pre amble eklemen gerekiyor.
tam olarak gelen veri formatı ve gönserilecek veriyi verirsen daha sağlıklı olabilir sanırım.
gelen verinin başlangıcı ve bitişini bir şekilde belirleyip, 1 setlik veri bitene kadar gelen veriyi array değişkene atmak lazım.
1 set veri tam olarak alındığında pre amble da eklenip Tx ile göderilir.
Bu şekilde kesme kullanmadan yapabilirsin ancak kodun HSERIN komutunda takılıp veri gelmesini bekleyecektir. veri gelmezse orada kalırsın.
Bunu aşmak için de HSERIN komutuna time out parametresini ekleyebilirsin.

En iyisi PC'den gelecek veiriyi net olarak belirtmen sanırım
Tüm işlemciler aynı hızda bekler!

Canermyn

#5
Şöyle anlatmaya çalışayım.
klavyeden yazdığım şeyleri pice bağlı rf ile 2. bir pice bağlı lcd de göstermeye çalışıyorum.
pc den usb seri port terminal kullanıyorum.
yani gelen bilgi "Merhaba" da olabilir "1234" de klavyeden ne yazıldıysa max 16 karakter olarak alıcı kısımdan alıp göndermem gerekiyor.
MAIN:
pause 50
for i=0 to 15
SERIN RX,T1200,b0
bilgi[i]=b0
next i

       for j=0 to 15
    SerOut TX ,T1200,[bilgi[j]]
        next j

GOTO MAIN
END

bu şekilde yaptım ama çalışmıyor.

Burak

#6
Alıntı yapılan: Canermyn - 19 Haziran 2016, 03:43:31
Şöyle anlatmaya çalışayım.
klavyeden yazdığım şeyleri pice bağlı rf ile 2. bir pice bağlı lcd de göstermeye çalışıyorum.
pc den usb seri port terminal kullanıyorum.
yani gelen bilgi "Merhaba" da olabilir "1234" de klavyeden ne yazıldıysa max 16 karakter olarak alıcı kısımdan alıp göndermem gerekiyor.
MAIN:
pause 50
for i=0 to 15
SERIN RX,T1200,b0
bilgi[i]=b0
next i

       for j=0 to 15
    SerOut TX ,T1200,[bilgi[j]]
        next j

GOTO MAIN
END

bu şekilde yaptım ama çalışmıyor.

Donanımsal USART arabirimini 9600 Baudrate 4MHZ için kullandığını varsayarak ..

DEFINE HSER_RCSTA 90h ' Enable serial port & continuous receive
DEFINE HSER_TXSTA 24h ' Enable transmit, BRGH = 1
DEFINE HSER_SPBRG 25  ' 9600 Baud @ 4MHz, 0,16%
DEFINE HSER_CLROERR 1 ' Clear overflow automatically

TRISC=%11000000

x var byte[30]
i var byte
n var byte

'************************
MAIN:

HSERIN [STR X\20\13]

for i=0 to 19
  if x[i]=0 then
    n=i   :   goto jump
  endif
next i

jump:

hserout [str x\n,13,10]
n=0

goto main
'************************


Kodu seri portta denedim çok güzel çalışıyor .. Kafana takılan birşey olursa sorarsın ..

Burak
Ω Gens Una Sumus Ω

Canermyn

#7
Çok teşekkür ederim hemen denicem.fakat bir kaç sorun olacak...

baudrate 1200 için bu şekilde mi olacak
DEFINE HSER_SPBRG 51  ' 1200 Baud @ 4MHz, 0,16%

MAIN:

HSERIN [STR X\20\13]

for i=0 to 19
  if x[i]=0 then
    n=i   :   goto jump
  endif
next i

jump:

hserout [str x\n,13,10]
n=0

goto main

burda da X\20\13 ü ve x\n,13,10 anlayamadım ayrıca  n değişkeni ne için kullandık?
son olarak
TRISC=%11000000
burda Rx ve Tx  pinleri sanırım ikiside 1 mi olacak?


Canermyn

Burak bey böyle bi hata aldım.Ne yapmalıyım.

Burak

#9
4 MHZ 1200 baud için bu şekilde olacak ...

DEFINE HSER_RCSTA 90h ' Enable serial port & continuous receive
DEFINE HSER_TXSTA 20h ' Enable transmit, BRGH = 0
DEFINE HSER_SPBRG 51  ' 1200 Baud @ 4MHz, 0,17%
DEFINE HSER_CLROERR 1 ' Clear overflow automatically


Aşağıdaki kodun anlamı enter tuşuna basıldığı ana kadar kaç karakter geldiyse o kadarını array içerisine yerleştir .. 
HSERIN [STR X\20\13]


Diyelim ki 6. array değişkeni enter tuşu olarak algılandı bu durumda 6'dan 19. array değişkenine kadar "0" (sıfır) değeri yazılır ...

Bu durumda bizim son değişkenimiz sıfır değişkeninin olduğu ilk array değişkeni olduğu için bizde 0 değişkenini bulduğumuz index değerine kadar olan tüm array'i hserout ile ;

hserout [str x\n]

şeklinde gönderiririz ..

Ben hserout [str x\n,13,10] kullandım çünkü seri port çevirici ile konuştuğum için Carriage return (13) ve Line Feed (10) kullanarak enter ve satır başı komutlarını girmiş oldum ... n yerine direkt i'de yazabilirdik ben sadece değişken değiş tokuşu yaptım güvenlik olarak ..

Burak
Ω Gens Una Sumus Ω

Burak

#10
Alıntı yapılan: Canermyn - 19 Haziran 2016, 05:53:51
Burak bey böyle bi hata aldım.Ne yapmalıyım.


Bütün 2 ile biten seri iletişim komutlarındaki 2'leri sil lütfen ben 18F26K22'nin 2. EUSART arabirimini kullanmıştım ondan o şekilde yazdım .. Senin komutların HSEROUT ve HSERIN şeklinde olacak ..

Edit : Komutlardaki 2'leri sildim ..

Burak
Ω Gens Una Sumus Ω

Canermyn

Peki kodu ısıste mi çalıştırdınız görnderdiğim her ne olursa olsun okudugum tek şey ? ? ? olarak oluyor bu neden olabilir

Canermyn

#12


verdiğiniz kodu direk çalıştıramadım fakat üzerinde biraz oynayınca entere basma ve satır başını kaldırınca bunu yakaladım.
sorun nerde olabilir sizce belki çok şey sordum ama kusura bakmayın lütfen bitirme projem bu bişeyler yapamazsam 1 sene uzayacak okulum.
DEFINE HSER_RCSTA 90h ' Enable serial port & continuous receive
DEFINE HSER_TXSTA 20h ' Enable transmit, BRGH = 0
DEFINE HSER_SPBRG 51  ' 1200 Baud @ 4MHz, 0,16%
DEFINE HSER_CLROERR 1 ' Clear overflow automatically


x var byte[20]
i var byte
n var byte
j var byte

'************************
MAIN:

HSERIN [STR X\20]

for i=0 to 19
  if x[i]=0 then
    n=i   :   goto jump
  endif
next i

jump:
for j=0 to n
hserout [str x[j]]
next j

goto main
end
'************************

Burak

Pc programinda da 1200 baud secilimi ? 8 data biti 1 stop biti , no parity secili mi ?

Burak
Ω Gens Una Sumus Ω

Burak

#14
Alıntı yapılan: Canermyn - 19 Haziran 2016, 10:19:42
Peki kodu ısıste mi çalıştırdınız görnderdiğim her ne olursa olsun okudugum tek şey ? ? ? olarak oluyor bu neden olabilir


Kod gercek devrede tikir tikir calisti ... Ayrica kodu hangi akla hizmet degistiriyosun anlamadim .. Program Carriage return olmadan 20 adet veri bekliycek surekli yani veri boyutu ve gondermenin bittigini bu sistem ile anlayamazsin ... For dongusu ise ayrica son derece gereksiz ... Calisan bir yazilimi begenmeyip modifiye ettigine gore vardir bi bildigin herhalde biz sana soralim " neden calismadigini" ?

Burak
Ω Gens Una Sumus Ω

Powered by EzPortal