avatar_ete

PIC Basic Ders-06 (Kesme (INTERRUPT) Kullanımı)

Başlatan ete, 28 Ağustos 2011, 16:13:09

ete

Hesaplamayı öğrendikçe sende bu hesapları daha güzel yapmaya başladın bile. Zamanla sende hangisini kullanacağını gayet iyi öğrenebilirsin.
Ben yaptığım hesaplarda 1000'e en yakın değeri verecek hesabı kullanırım. Hiç bir zaman bu değerler tutmaz aslında ufak tefek oynamalar komut gecikmelerinden dolayı hesabı şaşırtır. Bu nedenle çok fazla kafanı takma derim.
Saat yaptın diyelim kesme içinde yalnızca SAYAC=SAYA+1 dersen hesapların tutar. Ama saat yapıyorsan orada birde ;
IF SAYAC=61 then SN=SN+1 da demen gerekiyor. Bu işlem sana komut gecikmesi yarattırır. Onunlada bitmiyor. IF SN=60 then SN=0 : DAK=DAK+1 de demengerekiyor bunlarda komut gecikmelerini artırıcı unsurlar. Bu nedenle dikkat edersen saat programlarında sayacı 61 e kadar değilde bazen 58 e kadar saydırırım bu yaklaşık zamanı tutturmamı sağlar.
Bu nedenle kesme ile saat yapmak mantıklı değil oluyor ama hassas bir saat olmuyor. KOmut gecikmesi tutarını bilsen ona uygun timer on yükleme değeri verebilirsin ama komut gecikmelerini de her zaman hassas hesaplamak mümkün olamıyor maalesef.

Ete

Burak

Teşekkürler Hocam .. Sanırım vakit kaybetmeden RTC'lere adım atmak şart ..
Ω Gens Una Sumus Ω

mustafakaragol

HPWM komutu kullandığımda rb0 kesmesi aktif olmuyor. sebebi nedir acaba.

ete

Bir sebebi olduğunu sanmıyorum. Bir sorun vardır. Çalışması gerekir doğru kuruldu ise.
Ete


mustafakaragol

öğrencilere cizgi izleyen robot yaptırmaya calışıyoruz. 
TRISB=%11111111:TRISC=%00000000:TRISD=%11111111
PORTB=0:PORTC=0:PORTD=0
ENG VAR PORTB.0
SOL1 VAR PORTD.1
SOL2 VAR PORTD.2
SOL3 VAR PORTD.3
SOL4 VAR PORTD.4
SOL5 VAR PORTD.5
ORTA VAR PORTD.6
SAG7 VAR PORTD.7
SAG8 VAR PORTB.1
SAG9 VAR PORTB.2
SAG10 VAR PORTB.3
SAG11 VAR PORTB.4
SOLMG VAR PORTC.0
SOLMI VAR PORTC.1
SAGMI VAR PORTC.2
SAGMG VAR PORTC.3
HESAP VAR WORD
'ADC İÇİN AYARI
DEFINE OSC 4
DEFINE ADC_BITS 10
DEFINE ADC_CLOCK 1
DEFINE ADC_SAMPLEUS 3
ADCON1=7
'HPWM İÇİN AYAR
DEFINE CCP1_REG PORTC
DEFINE CCP2_REG PORTC
DEFINE CCP1_BIT2
DEFINE CCP2_BIT1
    CCP1CON.2=1
    CCP1CON.3=1
    CCP2CON.2=1
    CCP2CON.3=1
'-------------------------------------
ON INTERRUPT GOTO KESME 'kesme oluşursa KESME adlı etikete git.
OPTION_REG=%11000000 'düşen kenarda kesme olması için
INTCON=%10010000 'Tüm  Kesmeler aktif ve RB0/INT kesmesi aktif
BASLA:
    HESAP=(ORTA*11)+(SOL1*1)
    SELECT CASE HESAP
    CASE 11
    HPWM 2,127,1000:HPWM 1,127,1000
    SOLMG=0:SAGMG=0
    CASE 1
    CCP1CON.2=0
    CCP1CON.3=0
    CCP2CON.2=0
    CCP2CON.3=0
    SOLMI=1:SAGMI=1
    SOLMG=0:SAGMG=0
    CASE ELSE
    END SELECT         
    GOTO BASLA
