MSP430 PORT1 de iki tane kesme oluşturma

Başlatan Firzen, 28 Ocak 2013, 12:25:06

Firzen

Merhabalar UART üzerinden veri okuma konusunda birkaç çalışma yapınca hocam ile bir projeye başlamak istedik bu yüzden kullanacağımız kısımları tek tek farklı metodlara denemeye başladık.Aslında Stellaris veya STM32 kullanacaktık ama ondaki denemeler konusunda daha başlangıç seviyesinde olduğum için kontrol konusunda şimdilik bana MSP430 un yeterli olacağını düşünüyorum.Benim danışmak istediğim konu basit birşey aslında ama bir türlü bulamadım.MSP430 da iki porttan birden kesme oluşturma.Bu konuda bir kod yazdım ama doğru mu bilmiyorum bu yüzden size de danışayım dedim. ikinci if e bir türlü sokamadım sebebi nedir anlamadım.
Yardımlarınız için Şimdiden teşekkür ederim saygılar...

Yaptığım Küçük bir deneyin resmini gönderiyorum.

#define LED1 P1OUT_bit.P0
#define LED2 P1OUT_bit.P7
#define LED3 P1OUT_bit.P6
#define LED4 P1OUT_bit.P5

#include "io430.h"
#include "in430.h"

void delay(void)
{
int i;
for(i=0;i<30000;i++);
}

void main( void )
{
  WDTCTL = WDTPW + WDTHOLD;
  BCSCTL1 = CALBC1_1MHZ;
  DCOCTL = CALDCO_1MHZ;
  __delay_cycles(1000000);
  
  P1DIR = 0xE1;
  P1OUT = 0x18;


  P1IE =  BIT3 + BIT4;
  P1IES = BIT3 + BIT4;
  P1IFG_bit.P3 = 0;
  P1IFG_bit.P4 = 0;
    
__bis_SR_register(GIE);

while(1)
{
LED1 = ~LED1;

__delay_cycles(1000000);
LED2 = ~LED2;
__delay_cycles(1000000);
LED3 = ~LED3;
__delay_cycles(1000000);
LED4 = ~LED4;
__delay_cycles(1000000);
}
}

#pragma vector = PORT1_VECTOR
__interrupt void kesme1(void)
{
if(P1IE_bit.P3 = 1)
{
LED1 = 1;
LED2 = 1;
LED3 = 1;
LED4 = 1;
delay();
P1IFG_bit.P3 = 0;
}

if(P1IE_bit.P4 = 1)
{
LED1 = 0;
LED2 = 0;
LED3 = 0;
LED4 = 0;
delay();
P1IFG_bit.P4 = 0;
}

}


[IMG]http://img465.yukle.tc/images/7559fotograf.JPG[/img]
Kararsız...

fgokcegoz

Derleyici bu kodu derlerken hata veya uyarı vermiyor mu, acaba ? if komutunda eşitlik sorgulanırken çift eşittir işareti kullanılır, çünkü...
"Vicdanın ziyası, ulûm-u diniyedir. Aklın nuru, fünun-u medeniyedir. İkisinin imtizacıyla hakikat tecelli eder." (Bediüzzaman Said Nursi)

Firzen

#2
aa evet evet onu unuttum haklısınız :)
Onun haricinde bir sorun var mı?

mesaj birleştirme:: 28 Ocak 2013, 13:59:04

burada kodu kopyalarken eksik kopyalamaışım daha doğrusu ilk yazdığımı kopyalamışım normal kodumda "==" var.Şimdi baktım :)
son olarak sorun hala devam ediyor.
Kararsız...

fatih6761

MSP430 hakkında bilgim yok ama C ile ilgili bir not : ANSI C standardı derleyiciler için if'e verilen ifadede tek '=' işareti var olabilir ve kod bu haliyle de çok mantıklı bir şekilde derlenecektir. Bu halinde derleyici o satırı şu şekilde yorumlar:

  • P1IE_bit.P3 bitine 1 yükle
  • Yüklenen değeri test et
  • Zero bayrağı çekili değilse, yani if içindeki ifade 0'dan farklı ise takip eden kod bloğunu işlet.
