hi tech pic c de kesme

Başlatan deserteagle, 23 Nisan 2007, 10:59:20

deserteagle

bu hi tech c de kesmeler nasıl oluyor.cok araştırdım ama bir türlü işin içinden çıkamadım acaba basitçe biraz bilgi verebilecek hocalarımdan yardım bekliyorum.
bu kesmeler 877 de olmadan programlar bir sürü döngü ile oluyor ve bu da boşuna hafızaydolduyor ve ben de istediğim kadar özellik kullanamıyorum.
yardımlarınızı bekliyorum
saygılarımla

arslan74

Merhaba,

Hi-Tech içinde samples klasörü var orada kesmelerle ilgili örnek kodlar var onları öncelikle bir incele. Ayrıca kesme deyince akla bir sürü kesmeler geliyor. timer0, timer1, timer2, int0, intrb, usart, pwm, ccp v.b. bir sürü kesmeler var sen hangisini kullanacaksın?


Selamlar,

Hasan ARSLAN.

deserteagle

sayın arslan hocam dediklerinize baktım ama pek birsey anlamadım.mesela 16f877 de dış kesme olarak buton ekliyeceğim ve buna göre programı kontrol edeceğim burada yanı 877 de 5 tane dı kesme uygulayabılıyoruz dıye duymustum .işte ben bunun nasıl olduğunu belirtmenizi isteyorum.
teşekkürler
saygılarımla.

arslan74

Merhaba,

Samples klasörünün içinde ki "intr1.c" dosyasını incele. aşağıda kodu tekrar yayınlıyorum.



#include	<pic.h>

/*
 *	Interrupt demo for PIC; wait for button press on RB0/INT,
 *	turn on a relay on another port bit for a period of time.
 *	For simplicity here, literal constants are used, usually these
 *	should be calculated with compile-time arithmetic.
 */


static bit		RELAY @ (unsigned)&PORTB*8+7;	// use this bit to drive relay
static unsigned int	relay_timer;			// timer value for relay driver

void
main(void)
{
	/* setup stuff */

	RELAY = 1;		// ensure relay is off before enabling output
	TRISB = 0x3F;		// Port B bits 7 and 6 are output 
	T0CS = 0;		// Timer increments on instruction clock
	T0IE = 1;		// Enable interrupt on TMR0 overflow
	INTEDG = 0;		// falling edge trigger the interrupt
	INTE = 1;		// enable the external interrupt
	GIE = 1;		// Global interrupt enable
	for(;;)
		CLRWDT();	// Idly kick the dog
}

static void interrupt
isr(void)			// Here be interrupt function - the name is
				// unimportant.
{
	if(T0IF) {				// timer interrupt
		TMR0 -= 250; 			// reload the timer - 250uS per interrupt
		T0IF = 0;			// clear the interrupt flag
		if(relay_timer != 0)		// is the relay timer running?
			relay_timer--;		// decrement it
		if(relay_timer == 0)		// if it has time out
			RELAY = 1;		// turn the relay off
		PORTB ^= 0x40;			// toggle a bit to say we're alive
	}
	if(INTF) {				// did we see a button press?
		RELAY = 0;			// turn the relay on
		relay_timer = 4000;		// start the timer - 4000 ticks = 1 second
		INTF = 0;			// clear the interrupt
	}
}


İnterrupt alt programı

static void interrupt
isr(void)  


ile başlar, o kodun içinden interupt flaglerine bakarak interruptun nereden geldiğine anlayacaksın.

Mesela "T0IF" flagı timer0 için, "INTF" ide intRB0 ait flaglerdir.

Selamlar.

deserteagle

sayın arslan hocam ağzımın payını aldım.artık ben bu işleri bırakacağım.yine birşeyler anladım ama

static bit      RELAY @ (unsigned)&PORTB*8+7;   // use this bit to drive relay
static unsigned int   relay_timer;         // timer value for relay driver

kısımlarından ve main den pek birşey anlamadım.
ve kesme fonk siyonunda  kaç tane daha kesme ekleyebiliriz.butonsal bazda yani dış kesme olarak.bunun bir algoritma ve quick user guidesi yokmudur varsa ben bulamadım.veya bana bir kaynak önerebilirmisiniz.
belki yeni bir tartışma yaratmış olacağım ama bu pic işini öğrenmek için doğan ibrahimin tüm kitaplarını aldım fakat bir kaç basit özelliğinden ileriye gidemedim.sizlere sonsuz saygı duyuyorum.böyle sınırlı kaynaklarla bu işi çözmüşünüz.
bense hayatımda ilk kez pes edeceğim

saygılarımla.

arslan74

Merhaba,

Öncelikle senin "C" bilgin ne seviyede. Cünkü sorduğun bu sorular PIC'den daha ziyade C ile alakalı sorular. Eğer C bilgin yoksa o zaman sana bu derleyici cok fazla zor gelir ve fazla birşey anlamassın. Sana tavsiyem parana kıyıb güzel C eğitimi veren bir kursa gitmek. C dili iyi öğrendiğinde işin cok daha kolaylaşacaktir.

