PIC C Harici kesme (YARDIM)

Başlatan rustuuckun, 03 Mart 2009, 11:53:14

rustuuckun

Arkadaşlar iş yerindeki bir tezgah için devre yapmam istendi. Bir boyama tezgahının filtrelerini otomatik olarak patlatan bir devre tasarladım. Ama benden bu devre çalışırken manuel olarak da palatılabilmesi istendi. Buraya kadar kodu C ile yazdım ama şöyle bir sorunum var. B0 pinine bağlı harici kesme sinyali sonunda programın başa dönmesini istiyorum ama öyle olmuyor. Sanırım kesme sonunda program kaldığı yerden devam ediyor. Benim isteğim ise kesme sonunda sanki pic resetlenmiş gibi davranmalı. Bunu nasıl çözebilirim??

AYRICA YAZDIĞIM KODU BİR KONTROL EDİP HATALI OLDUĞUM YERLERİ BANA SÖYLERSENİZ ÇOK SEVİNİRİM.

http://rapidshare.com/files/204732034/C_KODU_VE_HEX___PROTEUS__ALI__350_MASI.rar.html

KOD:

#include "16f84.h"
#fuses XT,NOWDT,NOPROTECT
#use delay (clock=4000000)
#use fast_io(b) //Port yönlendirme komutları B portu için geçerli
#use fast_io(a)


//****** Dış Kesme Fonksiyonu *****************
#int_ext                // Dış (External) RB0/INT kesmesi
void  ext_kesmesi ()    // Dış kesme fonksiyonu
{
if(input(PIN_A0))
{
output_b(0);
delay_ms(250);
output_b(24);  // Lamba ve siren yak
delay_ms(5000);
output_b(2);
delay_ms(500);
output_b(0);
} else output_b(0);
}


/********* ANA PROGRAM FONKSİYONU********/
void main(void)

{
  set_tris_b(0x01);
  set_tris_a(0xFF);
  output_b(0x00);     // B portu çıkışı ilk anda sıfırlanıyor

  ext_int_edge(L_TO_H);   // INT_EXT kesmesinin düşen kenarda aktif olacağını belirtir

  enable_interrupts(INT_EXT);  // INT_EXT kesmesini aktif yapar
  enable_interrupts(GLOBAL);   // Aktif edilen kesmelere izin ver


while(input(PIN_A0))
{
int i;

output_b(0);
i=1;
while(i>0)
{
output_b(16);
delay_ms(5000);
output_b(0);
i=i-1;
}

i=180;
while(i>0)
{
delay_ms(20000);
i=i-1;
}
output_b(16);
i=21;
while(i>0)
{
delay_ms(20000);
i=i-1;
}
output_b(24);
delay_ms(5000);
output_b(2);
delay_ms(1000);
output_b(0);
delay_ms(500);
}
}

rustuuckun

Aslında yapmak istediğimi tam olarak açıklarsam:

Eğer A0 pininde enerji varsa pic kodları yürütecek eğer A0 pini pasifse (Tezgah devresi çalışmıyor) pic de çalışmayacak.

Tezgah çalışıyorsa ;

ana program fonksiyonu yürütülecek fakat eğer b0 pininde kesme oluşursa kesme fonksiyonu yerine getirilecek ve ana program fonksiyonu en baştan başlatılacak (PIC resetlenmiş gibi). İşte bu kısmı başaramadım. Ayrıca A0 pini enerji gelmezse program çalıştığı noktada sona erecek ve A0 enerji alana kadar hiçbirşey yapmayacak ve A0 enerji aldığı anda en baştan ana program fonksiyonu çalıştırılacak (RESET gibi).

Biraz karmaşık oldu ama yapmam gerekli  8O

rustuuckun

yazdığım kodu biraz toparladım ve A0 pini için kod içerisine belli yerlere kontrol kodları yerleştirdim ama ne kadar sağlıklı bir çözüm oldu bilemiyorum. Yazdığım kod çalışır gibi görünse de istediğim şeyi yapmayı başaramadım. hala kesme sonunda program kaldığı yerden devam ediyor. hala buna bir çözüm yolu bulmuş değilim.

yazdığım kodun son hali:

#include "16f84.h"
#fuses XT,NOWDT,NOPROTECT
#use delay (clock=4000000)
#use fast_io(b) //Port yönlendirme komutları B portu için geçerli
#use fast_io(a)


//****** Dış Kesme Fonksiyonu *****************
#int_ext                // Dış (External) RB0/INT kesmesi
void  ext_kesmesi ()    // Dış kesme fonksiyonu
{
if(input(PIN_A0))
{
output_b(0);
delay_ms(250);
output_b(24);  // Lamba ve siren yak
delay_ms(5000);
output_b(2);
delay_ms(500);
output_b(0);
} else output_b(0);
}


/********* ANA PROGRAM FONKSİYONU********/
void main(void)