Bu noktalara dikkat etmeniz sizin için daha iyi olacaktır.
Ek olarak C# dili bu özelliği desteklemez. Çünkü C#'ta if ancak Bool türünden ifadeleri (true-false) denetleyebilir.
Örnek:

volatile unsigned int a = 3;

if (a)
{
    /*  a sıfırdan farklı ise bu blok işletilir  */
}

C için bu kod derlenebilir, ama C# için derlenemez.

fgokcegoz

Yanlış düşünüyorsunuz. C de her zaman bool türünden test yapar. Mesela a değişkeninin değeri 10 olsun. Siz if(a==10) diye bir şart yazdığınızda if in içindeki kısım ya true dur yada false. Yoksa a değişkeninin 10 olup olmadığına göre çalışmaz. Ayrıca sizin verdiğiniz örnek, öne sürdüğünüz şeyi desteklemez. a=3; tanımlanan a değişkeni, if(a) şeklinde sorgulanırsa, bu şart hep sağlanacaktır. Çünkü sadece '0' false dur. '0' dan farklı her sayı true dur. Çift işaret zaten bu yüzden anlam ifade eder. a nın true yada false luğuna göre değil, a nın istenilen sayıya eşit olup olmamasının true yada false luğunu ifade eder. İnşallah aradaki nüans ı anlatabilmişimdir.
"Vicdanın ziyası, ulûm-u diniyedir. Aklın nuru, fünun-u medeniyedir. İkisinin imtizacıyla hakikat tecelli eder." (Bediüzzaman Said Nursi)

fatih6761

Alıntı yapılan: fgokcegoz - 28 Ocak 2013, 14:36:22
Yanlış düşünüyorsunuz. C de her zaman bool türünden test yapar. Mesela a değişkeninin değeri 10 olsun. Siz if(a==10) diye bir şart yazdığınızda if in içindeki kısım ya true dur yada false. Yoksa a değişkeninin 10 olup olmadığına göre çalışmaz. Ayrıca sizin verdiğiniz örnek, öne sürdüğünüz şeyi desteklemez. a=3; tanımlanan a değişkeni, if(a) şeklinde sorgulanırsa, bu şart hep sağlanacaktır. Çünkü sadece '0' false dur. '0' dan farklı her sayı true dur. Çift işaret zaten bu yüzden anlam ifade eder. a nın true yada false luğuna göre değil, a nın istenilen sayıya eşit olup olmamasının true yada false luğunu ifade eder. İnşallah aradaki nüans ı anlatabilmişimdir.
İlk olarak bunlar düşünce değil, C standartlarıdır. İkinci olarak
Alıntı Yap
C de her zaman bool türünden test yapar.
C standardında bool veri tipi yoktur. Dolayısıyla true veya false yoktur. Sonucu mantıksal olarak yanlış (false) olan işlemler 0 olarak ele alınır. Doğru olanlar ise 1'dir. Biraz Assembly çıktısı incelerseniz, durumu görürsünüz. a = 0 için if(a) şartı sağlanmaz. Ama a = 1 için sağlanır değil mi? Ya da a = 2 için if(a) ne olur? Tabi ki sağlanacaktır.
a = 1 için if(a == 0) şartı sağlanmaz. Zaten ben bu kısmından bahsetmedim. Karşılaştırma ifadesi olsun yada olmasın C için önemli olan if ifadesi 0 ( Ansi C için aynı zamanda false anlamına gelir ) ise şart sağlanmamıştır. Kodlardan gidelim isterseniz:
volatile int a = 3;  // iyileştirmelerin dışında tut

if(a)
{
   a = a + 1;
}
else
{
   a = a - 1;
}