'kesme olmadığı müddetce proğram basla-goto basla arasında normal calısır.
DISABLE'yeniden kesme  oluşması önleniyor
KESME:'program buraya  geldiginde kesme oluşmus demektir.
    PORTD=%00000000'portd'nin çalışması durduruluyor.
    WHILE ENG=1 'tuşa basılıysa eger
    SOLMI=0:SAGMI=0
    SOLMG=0:SAGMG=0   'led'i yak
    WEND 'tuş bırakılıncaya kadar bekle     
    INTCON.1=0 'RB0/INT Bayragı (flag) silindi.
    RESUME 'geldigin yere dön
    ENABLE 'kesmeler yeniden  aktif.
END

örnek olarak yazdığımız komut yuarıdaki gibi. bu komutta hpwm komutu kullanmasak engel sensörü 1 olunca kesme devreye girerek motorları durduruyor. hpwm li kısımda engel sensörü 1 olsada motorlar çalışmaya devam ediyor.  hpwm komutu çalışırkede engel gördğünde motorların durması gerekirdi. sorunumuz budur.
cevap için şimdiden yeşekkür ediyoruz.

Hattuşa

slm ete hocam bişey sormak istiyorum.
bir sinyalden gelen pulseyi portb.0 kesmesi ile yakalayarak belli bir noktadan adc okutması yapıyorum (sizin yardımınızla)
şimdi iki veya üç ayrı pulsem var bu pulselerin yükselen kenarlarını portb4-7 change kesmesi ile yakalayarak istediğim noktadan adc okuma imkanım olabilir mi?
bir diğer sorum ise;
portb4-7 kesmesi ile iki ayrı noktadan yakaladığım kenara göre kesme içinden goto ile çıkabilirmiyim, az önce isisde denedim sanırım kesme içinden dallanma işinde stack taşması oluyor bunu nasıl bir algoritma ile aşarım,

usta bu stack taşmaları bizide taşıracak yakında

ete

Kesme içinden kesem dışına goto ile gidemezsin. Gidersen stack bozulur. Bunu yapmanın en iyi yolu pinter (işaretçi kullanmaktır)
Kesme içinde bir yere gidecek isen gitmeyeceksin ama o anda GIT=1 diyeceksin.
Kesmeden çıkınca,
IF GIT=1 then, 
  GIT=0
  GOTO GIDILECEKYER
ENDIF
şeklinde halledeceksin.

PORTB Change kesmesi ilgili pinlerdeki değişikliği algılar. Sen yükselen kenarı algılatmak istiyorsan gerek programa başlarken ve gerekse kesme oluştuğunda kesmeden çıkmadan evvel bu pinleri bir kere okutursun (DURUM=PORTB & %11110000)  bu okuma esnasında ilgili pinler low konumda iseler ve sonradan herhangi brisi HIGH olmuş ise hemen kesme oluşur. Bu nedenle illaki yükselen kenarda kesme olacak ise mutlaka kesmeden çıkmadan evvel ilgli pinlerin low olduklarından emin olduktan sonra port durumunu okumak en doğrusudur.

Ete

Hattuşa

hocam benim derdim portb.0 kesmesi benim devrede 2 adet lazım oldu yani 2 farklı sinyalden gelen yükselen 10uS luk sinyali yakalayıp çok hassas bir zaman içerisinde başka bir sinyalden adc okutmak istiyorum. bu sizce portb4-7 change kesmesi ile mümkünmüdür

ete

Neden olmasınki, zatenbu amaçla yapmışlar bu portb_Change kesmesini.
Aklın yatmıyorsa 18F serisinden bir şey kullan onlarda INT0 ve INT1 şeklinde iki tane var zaten.

Ete

Hattuşa

#84
Alıntı yapılan: ete - 22 Şubat 2014, 10:57:41
Neden olmasınki, zatenbu amaçla yapmışlar bu portb_Change kesmesini.
Aklın yatmıyorsa 18F serisinden bir şey kullan onlarda INT0 ve INT1 şeklinde iki tane var zaten.

