avatar_ete

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

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

ete

Portb kesmesinden sonra ikinci bir timer çalıştırıp 500us lik süreyi geçirmek gerekir.
Kesme içinde adc okunanbilmesi gerekir. Hiç denemek fırsatım olmadı ama olması gerek diye düşünüyorum. Sorun oluyorsa adc okumayı komutla değil register leri set ederek yapmak gerekebilir. Bunun için data sheet de adc okuma kısmını ve varsa orada örnek adc okuma kısmını (asm de) incelemen gerek. Başka bir yol aklıma gelmiyor maalesef.
Ete

Hattuşa

ETE hocam, demek istediğim RB0 kesmesini alt programımda nasıl algılatabilirim. yoksa 500uS luk beklemeyi timer kullanmadanda yapabiliyorum zira iki pulse arası 10mS olduğu için sıkıntı yratmıyor

ete

Kesme bayrağı kesme açık olmasada set edilir.  Onu kontrol ederek kesme b0 ın yukselen kenar kesme ortamına girdiğini anlayabilirsin.
Ete

Hattuşa

ETE hocam;

GIE =0
ANA PROGRAM:
gosub hesapgosub ekrana yaz
gosub buton işlemleri
goto alt program
Altprogram:
GIE =1
alt:
while INT0IF =1
portd.0 =1
delayus 500
adc,adin 1
delayus 20
portd.0 =0
wend
GIE =0
goto ANA PROGRAM

diyerek kesme bayrağına döngüyü kilitliyorum, ancak osilaskoptan baktığımda RB0 a uygulanan pulseler ile adc okuttuğum noktayı tutturamıyorum. yani ADC okuyor okumasına ama RB0 dan kesmeye göre değil, kafasına göre yapıyor

alt:
while INT0IF =1
portd.0 =1
delayus 500
adc,adin 1
delayus 20
portd.0 =0
wend
GIE =0
goto ANA PROGRAM

ete

While kesme bayrağı=1 diye döngü kurmak yerine. İf bayrak=1 ise then deyip altındakileri yazar ve goto demeden öncede bayrağı sıfırlarsın. Yoksa sistem çlışmaz.
Ete

Hattuşa

slm ete hocam;
yukarıda da eskiden uğraşmışım ama o zamanda başarılı olamadım sanırım, o projeye tekrar döndüm, yapmak istediğim şöyle bir şey nasıl yapabilirim acaba?
harici bir pulse kaynağım var (300 hertz civarı) bu pulse kaynağının yükselen kenarını yakalamak sonra 300 us bekleyip adc okutmak istiyorum, bu portb.0 kesmesini 50 kez yakalayıp, 300 us bekledikten sonra okuttuğum adc leri işlemek ve ekrana print yapmak için kesmeyi kapatmak istiyorum. işim bittiğinde tekrar kesmeyi açıp aynı şekilde 50 kez kesmeyi algılayarak baştaki gibi işlemlerime devam etmek istiyorum.
söylediğim şekliyle bir kod yazdım, ancak sorunum kesmeyi yakaladıktan sonra ki 300 usluk bekleme süresi şaşırıyor, şimdilik adc okutmak yerine bir pini hig-low yaptım,  yazdığım kodda 10 kez yapmak istedim ancak 30 un üzerinde gözüküo ve hiç sağlıklı değil.
Device 18F2520
Xtal 10
Config_Start
   OSC = HS'PLL ; HS oscillator, PLL enabled (Clock Frequency = 4 x FOSC1)
   FCMEN = OFF ; Fail-Safe Clock Monitor disabled
   IESO = OFF ; Oscillator Switchover mode disabled
   PWRT = OFF ; PWRT disabled
   BOREN = OFF ; Brown-out Reset disabled in hardware and software
   WDT = OFF ; WDT disabled (control is placed on the SWDTEN bit)
   MCLRE = On ; MCLR pin enabled; RE3 input pin disabled
   LPT1OSC = OFF ; Timer1 configured for higher power operation
   PBADEN = OFF ; PORTB<4:0> pins are configured as digital I/O on Reset
'   CCP2MX = PORTB ; CCP2 input/output is multiplexed with RB3
   STVREN = OFF ; Stack full/underflow will not cause Reset
   LVP = OFF ; Disabled
   XINST = OFF ; Instruction set extension and Indexed Addressing mode disabled (Legacy mode)
   Debug = OFF ; Background debugger disabled, RB6 and RB7 configured as general purpose I/O pins
