Main fonkisoynundaki delay ve interrupt timer

Başlatan mustafay, 25 Mayıs 2010, 16:02:28

Salih

Alıntı yapılan: bulut_01 - 25 Haziran 2010, 14:51:07
pbp konusunda yanılıyorsun arkadasım ınt ile kare dalga elde  ettıgım pause gecikme yaptıgımda kesme ana döngüsünde int iptal olmadıgı resımde ve kodda ıspatıdır

While içinde 1000 ms geçikme yapıp tekrar denermisin.

radres

Alıntı yapılan: salih - 25 Haziran 2010, 16:31:47
Alıntı yapılan: bulut_01 - 25 Haziran 2010, 14:51:07
pbp konusunda yanılıyorsun arkadasım ınt ile kare dalga elde  ettıgım pause gecikme yaptıgımda kesme ana döngüsünde int iptal olmadıgı resımde ve kodda ıspatıdır

While içinde 1000 ms geçikme yapıp tekrar denermisin.

Biraz uzun süre denemek lazım doğru...

50Cal

#32
Arkadaşlar, JKramer'in anlatmaya çalıştığı şey yanlış anlaşılmış.
-Eğer programda sadece main fonk. altında delay_ms kullanılırsa, bu dela_ms fonksiyonu işletilirken kesmeler aktif durumda ve program kesmeye girebiliyor.
-Eğer timer kesmesinin içinde de delay_ms kullanılırsa, program dela komutunu işletirken kesmeleri sallamıyor.

Aşağıdaki 2 program arasındaki tek fark kesmenin içerisinde 1 ms gecikme olup olmamasıdır.

1.durum:sadece ana fonksiyonda delay_ms kullandım (delay_ms(100)) (sinyal periyodunu 8ms olarak ayarladım)
görüntüden de görüldüğü üzere sinyal periyodu 8ms, düzgün çalışıyor.
http://img153.imageshack.us/img153/7140/t8ms.png


2.durum: kesmenin içerisine de delay ms ekledim(delay_ms(1)) (sinyal periyodu yine 8 ms olarak ayarlanmış durumda)
fakat görüldüğü gibi ana fonksiyon içerisindeki 100 ms lik gecikmeye girildiğinde kesmeye gidilmiyor ve bu yüzden sinyal periyodu 200ms oluyor.
http://img248.imageshack.us/img248/4696/t200ms.png

#include <16F877A.h>
//#Device ADC=10
#FUSES NOWDT, HS,PUT, NOPROTECT, NOBROWNOUT, NOLVP, NOCPD
#use delay(clock=8000000)

#INT_TIMER0 
void tmr0()
{
set_timer0(6);
output_toggle(Pin_B1);
//delay_ms(1);              // 2 PROGRAM ARASINDAKİ TEK FARK BU SATIRIN OLUP OLMAMASIDIR..
}
void main(){

setup_psp(PSP_DISABLED); 
setup_spi(SPI_SS_DISABLED);
setup_timer_0(RTCC_INTERNAL | RTCC_DIV_32); //sinyal periyodu 8ms !!!
setup_timer_1(T1_DISABLED);  
setup_timer_2(T2_DISABLED,0,1);  
setup_CCP1(CCP_OFF); 
setup_CCP2(CCP_OFF); 
enable_interrupts(GLOBAL);
enable_interrupts(INT_TIMER0);

while(true){
output_toggle(Pin_B0);
delay_ms(100);
}
}


Konuyu başlatanlara ve JKramer'e teşekkürler, öğrenmeseydim bu durum, birgün gelir saç baş yoldururdu.. :)

picmanya

ben adc sorumu burda sormakla hata yaptım galiba buna bir konu açmak en iyisi sırf başlıkdan dolayı bu konuya girmeyen olabilir.

radres

50Cal, bilgiler için teşekkürler. Peki 2. programında void main() komutunun üstüne bir kez daha #use delay(clock=8000000) yazınca sinyal çıkışının durumunu söyleyebilirmisin?

Erol YILMAZ

Alıntı yapılan: picmanya - 25 Haziran 2010, 16:04:48
anladım.
fırçalı dc 12 volt motor kontrolünde şase ile H köprü arasına bağlı 0,033R 4W. şönt bir direnç üzerinden akım okumaya çalışıyorum.devre donanımsal olarak gayet güzel çalışıyor sorun yok yalnız C programında işin içinden henüz çıkamadığım bir kısım var.