Burada 'a' nın sıfırdan farklı tüm değerleri için a = a + 1 bloğu işletilecektir. Eğer başta a = 0 atanırsa a = a - 1 bloğu işleyecektir.
Kodun assembly çıktısını inceleyelim ( neden assembly? çünkü işlemci doğrudan bu kodlar işleyecek, en önemlisi bu kısım )
//	int a = 3;
00F013BE  mov         dword ptr [a],3  

//	if(a)
00F013C5  cmp         dword ptr [a],0      /*  a nın değerini 0 ile karşılaştır  */
00F013C9  je          main+36h (0F013D6h)  /*  Sıfıra eşit ise ( Jump if Equal ) else bloğuna atla değilse devam et  */
//	{
//		a = a + 1;
00F013CB  mov         eax,dword ptr [a]    /*  a nın değerinia eax'a al. 1 ekle ve a nın adresine yaz  */
00F013CE  add         eax,1  
00F013D1  mov         dword ptr [a],eax  
00F013D4  jmp         main+3Fh (0F013DFh)   /*  programı sonlandır  */
//	}
//	else
//	{
//		a = a - 1;
00F013D6  mov         eax,dword ptr [a]    /*   Else bloğu, a sıfırdan farklı ise a =  a - 1 işlet.   */
00F013D9  sub         eax,1  
00F013DC  mov         dword ptr [a],eax  
//	}

Bu kısım tamam değil mi? Aynı şeyi düşünüyoruz. Peki if içerisinde atama yaparsak ne olacak?
volatile int a = 3;

if(a = 2)
{
	a = a + 1;
}
else
{
	a = a - 1;
}

Burada ilk başta a=3. Sonra a = 2 yapılıyor ve a ile 0 karşılaştırılıyor. Buna göre otomatik olarak atanan değerle karşılaştırma yapılıyor. Her şekilde ifadeler true-false değil, == 0 veya != 0
Assembly çıktısı:
//	volatile int a = 3;
008F13BE  mov         dword ptr [a],3  /*  a ya 3 yükle.  */

//	if(a = 2)
008F13C5  mov         dword ptr [a],2  /*  öncelikle a ya 2 yükle  */
008F13CC  cmp         dword ptr [a],0  /*  sonra a yı 0 ile karşılaştır. */
008F13D0  je          main+3Dh (08F13DDh)  /*  karşılaştırma sonucunda a = 0 ise ( a == 0 ifadesi doğru ise ) else bloğuna atla */
//	{
//		a = a + 1;
008F13D2  mov         eax,dword ptr [a]   /*   Eğer a != 0 ise if içindeki bloğu işlet   */
008F13D5  add         eax,1  
008F13D8  mov         dword ptr [a],eax  
008F13DB  jmp         main+46h (08F13E6h)  /*  programı sonlandır  */
//	}
//	else
//	{
//		a = a - 1;
008F13DD  mov         eax,dword ptr [a]  /*   Eğer a = 0 ise bu bloğu işlet   */
008F13E0  sub         eax,1  
008F13E3  mov         dword ptr [a],eax  
//	}

Gördüğünüz gibi, bu kısımda tamam ise, karşılaştırma operatörlerine geçelim. Değişik bir örnek olsun ve karşılaştırma sonuçlarını değişkenlere aktaralım.
volatile int a = 3;
volatile int b, c, d;

b = (a > 2);
c = (a == 3);
d = (a == 10);

Assembly çıktısı:
//	volatile int a = 3;
00C333FE  mov         dword ptr [a],3  
//	volatile int b, c, d;

