18F24K22 çift USART interrupt yapısı,çalışma şekli ve tanımlamaları ?

Başlatan mustafa_cmbz, 26 Kasım 2018, 22:05:25

mustafa_cmbz

Merhabalar..

Geçenlerde forumdaki konulardan yola çıkarak örnek kodları inceleyerek usart interrupt olayını isiste denedim ve gayet başarılı çalışıyordu.

Fakat 18F24K22 nin her iki usart ını da kullanacağım ve yeni gelişen durumlardan dolayı 2 usartı da interrupt ile okumak istiyorum.

Fakat bir türlü 2. interrupt ı kuramadım yada kesme oluştuktan sonra ayırt edemiyorum.bilemedim..

Diğer ıvır zıvır etiketler tanımlamalar ve değişkenler olmadan kodu sade bir şekilde paylaşıyorum.

Device=18F24K22
 Xtal=20


 All_Digital=TRUE
 Declare Hserial_Baud  = 9600 ' Set baud rate to 9600
 Declare Hserial_RCSTA = %10010000 ' Enable continuous receive
 Declare Hserial_TXSTA = %00100000 ' Enable transmit and asynchronous mode       ' LCD İÇİN KULLANILACAK
 Declare Hserial_Clear = On ' Clear the buffer before receiving

 Declare Hserial2_Baud = 9600
 Declare Hserial2_RCSTA = %10010000 ' Enable continuous receive
 Declare Hserial2_TXSTA = %00100000 ' Enable transmit and asynchronous mode      ' DIGER HABERLEŞME İÇİN KULLANILACAK
 Declare Hserial2_Clear = On ' Clear the buffer before receiving


 Symbol PEIE2 = INTCON2.6       'Peripheral(çevresel) interrupt enable bit usart kesmesi için
 Symbol GIE2  = INTCON2.7       'global interrupt enable
 Symbol RCIE2 = PIE2.5          'Receiver interrupt enable bit
 Symbol RCIF2 = PIR2.5          'Receiver interrupt flag


 Symbol PEIE = INTCON.6      'Peripheral(çevresel) interrupt enable bit usart kesmesi için
 Symbol GIE  = INTCON.7      'global interrupt enable
 Symbol RCIE = PIE1.5        'Receiver interrupt enable bit
 Symbol RCIF = PIR1.5        'Receiver interrupt flag
 
 ' PIR1.5 ve PIR3.5
 
 GIE=0
 GIE2=0
 RCIE=1
 RCIE2=1
 PEIE=1
 PEIE2=1
 GIE=1
 GIE2=1

 On_Interrupt GoTo KESME       'Hardware Interrupt oluştuğunda int etiketine dallan



 
 BASLA:

 SENSORLERI_EKRANA_YAZ :  NEXTION_BILGI=0  ' EKRAN ACILDI DEGERLERI ILK OLARAK OKU 
 GoSub SENSOR_OKU
 DelayMS 4000 : GoSub MELODI : GoSub MELODI
 ORTAM_SICAKLIK=10
 GoSub SENSORLERI_EKRANA_YAZ
 DelayMS 1000 
 
 
 GoTo BASLA
 
 
 KESME:
 Context Save
 GIE=0                     
 GIE2=0
 PEIE2=0
 PEIE=0                     
 RCIE=0                     
 RCIE2=0 
                        
 If RCIF  = 1 Then SERIAL_1_BAK
 If RCIF2 = 1 Then SERIAL_2_BAK
 GoTo KESME_BITTI
 
 SERIAL_1_BAK:
 HSerIn [NEXTION_BILGI]
 GoTo KESME_BITTI
 
 SERIAL_2_BAK: 
 HSerIn2[ID,TORBA_SICAKLIK]
 GoTo KESME_BITTI                   
                      
                           

 
 KESME_BITTI:

 RCIE=1                     'Receiver interrupt enable bit
 RCIE2=1
 PEIE=1
 PEIE2=1                     'Peripheral interrupt enable bit
 RCIF=0
 RCIF2=0                     ''Receiver interrupt flag
 GIE=1 
 GIE2=1 
                   
                        

 Context Restore
 End 