adc kesmesinin çalışma şartlarını bu yazılım için sormuştum.ama umduğumu bulamadım.

sorunum şöyle;
motor normalde 12 volt dc altında 1,5 amper çekiyor.
ama motor ilk kez enerjilendiğinde yada düşük bir devirde çalışıyorken birden daha yüksek devire geçildiğinde zannediyorum motor noramal akımının çok üstünü asılıyorki ben programda aşırı akım bilgisini okuyup motoru durduruyorum.

bu tür fırçalı dc motor akımını adc pini üzerinden 0...5 volt aralığında okuyan varmı daha önce?
bu işin yazılımı nasıl yapılıyor mantığı nasıl dır bilgi verebilirmi?


Merhaba;

1. Akımı okurken 2 veya katları kadar (4.8.16.32...) defa okuyup ortalamasını alırsan anlık değişimlerden sıyrılırsın.

2. ADC pini ile şase arasına 100nF koymayı denermisin ?

3. Yine de yeterli gelmiyorsa Akım sinyalini skopla inceleyerek bi algoritma düşünebilirsin...

4. Halen olmadı ve bu ticari bir uygulama ise sana "özel yardım" da bulunmam gerekir.

Salih

#36
Alıntı yapılan: radres - 25 Haziran 2010, 16:57:28
50Cal, bilgiler için teşekkürler. Peki 2. programında void main() komutunun üstüne bir kez daha #use delay(clock=8000000) yazınca sinyal çıkışının durumunu söyleyebilirmisin?
Dediğin gibi denedim Main() satırının üstüne
#use delay(clock=8000000)
ifadesini tekrar yazınca problem hal oluyor. Sinyal tekrar 8 ms periyotlu çalışıyor. içinde Delay_ms(1)
kullanılsa bile.
Anladığım kadarıyla her
#use delay(clock=8000000)
satırından sonra CCS farklı bir gecikme alt yordamı oluşturuyor.

50Cal

Alıntı yapılan: radres - 25 Haziran 2010, 16:57:28
50Cal, bilgiler için teşekkürler. Peki 2. programında void main() komutunun üstüne bir kez daha #use delay(clock=8000000) yazınca sinyal çıkışının durumunu söyleyebilirmisin?
Evet, main'in üstüne de #use delay(clock=8000000) satırını ekleyince sorun ortadan kalkıyor..(T=8ms)

radres

50Cal denemen için teşekkürler. Tartışmanın sonuçlarını aşağıya özetlemeye çalışayım.

1- CCS C'de sadece ana programda delay komutları kullanılıyorsa (kesme fonksiyonlarında kullanılmıyorsa) delay komutu icra edilirken kesme kelirse program kesmeye gidiyor. Kesme dönüşü delay komutu kaldığı süreden devam ediyor (Bu nedenle delay komutu icra edilirken kesme meydana gelirse delay komutu ile belirtilen süre kesme düresi kadar uzar)

2- CCS C'de kesme fonksiyonları içinde delay komutları kullanılırsa ana programdaki delay komutları çalışırken herhangi bir kesme gelirse program kesmeye gitmiyor.

3- Yukarıda belirtilen 2. durumu önlemek için kesme fonksiyonu üstünde tanımlanan #use delay(clock=XXXXXXX) komutunun aynısını ana program da "void main()" komutunun üstüne de koymak gerekir. Bu işlem yapılırsa 2. durumdaki sorun ortadan kalkıyor ve delay komutları hiç bir suretle kesmeleri engellemiyor.

bulut_01

#39
Alıntı yapılan: salih - 25 Haziran 2010, 16:31:47
Alıntı yapılan: bulut_01 - 25 Haziran 2010, 14:51:07
pbp konusunda yanılıyorsun arkadasım ınt ile kare dalga elde  ettıgım pause gecikme yaptıgımda kesme ana döngüsünde int iptal olmadıgı resımde ve kodda ıspatıdır

While içinde 1000 ms geçikme yapıp tekrar denermisin.

O zaman arkadasım dedıgın  işlemi yapacak kücük bi algoritma koyarız işlem tamam
40 sn kadar gecıkme yapar  ınt calısır hemde ok