//	b = (a > 2);
00C33405  cmp         dword ptr [a],2    /*   a yı 2 ile karşılaştır   */
00C33409  jle         main+37h (0C33417h)  /*  jle -> Jump if Less or Equal  yani a küçük veya eşit 2 ise rölatif 37h adresine atla */
00C3340B  mov         dword ptr [ebp-0F4h],1  /*   (küçük veya eşit) değilse yani büyükse b = 1 aktar. True anlamına gelir, ama ortalıkta true yok.   */
00C33415  jmp         main+41h (0C33421h)  /*  değeri yazma aşamasına atla  */
00C33417  mov         dword ptr [ebp-0F4h],0  /*  rölatif 37h adresi = eğer a <= 2 ise 0 döndür. False anlamında, ama false değil, 0.  */
00C33421  mov         eax,dword ptr [ebp-0F4h]  
00C33427  mov         dword ptr [b],eax  /*  dönen değeri b ye yaz, ki burada b = 1 olacaktır.  */
//	c = (a == 3);
00C3342A  cmp         dword ptr [a],3    /*  a yı 3 ile karşılaştır.  */
00C3342E  jne         main+5Ch (0C3343Ch)   /*  jne -> Jump if Not Equal yani a eşit değildir 3 ise rölatif 5Ch adresine atla   */
00C33430  mov         dword ptr [ebp-0F4h],1  /*  eğer a = 3 ise ya da a == 3 ifadesi 'true '  ise 1 döndür.  */
00C3343A  jmp         main+66h (0C33446h)  /*  değeri yazma aşamasına atla  */
00C3343C  mov         dword ptr [ebp-0F4h],0  /*  rölatif 5Ch adresi : eğer a != 3 ise 0 döndür.  */
00C33446  mov         eax,dword ptr [ebp-0F4h]  
00C3344C  mov         dword ptr [c],eax  /*  dönen değeri c ye yaz, burada c = 1 olacaktır.  */
//	d = (a == 10);
00C3344F  cmp         dword ptr [a],0Ah  /*  a yı 10 ile karşılaştır  */
00C33453  jne         main+81h (0C33461h)  /*  eşit değilse rölatif 81h adresine atla  */
00C33455  mov         dword ptr [ebp-0F4h],1  /*  eşit değil kısmı işlenmeden atlanmış ise eşittir.O halde 1 döndür. True anlamında.  */
00C3345F  jmp         main+8Bh (0C3346Bh)  /*  değeri yazma aşamasına atla   */
00C33461  mov         dword ptr [ebp-0F4h],0   /*  rölatif 81h adresi : eğer a != 10 ise 0 döndür. False anlamında, ama false değil.  */
00C3346B  mov         eax,dword ptr [ebp-0F4h] 
00C33471  mov         dword ptr [d],eax  /*  dönen değeri d ye yaz, burada d = 0 olacaktır.  */


Değişkenler false anlamında 0 veya true anlamında 1 değerini aldı.
Eğer sıfırlar her zaman false ise, C çapında standandartlaşan makrolara bir göz atalım. Mesela Windows makrolarından örnekler:
//
// Generic test for success on any status value (non-negative numbers
// indicate success).
//

#define SUCCEEDED(hr) (((HRESULT)(hr)) >= 0)

//
// and the inverse
//

#define FAILED(hr) (((HRESULT)(hr)) < 0)

Burada 0 değeri başarılı yani doğru kabul ediliyor. Demek ki low-level de true ya da false yok. True ve False'lar sadece yazlımı seviyesinde. İşlemci yönergeleri (ing:instruction) sadece bayrakların durumuna göre iş yapıyor. Zero Flag, Sign Flag, Carry Flag, Overflow Flag vs... Eğer Zero Flag 1 ise ( burada 1 in anlamı SET veya Çekili oluyor, yani true değil ) işlemin ( aritmetik, lojik, her türlü ) sonucu 0 demek oluyor.

Umarın söylemek istediğimi anlatabilmişimdir. Düşünce şekliniz doğru, 0 dönen işlemler lojik(mantıksal) olarak Yanlış, 1 dönen işlemler ise Doğru anlamını taşıyor. Ama işlemci için böyle bir ayrım yok. Değerin sıfır ya da bir olması işlemcinin umrunda değildir. İşlemci sadece bayrakların durumuna bakar.
Dolayısıyla C de de bool düzeninde işlemler yapılır, ama sadece yorumlarken True ya da False denilir, yazılımda bulunmaz.

