This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

C2000中Fir滤波算法的疑问,求解答

Other Parts Discussed in Thread: CONTROLSUITE, TMS320F28335

借鉴controlSUITE中的DSP libraries中的Floating Point中的2833x_FIR例子代码(路径:C:\ti\controlSUITE\libs\dsp\FPU\v120\examples_ccsv4\2833x_FIR)中的滤波算法做了电流环电流采集的滤波,从ADC读取的数据转换后的约为0.8820A,经过FIR滤波后的值为4.8997A左右。

2833x_FIR例子中的滤波算法实现:

   for(i=0; i < SIGNAL_LENGTH; i++)
  {
        xn=0.5*sin(Rad) + 0.5*sin(Rad2); //Q15
        sigIn[i]=xn;
        firFP.input= xn;
        firFP.calc(&firFP);
        yn = firFP.output;
        sigOut[i]=yn;
        Rad = Rad + RadStep;
        Rad2 = Rad2 + RadStep2;
   }  

xn为信号产生,yn为滤波后的结果。

我在电流环中滤波实现的方法基本一致,如下:

 I_measure_L=left.dccurrent*0.006105;     // I = ADC1 / 4095 * 3 / (6 * RS) A   ( RS=0.02 omega)   = 25 * ADC1 / 4095

 sigIn=I_measure_L;
 sigOut = Fir_filter(sigIn);
 I_filter_L=sigOut;

float Fir_filter(float intput)
{
 float output;
 firFP.input= intput;
    firFP.calc(&firFP);
    output = firFP.output;
    return output;
}

用上位机软件获取I_measure_L,与 I_filter_L的数据,I_measure_L的平均值为0.8820,而I_filter_L的平均值为4.8997。用matlab画图,得到的曲线如下图,图中红色线是ADC采集转换后的电流值,而绿色线是对电流值进行上述滤波后的值:

而当我利用2833x_FIR例子代码中的matlab下的FIR32forC28x.m对I_measure_L的数据进行滤波,在保留原代码的基础上增加了我的数据,修改后的代码如下

%S = 0.5*(sin(2*pi*k1*i) + sin(2*pi*k2*i));
[time cur_mea cur_fit pwm] = textread('filter_pwm=1750.txt','%d%f%f%f');
%len = length(time);
S=cur_mea(1:BUFFER_SIZE);

(数据文件在附件中,文件名filter_pwm=1750.txt),其结果如下:

 

当我改变电机的转速时,电流环采集到的电流值及相应的滤波值都会有明显的变化,见图

