proton basic için uart alıcı

Başlatan ankayca, 19 Ağustos 2019, 14:44:22

ankayca

Merhabalar foruma yeni üye oldum bu yüzden herhangi bir hatam olursa şimdiden özür dilerim.

Proton ile asenktron uart kodu yazıyorum
bu alıcı ama alıcıda sorun yaşıyorum
 
Include "lcd_deneme2.bas" 
Device 16F628A 
Config INTRC_OSC_NOCLKOUT, WDT_OFF,MCLRE_OFF,LVP_OFF,CP_OFF,BODEN_OFF
Declare Xtal 4
CMCON=7
VRCON=0    

OPTION_REG=%01010101
INTCON=%10100000
 All_Digital true
TRISA=%00000000
TRISB=%00000010
'Declare hserin_pin PORTB.1
'Declare Hserout_pin PORTB.2   *bu kısımlar HSERIN komudutu için 
'Declare Hserial_Baud 9600     *tanımlamalar ama hserın yerine serin kullanmaya karar verdim 
'Declare Hserial_RCSTA 90h      *manuel kitabında asenkron uart için SERIN önermişler
'Declare Hserial_Clear = On
'Declare Hserial_TXSTA 20h

Dim varl As Byte 

DelayMS 500




program:



SerIn PORTB.1,84,[varl]
Print Dec varl
If varl=65 Then Toggle PORTA.1
 DelayMS 1000



GoTo program


 kullandığım program Realterm.
uart dönüştürücüsü olarakta esp8266 adaptörünü kullanıyorum.

veri gönderimini Hserin ve Serin de yapabiliyorum ve bilgisayarda izleyebiliyorum ama alma işini bir türlü çözemedim
rica etsem nerde yanlış yaptığımı söylermisiniz ve mümkünse Serin komutu ile açıklarmısınız yanlışımı ? 

ete

RF olsun kablulu alışverişler olsun hepsi için geçerli bir altın kural vardır.
Bu verici mesajını verdiği zaman alıcıda onu almaya hep haır halde beklemelidir.
Alıcı programlarda kullanılan pause ler programın orada çakılıp kalmasına sebep olur ve o anda veri gelmiş ise alıcının bu veriyi kaçırması da kaçınılmaz olur. Zira alma işini senin SERIN komutun yapacak. Program henüz SERIN komutuna gelemeden verici veriyi aktarmış ise başka bir sonuç beklenmesi doğru olmaz.

Çözüm USART kesmesi kullanmaktadır. USART kesmesi şu işe yarar. Programın bir yerde bekliyor ise ve aynı anda veri geliyor ise geri planda çalışan Pic içindeki kendi programı (ROM diyelim) veriyi alır ve Buffera (RCREG) koyar ve kesme bayrağını kaldırarak programın otomatikman alma rutinine yönlendirilmesini sağlarki tamda istediğimiz budur. Böylece program derhal alma işlemine girişir ve gelen verileri alır.

Serin komutu otomatikman programı da bloke eder ve yaklaşık 65 ms orada veri gelmesini bekler. Gelmiyor ise 65 ms sonra komutu atlar ve alttaki satıra geçer. Alttaki satırlarda Delayms 1000 komutun varki bütün sorunu bu komut çıkartıyor bence.
Bu gecikmeleri bedava dağıtılıyor gibi kullanmayın. Mantıklı yerlerde gereken süreleri verin.
O gecikmeyi kaldırıp yeniden dene diyeceğim ama yinede tekrarlıyorum. Kesin çözüm USART kesmesinde dir.
Ete

ankayca

hocam 320volt.com da ki kesmeler hakkındaki yazınızı okudum. Kodları tekrar düzenledim ve uart kesmesi ekledim ama hala çalışmıyor en son kodları buraya bırakıyorum.
Declare LCD_DTPin PORTB.4
Declare LCD_Data4_Pin PORTA.2
Declare LCD_Data5_Pin PORTA.3
Declare LCD_Data6_Pin PORTB.3
Declare LCD_Data7_Pin PORTB.4
Declare LCD_RSPin PORTB.5
Declare LCD_ENPin PORTB.6
Declare LCD_Interface 4
Declare LCD_Lines 2


'-------------------LCD AYARLARI--------
Device 16F628A 
Config INTRC_OSC_NOCLKOUT, WDT_OFF,MCLRE_OFF,LVP_OFF,CP_OFF,BODEN_OFF
Declare Xtal 4
INTCON=%10100000
OPTION_REG=%01010000
TRISA=%00000000
TRISB=%00000010
All_Digital true
On Interrupt GoTo time0
Dim varl As Byte 