Maxim


mustafa_cmbz

Alıntı yapılan: Maxim - 27 Kasım 2018, 09:06:43RCSTAx registerlarını kontrol edermisin
rcsta1.7=1
rcsta2.7=1

Kesmenin oluşup oluşmadığına mı bakacağız onu anlamadım ?

Declare Hserial2_RCSTA = %10010000

Başta tanımlı olan kısımda 7. Bit 1 olarak ifade edilmiş

yas

@mustafa_cmbz hocam,

Alıntı YapHSerIn [NEXTION_BILGI]

Alıntı YapHSerIn2[ID,TORBA_SICAKLIK]

Burada kayıtsız şartsız bilgi gelmesi bekleniyor. Koda timeout eklemenizi öneririm.
Birde uart bayraklar yani "RCIF" lere sıfır atanınca temizlenmiyor. "RCREG" ler okunduğunda temizleniyor.

yas

Alıntı yapılan: mustafa_cmbz - 27 Kasım 2018, 10:04:28Kesmenin oluşup oluşmadığına mı bakacağız onu anlamadım ?

Declare Hserial2_RCSTA = %10010000

Başta tanımlı olan kısımda 7. Bit 1 olarak ifade edilmiş

@Maxim in söylediği de ihtimaller arasında bazı durumlarda uart hataya düşerek donanımı kapatıyor. Tekrar kontrol etmek gerekiyor. Yalız ben şu şekilde kontrol ediyorum

If RCSTA.1=1 Then
  RCSTA.4 = 0 
  RCSTA.4 = 1
EndIf

fide

Her birimiz, geride bıraktığımız eserler kadar ölümsüzüz. Evlat gibi, talebe gibi, icatlar gibi...   http://fidenetgaraj.blogspot.com

mustafa_cmbz

Alıntı yapılan: yas - 27 Kasım 2018, 12:40:04@mustafa_cmbz hocam,

Burada kayıtsız şartsız bilgi gelmesi bekleniyor. Koda timeout eklemenizi öneririm.
Birde uart bayraklar yani "RCIF" lere sıfır atanınca temizlenmiyor. "RCREG" ler okunduğunda temizleniyor.

Hocam timeout a gerek varmı ki kesme kullanırken?

Kesmeye girmesi için zaten serialden bilgi gelmesi lasım. Geldiyse buraya dallanıyor veriyi alıp kesmeleri tekrar açıyor vs vs vs.


Son olarak alayli hocamla görüştüm öncelik vermelisin falan dedi kesmelere aynı anda gelirse falan diye o kısımlar nasıl olmalı acaba ?

Maxim

18 serisinde int kesmeleri için öncelik sıralaması tanımlayabiliyorsun
tanımlamazsan 16F serisi gibi standart olur

bu olay RCON registerından yapılıyor
önce RCON.7=1 diyorsun ve (Enable priority levels on interrupts) oluyor
artık her kullandığın interrupta öncelik verebiliyorsun.

mesela bu uart kesmesini high interrupt yaparsın
ama basit bir timer vardır onu low yaparsın
eğer çok interrupt yoksa sadece serial varsa bence bunlara gerek yok.

mesela diyelim timer1 high interrupt yapıcaz
IPR1.0=1 (TMR1IP: TMR1 Overflow Interrupt Priority bit)
bu sıfır ise low interrupt oluyor (yani düşük seviyeli interrupt)

uart da aynı registerdaymış
RC1IP: EUSART1 Receive Interrupt Priority bit
IPR1.5=1 dersen eusart 1 alma int high seviyede oluyor

TX1IP: EUSART1 Transmit Interrupt Priority bit
IPR1.4=1 dersen usart 1 gönderim int high oluyor..

