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] (http://bit.ly/V0BZqe)
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ü...
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.
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.
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.
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.
İ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]
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]