Hserin ve Rb0 kesmesi

Başlatan gigabytetr, 19 Mart 2017, 11:46:38

gigabytetr

16f628'de  hserin ile rf butondan veri alıyorum aynı zamanda rb0 kesmesiyle sayma yapmak istiyorum mesela 1sn içinde 3 puls geldiyse çıkış verecek .ekteki kodda rf çalışıyor ama sayma sadece rf buton basılıyken ve rf modül ün data bacağı pice bağlı değilken çalışıyor, acaba nerelerde yanlış yapıyorum ?(similasyonda herşey normal)
@ __config _XT_OSC & _WDT_ON & _PWRTE_ON & _LVP_OFF & _CP_OFF
define OSC 4
PORTB=0
TRISB=%11110111
TRISA=%00011100
define HSER_RCSTA 90h
define HSER_TXSTA 20h
DEFINE HSER_SPBRG 5
DEFINE HSER_CLROERR 1
SYMBOL RCIE =PIE1.5     'USART Recive interrupt enable bit
SYMBOL RCIF =PIR1.5     'USART Receive interrupt flag bit
ON INTERRUPT GoTo KESME
INTCON=%10010000
BILGI VAR BYTE
GIRIS VAR PORTB.1
SINYAL VAR PORTB.3
UYARI VAR PORTA.1

SAYAC VAR WORD
A VAR BYTE
KESTIR VAR BIT
BILGI=0
SAYAC=0

BASLA:
  IF KESTIR=1 then
    KESTIR=0
    COUNT KESTIR=1, 2000, A
    IF A>2 THEN :HIGH UYARI
    gosub IKAZVER
    endif       
     
hSerIn 10,ATLA,[WAIT("YAM"),BILGI]   
SAYAC=0
IF BILGI=111 THEN :HIGH SINYAL :HIGH PORTB.5
IF BILGI=222 THEN :HIGH SINYAL :HIGH PORTB.4

     
ATLA:
     
SAYAC=SAYAC+1
IF SAYAC=2 THEN : SINYAL=0 :PORTB.5=0  :PORTB.4=0


GOTO BASLA
'-------------------------------------------------------------------
IKAZVER:
  PAUSE 5000
  LOW UYARI
  RETURN
 

       DISABLE   
KESME:
       KESTIR=1 
       INTCON.1=0 
       Resume     
   Enable     
   
End

Hattuşa

#1
slm interruptunuzda sadece "kestir" adlı bir etiket var, bu etiket 1 olduğunda işlem yapıyorsunuz. programınızın takılma nedeni usart beklemesi yüzünden. bence siz interrupta int0 ı ve usart kesmesini aktif edip ana döngüde de diğer işlerinizi yapmış olsanız hiç bu tür sıkıntı
lar yaşamazsınız

kaba bir örnek vereyim;


main:
'burada yapılacak işlemlerinizi yapın

goto main


disable
Kesme:
if int0if =1 then
int0if =0

burada rb0 kesmesi oluşunca yaptırmak istediğiniz işlemleri kısa bir şekilde yapabilirsiniz veya buraya bir bayrak ekleyip ana döngüde bu bayrağı kontrol edebilirsiniz. tıpkı sizin "kestir" bayrağı gibi

else

hSerIn 10,ATLA,[WAIT("YAM"),BILGI]

atla:
rcif =0
temp =RCREG
endif

resume
enable
endif



gigabytetr

hocam yapamadım bu seferde sadece rb0 da sayma yapıyor ama hserın çalışmadı acaba tanımlamalarda mı hata yapıyorum


@ __config _XT_OSC & _WDT_ON & _PWRTE_ON & _LVP_OFF & _CP_OFF
define OSC 4
PORTB=0
TRISB=%11110111
TRISA=%00011100
define HSER_RCSTA 90h
define HSER_TXSTA 20h
DEFINE HSER_SPBRG 5
DEFINE HSER_CLROERR 1
SYMBOL RCIE =PIE1.5     'USART Recive interrupt enable bit
SYMBOL RCIF =PIR1.5     'USART Receive interrupt flag bit
Symbol INT0IF =INTCON.1

ON INTERRUPT GoTo KESME

INTCON=%10010000


GIRIS VAR PORTB.1
SINYAL VAR PORTB.3
UYARI VAR PORTA.1
BILGI VAR BYTE
SAYAC VAR WORD
A VAR BYTE
KESTIR VAR BIT
TEMP  VAR BYTE
B VAR BIT
GELEN VAR BYTE
BILGI=0
SAYAC=0
BASLA:

IF KESTIR=1 then
  KESTIR=0
    COUNT KESTIR=1, 2000, A
   IF A>2 THEN :HIGH UYARI
    gosub IKAZVER
    endif       
   
'HSerIn 10,ATLA,[WAIT("YAM"),BILGI]

IF GELEN=111 THEN :HIGH SINYAL :HIGH PORTB.5
IF GELEN=222 THEN :HIGH SINYAL :HIGH PORTB.4   
               
'ATLA:

'SAYAC=SAYAC+1
'IF SAYAC=2 THEN : SINYAL=0 :PORTB.5=0  :PORTB.4=0
             

GOTO BASLA
'-------------------------------------------------------------------
IKAZVER:
  PAUSE 5000
  LOW UYARI
  RETURN
 
 
 
disable
Kesme:
if int0if =1 then
int0if =0

KESTIR=1
else

hSerIn 100,ATLA,[WAIT("YAM"),BILGI]
GELEN=BILGI
   
  ATLA:
rcif =0
temp =RCREG

endif
resume
enable

ete

Biraz dikkat lütfen. Bak tanımlamalarında ne yapmışsın.
SYMBOL RCIF =PIR1.5     'USART Receive interrupt flag bit
Bunun anlamı şu. Şayet USART kesmesi oluşmuş ise yada başka bir deyişle seri portdan bir veri gelmiş ise RCIF=1 olacaktır. Diğer taraftan USART kesmesini aktif edebilmen için iki şey yapman gerekiyor.
1. INTCON.6=1 vermen ve RCIE=1 vermen gerekiyor. İkisinide yamamışsın.
O halde programın baş kısmına BASLA satırından evvel ;
INTCON.6=1
RCIE=1
komut satırlarını eklemen gerekiyor.
Programa bakılırsa 2 tane kesme kaynağın olacaktır. Birisi PORTB.0 kesmesi ve diğeride USART kesmesi.
Birinin Kesme bayrağı INT0IF diğerininde RCIF olacaktır. Kesme oluştuğunda hangisi ile iş yapacaksan belirgin bir şekilde bunları ayırmanda yarar var.

DISABLE
KESME:
IF INT0IF=1 then
  INT0IF=0
  KESTIR=1
  GOTO CIK
ENDIF
IF RCIF=1 THEN
  HSERIN 100,ATLA,[WAIT("YAM"),BILGI]
  GELEN=BILGI
ATLA:
   TEMP=RCREG:RCIF=0
ENDIF
CIK:
RESUME
ENABLE

Şeklindeki bir kod düzeni daha uygun olmalı bence.
Ete


gigabytetr

#4
teşekkürler hocam.
rb0 ve veri alma çalıştı ,daha önce sadece rf kullanırken alttaki kod ile buton bırakıldığında sinyal gelmiyorsa durumu sıfırlıyodum verdiğiniz kodlar üzerinden yapmaya çalıştım ama olmadı bitürlü , böyle bişey yapmak mümkünmü ?üstüste çok oluyorum ama kusura bakmayın.

HSERIN 10,ATLA,[WAIT("YAM"),BILGI]
sayac=0
BILGI=111 THEN : HIGH SINYAL : HIGH PORTB.5
ATLA:
SAYAC=SAYAC+1 

IF  SAYAC=2  THEN :SINYAL=0 :PORTB.5=0  :PORTB.4=0

ete

Gelecek olan veriye bağlı veri gelmeme tespiti olmaz. Sen veri geldikçe sayac değişkenini artıyorsun. Veri hiç gelmez ise orada da sıfırlamaya yapamazsın.
Sıfırlama için en güzeli Ana program kısmında sayac değişkenini her GOTO BASLA komutundan önce bir artır ve belirli bir sayıya ulaşıldığı zaman sıfırlamayı yaptır. Ama her veri geldiğinde SAYAC değişkenini sıfırla.
En güzel yöntem budur.
Ete

gigabytetr

Yapamadım hocam ya hserın yada rb0 çalışmıyo  .yukarıdaki verdiğim kod  kesme leri kullanmadan rf için  istediğim şeyi yapıyodu ,butona bastığım'da belirli çıkışı verip bıraktığımda çıkışı kesecek.rb0 dan saydığım pals 1 sn içinde 3'ü geçerse çıkış verecek bunları birlikte çalıştıramadım bi türlü


BASLA:
   
IF KESTIR=1 then
KESTIR=0
COUNT KESTIR=1,1000, A
IF A>3 THEN : HIGH UYARI: gosub IKAZVER
endif       

