serin2 komutu icra edilirken diğer işlemlere nasıl geçilir ?

Başlatan sinasos, 09 Şubat 2018, 14:30:26

sinasos

merhabalar,
bir program algoritmasın da daha sıkıntı çektim o konuda ustalardan yardım rica ediyorum. 16f628a işlemcisi ve dahili osilatör kullanıyorum. bu işlemciye hem RF alıcı hemde RF verici bağlı. aynı zamanda 2x16 LCD ve 5 adet buton.
sorun şu ;
kumanda dan gönderdiğim RF sinyallerini gayet iyi alıyor ve aktarıyor. ancak
SERIN2 GIRIS,396,[WAIT("TSRM"),ALICI]

satırında sinyal beklediği için butonlardan gelen bilgileri okutamıyorum. bunu okutmanın bir yolu varmı ? devre hazırlanmış olduğundan usart girişlerini kullanamıyorum. kesme tarzı bir şeyler yapmayı istedim başaramadım !


'***********BU KODLAR U1 İŞLEMCİSİNE AİTTİR*************

@ DEVICE pic16F628A 'işlemci 16F628 
@ DEVICE pic16F628A, WDT_on 'Watch Dog timer kapalı 
@ DEVICE pic16F628A, PWRT_ON 'Power on timer açık 
@ DEVICE pic16F628A, PROTECT_OFF 'Kod Protek kapalı 
@ DEVICE pic16F628A, MCLR_off 'MCLR pini kullanılıyor. 
@ DEVICE pic16F628A, INTRC_OSC_NOCLKOUT 'Dahili osilatör kullanılacak
include "modedefs.bas"
DEFINE OSC 4
'-------------------------- LCD Tanımlama --------------------
DEFINE LCD_DREG PORTB 'LCD data bacakları hangi porta bağlı?
DEFINE LCD_DBIT 4 'LCD data bacakları hangi bitten başlıyor?
DEFINE LCD_RSREG PORTB 'LCD RS Bacağı Hangi Porta bağlı ?
DEFINE LCD_RSBIT 2 'LCD RS bacağı Hangi Bite bağlı ?
define lcd_RWREG    PORTB
'define LC_RWBIT     2
DEFINE LCD_EREG PORTB 'LCD Enable Bacağı Hangi Porta bağlı?
DEFINE LCD_EBIT 3 'LCD Enable Bacağı Hangi bite bağlı ?
DEFINE LCD_BITS 4 'LCD 4 bit mi yoksa 8 bit olarak bağlı?
DEFINE LCD_LINES 2 'LCD Kaç sıra yazabiliyor
OPTION_REG.7=1

CMCON=7
TRISA=%00111101
TRISB=%00000011
PORTA=0
PORTB=0

ALICI VAR BYTE
VERICI VAR BYTE
MESAJ VAR BYTE

VERICI=0
PAUSE 10

SYMBOL GIRIS=PORTA.0    'RF SİNYAL ALICI
SYMBOL VER=PORTA.1      'RF SİNYAL VERİCİ
SYMBOL HAZIRLAN=PORTA.2 'HAZIRLAN BUTONU
symbol HABERCI=porta.3  'HABERCİ  BUTONU
SYMBOL TOPLANTI=PORTB.0 'TOPLANTI BUTONU
SYMBOL MESGUL=PORTB.1   'MEŞGUL BUTONU
SYMBOL RST=PORTA.5      'RESET BUTONU GİRİŞİ
SYMBOL BZR=PORTA.6      'BUZER ÇIKIŞI
SYMBOL LED=PORTA.7      '

BASLA:
GOSUB BUTONBAK
gosub RFBAK
GOSUB EKRAN