DelayMS 500

program:
Print Dec2 varl
If varl=65 Then High PORTA.1
 DelayMS 2000
 Low PORTA.1
 varl= 0
GoTo program

Disable
time0:
SerIn PORTB.1,84,[varl]
INTCON.2=0
Resume
Enable
End


  



herşey için teşekkürler

ankayca

kırmızı yazı gözleri yorduğu için yorum satırını kaldırıp tekrar atıyorum kodları bu kodlar yukarıdaki yanıttakiler ile aynıdır
Declare LCD_DTPin PORTB.4
Declare LCD_Data4_Pin PORTA.2
Declare LCD_Data5_Pin PORTA.3
Declare LCD_Data6_Pin PORTB.3
Declare LCD_Data7_Pin PORTB.4
Declare LCD_RSPin PORTB.5
Declare LCD_ENPin PORTB.6
Declare LCD_Interface 4
Declare LCD_Lines 2
Device 16F628A 
Config INTRC_OSC_NOCLKOUT, WDT_OFF,MCLRE_OFF,LVP_OFF,CP_OFF,BODEN_OFF
Declare Xtal 4
INTCON=%10100000
OPTION_REG=%01010000
TRISA=%00000000
TRISB=%00000010
All_Digital true
On Interrupt GoTo time0
Dim varl As Byte 

DelayMS 500

program:
Print Dec2 varl
If varl=65 Then High PORTA.1
 DelayMS 2000
 Low PORTA.1
 varl= 0
GoTo program

Disable
time0:
SerIn PORTB.1,84,[varl]
INTCON.2=0
Resume
Enable
End

 hocam ısıs çizimini yapmadım çünkü programı bilgisayardan kontrol ediyorum verici için

ete

Yazıları okumuşsun ama anlamamışsın.
Burada biraz daha detay vermeye çalışacağım.
USART kesmesi için kullandığın 16F628A işlemcinin USART modülünü ve portunu kullanman gerekiyor.
Bu şu demek oluyor. PORTB.1 pininden Alış yani RX yapacaksın. PORTB.2 pininden ise TX yani gönderme yapacaksın. USART portunu kullandınmı bir kere bu iki pin port tarafından bloke edilir ve bu pinleri başka amaçla kullanamazsın. Örnek vereyim Bir programda yalnızca TX yapıyorsun diyelim RX pinini hiç kullanmıyor olsan bile onu başka amaçla kullanamazsın. En azından kullanmadığın bu pini boş bırakman gerekir.

USART portunu aktive etmen için ;
Declare hserin_pin PORTB.1
Declare Hserout_pin PORTB.2    
Declare Hserial_Baud 9600      
Declare Hserial_RCSTA 90h       
Declare Hserial_Clear = On
Declare Hserial_TXSTA 20h
komut satırlarını programın başına eklemen gerekiyor.
RX pini ise TRISB registerinde giriş olarak tanımlanmalıdır.

Bütün bunları yaptıktan sonra,
Şimdi gelelim TX yani verici programına,
Daha öncede belirtmiştim. RF sistemlerinde senkron tutturmak önemlidir. Yani verici veriyi verirken alıcıda alma konumunda hazır olmalıdır. Bu programların birinde en ufak bir gecikme olması durumunda veren vereceğini verirken alacak olan senkron tutturamadığı için alması gerekenleri alamaz.

Senkron tutturmanın en önemli şartlarından birisi Verici tarafında veri yollanmadan önce alıcı tarafındaki USART portunu uyandırmak ve programı kesmeye sevk etmek için bir Preambl denilen ön uyandırma sinyali gönderilir.
       HSEROUT [REP$AA\5,REP$00\5,REP$FF\5]'uyandirma sinyali preambl
       HSEROUT ["E","T","E",VERI1,VERI2,VERI3]