Ete


hocam bakmakla görmek arasında büyük fark var, ben 18F4520 kullanıyorum ve siz şimdi söyleyince farkettim INT0, INT1, INT2 var bunda,, yani 3 adet mevcut ben 2 tanesini kullansam yeter.
şimdi 2 adet kesmeyi nasıl kullanmalıyım?
yani  bu int1 ve int2 girişlerinde kesme içerisinde nasıl adlandırmalıyım?

edit:
datasheette  intcon3 registerinde int1 için bit3 ve bit0 ile açılıp falg temizleme yapılıyor ancak kesme içinde hangi bayrağı temizleyeceğimi veya hangisinden kesme oluştuğunu nasıl bileceğim. hocam bazen ya panikten yada başka bişeyden basit yerlerde tıkanıyorum.

Hattuşa

#85
hocam teşekkür ederim istediğim gibi oldu nihayet ben 1 hafta boşuna tırmalamışım yalnız bu tırmalayış bilgi yetersizliği ve dikkatsizliktenmiş.

ben INT1 ve INT2 girişlerini kullandım isisde gayet güzel çalışıyor, şimdi uygulamaya gecebilirim. kodu şu şekilde yazdım, belki ihtiyac olanlara da örnek teşkil eder.

kesme ayarları;
Symbol gIe  =INTCON.7
Symbol InT1Ie =INTCON3.3  'int1 kesmesi aktif
Symbol InT2Ie =INTCON3.4  'İnt2 kesmesi aktif
Symbol InT2If =INTCON3.1  'int2 bayrak biti
Symbol InT1If =INTCON3.0   'int1 bayrak biti
Symbol InT1Ip =INTCON3.6   'int1 yükselen kenarı yakala
Symbol InT2Ip =INTCON3.7   'int2 yükselen kenarı yakala
gIe =1
gIe =0
InT1Ie =1
InT1If =0
InT1Ie =1
InT1If =0
InT1Ip =1
InT2Ip =1


kesme rutini;
 KeSMe:
        Context Save
        If InT1If =1 Then gIt0 =1
        If InT2If =1 Then GIt1 =1
        InT1If =0
        InT2If =0
        Context Restore


alt program;

 gIe =1 
On_Hardware_Interrupt GoTo KeSMe
bAsLa:

If gIt0 =1 Then BaK0
If GIt1 =1 Then BaK1
GoTo bAsLa

BaK0:
gIt0 =0
Toggle lEd1
GoTo bAsLa

BaK1:
GIt1 =0
Toggle LeD2
GoTo bAsLa

ete

En baştan işlemcinin data sheet'ine baksan bukadar boşuna beklemeyecektin.

Her zaman söylüyorum Data sheet'e bakma alışkanlığını edinin d,ye boşuna söylemiyorum.
Her şeyi kafada tutamazsınız. O yüzden data sheet başvurulacak ilke döküman olmalı.
Yine her zaman söylüyorum. İlla lisan bilmek gerekmiyor. Mantık yürüteceksin. Önce işlemci bacaklarına data sheet de yada isis de bakacaksın. INT bacakları birden fazla ise ki INT daima PORTB.0 kesme bacağıdır. Fazlası var ise mutlaka INT0 - INT1-INT2 diye gidiyor o zaman hemen INTCON registerine bakacaksın. Orada zaten bütün detay görülüyor.

Ete

Hattuşa

Alıntı yapılan: ete - 22 Şubat 2014, 13:08:42
En baştan işlemcinin data sheet'ine baksan bukadar boşuna beklemeyecektin.

Her zaman söylüyorum Data sheet'e bakma alışkanlığını edinin d,ye boşuna söylemiyorum.
Her şeyi kafada tutamazsınız. O yüzden data sheet başvurulacak ilke döküman olmalı.
Yine her zaman söylüyorum. İlla lisan bilmek gerekmiyor. Mantık yürüteceksin. Önce işlemci bacaklarına data sheet de yada isis de bakacaksın. INT bacakları birden fazla ise ki INT daima PORTB.0 kesme bacağıdır. Fazlası var ise mutlaka INT0 - INT1-INT2 diye gidiyor o zaman hemen INTCON registerine bakacaksın. Orada zaten bütün detay görülüyor.