Config_End
'Declare PLL_Req TRUE '40mhz
Declare CCP2_Pin=PORTB.3
All_Digital =0
TRISA =%00101111   :PORTA =0
TRISB =%00000001   :PORTB =0
TRISC =%00000000   :PORTC =0

Symbol TuNe =PORTA.5  :Input TuNe
Symbol T    =PORTB.7  :Output T
T =0

Declare LCD_DTPort =PORTC
Declare LCD_RSPin =PORTB.6
Declare LCD_ENPin =PORTB.4
Declare LCD_RWPin =PORTB.5
Declare LCD_CS1Pin =PORTB.1
Declare LCD_CS2Pin =PORTB.2
Declare LCD_Type =GRAPHIC
Internal_Font = On
'GLCD_EXTERNAL_PRINT = PPRINT
Declare GLCD_STROBE_DELAY =100
Cls
DelayMS 100

INTCON2 =%11000000 'portb_pullups OFF
ADCON0 =%00000011
ADCON1 =%00001011  '4 kanal aktif
ADCON2.7 =1
'ADCON2 =%10100010
Declare Adin_Res 10         ' 10-bit result required
Declare Adin_Tad FRC        ' RC OSC chosen
Declare Adin_Stime 10      ' Allow 50us sample time

Symbol INT0IF = INTCON.1 ' INT0 External Interrupt Flag
Symbol INT0IE = INTCON.4 ' INT0 External Interrupt Enable
Symbol GIE = INTCON.7    ' Global Interrupt Enable
GIE =1
INT0IE =1
GIE =0


Dim SaYaC As Byte
Dim sAy As Byte
Dim A As Word
Dim TeMp As Byte

A =10
SaYaC =0
sAy =0
On_Hardware_Interrupt GoTo KESME
GIE =1



MaIn:

Print At 1,1,"MERHABA"
DelayMS 100
GIE =1
aLt:
If SaYaC =1 Then
    DelayUS 600
    T=1
    DelayUS 50
    T =0
    EndIf
If SaYaC =2 Then
    DelayUS 600
   T=1
    DelayUS 50
    T =0
   
    EndIf 
If SaYaC =3 Then
    DelayUS 600
   T=1
    DelayUS 50
    T =0
    EndIf
If SaYaC =4 Then
    DelayUS 600
    T=1
    DelayUS 50
    T =0
    EndIf
If SaYaC =5 Then
    DelayUS 600
   T=1
    DelayUS 50
    T =0
    EndIf
If SaYaC =6 Then
    DelayUS 600
   T=1
    DelayUS 50
    T =0
    EndIf
If SaYaC =7 Then
    DelayUS 600
   T=1
    DelayUS 50
    T =0
    EndIf 
If SaYaC =8 Then
    DelayUS 600
   T=1
    DelayUS 50
    T =0
    EndIf 
If SaYaC =9 Then
    DelayUS 600
    T=1
    DelayUS 50
    T =0
    EndIf
If SaYaC =10 Then
    DelayUS 600
    T=1
    DelayUS 50
    T =0
    EndIf
       
   
If SaYaC =11 Then  SaYaC =0 :GIE =0 :GoTo MaIn                   
GoTo aLt
KESME:
        Context Save
'        If INT0IF =1 Then
'        If SaYaC <10 Then
        Inc SaYaC
        INT0IF =0
'        Else
'        SaYaC =0
'       GoTo cIk
'        EndIf
'        EndIf
       
'        Inc SaYaC
'        If SaYaC =20 Then SaYaC =0 '2,580 mS =348 hertz
       
'cIk:
'TeMp =RCREG 
Context Restore     
    End
   
Include "FONT.INC"   



bunu başka nasıl yapabilirim.bir çözüm önerisi hocam

ete

3 şekilde yapılabilir gibi geliyor bana.
1. Int0 kesmesi açılır   Kesme oluşunca poz=1 yapılır ayrıca Inc  sayac yapılır kesmeden çıkılır
Ana program kısmında poz=1 ise delayus 300 verilip ardından adc okunur ve okunan değer gerekirse dizi değişkenine atılır. Poz=0 yapılır.
Ana program bölümünde ;
If sayac=50 ise Intcon=0 yapılarak kesme ler iptal edilir. Sayac=0 yapılır ve diğer işler yapıldıktan sonra kesmeler açılıraka aynı işler tekrar edilir.
Sayac sayısının 50 ye ulaşması durumunda kesme iptali kesme içinde yapılırsa dahanuygun olur kanısındayım.