Burada ilk satırda verilen bilgiler işin uyandırma kısmıdır. ALıcı bu bilgileri ilk olarak aldığında hemen porta bilgi gelmeye başladığını anlar ve programı kesme kısmına sevk eder.
Veriler ie bir paket halinde gönderilmeli ve başına bir işaret koyularak alıcının önce bu işareti yakalaması sağlanmalıdır.
Bu örnekte işaret ETE bilgisidir. Peşinden Veri1, Veri2, Veri3 şeklinde Byte bilgisi olarak veriler sıralanır. Burada şu noktaya işaret etmek isterim. TX tarafı kaç byte yollamış ise alıcı tarafında da o kadar sayıda byte alınmalıdır. Bir taraf eksik olursa yine senkron kayabilir.
Burada görüleceği üzere veri bir paket şeklinde verilir. Her zaman TREN vagonlarına benzetirim bu sistemi.
Lokomotif işaretçi konumundadır. Vagonlar ise verileri temsil eder. Birisine vagonları bul dediğinizde o kişi önce lokomotifi arayarak peşinden gelen vagonları bulmalıdır. İşin temelinde bu fikir yatıyor. Şayet işaretçi kullanmazsanız alan taraf veriye ortadan girer ve hiç bir tutarlı bilgi alamaz.
TX tarafında kesme kullanmaya gerek yoktur. Çünki ne zaman veri yollanacağını siz belirlersiniz ve direk yukarıdakine benzer satırlar ile veriyi yollarsınız.
İşin alıcı kısmında ise Kesme kullanılması zorunludur. Ancak bu şekilde senkron yakalanır. Bu işi Serin komutu ilede yapabilirsiniz ama programda,
Basla:
SerIn PORTB.1,84,[varl]
goto basla 
komutlarındanbaşka birşey olmaması gerekir. Böylece program yalnızca gelen veriye odaklanmış olur.
USART kesmesi kullanılırken ise program başka işlerle uğraşırken geri planda veri alınır ve program bu alınan veriyi değerlendirir. İşin güzel yanı buradadır.
Alıcı tarafında USART kesmesi açmak için;
Önce INTCON registerine INTCON=%11000000 değeri verilerek global kesmeler ve peripheral kesmeler aktive edilir.
Ardından USART kesmesi için PIE1 registeri 5 nolu biti (RCIE) set edilir . Bu Usart kesmesini aktive eder. Kesme oluştuğunda kesme bayrağı set edilir. Bu bayrak PIR1 registeri 5 nolu biti (RCIF) ile kontrol edilir. Önceden oluşmu kesmelerde set edilmiş kesme bayrağı ihtimaline karşın önce bu bayrak sıfırlanır. PIR1.5=0. Ancak bu bayrak aslında programcı tarafından direk ulaşılabilen bir bit değildir. Üretici (microchip) bunu otomatiğe bağlamıştır. Bunun için RCREG denilan alma registerinin içinin boşaltılması yani TEMP=RCREG şeklinde başka bir değişkene aktarılması söz konusu bayrağı otomatikmen sıfırlar. Bu nedenle BASLA satırından evvel TEMP=RCREG komutununda verilmesi uygun olacaktır.
Programa birde ON INTERRUPT GOTO KESME komutunu ekledinmi sistem tamamlanmış olacaktır. Proton da komutun yazılım şeklinde farklılıklar olabilir onları sen düzeltirsin. Ben Proton kullanmıyorum. PBP kullanırım.
Program içinde KESME şeklinde bir etiket belirliyoruz. BU etiketten önce Global gesmelerin pasif edilmesi amacı ile DISABLE komutu yer almalıdır. Böylece program kesme etiketine geldiğinde bir başka kesme oluşması engellenmiş olur ve DISABLE bunu otomatik yapar.
Program kesmeye nasıl geldi o kısmı bir kez daha yinelemek isterim. Geri planda çalışan kontrolcü USART portuna bir veri geldiğini tespit etti ve RCIF=1 yaparak kesme bayrağını set etti. Bu nedenle programda hemen kesme etiketine atlamış oldu. Demekki bir veri geliyor. Tabiiki önce Uyandırma sinyali porta ulaşacak ve program kesme etiketine gelinceye kadar bir kaç veri alınmaya devam edecektir. Bu nedenle uyandırma sinyalimiz bir kaç byte dan oluşuyor (toplamda 15 byte). Kesme etiketinde;
hSerIn ,10,ATLA,[WAIT("ETE"),VERI1,VERI2,VERI3] 
komut satırı yer alıyor. Altında ise ATLA isimli etiket yer alıyor. Komut içindeki 10 rakamı Timeout değeridir. Anlamı şu, bir veri geldiğinde 10 ms süre ile ETE bilgisini ara. gelmemiş ise ATLA isimli etikete geç demektir. Komuta timeout değeri ve atlama etiketini eklemeyebilirsiniz. O zaman yanlış (parazit gibi) bir veri geldiğinde program orada epeyce ETE bilgisini almak için beklemek zorunda kalır. BU şekilde ise belirli bir zaman peryodu koymuş olursunuz. Zaten gelecek ise bu süre içinde mutlaka gelir.
ATLA etiketi altına ise,
TEMP=RCREG
RESUME
ENABLE
komutları yer alır.
Program beklenen verileri alsada almasada mutlaka RCREG içini boşaltarak kesme bayrağını sıfırlamalıdır. Böylece yeniden ve gereksiz yere kesme oluşması engellenmiş olur.   