mehmet

#6
İnterrupt içinde port enable değil de port flag
kontrol edilecek.

#define LED1 P1OUT_bit.P0
#define LED2 P1OUT_bit.P7
#define LED3 P1OUT_bit.P6
#define LED4 P1OUT_bit.P5

#include "io430.h"
#include "in430.h"

void delay(void)
{
int i;
for(i=0;i<30000;i++);
}

void main( void )
{
  WDTCTL = WDTPW + WDTHOLD;
  BCSCTL1 = CALBC1_1MHZ;
  DCOCTL = CALDCO_1MHZ;
  __delay_cycles(1000000);
  
  P1DIR = 0xE1;
  P1OUT = 0x18;


  P1IE =  BIT3 + BIT4;
  P1IES = BIT3 + BIT4;
  P1IFG_bit.P3 = 0;
  P1IFG_bit.P4 = 0;
    
__bis_SR_register(GIE);

while(1)
{
LED1 = ~LED1;

__delay_cycles(1000000);
LED2 = ~LED2;
__delay_cycles(1000000);
LED3 = ~LED3;
__delay_cycles(1000000);
LED4 = ~LED4;
__delay_cycles(1000000);
}
}

#pragma vector = PORT1_VECTOR
__interrupt void kesme1(void)
{
if(P1IFG_bit.P3 == 1) // Burada interrupt flag kontrol edilecek
{
LED1 = 1;
LED2 = 1;
LED3 = 1;
LED4 = 1;
delay();
P1IFG_bit.P3 = 0;
}

if(P1IFG_bit.P4 == 1) // Burada interrupt flag kontrol edilecek
{
LED1 = 0;
LED2 = 0;
LED3 = 0;
LED4 = 0;
delay();
P1IFG_bit.P4 = 0;
}

}
/code]
Olan olmuştur,
olacak olan da olmuştur.
Olacak bir şey yoktur.
---------------------------------------------
http://www.mehmetbilgi.net.tr

Firzen

Teşekkür ederim Mehmet Bey;
Saygılarımla İyi Akşamlar Diliyorum Herkese...

Alıntı yapılan: mehmet - 28 Ocak 2013, 22:59:23
İnterrupt içinde port enable değil de port flag
kontrol edilecek.

#define LED1 P1OUT_bit.P0
#define LED2 P1OUT_bit.P7
#define LED3 P1OUT_bit.P6
#define LED4 P1OUT_bit.P5

#include "io430.h"
#include "in430.h"

void delay(void)
{
int i;
for(i=0;i<30000;i++);
}

void main( void )
{
  WDTCTL = WDTPW + WDTHOLD;
  BCSCTL1 = CALBC1_1MHZ;
  DCOCTL = CALDCO_1MHZ;
  __delay_cycles(1000000);
  
  P1DIR = 0xE1;
  P1OUT = 0x18;


  P1IE =  BIT3 + BIT4;
  P1IES = BIT3 + BIT4;
  P1IFG_bit.P3 = 0;
  P1IFG_bit.P4 = 0;
    
__bis_SR_register(GIE);

while(1)
{
LED1 = ~LED1;

__delay_cycles(1000000);
LED2 = ~LED2;
__delay_cycles(1000000);
LED3 = ~LED3;
__delay_cycles(1000000);
LED4 = ~LED4;
__delay_cycles(1000000);
}
}

#pragma vector = PORT1_VECTOR
__interrupt void kesme1(void)
{
if(P1IFG_bit.P3 == 1) // Burada interrupt flag kontrol edilecek
{
LED1 = 1;
LED2 = 1;
LED3 = 1;
LED4 = 1;
delay();
P1IFG_bit.P3 = 0;
}

if(P1IFG_bit.P4 == 1) // Burada interrupt flag kontrol edilecek
{
LED1 = 0;
LED2 = 0;
LED3 = 0;
LED4 = 0;
delay();
P1IFG_bit.P4 = 0;
}

}
/code]

Kararsız...