2 ci şekilde her kesme oluştuğunda kesme içinde 300 us bekleyi adc okunur ve dizi değişkenine değer atıldıktan sonra kesmeden çıkılır. Bu bir alternatif şekil ama pek uygun gelmedi bana zira 300 us lik süre kesme süresinden çalınarak yapılıyor. Gerçi frekans kaynağı çalışmasını durdurmayacak ama en iyisi bunuda denemek sorun olmaz ise kullanırsın.
Sayac 50 ise ana program kısmında veya kesme içinde kesmeyi kapatıp ekran billgileri verip yeniden başlarsın.

3. Cü şekilde ise kesme içinde tmr0 kesmesini 300us ye ye kurup aktif edersin tmr0 kesmesi oluşunca poz=1 deyip tmr0 kesmesini kapatırsın. Ana program kısmında poz=1 ise adc okursun. Sayac kontrolü aynen diğerlerindeki gibi. Burada yalnızca zamanı timr0 ile tutmuş olacaksın.
Aklıma gelenler bunlar.
Ete

Hattuşa

peki ete hocam 1. yöntem mantıklı geldi ve denememde istediğim nokta tutuyor gibi artık gerçek devrede denemek lazım, ancak algoritma olarak bir nokta da daha tıkandım. şöyle ki;
diyelim ki iki kesme arasında gecen süre 10mS ve benim işlemim 2 ms sürüyor, geriye kalıyor 8mS boşluk ve bu boşlukta bir işlem yapmak istemiyorum, yani ekteki resimde dediğiniz gibi yapıp kesme anını yakaladım, 300 bekledim ve bir pini 100uS süre ile açıp kapadım. işte bu açıp kapama işlemi tekrarlıyor.ben tekrarlamasını istemiyorum  ;D
hocam yani düşünüyorum da o pin yerine adc okutması olsa istediğim noktadan adc yi okuttuğumda, okuma işlemi tekrarlayacağı için, istediğim noktadan okutmamış olacağım, yanlışmıyım. biraz kafam durdu özür dilerim.

ete

İşlemi tekrarlıyor demekle neyi kast ettin pek anlamadım doğrusu. İstediğini elde ettiğine göre olmayan nedir?  Çok güzel izah etmişsin aslında zamanlama harika her şey uyuyor uymayan şu senin tekrarlama dediğin olay nedir merak ettim.  Ama görünen oki başka bir çare gözükmüyor gibi geliyor bana.
Ete

Hattuşa

#54
hocam şöyle ki
If SaYaC =6 Then
     If poz =1 Then DelayUS 600 :poz =0
    T=1
    DelayUS 100
    T=0
   
    EndIf

burada T=1
delayus 100
T=0
diye pini açıp kapatıyorum ya, bunu diğer kesme gelinceye kadar tekrar ediyor. yani istediğim
kesme oluştu, bi şekilde 300 uS bekledim ve adc mi okuttum, bundan sonra bu adc okuma işlemi tekrar etmesin. yukarıdaki örnekte adc okuma yerine T adlı pini high ve low yaptım, işte bu T pininin high ve low kısmı tekrarlıyor, ta ki diğer kesme gelene kadar,ben tekrarlamasını istemiyorum.  ;D


EDIT:
tekrar özür dilerim hocam ya, mevsimsel sanırım biraz psikolojimiz bozuk bu sıralar mazur görün.
dediğim sorunu aştım, şöyle ki
If SaYaC =6 Then
    If poz =1 Then
    DelayUS 600
    T=1
    DelayUS 100
    T=0
    poz =0
    EndIf
        EndIf

yani poz =1 konumunun içine aldım yapmak istediğim şeyi sorun çözüldü ;)
tekrar özür dilerim.



ete

Şimdi anladım ne olduğunu. Bu gibi durumlarda bir işaret değişkeni kullanılması işi çözer. Zaten sende düşünüp öyle çözmüşsün.
KOlay Gelsin
Ete

est32