Basic de birde şöyle bir kural vardır. Bu kural Proton için kısmen geçerli. Ama yinede uyulmasında yarar vardır. Kesme aktive edilmiş bir programda kesme bayrağı set edilmiş ise program kesme etiketine gitmeye çalışır. Ancak o anda bir basic komutu (mesela Dleayms 1000 gibi) icra ediliyor ise bu komut işlemesi bitmeden kesmeye geçmesi mümkün olmaz. Bu nedenle biz özellikle kesme kullandığımız programlarda uzun süreli Delayms (veya Pause) kullanmaktan kaçınırız. EN büyük süre 5us olmalıdır. Böylece program kesmeye gidebilmek için en fazla 5us beklemiş olurki bu ihmal edilebilecek bir süredir. Uzun gecikmeler gerekirse bir döngü kurularak gecikme adedi artırılır. Örneğin,
FOR W=0 to 1000
  Delayus 5
Next
bu döngü size 1000 adet 5us lik gecikme yaratır. Döngünün kendi komut gecikmeside eklenirse bu gecikme yaklaşık 10 ms dolayında gerçekleşir. Tahmini bir değerdir daha az da olabilir.
Kesme içinde Hserin komutu altına birde ALdı=1 şeklinde bir bit değişkeni set edilir ise ve Programın ana kısmında (BASLA etiketi altındaki komut satırlarında, IF ALDI=1 then şeklinde başlayan bir komut olursa programın herhangi bir bilgi alma durumunda alınan bilgileri ne yapacağınıza o komut altında karar verebilirsiniz ALdı=0 deyip işi bitirirsiniz.

Anlatacaklarım bu kadar. Umarım artık anlaşılmıştır.
Ete projelerinde RF_Termometre isimli bir çalışma var. Örnekleri incelemni öneririm. Bütün bu yazdıklarımı anlatıyor.

Ete








yorgunadam

#5
ETE BEY FENDİ BEN YAZILIM YAPMAYA CALIŞIYORUM MİSAL METAL PARCA VAR 5.8 KHZ DEĞERDE FREKANSA SAHİP BU METALİN FREKANSINI ALGILADIĞINDA BANA BUZZER İLE ÖTEREK HABER VERECEK YAZILIMCI BULSAYDIM YAPTIRICAMDA BULDUĞUM YAZILIMCILAR BENİ DELİ ZANNEDİYOR KİMSEYE DERDİNİMİ ANLATAMIYORUM 16F628A KULLANIYORUM HİC BİR ŞEKİLDE HARİCİ OSİLATÖR KULLANMADAN ALICI VERİCİ DEVRE KULLANAMDAN SADECE ENTEGRENİN İCERSİNE YAZILAN RAKAM 5.8 DİYELİM BU FREKANSI ÜRETMEKTE OLDUĞUNU FARKETTİM

Dikkat !!!!! Mesajlarınızı Büyük harflerler ile ve Bold yani kalın harflerle yazmayınız!!!!!. Bu forum dilinde Kızmak Bağırmak anlamına geliyor. Şimdi mesajınızı küçük harflerle yeniden yazın. Yoksa sileceğim !!!!!.
Ete

ete

Yazdıklarınızdan bir şey anlamadım. Metalin frekansı olmaz. Metal kendi kendine frekans üretmez. Bir frekans dan bahsediyorsunuz ama ne olduğu mechul. İşlemci frekans (kare Dalga) üretebilir. Bunu her işlemci üretir ancak içinde dahili HPWM modülü bulunan bir işlemci bu işi daha kolay yapabilir. Kullandığınız 16F628 de bunlardan birisi. İşlemci haricten gelen bir frekansı da ölçebilir. Bunun için o frekansın mümkün ise kare dalga formunda olması ve sınırlar dahilinde bir frekans olması gerekir.  Ama ne istediğinizi yada ne yapmak istediğinizi anlamayınca daha fazla yorum yapmak mümkün olmuyor maalesef.

Ete

elektro77

Arkadaş defineci anlaşılan. Metal Dedektörü yapmaya çalışıyor.
"Eğer bir konuyu öğrenmek istiyorsan o konunun öğretmeni ol; daha iyi öğrenmek istiyorsan o konuda bir kitap yaz; daha da iyi öğrenmek istiyorsan yazdığın kitabi oku"

Powered by EzPortal