IF SAYAC=3 THEN :SINYAL=0 :PORTB.5=0  :PORTB.4=0:PAUSE 1

IF GELEN=222 THEN :  HIGH SINYAL: HIGH PORTB.5 
 
       SAYAC=SAYAC+1
 
GOTO BASLA
'-------------------------------------------------------------------
IKAZVER:
  PAUSE 5000
  LOW UYARI
  RETURN

DISABLE
KESME:
IF INT0IF=1 then
  INT0IF=0
  KESTIR=1
   
  GOTO CIK

ENDIF
IF RCIF=1 THEN

  HSERIN 100,ATLA,[WAIT("YAM"),BILGI]
  GELEN=BILGI: SAYAC=0

ATLA:
  TEMP=RCREG:RCIF=0
     
   ENDIF
CIK:

RESUME
ENABLE

ete

Bunu yapsan yapsan sen yaparsın. Tam olarak ne istediğini pek anlamadım. Anlamayınca vereceğim öneriler işin temelini bozabilir ki öylede oluyor zaten.
İyice düşün. Gerekirse flag (Bayrak) kullan.
B0 daki tuşa bastın kesme oluştu. Kesmeden çıkmadan önce sayac saysan tuşun bırakılmadığı belli değil. Orada tuşun bırakılmasını beklesen bu seferde veri alma işi aksayacak. SIkıntıı bir istek bu seninkisi.
Ete

gigabytetr

#8
teşekkürler hocam biraz daha kurcalıyayım ,yapmak istediğim rf modül ile vericiye enerji verince alıcıda portb.5 high olcak vericide enerji kesince low' döncek( bukısım ilk eklediğim kodda çalışıyor), birde  alıcıda  bir metal  sensörü var sensörün önünden bir 1sn içinde 3 den fazla metal geçerse ayrı bir çıkış verecek .yani sensör ve rf buton birbirinden bağımsız çalışacak .
(ekteki similasyonda istediğim gibi çalışıyor uygulamada rf buton sinyal göndermiyosa  sensörü saymıyor)

gigabytetr

Hocam devrede sadece sinyal geliyoken pals sayıyodu , bi sakıncası varmı bilmiyorum ama  count lu bölümü bu şekilde  iki yere koyunca devredede sinyal varkende yokkende çalıştı  .


BASLA:

   
       
     
hSerIn 10,ATLA,[WAIT("YAM"),BILGI]   
SAYAC=0
IF BILGI=111 THEN :HIGH SINYAL :HIGH PORTB.4
IF BILGI=222 THEN :HIGH SINYAL :HIGH PORTB.5


  IF KESTIR=1 then
KESTIR=0
COUNT KESTIR=1,1000, A
IF A>2 THEN : HIGH UYARI: gosub IKAZVER
endif       
   
ATLA:
     
SAYAC=SAYAC+1
IF SAYAC=2 THEN : SINYAL=0 :PORTB.5=0  :PORTB.4=0
 
  IF KESTIR=1 then
KESTIR=0
COUNT KESTIR=1,1000, A
IF A>2 THEN : HIGH UYARI: gosub IKAZVER
endif     

GOTO BASLA
'-------------------------------------------------------------------
IKAZVER:
  PAUSE 5000
  LOW UYARI
  RETURN
 

       DISABLE   
KESME:
       KESTIR=1 
       INTCON.1=0 
      Resume     
   Enable     
   
End

ete

hSerIn 10,ATLA,[WAIT("YAM"),BILGI]   komut satırı ne iş yapar ona bir bakalım istersen.
10 ms müddetle seri porta bakar. Belgi geliyor ise komutun devamı çalıştırılır. Gelmez ise program ATLA isimli etikete atlayacaktır.
Bu durumda yalnızca ATLA etiketinden sonra o count komutunu koysan yeterli olacaktır. Zira bilgi gelsede gelmesede program ATLA isimli etiketten geçecektir nasıl olsa.
Programın tamamını yazmayınca bazen yazanın ne düşündüğünü anlamak zor oluyor. Zor oluncada şunu yap bunu yap şeklinde öneride bulunmak hepten zor oluyor. Burada da aynı durumla karşı karşıyayım. Bu nedenle elimden daha fazlası gelmiyor maalesef. Çalıştı dediğine göre daha fazla kurcalamaya gerek yok sanırım.
Ete

gigabytetr

hocam verdiğiniz bilgiler için tekrar teşekkür ederim sayenizde öğreniyoruz.(programın tamamı bu başka bişey yapmıyor.)

Powered by EzPortal