Kısaca yapılan işlemleri anlatayım.

RB7 bacağını Role cıkışı olarak tanımlamış.
static bit      RELAY @ (unsigned)&PORTB*8+7;   // use this bit to drive relay



relay_timer diye int(2byte) türünden bir değişken tanımlamış.
static unsigned int   relay_timer;         // timer value for relay driver


Şimdi main konumuna, yani ana program kısmına gelelim.

   RELAY = 1;      // ensure relay is off before enabling output
   Röle cıkışını kapatmış. 

   TRISB = 0x3F;      // Port B bits 7 and 6 are output
   RB6 ve RB7 bacaklarını cıkış yapmış.

   T0CS = 0;      // Timer increments on instruction clock
   Timer0 giriş sinyalını pic kristalıne bağlamış.

   T0IE = 1;      // Enable interrupt on TMR0 overflow
   Timer0 (interrupt) kesemesini aktif yapmış.

   INTEDG = 0;      // falling edge trigger the interrupt
   RB0 kesmesini düşen kenarda ayarlamış.

   INTE = 1;      // enable the external interrupt
   RB0 kesmesini aktif yapmış.

   GIE = 1;      // Global interrupt enable
   aktif olan bütün kesmeleri devreye sokmuş.

   for(;;)
      CLRWDT();   // Idly kick the dog
   burdada sonsuz döngü yaparak işlemi burada sonlandırmış. Sonsuz döngü içinde eğer Watchdog timeri acık ise devreye girmemesi için Watchdogu sıfırlıyor.

Yan ana program içinde hiç bir işlem olmuyor. bütün işlemler kesmede yapılıyor.

  Şimdi kemse alt programını inceleyelim.

  Timer 0 gelmişmi diye sorgu yapiyor.
   if(T0IF) {            // timer interrupt
    Evet timer0 gelmiş ise bu bok içikei işlemleri yapiyor.

      TMR0 -= 250;          // reload the timer - 250uS per interrupt
     Timer 0 registerinden 250 değerini cıkartiyor. 250 us ayarlamak için.

      T0IF = 0;         // clear the interrupt flag
      timer 0 bayrağını sıfırlıyor. 

      Eğer reay_timer değişteni sıfır değil ise. 
      if(relay_timer != 0)      // is the relay timer running?

         relay_timer değişkenini bir azaltiyor.
         relay_timer--;      // decrement it
    
      sonuc sıfır mı?
      if(relay_timer == 0)      // if it has time out
     Evet sonuc sıfır
      
     Role Cıkışını kapat.
      RELAY = 1;      // turn the relay off

   PortB cıkışını '01000000' değeri ile özel veya işlemime tabi tutuyor.
   Sonucta RB6 cıkışı nın durumu değişmiş olacak.

      PORTB ^= 0x40;         // toggle a bit to say we're alive
   } // timer0 ait blok sonu.

  // RB0 tan kesme gelmişmi? Yani butona basılmışmı?

   if(INTF) {            // did we see a button press?
  // Evet basılmış.

      Röleyi ac.
      RELAY = 0;         // turn the relay on

      relay_timer değerini 4000 yap.
      relay_timer = 4000;      // start the timer - 4000 ticks = 1 second
   

     RB0 kesem bağraını sıfırla.
      INTF = 0;         // clear the interrupt
   }


Aslında oluşan olay kısaca söyle. RB0 bacağına bağlı bir buton var. ona bastğımızda roleyi devreye sokuyor ve 1 saniye sonra röle kendisi kapaniyor. rölenin her kapanmasında RB6 cıkışının durumu değişiyor.

Çalışmalarında başarılar.

deserteagle

sayın arslan hocam dediklerinizi iyice inceledim.c bilgim orta düzeylerdeyani kendim biraz c de progra yazabiliyorum.
mesela ben bu programı yazmıs olsa