BASLA:
for S=0 TO 65535
PAUSEUS 500
NEXT
TOGGLE GPIO.1
GOTO BASLA
YENİLMEZ..

Salih

#40
  Alıntı yapılan: bulut_01 - Bugün, 19:48:47 
   
Alıntı yapılan: salih - Bugün, 16:31:47 
   
Alıntı yapılan: bulut_01 - Bugün, 14:51:07 
pbp konusunda yanılıyorsun arkadasım ınt ile kare dalga elde  ettıgım pause gecikme yaptıgımda kesme ana döngüsünde int iptal olmadıgı resımde ve kodda ıspatıdır

    While içinde 1000 ms geçikme yapıp tekrar denermisin.
 
O zaman arkadasım dedıgın  işlemi yapacak kücük bi algoritma koyarız işlem tamam
40 sn kadar gecıkme yapar  ınt calısır hemde ok

BASLA:
for S=0 TO 65535
PAUSEUS 500
NEXT
TOGGLE GPIO.1
GOTO BASLA
     
Bulut_01,  Mesele derleyicilerin davranışları hakkında bir tesbitde bulunmak. Yoksa elbette problem bir şekilde aşılır.  Dediğim gibi Pic basic de eğer son versiyonlarında değiştirmedilirse komutlar başladığında -buna  gecikme komutlarıda- dahil, kesmeler iptal oluyor. Komutun çalışması bitince kesmeler tekrar kullanılır  hale geliyor.     

picmanya

#41
1. Akımı okurken 2 veya katları kadar (4.8.16.32...) defa okuyup ortalamasını alırsan anlık değişimlerden sıyrılırsın.
2. ADC pini ile şase arasına 100nF koymayı denermisin ?
3. Yine de yeterli gelmiyorsa Akım sinyalini skopla inceleyerek bi algoritma düşünebilirsin...
4. Halen olmadı ve bu ticari bir uygulama ise sana "özel yardım" da bulunmam gerekir.

merhabalar,

1. adc kanalı bende genelde çoklu okuyup ortalamasını alırım belirttiğiniz gibi 2 ve katlarında bunu yaparım
çünkü toplam sayısını daha sonra bölme işlemi yaparak değilde gerekli oranda sağa kaydırma ile işlem sonucunu bulmak için
2. akım örneklemesi almak için kullandığım girişine şöntü bağladığım opamp çıkışında adc kanalın beslemesi akım yönündende gariban kalmasın diye en az 300R en fazla 470R direnç ile opamp çıkışını pice girerim ve belirttiğiniz low pass filtre seramik kapasitesinide hep kullanırım ama en az 100pF. en fazlada 1nF. olarak

burda 300R dirençle 1nF. seramik kapasite kullandım.10nF. ila 47nF. arası gibi kapasiteleri opampın şönt tarafındaki low pass filtrede kullanıyorum burda bile 100nF. fazla gelir düşüncesindeyim.
bu tür uygulamaların hiç birinde şönt tarafında 47nF. üzeri pic adc girişinde ise 300R altı ve 1nF. üstü elemanların kullanıldığını görmedim.

gerekiyorsa şemayıda ekleyebilirim ama olay zannediyorum donanımsal değil.

3. akım sinyalini inceledim aslında sorun işte o bahsettiğiniz algoritmayı oluşturamamda olay çok büyük bir yeri gözden donanımsal olarak kaçırmıyorsam kesinlikle algoritmayı kurmamda.

4. yanlış değilsem son madde ticari oluyor değilmi  eski takas usul pcb kart baskısı karşılığında anlaşabilirsek neden olmasın ama bu şekilde çalışmada daha farklı bir konuda yardım isterim öyle program yazımı yada algoritma desteği falanda değil 

burda sorunum aslında fırçalı dc motor akımını pic ile adc üzerinden okurken.picde koşan programın adc den akım bilgisini okurken adab yönünden usulü erkana nasıl riayet edeceği hakkında.
akım okumanın bir adabı varsa bilmek isterim bu motor denen meret zırt pırt zıplamalı akımlar asılıyor bunu yazılımsal filtrelemede hangisi boşuna haybeye zıplama hangisi gerçekden motorun sııkışıp kendini yakmadan çok önce mosfetleri gümleteceği akım bunu tespit sorunum var.

ilginize teşekkürler.