ama dediğim gibi bu durum çok interrupt kullanıyorsan sana fayda sağlar.
2 tane serial
3 tane timer
2 tane ccp
zaten o zaman işin oldukça zor


mustafa_cmbz

Benim yapmak istediim kısaca şu şekilde hocam :

18f24k22 nin her iki usart girişini interupt ile dinlemek istiyorum.kısacası ama biraz açmak gerekirse:

2 tane kartım var biri nextion lcd nin olduğu ana kartım birde uzakta olan ve üzerinde 2 adet ds18b20 ve 1 adet dht22 olan bir kartım var.

Senaryo şöyle :

ana program koşarken nextion dan butonlara basıldığında bilgiyi almalıyım. ( buraya kadar sorun yok )

ama 2. usartıda interupt tan almak istersem yani:

ana programda atıyorum 2dk da bir sensör kartına basit bir 10 bilgisi gönderiyor sensör kartı bunu alınca sensörleri ölçüp tekrar ana karta ölçtüğü değerleri gönderiyor.

bunu interupt ile yapmak istiyorum ki ana programı kullanması daha kolay olsun.ana program içerisinde devam lı HSERın ile data beklemek istemiyorum.

yani kısacası 2. usartı ta intertup ile almak istiyorum ama aynı anda nextionda gelen bilgiyi de yine aynı şekilde interupt tan almam gerek.Öncelik bu durumda gerekir mi onuda bilmiyorum.

register ayarları konusunda yardımcı olabilirmisiniz ?


OG

Data gelmiş
Kesme oluşmuş
Kesme için gittiğin yerde

tekrar data beklemişsin, üstelik birisi için 2 byte beklemişsin

HSerIn [NEXTION_BILGI]
HSerIn2[ID,TORBA_SICAKLIK]

Kesmenin oluşmasına sebep data alınmış olması,
data gelmiş ki kesme oluşmuş.

Gelen data nerede?  RCREG içeriğinde, gelen datayı değişkenine almak için
NEXTION_BILGI = RCREGx  (x = usart 1 için 1, diğeri için 2 )
demelisin.
mantık böyle olmalı.

Diğer kesmeye giriş, çıkış, bayrak temizleme falan onlara bakmadım.
FORUMU İLGİLENDİREN KONULARA ÖM İLE CEVAP VERİLMEZ.

Hattusa

vardım ilim meclisine eyledim talep, meğer ilim en gerideymiş illa EDEP, illa EDEP <muhyiddin Arabi K.S.>

mustafa_cmbz

Alıntı yapılan: OG - 29 Kasım 2018, 03:42:13Kesmenin oluşmasına sebep data alınmış olması,
data gelmiş ki kesme oluşmuş.

Gelen data nerede?  RCREG içeriğinde, gelen datayı değişkenine almak için
NEXTION_BILGI = RCREGx  (x = usart 1 için 1, diğeri için 2 )
demelisin.
mantık böyle olmalı.


Hocam incelediğim örneklerde öyle idi.

Yani kesme içinde:
dediğiniz gibi kesme olduysa data gelmiştir onu değişkene çek diyorsun.

Peki benim örnekteki gibi 2 tane word gelecekse nasıl olacak onu anlamadım.

Yani Hserout [var1,var2] diye 2 word gönderdiğimde alıcı tarafta bu 2 word ü nasıl alacağım ?


OG

Öncelikle, usart kesmesi kullanılıyorsa, yani datanın alımı kesme ile sağlanıyor ise HSerIn gibi komutlar kullanılmaz.
Kesmeli calismada;
Yazılımın içinde bir şeyler birşeyler ile uğraşırken, usart donanımı datayı aldı ise, yazılımında o an yaptığın işten bağımsız olarak kendisi kesme rutinine zıplar,
o rutin içinde ne işler yapacağımızı da biz daha önceden belirlemişizdir.