Ete



haklısınız hocam benim en büyük kusurum bu, yani bir devre tasarlamaya başlayınca hemen heyecana kapılıyorum, yeterince araştırma ve inceleme yapmadan devreyi dizayn işlemine geçiyorum, tabi devamında başlıyor tırmalama vaziyetleri, oysa her detayı inceleyip tasarı aşamasını en sona bıraksam sorunsuz işler yürüyecek.

birde hocam yukarıdaki kodda;
18F4520 de 3 adet (INT0,INT1 ve INT2) kesmesi var ve ben sadece INT1 ve INT2 yi kullandım yani INT0 ı pas geçtim ya (o pini çıkış olarak kullandım) bu durum sıkıntı yaratırmı?
bunu şunun için soruyorum malum ADC okuma işleminde böylesi bir kural var malum, yani bir adc okutacaksak adin0 i atlayıp adin1 i kullanamadığımız gibi INT kesmesinde de bu durum söz konusu olabilir mi?

ete

#88
O dediğin ADC kuralıda geçerli değil. İstediğini kullanır istediğini kullanmazsın.
INT konusunda da zorunluluk yok istediğini kullanırsın.
Sorun, sadece bazı piclerde gurup seçimi vardır. Bazılarında (genelde ANSEL registeri olanlarda) ise istediğin pini kullanırsın.
Guurp seçimine örnek mesela 16F877 . Bunda gurup seçimi var Data sheet deki tablodan görebilirsin.

Ete

pwm3434

ete  hocam  bu  kodda rb0  kesmesinin  düşen  kenar  yükselen  kenar  damı   olacağını  OPTION_REG  kaydedicisinden  yapılıyor  anladım  ve  aşağıdaki kodda da   OPTION_REG  6.  biti  0  yapıldığı  için  düşen  kenarda  kesme  oluşacak.  peki  pullup  direnci ayarının  düşen yükselen kenar olan  6.bitin  0 yada  1  olması  ile  alakası  varmıdır.

@ DEVICE pic16F628 'işlemci 16F628
@ DEVICE pic16F628, WDT_on 'Watch Dog timer açık
@ DEVICE pic16F628, PWRT_ON 'Power on timer açık
@ DEVICE pic16F628, PROTECT_OFF 'Kod Koruma kapalı
@ DEVICE pic16F628, MCLR_OFF 'MCLR pini kullanılmıyor.
@ DEVICE pic16F628, INTRC_OSC_NOCLKOUT 'Dahili osilatör kullanılacak
'-----------------------------------------------------------------
ON INTERRUPT GoTo KESME 'kesme oluşursa KESME adlı etikete git.
OPTION_REG=%0000000 'dahili Pull up dirençleri aktif edildi ayrıca pullup direncine gerek yok.
INTCON=%10010000 'Tüm Kesmeler aktif ve RB0/INT kesmesi aktif
TRISB=%00000001 'PortB.0 giriş diğerleri çıkış yapıldı.
TRISA=%00000000 'A portu tamamı çıkış yapıldı.
CMCON=7 '16F628 de komparatör pinleri iptal hepsi giriş çıkış
'-----------------------------------------------------------------
SYMBOL TUS=PORTB.0
SYMBOL LED=PORTA.0
'-------------------------------------------------------------------
BASLA: 'Ana program bölümünde program bir şey yapmayacak
pauseus 100 'kesme oluşmadığı müddetçe program
goto basla ' bu satırlar arasında dolaşır
DISABLE 'yeniden kesme oluşması önleniyor
KESME: 'program buraya geldiğinde kesme oluşmuş demektir.
TOGGLE LED 'LED konum değiştirdi
PAUSE 1
INTCON.1=0 'RB0/INT Bayrağı (flag) silindi.
Resume 'geldiğin yere dön
Enable 'kesmeler yeniden aktif.
End
'-------------------------------------------------------------------------------------------------

Powered by EzPortal