Hocam müsaadeniz olursa bir soru da ben sorsam.
Bir kayan yazı devresi düşünüyorum, hatta tasarımı ile de uğraştım isiste ve bord üzerinde sorunları olsa da iyi kötü çalıştırmayı başardım.
Ben bu devreye kumanda ve saat de eklemeyi düşünüyorum, hem malzeme hem de kod tasarrufu için saati timer1 ile çalıştıracağım(dışarıdan 32.768 kristal bağlayarak).
Timer 1'i RB0 kesmesi ile kalibre etmeyi düşünüyorum. Şu şekilde;

ucuzlukçularda 1 tl ye masa saatleri satılıyor ve bu saatlerin içinde 1Hz osilatör devresi mevcut. Bazıları çok stabil çalışıyor. Onlardan bir tanesi ile RB0 kesmesi kullanarak timer 1'i kalibre edebileceğimi düşünüyorum.
Acaba işlemler sırasındaki komut gecikmeleri(74hc595 ler var, programı yavaşlatıyor) ve bekleme komutları timer1'i etkiler, saatte geri kalma sorunu yaşar mıyım?

PCB çizmeden önce görüşünüzü almak istedim, çünkü tasarımı etkileyecek bir durum. Aslında yazılımda sormak istediğim bazı noktalar var ama daha önce söylemiştiniz bir daha kayan yazı sorusu görmek istemiyorum diye, o nedenle soramıyorum :)

ete

Birincisi saatler içindeki 1 Hz lik OSC bildiğin şekilde çalışmıyor. BU osc saat motorunu sürdüğü için Bir ters bir düz çıkış verir.
Dolayısıyla bunu kullanınca 2Hz lik bir osc elde etmiş olacaksın. Bir aralar bunu kullanarak bir şeyler yapmaya çalışmıştım. Oradan hatırlıyorum. İkincisi şayet kaydırma devrende pause ler ve kesme kullanımı var ise birinden birisi aksayacaktır mutlaka.
Başka bir çözüm ara bana kalırsa. Bence sisteme 1 DS1307 ilave etmek daha uygun gözüküyor.

Ete

est32

Hocam daha önce kullandım bunlardan. Acemilik zamanımda saat yaptım, aslında kötü bir tasarımdı sorunları vardı ama sonuçta senelerdir çalışıyor. Yani çalışma mantığını biliyorum ve 2 adet bc547 ile sürüp 1hz'e indirerek, RB0 kesmesi için kullanmıştım. Hala daha bu saati kullanıyorum odamda.

Sonuçta siz benden çok çok daha tecrübelisiniz, tavsiyenize uyarak bundan vazgeçtim. Peki hocam bu masa saatlerinin osilatörlerini ayrı olarak satın alabileceğim bir yer var mı? Ebay da aradım(1 hz osc, watch osc, clock oscillator...gibi) ben bulamadım. Bunların ds1307 den ucuz olacağını düşünüyorum. Hem kesme dışında iletişim için yazılıma da gerek yok.

ete

Dediğin yöntemle hassas bir saat yapılabileceğine kesinlikle inanmıyorum. İşin içine birde işlmeci frekansı giriyor. Onuda hassas bir şekilde tutturman gerekiyor. RTC kullandığın zaman osc sini hassas yapar yada ayarlarsan işin bitmiştir. ELinde hassas bir saat var demektir. Üstelik voltaj kesilsede ayarlarını yitirmeyen bir saat. Saat işinde fayda/masraf oranına bakmak gerekir.
Bence hiç bir şey RTC nin eline su dökemez. Bu nedenle benim fikrim RTC kullanman yönünde.  Yok ben kendi fikrimi uygularım diyorsan aramaya devam et. Ama unutma o saatlerin hiç birisi sıfır hata ile çalışmıyor. Ama bir RTC yi sıfır hata ile çalıştırabilirsin yada sıfıra en yakın hata payı ile çalıştırabilirsin. Bu alete kristal alırken Load kapasite 12,5pF , Frekans toleransı 10 +- 10ppm, çalışma sıcaklık aralığı -40 ile +80 derece arası seçilerek alınırsa saat son derece kararlı çalışır ve doğru gider.
Yada ,TCO denilen sıcaklık kompanizasyonu yapılmış hazır osilatör alırsanız saat birer bir doğru çalışır.

Ete

Powered by EzPortal