GOTO BASLA
'***********************RF  KONTROL KISMI ***********************************
RFBAK:
LED=0:PAUSE 100
SERIN2 GIRIS,396,[WAIT("TSRM"),ALICI]
GOSUB BUTONBAK
IF ALICI=10 THEN LCDOUT $FE,$80,"    TELEFON1    ":GOSUB TEL
IF ALICI=15 THEN LCDOUT $FE,$80,"    TELEFON2   ":GOSUB TEL
IF ALICI=20 THEN LCDOUT $FE,$80,"    TELEFON3    ":GOSUB TEL
IF ALICI=25 THEN LCDOUT $FE,$80,"    TELEFON4    ":GOSUB TEL
IF ALICI=30 THEN LCDOUT $FE,$80,"   KAPI  ACIK    ":GOSUB KAPI1
IF ALICI=35 THEN LCDOUT $FE,$80,"   DiNLENiYOR   ":GOSUB KAPI2

RETURN

BUTONBAK:
LED=1:PAUSE 100
IF HAZIRLAN=0 THEN LCDOUT  $FE,$80,"CIKIS  YAPILACAK":gosub HAZIR
IF HABERCI =0 THEN LCDOUT  $FE,$80," HABERCi GELSiN ":gosub HABER
IF TOPLANTI=0 THEN LCDOUT  $FE,$80,"  TOPLANTI VAR  ":gosub TOPLAN
IF MESGUL  =0 THEN LCDOUT  $FE,$80,"RAHATSIZ ETMEYiN":gosub MSGL
IF RST     =0 THEN LCDOUT  $FE,$80,"                         ":gosub RESET
RETURN

GONDER:
SEROUT2 VER,396,[REP$AA\5,REP$00\5,REP$FF\5]
SEROUT2 VER,396,[$24,$52,$46,"T","S","R","M",VERICI,$45,$4E,$44,$0D,$0A]
SEROUT2 VER,396,[$24,$52,$46,"T","S","R","M",VERICI,$45,$4E,$44,$0D,$0A]
SEROUT2 VER,396,[$24,$52,$46,"T","S","R","M",VERICI,$45,$4E,$44,$0D,$0A]
SEROUT2 VER,396,[$24,$52,$46,"T","S","R","M",VERICI,$45,$4E,$44,$0D,$0A]
SEROUT2 VER,396,[$24,$52,$46,"T","S","R","M",VERICI,$45,$4E,$44,$0D,$0A]
SEROUT2 VER,396,[$24,$52,$46,"T","S","R","M",VERICI,$45,$4E,$44,$0D,$0A]
RETURN

HAZIR:
VERICI=45
GOSUB GONDER
RETURN
HABER:
VERICI=50
GOSUB GONDER
RETURN
TOPLAN:
VERICI=55
GOSUB GONDER
RETURN

MB_77

bu mesaj tarafımdan silinmiştir.

MB_77

bu mesaj tarafımdan silinmiştir.

ete

Serin komutu veri alınıncaya kadar programı orada bloke eder. Ama MB_77 ninde dediği gibi program da son derece gereksiz pause ler mevcut.
Her şeyden önce program başla satırına gelmeden önce en azından bir 150-200 ms lik açılış gecikmesi koymak gerekirdi onu koymayıp program içinde akışı engelleyecek gecikmeler yerleştirilmiş.
RF alışverişleri senkron gerektirir. Yani biri bir şey veriyor ise alan da alma konumunda bekliyor olması gerekir ve bu alışverişler bir kaç ms sürer yalnızca. Veren verirde alan alma pozisyonunda değilde pause ye takılıp beklemede ise hiç bir şey alamaz. Bu nedenle alan taraf ta gecikme komutlarından sakınmak gerekir.
Bu tür hem alan hem veren sistemlerde alış için mutlaka USART kesmesi kullanmak gerekir. Verme meselesi kendi elinde olduğu için onunla ilgili bir şey yapmaya gerek yok ver dediğin zaman gönderiyor zaten. Ama alma senin kontrolünde değil. Ne zaman veri geleceğinide bilemezsin o halde çözüm kesme kullanmaktır.

Ete


Elektronikprojem

İlla gecikme kullanacağım diyorsan işlemcide usart pinlerini kullanarak usart kesmesini aktif et gecikmeleri de

for I=1 to 1000
pause 1
next


şeklinde kullanırsın. Ben bu şekilde yapıyorum.

sinasos