我的问题就是为什么我在TMS320F28335中实现Fir滤波时,滤波后的结果会有平移量,请TI FAE和广大工程师朋友解答。

  • Ken,

    你使用的是几阶的FIR滤波器?

    在初始化FIR滤波器的时候有没有把对应阶数的参数赋给FIR滤波器。

    float const coeff[FIR_ORDER+1]= FIR_FP_LPF64;

    firFP.coeff_ptr=(float *)coeff;

    firFP.init(&firFP);

    另外你在watchwindow中可以查看sigOut[i],确认一下跟sigIn是否真的有偏移。

    还有,可以使用V131的例程。

    Eric

     

     

  • Eric,

    我的滤波器的初始化如下:

    // Filter Symbolic Constants                        //
    #define FIR_ORDER    63 // ORDER = NUM_TAPS - 1  
    #pragma DATA_SECTION(firFP, "firfilt");
    FIR_FP  firFP = FIR_FP_DEFAULTS;

    #pragma DATA_SECTION(coeff, "coefffilt");
    float const coeff[FIR_ORDER+1]= FIR_FP_LPF64;

    #pragma DATA_SECTION(dbuffer, "firldb")
    float dbuffer[FIR_ORDER+1];
    #pragma DATA_SECTION(sigIn, "sigIn");
    #pragma DATA_SECTION(sigOut, "sigOut"); 
    float sigIn;
    float sigOut;

    .......

    //FIR filter iniinitialize
     firFP.order=FIR_ORDER;
     firFP.dbuffer_ptr=dbuffer;
     firFP.coeff_ptr=(float *)coeff;
     firFP.init(&firFP);

    基本的配置都已设置。

    对于你说的断点单步调试,当我把sigIn的值固定为0.8820时,要经过大约40次的滤波后才能达到近似值。跟理论相符。其结果如下图1,图2所示:

    图1:第一次滤波结果 

    图2:循环45次滤波后的结果

    当sigIn的值变化时,其结果会怎样,还有待测试。

    至于V131中的例程代码和V120中的是一样的。

  • Eric,

    最近一次测试又发现新的问题。

    当我对两个变量进行滤波,

     sigIn=I_measure_L;
     sigOut= Fir_filter(sigIn);
     I_filter_L=sigOut;


     sigIn=I_measure_R;
     sigOut = Fir_filter(sigIn);
     I_filter_R=sigOut;

    或者这样写

     I_filter_L = Fir_filter(I_measure_L);
     I_filter_R = Fir_filter(I_measure_R);

    或者是这样的写法,

     sigIn_l=I_measure_L;
     sigOut_l = Fir_filter(sigIn_l);
     I_filter_L=sigOut_l;


     sigIn_r=I_measure_R;
     sigOut_r = Fir_filter(sigIn_r);
     I_filter_R=sigOut_r;

    都会出现我之前描述的问题,在watchwindow中观测的结果如图3所示:

    当我将其中一个变量的滤波过程注释掉,只对一个变量进行滤波,

     sigIn_l=I_measure_L;
     sigOut_l = Fir_filter(sigIn_l);
     I_filter_L=sigOut_l;
    /*
     sigIn_r=I_measure_R;
     sigOut_r = Fir_filter(sigIn_r);
     I_filter_R=sigOut_r;
    */

    在watchwindow中观测其滤波后的结果是令人满意的,如图4:

    图4:一个变量滤波监测结果(sigIn_r,sigOut_r是上次测试时留下的结果)

  • Ken,

    从你在watchwindow观察到的结果来看,FIR滤波器的结果是对的。

    Eric

  • 至于你新出现的问题,我在例程上进行修改,并没有出现你说的那个问题。

    在main中,

    这是使用一个FIR滤波器:

    for(i=0; i < SIGNAL_LENGTH; i++)    

     {   sigIn[i]=0;         sigOut[i]=0;         sigIn1[i]=0;         sigOut1[i]=0;     }  

    /* FIR Generic Filter Initialisation    */  

    firFP.order=FIR_ORDER;

     firFP.dbuffer_ptr=dbuffer;  

    firFP.coeff_ptr=(float *)coeff;  

    firFP.init(&firFP);

     

    for(i=0; i < SIGNAL_LENGTH; i++)  

      {     

    //xn=0.5*sin(Rad) + 0.5*sin(Rad2); //Q15      

    xn = 0.5;   sigIn[i]=xn;   

    sigIn1[i]=xn;        

    firFP.input= xn;        

    firFP.calc(&firFP);        

    yn = firFP.output;        

    sigOut[i]=yn;

     

    firFP.input = xn;        

    firFP.calc(&firFP);        

     yn = firFP.output;

     sigOut1[i]=yn;

     }

     

    这是使用两个FIR滤波器

    #pragma DATA_SECTION(firFP, "firfilt")

    #pragma DATA_SECTION(firFP1, "firfilt")

     //#pragma DATA_SECTION(firFP_c, "firfilt")

    FIR_FP  firFP = FIR_FP_DEFAULTS;

    FIR_FP  firFP1 = FIR_FP_DEFAULTS;

    FIR_FP  firFP = FIR_FP_DEFAULTS;

    FIR_FP  firFP1 = FIR_FP_DEFAULTS;

     

    main中

    /* FIR Generic Filter Initialisation    */  

    firFP.order=FIR_ORDER;

     firFP.dbuffer_ptr=dbuffer;  

    firFP.coeff_ptr=(float *)coeff;  

    firFP.init(&firFP);  

     firFP1.order=FIR_ORDER;

     firFP1.dbuffer_ptr=dbuffer;

     firFP1.coeff_ptr=(float *)coeff;  firFP1.init(&firFP);

     

    for(i=0; i < SIGNAL_LENGTH; i++)    

    {    

     //xn=0.5*sin(Rad) + 0.5*sin(Rad2); //Q15     

     xn = 0.5;   

    sigIn[i]=xn;  

     sigIn1[i]=xn;        

     firFP.input= xn;        

    firFP.calc(&firFP);       

      yn = firFP.output;        

     sigOut[i]=yn;

     firFP1.input = xn;        

    firFP1.calc(&firFP1);        

     yn = firFP1.output;

      sigOut1[i]=yn;

      Rad = Rad + RadStep;   Rad2 = Rad2 + RadStep2;   

      }

    Eric

  • 我采用的是C:\ti\controlSUITE\libs\dsp\FPU\v131\examples\2833x_FIR 例程

    这是我的main 文件

    我在watchwindow观察到的结果:

    sigOut

     

    sigOut1

     

     

     我认为可能是你的Filter函数有问题。

    还原回这种方式firFP.calc(&firFP);

    Eric

     
  • Eric,

    我说的那个问题你并没有解决,你没出现那个问题是因为你的输入是定值,xn=0.5。

    在你的程序上稍作修改,即在第二个滤波器执行前,增加一行xn=1.5,我所说的那个问题就出现了。

    代码为:

        for(i=0; i < SIGNAL_LENGTH; i++)
       {
        //xn=0.5*sin(Rad) + 0.5*sin(Rad2); //Q15
         xn = 0.5;
           sigIn[i]=xn;
           sigIn1[i]=xn;
            firFP.input= xn;
            firFP.calc(&firFP);
            yn = firFP.output;
            sigOut[i]=yn;

            xn=1.5;                      //Added by Ken Lee
            firFP1.input = xn;
            firFP1.calc(&firFP1);
            yn = firFP1.output;

            sigOut1[i]=yn;

      Rad = Rad + RadStep;
      Rad2 = Rad2 + RadStep2;
        }

    我在while循环前加断点,程序到断点时刚好运行完滤波部分,在watchwindow中观看数组sigOut、sigOut1的值,如图:

    对xn=0.5滤波后数组sigOut的值

    对xn=1.5滤波后的数组sigOut1的值

    我的问题就是为什么当滤波器前后要对多个数据进行滤波时,其输出的是对最后一个数据的结果(从实验结果来看)。

    Ken

  • 虽说是很久的帖子了,我还是回复一把试试,我认为是不能共用一个buffer,我试了一下,两个滤波器分别使用各自的buffer就行了。