MSP430 nota sorunu ve kesme

Başlatan metaltrrocker, 12 Ocak 2013, 01:12:27

metaltrrocker

arkadaşlar merhabalar yine bir msp430 sorunuyla karşı karşıyayım.Kesmeleri az çok kavradım sayılır ama bazı kafamda oturmayan şeyler var,onları sormak istiyorum.msp430 da melodi oluşturmak istiyorum.Notaları tek tek çalabiliyorum hatta sıralı çalabiliyorum ancak birden fazla notayı çalmak istediğimde for dongüsü yazıyorum belli bir sayıya kadar sayıyor dongü ve bitiyor.bu durumda 440 hz ve 392 hz'nin dalga uzunlukları aynı olmuyor ve notaların çalma süreleri de farklı oluyor.benim amacım notaların hepsini aynı sürede çaldırmak ve bu kısmı kullanarak melodiler yazmak ve çalmak.
Aşağıya kodlarımı yazıyorum ondan sonra da video ekliyorum.
Lütfen bi el atın.
video
2013 01 12 01 08 46
#include "io430.h"
#include "in430.h"



unsigned char j;
   
   void c_nota(void)        //Do notası için fonksiyon tanımladık
   {
     unsigned long i;
     for(i=0;i<=200;i++)
  {
    P1OUT = BIT6;
    __delay_cycles(1911);
    P1OUT &= ~BIT6;
    __delay_cycles(1911);
  }
   }
   void d_nota(void)       //Re notası için fonksiyon tanımladık
   {  
      unsigned long i;
      for(i=0;i<=200;i++)
  {
    P1OUT = BIT6;
    __delay_cycles(1702);      
    P1OUT &= ~BIT6;
    __delay_cycles(1702);
  }
   }
   
   void e_nota(void)       //Mi notası için fonksiyon tanımladık
   {  
      unsigned long i;
      for(i=0;i<=200;i++)
  {
    P1OUT = BIT6;
    __delay_cycles(1516);      
    P1OUT &= ~BIT6;
    __delay_cycles(1516);
  }
   }
   
   void f_nota(void)       //Fa notası için fonksiyon tanımladık
   {  
      unsigned long i;
      for(i=0;i<=200;i++)
  {
    P1OUT = BIT6;
    __delay_cycles(1431);      
    P1OUT &= ~BIT6;
    __delay_cycles(1431);
  }
   }
   
   void g_nota(void)       //Sol notası için fonksiyon tanımladık
   {  
      unsigned long i;
      for(i=0;i<=200;i++)
  {
    P1OUT = BIT6;
    __delay_cycles(1275);      
    P1OUT &= ~BIT6;
    __delay_cycles(1275);
  }
   }
   
   void a_nota(void)       //La notası için fonksiyon tanımladık
   {  
      unsigned long i;
      for(i=0;i<=200;i++)
  {
    P1OUT = BIT6;
    __delay_cycles(1136);      
    P1OUT &= ~BIT6;
    __delay_cycles(1136);
  }
   }
   
   
   void b_nota(void)       //Si notası için fonksiyon tanımladık
   {  
      unsigned long i;
      for(i=0;i<=200;i++)
  {
    P1OUT = BIT6;
    __delay_cycles(1012);      
    P1OUT &= ~BIT6;
    __delay_cycles(1012);
  }
   }
   
   void c2_nota(void)       //Do2 notası için fonksiyon tanımladık
   {  
      unsigned long i;
      for(i=0;i<=200;i++)
  {
    P1OUT = BIT6;
    __delay_cycles(955);      
    P1OUT &= ~BIT6;
    __delay_cycles(955);
  }
   }
   




int main( void )
{
  // Stop watchdog timer to prevent time out reset
  WDTCTL = WDTPW + WDTHOLD;
  P1DIR = BIT6;                 //p1.6 PORTUNU ÇIKIŞ OLARAK AYARLADIK
  P1OUT = 0X00;                 //P1.6 PORTUNU SIFIRLADIK
  __delay_cycles(10000);       //rüzgün çalışması için delay verdik
  TACCTL0 = CCIE;               //timerA interrupt enable
  TACCR0  =50000;               //TİMERA 50000'e kadar sayacak
  TACTL   =TASSEL_2 + MC_1 + TAIE;     //MODLARI SAÇTİK
  _BIS_SR(GIE);                 //tüm genel kesmelere izin verdik
  for(;;);                      //sonsuz dongüye gidilerek kesmeler bekleniyor
}


#pragma vector =TIMER0_A0_VECTOR        //timerA kesme vectorü tanımlaması
__interrupt void Timer_A0 (void)
{
       c_nota();
       d_nota();
       e_nota();
       f_nota();
       g_nota();
       a_nota();
       b_nota();
       c2_nota();
  //TAIFG = 0x00;
}

berat23

#1
ben olsam byle yapmam.

bence notaları sadece temel frekanslarıyla değilde 3-5 harmoniği ile beraber ,en düşük frekanslı harmoniğin 1 periyodu sürede örnekleyip öyle çalmak daha mantıklı.