Öncelikle ilginizden dolayı teşekkür ederim. Size şu şekilde açıklama yapayım ! Normalde yazılıda pause komutunu neredeyse hiç kullanmadım. orada gördüğünüz 2 tane pause 100 nerede takıldığını görebilmek içindi. buraya koyarken silmeyi unutmuşum. Devre bu haldeyken butonları kontrol etmek ve onlardan gelen bilgileri işleyebilmek için bir yol  arıyorum. Usart kullanmak için devreyi atıp yeniden yapmam lazım ve o da olmasın istiyorum. Bu şekli ile programsal yapılabilecek bir durum varmı öncelikle bunu ortaya çıkartabilirsek onu denemek istiyorum. Örneğin "kesme" gibi. Kesme şeklinde olabilirse eğer o konuda ayrıca yardım da rica ediyorum. (örnek)
Saygılarımla.

Sayın MB_77 ;
"devreni değiştiremiyorsan buton fonksiyonlarını değiştirmeyi dene" şeklinde bir ibare var. Ne tür bir şey olabilir buton fonksiyonu ? o konuda bilgi verebilirmisin.
Teşekkürler.

MB_77

bu mesaj tarafımdan silinmiştir.

sinasos

sayın mb_77 teşekkür ederim çok ilgili davrandığınız için. iç içe olan alt programları kaldırmak düzeltmek konusunda haklısın ! onların haricinde kesme konusunda yardımcı olursan sevinirim. picbasic de en sıkıntılı şey bana göre kesmeler. onun için uğraştım olmadı. yardımcı olabilirsen sevinirim.

Alıntı Yapbuton fonksiyonlarında ise;
bildiğim kadarıyla yaklaşık 40ms de bir butonları okumak uygun olacaktır. programında tabi bu sağlanamıyor.

o zaman sende, 40ms'de bir taşacak(kesme oluturacak) şekilde bir timer kur ve kesme içinde fazla bir komut eklemeden sadece bu beş butonu kontrol et ve her buton için ayrı bir değişkene yükle. tabi bu değişkenleri de tanımlaman gerek.

MB_77

bu mesaj tarafımdan silinmiştir.

ete

Kesme konusunda beklentin şayet Serin komutu icra edilirken kesme emri gelirse bende serin de beklemekten kurtulurum diye düşünüyorsan boşuna heveslenme. Bu seferde Serin komutu bitinceye kadar program kesmeye gitmeyecektir. Genel kaide şudur. PBP da kesme oluştuğu esnada herhangi bir basic komutu ica ediliyor ise o komutun icrası sona erinceye kadar program bekler daha sonra kesmeye atlar.
Kesme sana yalnızca buton kontrolünde yardımcı olabilir ama bu programda bence kesmeye hiç gerek yok. Çünki yardımdan çok engelleme yapacak sana.
Aslında sorunun çözümü Serin komutunda Timeout fonksiyonunu kullanmakta yatıyor ama her ne hikmetse 2.60 versiyonda bu timeout sistemi çalışmıyor. Bunda en büyük etkenin Serin işleminin yapılacağı port pininin stabil durmamasıdır. Genelde bir RF çıkış pinine bağlı olan bu pin sürekli olarak bir aşağı bir yukarı çıkınca program onu boşta bekliyor kabul etmiyor data alıyor kabul ediyor. Bu durumda Timeout da çalışmıyor. Şayet araya bir direnç atıp pini stabil bekleme konumuna getirebilirsen timeout sisteminin çalışacağını umuyorum. HSERIN sisteminde Timeout fonksiyonu kusursuz çalışıyor çünki o komut WAIT olarak beklenen değeri belirlenen süre içinde almaz ise timeout için verilen etikete atlatıyor programı. Serin de ise pinin boşta beklemesi esas alınmış. Belki PBP3.1 versiyonda bu sorunu düzeltmişlerdir.
Programın en son halini buraya koy ben 3.1 ile derleyeyim bakalım timeout çalışacakmıdır.
Ete

sinasos

