Sinus ve Cosinus sinyal dizisi üreteci

Başlatan fırat, 16 Temmuz 2017, 15:23:23

fırat

Formun genelinde sinus üreteci ile ilgili bazı sıkıntılar ve yardım ihtiyaçları mevcut. Birden fazla başlık altında oldukları
için bende yeni bir başlıkla ihtiyacı olan arkadaşlara çözüm olabilecek yazdığım bir fonksiyonu paylaşmak istedim.

Bu fonksiyonu aşağıdaki configuration ile kullanmaktayım;

   #include <33FJ128MC708.h>   
   #FUSES HS                       
   #FUSES PR_PLL                   
   #device ADC=12
   #use delay (clock=80M, crystal=10M)

   #include <math.h> // mutlaka projeye eklenmeli

fonksiyona ait çıkış grafikleri:



/**************************************************************************************************************************************************************************
***************************************************************************************************************************************************************************
***************************************************************************************************************************************************************************
Bu fonksiyon ile sinus yada cosinus formunda frekansı, genliği ve ofseti ayarlanabilen
istenilen örnek sayısana sahip 12 bit çözünürlükte sinyal dizisi oluşturabilirsiniz.

sin_cos_uretec(   *dizi,                       --> üretilecek dizinin kayıt edileceği dizinin adresi. 
                  float V_tepe,                --> 0 ile 1 arasında seçilebilen float değer. 1 değeri max. voltaj değeridir.
                  float frekans,               --> bir dizi içindeki periyot sayısını belirler. 
                  unsigned int16 ornek_sayisi, --> dizinin eleman sayısını belirler 
                  signed int pol,              --> 1 ise sinyal pozitif alandadır. 0 ise simetriktir. -1 ise negatif alandadır.
                  char form                    --> 0 ise cosinus form, 1 ise sinus form üretilir.
              )


örnek:-----------------------------

int16 sinyal[360];

sin_cos_uretec(sinyal,1,1,360,0,1);   // sinyal adlı dizi içine max genlikte, 1 tam periyotta, 360 elemanlı, simetrik sinüs formu üret.
      
for(i=0;i<360;i++)                    // uart birimi üzerinden üretilen değerleri pc'ye gönder 
{   
   printf ("%d;%d;\n\r", i, sinyal[i]);
   Delay_ms(1); 
} 

*/

void sin_cos_uretec( *dizi, float V_tepe, float frekans, unsigned int16 ornek_sayisi, signed int pol, char form )
{ 
   unsigned int16 t;
   float Decimal_max=2047;             // pozitif alternansda decimal tepe değeri (sabit)
   float voltaj_deger_float;           
   float derece_step;                  // 360 dereceyi örnek sayısına böldüğünüzde elde edeceğiniz örnek başına hesaplanacak açı değeri.
   int16 voltaj_deger_int=0;
   int16 Vmin_genlik = 10000;          // min değeri bulmak icin yüksek değer yüklenir
   int16 Vmax_genlik = 0;              // max değeri bulmak icin 0 değeri yüklenir
   int16 Vmax_Vmin_fark_simetri=0;
   int16 Vmax_Vmin_fark_negatif=0;
   float omega;
   
   // örnek sayısı ne olursa olsun bir tam periyot için 360 derecelik hesaplama yapılır.
   // hesaplanacak herbir değer için kaç derecelik işlem yapılacağı "derece_step" ile belirlenir.
   derece_step = (float)360 / (float)ornek_sayisi;   
      
   for(t=0;t<ornek_sayisi;t++)
   { 
      // o an işlenecek olan örnek sayısı değeri ile anlık derece değerinin çarpımını 180 dereceye 
      // bölersek açı değerini radyan cinsine çeviririz.      
      
      omega = PI * frekans * ( ((float)t * derece_step)/ (float)180);
      
      switch(form) 
      {      
         case 0: // cosinus için
            voltaj_deger_float = cos(omega);   
            break;
         
         case 1: // sinus için
            voltaj_deger_float = sin(omega);   
            break;
      }
      
      // Bu satır ile anlık voltaj değerinin istenilen voltaj seviyeye çekilmesi
      // sağlanır. Anlık genlik değeri, Vp genlik katsayısı ile çarpılarak sinyalin 
      // Vmax değeri kontrol edilir.Decimal_max ile çarpılarak -2047 ile +2048 
      // arasına ölçeklenir.  
      
      voltaj_deger_int = (signed int16)( V_tepe * voltaj_deger_float * Decimal_max ); 
      
      // Tüm dizi içinde en küçük ve en büyük değer tespit edilir. ( DC ofset kontrolü için)
      
      if( voltaj_deger_int < Vmin_genlik ) Vmin_genlik = voltaj_deger_int;            
      if( voltaj_deger_int > Vmax_genlik ) Vmax_genlik = voltaj_deger_int;
      
      dizi[t] = voltaj_deger_int; 
   }  
   
   Vmax_Vmin_fark_simetri = (Vmax_genlik - Vmin_genlik)/2;
   Vmax_Vmin_fark_negatif = (Vmax_genlik - Vmin_genlik);
  
   switch(pol) // dc ofset kontrolü ile polarite belirlenir.
   {                                                                           
      case 1: // pozitif bölgede -----------------------------------------------------------------------------------------   
                                                                               //    4095 |     * *                          
         for(t=0;t<ornek_sayisi;t++)                                           //         |   *     *                        
         {                                                                     //         | *         *                      
             dizi[t] =  dizi[t] - Vmin_genlik ;                                //         |*           *           *         
         }                                                                     //         |             *         *          
         break;                                                                //         |               *     *            
                                                                               //       0 |                 * *              
      case 0: // simetri -------------------------------------------------------------------------------------------------                                                                
                                                                               //    2048 |     * *                        
         for(t=0;t<ornek_sayisi;t++)                                           //         |   *     *                      
         {                                                                     //         | *         *                    
             dizi[t] =  dizi[t] - Vmin_genlik - Vmax_Vmin_fark_simetri ;       //      0  |*           *       
         }                                                                     //         |             *         *        
         break;                                                                //         |               *     *          
                                                                               //   -2047 |                 * *            
      case -1: // negatif bölgede ----------------------------------------------------------------------------------------
                                                                               //       0 |     * *                     
         for(t=0;t<ornek_sayisi;t++)                                           //         |   *     *                   
         {                                                                     //         | *         *                       
               dizi[t] =  dizi[t] - Vmin_genlik - Vmax_Vmin_fark_negatif ;     //         |*           *           *    
         }                                                                     //         |             *         *     
         break;                                                                //         |               *     *       
   }                                                                           //   -4095 |                 * *  
           //-------------------------------------------------------------------------------------------------------------
}

 
//*************************************************************************************************************************************************************************
//*************************************************************************************************************************************************************************
//*************************************************************************************************************************************************************************