costas_loop.cpp
上传用户:jtjnyq9001
上传日期:2014-11-21
资源大小:3974k
文件大小:6k
源码类别:

3G开发

开发平台:

Visual C++

  1. //
  2. //  File = costas_loop.cpp
  3. //
  4. //#include <stdlib.h>
  5. //#include <fstream.h>
  6. #include "parmfile.h"
  7. #include "misdefs.h"
  8. #include "model_error.h"
  9. #include "costas_loop.h"
  10. #include "butt_filt_iir.h"
  11. #include "model_graph.h"
  12. //#include "sinc.h"
  13. extern ParmFile *ParmInput;
  14. extern PracSimModel *ActiveModel;
  15. //======================================================
  16. CostasLoop::CostasLoop( char* instance_name,
  17.                         PracSimModel* outer_model,
  18.                         Signal<float>* fsig_input,
  19.                         Signal<float>* fsig_phase_error,
  20.                         Signal<float>* fsig_filtered_error,
  21.                         Signal<float>* fsig_vco_output,
  22.                         Signal<float>* vco_freq_sig,
  23.                         Signal<float>* ref_phase_sig,
  24.                         Signal<float>* out_sig )
  25.                 :PracSimModel(instance_name,
  26.                               outer_model)
  27. {
  28.    MODEL_NAME(CostasLoop);
  29.    //---------------------------------------
  30.    //  Read model config parms
  31.    OPEN_PARM_BLOCK;
  32.    GET_DOUBLE_PARM(K_Sub_D);
  33.    GET_DOUBLE_PARM(K_Sub_0);
  34.    GET_DOUBLE_PARM(Center_Freq_Hz);
  35.    GET_BOOL_PARM(m_UsingDco);
  36.    //GET_DOUBLE_PARM(Scaler_Divisor);
  37.    Scaler_Divisor = 1.0;
  38.    //--------------------------------------
  39.    //  Connect input and output signals
  40.    fsig_Input = fsig_input;
  41.    fsig_Phase_Error = fsig_phase_error;
  42.    fsig_Filtered_Error = fsig_filtered_error;
  43.    fsig_Osc_Output = fsig_vco_output;
  44.    fsig_Osc_Freq = vco_freq_sig;
  45.    fsig_Osc_Phase = ref_phase_sig;
  46.    fsig_Output = out_sig;
  47.    MAKE_OUTPUT( fsig_Output );
  48.    MAKE_OUTPUT( fsig_Phase_Error );
  49.    MAKE_OUTPUT( fsig_Filtered_Error );
  50.    MAKE_OUTPUT( fsig_Osc_Output );
  51.    MAKE_OUTPUT( fsig_Osc_Freq );
  52.    MAKE_OUTPUT( fsig_Osc_Phase );
  53.    MAKE_INPUT( fsig_Input );
  54.    //----------------------------------
  55.    //  Compute derived parameters
  56.    Omega_Sub_0 = TWO_PI * Center_Freq_Hz;
  57.    //--------------------------------
  58.    // create loop filter object
  59.    char sub_name[50];
  60.    strcpy(sub_name, GetInstanceName());
  61.    strcat(sub_name, ":I_Filter");
  62.    I_Filter_Core = new ButterworthFilterByIir<float>( sub_name, this);
  63.    strcpy(sub_name, GetInstanceName());
  64.    strcat(sub_name, ":Q_Filter");
  65.    Q_Filter_Core = new ButterworthFilterByIir<float>( sub_name, this);
  66.    strcpy(sub_name, GetInstanceName());
  67.    strcat(sub_name, ":Prod_Filter");
  68.    Prod_Filter_Core = new ButterworthFilterByIir<float>( sub_name, this);
  69. }
  70. //======================================
  71. CostasLoop::~CostasLoop( void ){ };
  72. //=======================================
  73. void CostasLoop::Initialize(void)
  74. {
  75.    //------------------
  76.    int block_size = fsig_Output->GetBlockSize();
  77.    Samp_Intvl = fsig_Input->GetSampIntvl();
  78.    I_Filter_Core->Initialize(block_size, Samp_Intvl);
  79.    Q_Filter_Core->Initialize(block_size, Samp_Intvl);
  80.    Prod_Filter_Core->Initialize(block_size, Samp_Intvl);
  81.    Osc_Output_Prev_Val = 0.0;
  82.    I_OscOutput = 0;
  83.    Q_OscOutput = 0;
  84.    Phi_Sub_2 = 0;
  85.    Phi_Divided = 0;
  86. }
  87. //=======================================================
  88. int CostasLoop::Execute()
  89. {
  90.    // pointers for signal data
  91.    float *fsOutput_ptr;
  92.    float *fsPhaseError_ptr;
  93.    float *fs_filtered_error_ptr;
  94.    float *fsOscOutput_ptr;
  95.    float *fsOscFreq_ptr;
  96.    float *fsOscPhase_ptr;
  97.    float *fsInput_ptr;
  98.    float input_val;
  99.    float osc_output_val;
  100.    float i_filt_val;
  101.    float q_filt_val;
  102.    float inst_freq;
  103.    double samp_intvl;
  104.    double error_val;
  105.    double filt_val;
  106.    double i_arm_product;
  107.    double q_arm_product;
  108.    double err_sum=0;
  109.    double err_avg;
  110.    int is;
  111.    int block_size;
  112.    //--------------------------------------------------------------
  113.    // set up pointers to data buffers for input and output signals
  114.    fsOutput_ptr = GET_OUTPUT_PTR( fsig_Output );
  115.    fsPhaseError_ptr = GET_OUTPUT_PTR( fsig_Phase_Error );
  116.    fs_filtered_error_ptr = GET_OUTPUT_PTR( fsig_Filtered_Error );
  117.    fsOscOutput_ptr = GET_OUTPUT_PTR( fsig_Osc_Output );
  118.    fsOscFreq_ptr = GET_OUTPUT_PTR( fsig_Osc_Freq );
  119.    fsOscPhase_ptr = GET_OUTPUT_PTR( fsig_Osc_Phase );
  120.    fsInput_ptr = GET_INPUT_PTR( fsig_Input );
  121.    //---------------------------------------------------------------
  122.    samp_intvl = Samp_Intvl;
  123.    osc_output_val = Osc_Output_Prev_Val;
  124.    block_size = fsig_Input->GetValidBlockSize();
  125.    fsig_Output->SetValidBlockSize(block_size);
  126.    fsig_Phase_Error->SetValidBlockSize(block_size);
  127.    fsig_Filtered_Error->SetValidBlockSize(block_size);
  128.    fsig_Osc_Output->SetValidBlockSize(block_size);
  129.    fsig_Osc_Freq->SetValidBlockSize(block_size);
  130.    fsig_Osc_Phase->SetValidBlockSize(block_size);
  131.    //-------------------------------------------------------
  132.    for (is=0; is<block_size; is++)
  133.    {
  134.       *fsOscOutput_ptr++ = osc_output_val;
  135.       input_val = *fsInput_ptr;
  136.       i_arm_product = K_Sub_D * input_val * I_OscOutput;
  137.       q_arm_product = K_Sub_D * input_val * Q_OscOutput;
  138.       *fsPhaseError_ptr++ = i_arm_product;
  139.       //--------------------------------
  140.       //  filter the arm signals
  141.       i_filt_val = I_Filter_Core->ProcessSample(i_arm_product);
  142.       *fs_filtered_error_ptr++ = i_filt_val;
  143.       q_filt_val = Q_Filter_Core->ProcessSample(q_arm_product);
  144.       //----------------------------------------
  145.       //  multiply arm signals
  146.       error_val = i_filt_val * q_filt_val;
  147.       //----------------------------------------
  148.       //  filter the result
  149.       filt_val = Prod_Filter_Core->ProcessSample(error_val);
  150.       //----------------------------------------
  151.       // use filtered error signal to drive VCO
  152.       inst_freq = Omega_Sub_0 + K_Sub_0 * filt_val;
  153.       Phi_Sub_2 += inst_freq * samp_intvl;
  154.       if(Phi_Sub_2 > PI) Phi_Sub_2 -= TWO_PI;
  155.       I_OscOutput = -sin(Phi_Sub_2);
  156.       Q_OscOutput = -cos(Phi_Sub_2);
  157.       *fsOscPhase_ptr++ = Phi_Sub_2;
  158.       *fsOscFreq_ptr++ = inst_freq/TWO_PI;
  159.       Phi_Divided += inst_freq * samp_intvl/Scaler_Divisor;
  160.       if(Phi_Divided > PI) Phi_Divided -= TWO_PI;
  161.       *fsOutput_ptr++ = sin(Phi_Divided);
  162.       fsInput_ptr++;
  163.    }
  164.    err_avg = err_sum / block_size;
  165.    BasicResults << "avg PLL error = " << err_avg << endl;
  166.    Osc_Output_Prev_Val = osc_output_val;
  167.   return(_MES_AOK);
  168. }