İyi akşamlar ETE hocam;
uzun süredir serin2 komutu ile uğraştım ama sorunu çözemedim. Bende Hserin ile devreyi tekrar yaptım. Sizin ders14 den esinlenerek değişiklikler yapmaya çalıştım ancak sonuca ulaşamadım.
sorunum sinyal geldiğinde sistem sürekli kendini resetliyor (WDT off olunca da kilitleniyor). amacım şu; RF sinyali geldiğinde ilgili mesajı 20-30 saniye ekranda gösterecek sonra tekrar bekleme mesajına geçecek. ama bu arada farklı başka bir sinyal geldiğinde onu gösterecek.
hazırladığım program aşağıda ! hatayı bir türlü bulamıyorum. yardımcı olursanız sevinirim. Birde hatalı kısmın sebebinide bildirebilirseniz çok sevinirim.
Selam ve Saygılarımla



@ DEVICE pic16F628A 'işlemci 16F628 
@ DEVICE pic16F628A, WDT_on 'Watch Dog timer Açık 
@ DEVICE pic16F628A, PWRT_ON 'Power on timer açık 
@ DEVICE pic16F628A, PROTECT_OFF 'Kod Protek kapalı 
@ DEVICE pic16F628A, MCLR_off 'MCLR pini kullanılıyor. 
@ DEVICE pic16F628A, INTRC_OSC_NOCLKOUT 'Dahili osilatör kullanılacak
include "modedefs.bas"
DEFINE OSC 4
'-------------------------- LCD Tanımlama --------------------
DEFINE LCD_DREG PORTB 'LCD data bacakları hangi porta bağlı?
DEFINE LCD_DBIT 4 'LCD data bacakları hangi bitten başlıyor?
DEFINE LCD_RSREG PORTA 'LCD RS Bacağı Hangi Porta bağlı ?
DEFINE LCD_RSBIT 1 'LCD RS bacağı Hangi Bite bağlı ?
define LCD_RWREG    PORTA
define LCD_RWBIT    0
DEFINE LCD_EREG PORTB 'LCD Enable Bacağı Hangi Porta bağlı?
DEFINE LCD_EBIT 3 'LCD Enable Bacağı Hangi bite bağlı ?
DEFINE LCD_BITS 4 'LCD 4 bit mi yoksa 8 bit olarak bağlı?
DEFINE LCD_LINES 2 'LCD Kaç sıra yazabiliyor

'** BU ALAN SERİ İLETİŞİM PROTOKOLLERİ İÇERİR TÜM PİCLER İÇİN AYNIDIR **
DEFINE HSER_RCSTA 90h ' Enable serial port & continuous receive
DEFINE HSER_TXSTA 20h ' Enable transmit, BRGH = 0
DEFINE HSER_SPBRG 25  ' 2400 Baud @ 4MHz, 0,17%
DEFINE HSER_CLROERR 1 ' Clear overflow automatically

OPTION_REG.7=1 'portB deki dahili PULL-UP lar iptal edildi.
CMCON=7 'komparatör pinleri iptal hepsi giriş çıkış yapıldı
TRISA=%00011100
TRISB=%00000010
PORTA=0
PORTB=0

SYMBOL GIE  =INTCON.7 'genel interruptları açıyor
SYMBOL PEIE =INTCON.6 'peripheralinterruptları açıyor
SYMBOL RCIE =PIE1.5 'USART Recive interrupt enable bit
SYMBOL RCIF =PIR1.5 'USART Receive interrupt flag bit

temp var BYTE
AL  VAR BYTE
Y   VAR byte
x   var byte
q   var BYTE
V   VAR BYTE
AL=0
y=0
x=0
q=0
PAUSE 10
SYMBOL BZR=PORTA.6      'BUZER ÇIKIŞI

    BZR=1:PAUSE 50:BZR=0
    LCDOUT  $FE,1
    LCDOUT  $FE,$80,"   RF KONTROL   "
    LCDOUT  $FE,$C0,"   SiSTEMLERi   "
    pause 1500:BZR=1:PAUSE 250:BZR=0:LCDOUT  $FE,1:GOSUB EKRAN