Birden fazla data alınıyorsa (elbet genelde öyle olur) bir data sayac degiskeninden yardim alinir.
Gelen dataları depolamak icin de array (dizi) kullanılırsa islem kolaylasir.
Dizi'nin indexi de data sayac için atadigin degiskendir, ve her data alistan sonra +1 yapılıp sayac ilerletilir.

Yani kesme rutininde

gelen_data[sayac] = RCREG
Inc sayac  '' data alındıktan sonra sayac 1 artti


Gönderilen data da genelde 1'den fazladir ve bunlar ardi ardina gelir
Onemli olan bunlarin kacirilmadan alinmasidir.
USART kacirmaz ama gelen data usarttan cekilmez ise (RCREG okuyarak cekilmis olur) usart tasma hatasi verir.
Datayi kaciran USART donanimi degil, bizim yeterince hizli davranmamamiz olur.
Neler icin?
Kesme geldiginde kesme rutinine otomatik zipladik,
orada zaman kaybetmeden
-kesmeyi kapatma
-gereken bayraklari kontrol (tasma veya frame error gibi durumlar) ve temizleme
-error yok ise datayi RCREG'den cekme,
-tekrar kesmeyi acip o rutinden cikma
(kesmeyi kapatma ve acma otomatik yapiliyormu idi su an tam hatirlayamadim)
gibi, bunlar hic vakit kaybetmeden yapilmali.

Datayi gonderme hizina gore islemcin yeterince hizli ise bunlari problemsiz yaparsin
Veya,
Datayi gonderen taraf da zaten senin kendi yazilimin ise,
gonderimlerinin arasına 5-10 usn veya ne her kadar gerekli ise o kadar bekleme ilave edersin ki alis tarafinda bu isleri sıkıntısız yapabilesin.

Mesela 9600 hızda data gonderiyorsun ve islemcin 20MHz calisiyor, bu durumda alis genelde sorunsuz olur.

Emin olmadigim bir not daha;
Gecmis yillarda konusulmustu, delay rutinleri icinde isenve bu anlarda kesme olusursa delay'in bitmesini bekler gibi.
Emin degilim ama bu durumlarda data kacabilir, zaten usart ust uste data alip RCREG okunmadigi icin tasma hatasi verir (flag ile).
FORUMU İLGİLENDİREN KONULARA ÖM İLE CEVAP VERİLMEZ.

OG

Alıntı YapPeki benim örnekteki gibi 2 tane word gelecekse nasıl olacak onu anlamadım.
burayi atlamisim,
Word veya daha buyuk degiskenler de 8Nx gibi yapilarda byte byte gider, adı üstüne 8 bit yani byte.
Once en dusuk degerlikli byte gider, sonra daha yuksek degerlikli byte.

tx word yapida degisken olsun
Hserout [tx]
dersen aslinda sunu demissin anlamidadir
Hserout [tx.LowByte, tx.HighByte]

Alışda da
once tx.LowByte 'ı
sonra tx.HighByte'ı
alacagini bilerek islem yapmalisin.
FORUMU İLGİLENDİREN KONULARA ÖM İLE CEVAP VERİLMEZ.

Hattusa

OG ustam,usart alımında biz dataları gelen
  • =RCREG olarak çektiğimizi belirtmişsiniz,gelecek olan datanın adedini X belirliyor yani kaç byte olduğunu bilemiyoruz, bunu protonda belirleyebilirmiyiz?
yani java da şöyle bir örnek var;

 for (int i = 0; i < b.length; i++) {
                            deger[i] = b[i] & 0xff;    //convert to int
                        }

burada b.length gelen datanın byte cinsinden adedini belirtmekte, protonda gelen datanın adedini nasıl biliriz? yada nasıl yapabiliriz?


vardım ilim meclisine eyledim talep, meğer ilim en gerideymiş illa EDEP, illa EDEP <muhyiddin Arabi K.S.>