{
  set_tris_b(0x01);
  set_tris_a(0xFF);
  output_b(0x00);     // B portu çıkışı ilk anda sıfırlanıyor

  ext_int_edge(L_TO_H);   // INT_EXT kesmesinin düşen kenarda aktif olacağını belirtir

  enable_interrupts(INT_EXT);  // INT_EXT kesmesini aktif yapar
  enable_interrupts(GLOBAL);   // Aktif edilen kesmelere izin ver


while(true)
{
tek:

if(input(PIN_A0))
{
int i;

output_b(0);
i=1;
while(i>0)
{
if(!input(PIN_A0))
{goto tek;}
else {output_b(16);
delay_ms(5000);
output_b(0);}
i=i-1;
}

i=180;
while(i>0)
{
if(!input(PIN_A0))
{goto tek;}
else {
delay_ms(20000);
i=i-1;
}
}
output_b(16);
i=21;
while(i>0)
{
if(!input(PIN_A0))
{goto tek;}
else {
delay_ms(20000);
i=i-1;
}
}
if(!input(PIN_A0))
{goto tek;}
else {
output_b(24);
delay_ms(5000);
}
if(!input(PIN_A0))
{goto tek;}
else {
output_b(2);
delay_ms(1000);
}
output_b(0);
delay_ms(500);
} else output_b(0);
}
}

rustuuckun

Tüm bildiklerimle ve yaptığım araştırmalarla 2 yöntem olduğunu öğrendim. Ama nedense bende işe yaramıyor. bulduğum yöntemlerden biri "reset cpu();" gibi bir kod girmekmiş ama benim programımda işe yaramadı. Bir sitede ise kesinlikle işe yarar diye söylemişler. Bu yöntem ise C içinde Assembly kullanmak.

KOD:

#asm
movlw 00 //w ya hex 00 i yukledik.
movwf 02 //w daki hex 00 i PCL e yukledik
#endasm

Bu kodu kesme fonksiyonu sonunda kullanarak PCL değerini değiştiriyoruz ve böylece kesme sonunda program ana programdaki yerinden başlamıyor. Ana programın başından başlamış oluyor. Benim programımda işe yaramadı. Acaba nerede yanlış yapıyorum??
YOK MU BİR FİKRİ OLAN???

rustuuckun

tamam arkadaşlar ben sorunumu çözdüm. belki birilerine yardımcı olurum. Yaptığım değişiklik şu:

#asm
movlw 00 ==> yerine 122 yazmak oldu. Böylece PCL'ye ana programımın başlangıç adresini vermiş oldum. Eğer derleyicide asm kodlarını göster derseniz burada ana programınızın nerede başladığını görebilirsiniz. Biraz fazla uzun oldu ama size programımın son halini veriyorum. Eminim ki birilerine yardımcı olurum. Çünkü ben C ile dış kesme kullanılan pek örnek bulamadım. Zaten bulduğum bir ya da iki taneydi ben de onlardan yola çıkarak yazdım kodları.

#include "16f84.h"
#fuses XT,NOWDT,NOPROTECT
#use delay (clock=4000000)
#use fast_io(b) //Port yönlendirme komutları B portu için geçerli
#use fast_io(a)

#int_ext  

//****** Dış Kesme Fonksiyonu *****************

// Dış (External) RB0/INT kesmesi
void  ext_kesmesi ()    // Dış kesme fonksiyonu
{
if(input(PIN_A0))
{

output_b(0);
delay_ms(250);
output_b(24);  // Lamba ve siren yak
delay_ms(5000);
output_b(2);
delay_ms(500);
output_b(0);

} else output_b(0);

#asm

    movlw 122 //w ya hex 00 i yukledik.
    movwf 02 //w daki hex 00 i PCL e yukledik
#endasm
}

/********* ANA PROGRAM FONKSİYONU********/
void main(void)

{

set_tris_b(0x01);
  set_tris_a(0xFF);
  output_b(0x00);     // B portu çıkışı ilk anda sıfırlanıyor

  ext_int_edge(L_TO_H);   // INT_EXT kesmesinin düşen kenarda aktif olacağını belirtir

  enable_interrupts(INT_EXT);  // INT_EXT kesmesini aktif yapar
  enable_interrupts(GLOBAL);   // Aktif edilen kesmelere izin ver




             

while(true)
{

tek:

if(input(PIN_A0))
{
int i;

output_b(0);
i=1;
while(i>0)
{
if(!input(PIN_A0))
{goto tek;}
else {output_b(16);
delay_ms(5000);
output_b(0);}
i=i-1;
}

i=180;
while(i>0)
{
if(!input(PIN_A0))
{goto tek;}
else {
delay_ms(20000);
i=i-1;
}
}
output_b(16);
i=21;
while(i>0)
{
if(!input(PIN_A0))
{goto tek;}
else {
delay_ms(20000);
i=i-1;
}
}
if(!input(PIN_A0))
{goto tek;}
else {
output_b(24);
delay_ms(5000);
}
if(!input(PIN_A0))
{goto tek;}
else {
output_b(2);
delay_ms(1000);
}
output_b(0);
delay_ms(500);
} else output_b(0);
}
}