'*************   kesme oluşturma****************
INTCON=%11000000
ON INTERRUPT GOTO INT
RCIE=1
'***********************************************

BASLA:                     
if x=0 then LCDOUT $FE,$80,"    8. MESAJ    "

IF AL=10 OR AL=15 OR AL=20 OR AL=25  THEN LCDOUT $FE,$80,"    1. MESAJ    ":x=1:GOSUB SAY
                            IF AL=30 THEN LCDOUT $FE,$80,"    2. MESAJ    ":x=2:GOSUB BEEP':GOSUB SILME
                            IF AL=35 THEN LCDOUT $FE,$80,"    3. MESAJ    ":x=3:GOSUB BEEP':GOSUB SILME
                            IF AL=35 THEN LCDOUT $FE,$80,"    4. MESAJ    ":x=4:GOSUB BEEP':GOSUB SILME
                            IF AL=40 THEN LCDOUT $FE,$80,"    5. MESAJ    ":x=5:GOSUB BEEP':GOSUB SILME
                            IF AL=45 THEN LCDOUT $FE,$80,"    6. MESAJ    ":x=6:GOSUB BEEP:GOSUB SILME
                            IF AL=50 THEN LCDOUT $FE,$80,"    7. MESAJ    ":x=7:GOSUB BEEP':goto SILME
                            IF AL=55 THEN LCDOUT $FE,$80,"    8. MESAJ    ":x=8:GOSUB BEEP':GOSUB SILME
                            IF AL>1  THEN GOSUB EKRAN

GOTO BASLA

SILME:
FOR V=0 TO 100
PAUSE 10
GOSUB EKRAN
NEXT V
RETURN

SAY: 'SİNYAL GELDİĞİ SÜRECE BURASI BELLİ ARALIKLARLA UYARI VERECEK
IF Y=>210 THEN Y=0
Y=Y+1
if Y=1 OR Y=30 or y=60 or y=90 or y=120 or y=150 or y=180 then GOSUB BEEP
RETURN

BEEP: 'UYARI SESİ
BZR=1
PAUSE 20
BZR=0
RETURN

EKRAN:
    LCDOUT  $FE,$C0," SiSTEM BEKLEMEDE"
return

DISABLE
INT:
GIE=0
hserin 5,ATLA, [wait("ETE"),AL] 
ATLA:
TEMP=RCREG
GIE=1
Resume
enable

END

ete

Genel anlamda bir hata göremedim. Bazen bakarsın göremezsin. Ancak deneyince çıkan sonuca göre yorum yapıp hata bulmak daha kolay oluyor.
Ama programda kusurlar var. Bunları sıralayacak olursak;
1. Kesme kullanılan programda PAUSE diye bir komut kesinlikle kullanamazsın. Biraz mantığını çalıştır istersen. Timeout süresi olarak 5ms verdiğin bir RF alım işinde program içinde birden fazla PAUSE 10 komutu bulunuyorsa o sistem düzgün çalışırmı. Daha açık ifade ile sen 10 ms lik gecikmeyi uygularken RF den bir veri gelirse 10 ms bitmeden o veriye program ulaşamayacaktır. 10 sn bittiğinde ise veri çoktan verilmiş olacağı için veri alamayacaksın demektir.
Kesme kullanılan programda PAUSEUS 5 den büyük gecikme kullanmamaya çalış. Döngüsel gecikmeleri döngü miktarını artırarak çoğaltabilirsin. Bir döngü işleminde her bir komutu kaç kere icra edileceğide önemlidir. Yani;
FOR I= 0 to 255
  PAUSEUSE 5
Next
şeklindeki bir gecikme döngüsünde 255x5 =1.275 us den daha fazla bir gecikme yaratılır. Çünki 255 defa döngü komutuda bir gecikme yaratır ve sayede toplam gecikmen 1300 ms ler belkide daha fazla seviyelere çıkar.