illa kendi yazdığını değiştirmek istiyorsan,for döngüsünün tekrar sayısını notaların periyoduna oranlaman lazım. yani hepsi 200 tekrar yapmayacak,do dan do ya 2 kat süre farkı var,ona göre düzenlersen yazdığın kod istediğin gibi çalışır.

metaltrrocker

#2
hocam for döngüsüyle uğraşmadan yapılabilecek bir yöntem varmı peki?

mesaj birleştirme:: 13 Ocak 2013, 06:06:37

Sonunda üşengeçliğimden kurtulup for döngüsündeki değişkenle oynayıp ilk notayı referans alıp diğerlerinin çalma sürelerini ona göre ayarladım.bir sonraki adım olarak 1-2-4-8-16-32 lik notalar ve şarkıları rahat çalabilmek için 3 oktavlık nota tanımı yapacam.
fonksiyon kullanımı şöyle olacak do için==> c_nota(nota_olcusu);
bakalım artık entegrenin hafızası bu kadar kodu kaldırır umarım:(
kodları aşağıya yazıyorum ses ile ilgili pek türkçe kaynak bulamadığım için çalışan kodları bu sayfa üzerinden paylaşacağım.
aşağıdaki kodlar temel do majör gamını çalıyor.(do-re-mi-fa-sol-la-si-do)
#include "io430.h"
#include "in430.h"



unsigned char j;
   
   void c_nota(void)        //Do notası için fonksiyon tanımladık
   {
     unsigned long i;
     for(i=0;i<=200;i++)
  {
    P1OUT = BIT6;
    __delay_cycles(1911);
    P1OUT &= ~BIT6;
    __delay_cycles(1911);
  }
   }
   void d_nota(void)       //Re notası için fonksiyon tanımladık
   {  
      unsigned long i;
      for(i=0;i<=224;i++)
  {
    P1OUT = BIT6;
    __delay_cycles(1702);      
    P1OUT &= ~BIT6;
    __delay_cycles(1702);
  }
   }
   
   void e_nota(void)       //Mi notası için fonksiyon tanımladık
   {  
      unsigned long i;
      for(i=0;i<=252;i++)
  {
    P1OUT = BIT6;
    __delay_cycles(1516);      
    P1OUT &= ~BIT6;
    __delay_cycles(1516);
  }
   }
   
   void f_nota(void)       //Fa notası için fonksiyon tanımladık
   {  
      unsigned long i;
      for(i=0;i<=267;i++)
  {
    P1OUT = BIT6;
    __delay_cycles(1431);      
    P1OUT &= ~BIT6;
    __delay_cycles(1431);
  }
   }
   
   void g_nota(void)       //Sol notası için fonksiyon tanımladık
   {  
      unsigned long i;
      for(i=0;i<=300;i++)
  {
    P1OUT = BIT6;
    __delay_cycles(1275);      
    P1OUT &= ~BIT6;
    __delay_cycles(1275);
  }
   }
   
   void a_nota(void)       //La notası için fonksiyon tanımladık
   {  
      unsigned long i;
      for(i=0;i<=336;i++)
  {
    P1OUT = BIT6;
    __delay_cycles(1136);      
    P1OUT &= ~BIT6;
    __delay_cycles(1136);
  }
   }
   
   
   void b_nota(void)       //Si notası için fonksiyon tanımladık
   {  
      unsigned long i;
      for(i=0;i<=378;i++)
  {
    P1OUT = BIT6;
    __delay_cycles(1012);      
    P1OUT &= ~BIT6;
    __delay_cycles(1012);
  }
   }
   
   void c2_nota(void)       //Do2 notası için fonksiyon tanımladık
   {  
      unsigned long i;
      for(i=0;i<=400;i++)
  {
    P1OUT = BIT6;
    __delay_cycles(955);      
    P1OUT &= ~BIT6;
    __delay_cycles(955);
  }
   }
   




int main( void )
{
  // Stop watchdog timer to prevent time out reset
  WDTCTL = WDTPW + WDTHOLD;
  P1DIR = BIT6;                 //p1.6 PORTUNU ÇIKIŞ OLARAK AYARLADIK
  P1OUT = 0X00;                 //P1.6 PORTUNU SIFIRLADIK
  
  __delay_cycles(10000);       //rüzgün çalışması için delay verdik
  TACCTL0 = CCIE;               //timerA interrupt enable
  //TACCTL1 = CCIE;
  TA0CCR0  =100000;               //TİMERA 50000'e kadar sayacak
  TA0CCR1  =1136;
  TACTL   =TASSEL_2 + MC_1 + TAIE;     //MODLARI SAÇTİK
  //TACTL   =TASSEL_1 + MC_1 + TAIE;
  _BIS_SR(GIE);                 //tüm genel kesmelere izin verdik
  for(;;);                      //sonsuz dongüye gidilerek kesmeler bekleniyor
}





#pragma vector =TIMER0_A0_VECTOR        //timerA kesme vectorü tanımlaması
__interrupt void Timer_Kesmesi (void)
{
       
       c_nota();
       d_nota();
       e_nota();
       f_nota();
       g_nota();
       a_nota();
       b_nota();
       c2_nota();
  
  
     
  //TAIFG = 0x00;
}