#include<pic.h>
#include<delay.c>
#define tus RB0
#define cikis RB1
void bekle(unsigned int x)
{unsigned int y,i;
y=4*x;
for(i=0;i<=y;i++)
DelayMs(250);
}
void main()
{

TRISB=0b01;  // rb0 giriş rb 1 çıkış

for(;;)
{
if(tus==0)
{cikis=1;
bekle(4);
cikis=0;
}
}

şeklinde yazar ve 16f84 de bir butonla okurdum ama birkaçtane
buton olunca döngü çok karmaşık oluyor ve kontrol çok fazla yer kaplıyor.bundan dolayı kesmelerı oğrenmeye calışıyorum.
peki 877 de 4 tane buton bağlasaydık
TOIE=1 gibi dört tane daha nasıl tanımlayacaktık.burada
INTF den başka kaç tane daha tanımlayacaktık.bunları oluşturamıyorum.

yanıtlarınız için çok teşekkürler.
saygılarımla.

arslan74

Merhaba,

Öncelikle sen ne yapmak istediğini ayrıntılı anatırsan sana daha iyi yardımcı olunur.

Gördüğüm kadarıyla senin mikoişlemci bilginde zayıf. Öncelikle kullandığın PIC 'in datasheetini ayrıntılı bir şekilde okumanı tavsiye ederim. PIC'in donanım yapısını bilmeden sadece C bilgisiyle üstelik zayif bir C bilgisiyle birşeyler yapamassın. Mutlaka biryerde takılır ilerleyemessin.

İlk yapman gereken işlemler C bilgini biraz geliştiriyorsun. Ayrıca kullandığın PIC'in datasheetini güzelcene bir okuyub ezberliyorun, donanımın bütün çalışma prensibini öğreniyorsun. Bu işlemden sonrasında program yazmaya başlaman daha sağlıklı olacağı kanısındayım.

Cünkü burda sana vereceğim cevablar senin kafanı daha cok karıştıracak.


Selamlar.

deserteagle

arslan hocam dediinizi yapıp hemen iyi bir c kitabı alıp önce c yi geliştireceğim vede datasheet lere bi odaklanıyım bakalım ne çıkacak.
yardımlarınız için çok teşekkürler
saygılarımla

PARSIC

selamlar...
acaba hi-tech de 16f877a ile birden fazla kesmeyi nasıl kullanabiliriz tek kesmede sorun yok fakat birden fazla her türlü kesmede hatalar alıyorum ne yapmam gerekir nasıl bir yol izlemeliyim..şimdiden teşekkürler..
********************************************************************HI-TECH*******************************************************************

X-Fi

birden fazla kesmede kesme satırında hangi kesmenin geldiğini anlamanın bir yolu var oda şöyle;

if(T0IF)
{
   // işlenecek kod
T0IF=0;
}
if(TMR1IF)
{
   // işlenecek kod
TMR1IF=0;
}
if(TMR2IF)
{
   // işlenecek kod
TMR2IF=0;
}
http://www.coskunergan.dev/    (Yürümekle varılmaz, lakin varanlar yürüyenlerdir.)

PARSIC

bende bunun gibi bir program akışı izledim fakat bu sefer de anlamsız gecikmeler oluşuyor ...timer1 ile timer0 ı birlikte ccs c de sorunsuz kullanabiliyordum fakat hi-tech de şu an için bunu yapamadım ..
********************************************************************HI-TECH*******************************************************************

X-Fi

kod paylaşın daha detaylı yardımcı olalım konuşmakla olmuyor bazı şeyler.
http://www.coskunergan.dev/    (Yürümekle varılmaz, lakin varanlar yürüyenlerdir.)

PARSIC

yazdığım kod aşağıdaki gibi..belki de sorunum hi-tech ile kesmelere öncelik verememektir umarım bu sorunu çöebiliriz

#include <pic.h>
#include "delay.h"
__CONFIG(XT & WDTDIS & BORDIS & UNPROTECT);
const unsigned char
segment[]={0X3F,0X06,0X5B,0X4F,0X66,0X6D,0X7D,0X07,0X7F,0X6F};
char sn,dk,sa,i;
void interrupt saat(){
TMR1H=32768/256;
TMR1L=32768%256;
if(TMR1IF==1){
sn++;
if(sn==60){
sn=0;
dk++;
}
if(dk==60){
dk=0;
sa++;
}
if(sa==24){
sa=0;
}
TMR1IF=0;
}
if(T0IF==1){
TMR0=6;
i++;
if(i==2){
PORTB=0B11111110;
PORTD=segment[dk%10];
}
if(i==4){
PORTB=0B11111101;
PORTD=segment[dk/10];
}
if(i==6){
PORTB=0B11111011;
PORTD=segment[sa%10];
}
if(i==8){
PORTB=0B11110111;
PORTD=segment[sa/10];
i=0;
}
T0IF=0;
}
}
void main(){
TRISA=0B00010000;
TRISB=0X00;
TRISC=0X01;
TRISD=0X00;
PORTA=0X00;
PORTB=0X00;
PORTC=0X00;
PORTD=0X00;
ADCON1=0X07;
TMR0=6;
T0CS=0;
PSA=0;
PS2=0;
PS1=0;
PS0=1;
T0IF=0;
T0IE=1;
TMR1H=32768/256;
TMR1L=32768%256;
T1CKPS1=0;
T1CKPS0=0;
T1SYNC=1;
T1OSCEN=1;
TMR1CS=1;
TMR1ON=1;
TMR1IF=0;
TMR1IE=1;
PEIE=1;
GIE=1;
while(1);
}
********************************************************************HI-TECH*******************************************************************

X-Fi

hitech de kesmeler main altına yazılır.

ayrıca

static void interrupt KESME()
{
}


şeklinde çağrılır.

http://www.coskunergan.dev/    (Yürümekle varılmaz, lakin varanlar yürüyenlerdir.)