SILME:
FOR V=0 TO 100
PAUSE 10
GOSUB EKRAN
NEXT V
RETURN
satırlarında hem Pause 10  kusuru mevcut hemde 101 defa GOSUB EKRAN komutu çalıştırılmış oluyor ki bu gereklimi sence?
Bu satırları şöyle yazsan daha doğru olurdu;
SILME:
GOSUB EKRAN
FOR V=0 TO 100
PAUSE 10
NEXT V
RETURN
ama dediğim gibi PAUSE den kaçınman gerekiyor. Gerekirse word değişkeni kullanarak döngüyü artırabilirsin.

İlk açılışta     LCDOUT  $FE,1 komutunu verdikten sonra yaklaşık 200 ms lik bir gecikme koy bu komutun peşine. Bu LCD registerlerinin yerini alması için geçecek süredir yaklaşık olarak. Aksi halde olumsuz sonuçlar ortaya çıkabilir.

Gördüklerim bunlar. Varsa bir simulasyon dosyası sorunu daha iyi görmeye yardımcı olabilirdi.

Ete

sinasos

Teşekkürler Hocam,
Ben o döngüyü sadece gecikme koyabilmek adına ekledim ve ekranda nerede takıldığını görebilmek adına da pause uzun tuttum, haklısınız sizin söylediğiniz şekilde düzeltirim. Ama sorun kilitlenme olunca ! bahsettiğiniz dosya ektedir.

Verici program kodunu eklemeyi unutmuşum.



@ DEVICE pic12f675 'işlemci 12F675 
@ DEVICE pic12f675, WDT_on 'Watch Dog timer kapalı 
@ DEVICE pic12f675, PWRT_ON 'Power on timer açık 
@ DEVICE pic12f675, PROTECT_OFF 'Kod Protek kapalı 
@ DEVICE pic12f675, MCLR_OFF 'MCLR pini kullanılıyor. 
@ DEVICE pic12f675, INTRC_OSC_NOCLKOUT 'Dahili osilatör kullanılacak
include "modedefs.bas"
DEFINE OSC 4
define OSCCAL_1K 1
CMCON=7
ANSEL=0
OPTION_REG=7            'PULL UP DİREÇLERİ İPTAL
ADCON0=%10000000
TRISIO=%111110
WPU=0
SYMBOL AC=GPIO.0       'RF ÇIKIŞI
SYMBOL BUTON1=GPIO.1
symbol BUTON2=GPIO.2
SYMBOL BUTON3=GPIO.3
SYMBOL BUTON4=GPIO.4
SYMBOL BUTON5=GPIO.5

VERICI VAR BYTE
q      var byte
q=0
VERICI=0
PAUSE 10

BASLA:

IF BUTON1=0   THEN verici=35:GOSUB GONDER
IF BUTON2=0   THEN VERICI=40:GOSUB GONDER
IF BUTON3=0   THEN VERICI=45:GOSUB GONDER
IF BUTON4=0   THEN VERICI=55:GOSUB GONDER
IF BUTON5=0   THEN VERICI=50:GOSUB GONDER
VERICI=0
GOTO BASLA

GONDER:
for q=0 to 5
SEROUT2 AC,396,[REP$AA\5,REP$00\5,REP$FF\5]
SEROUT2 ac,396,[$24,$52,$46,"E","T","E",VERICI,$45,$4E,$44,$0D,$0A]
next q
return
            ASM
            SLEEP
            ENDASM
END


ete

Verdiğin 12F675 programında Heserin de kullanılan işaretçi bilgisi ETE ama yanına bir sürü şey ilave edilmiş.
628 programına baktığım zaman ise işaretçinin TSRM olduğunu görüyorum. Muhtemelen haberleşme sorununu bu yaratıyor.
He riki programıda ETE işaretçisi ile çalışacak hale getirdim. Ana programdaki gecikmeleri olması gereken şekle soktum ve denedim. Sorunsuz çalışıyor.
Sende dene bakalım herhangi bir olumsuzluk görecekmisin.

Ete


sinasos

Problem aynen devam ediyor Hocam. Şimdi video çektim onun linkini koyuyorum.

http://dosya.co/flsbd7igju07/20180303_125847.mp4.html

Powered by EzPortal