FIR IIR 数字滤波器 C++实现

 FIR实现,已验证
class CFilter_FIR  
{
public:
	CFilter_FIR();
	virtual ~CFilter_FIR();
private:
	double *m_pB;

	double *m_pdata_buf;

	int m_nB_order;

	int m_nFirIndex;
public:
	void reset();
	
	/*/*brief:注意:B数组为nB_order个
	*/
	*/
	void setPara(double B[], int nB_order);

	double filter(double data);
	void filter(double data[], int len);
	void filter(double data_in[], double data_out[], int len);

};

 cpp文件

CFilter_FIR::CFilter_FIR()
{
	m_pB = NULL;
	m_pdata_buf = NULL;
	m_nB_order = 0;

	m_nFirIndex = 0;
}

CFilter_FIR::~CFilter_FIR()
{
	if (m_pdata_buf)
	{
		delete m_pdata_buf;
		m_pdata_buf = NULL;
	}
	if (m_pB)
	{
		delete m_pB;
		m_pB = NULL;
	}
}
/** \brief 将滤波器的内部状态清零
 * \return
 */
void CFilter_FIR::reset()
{
    for(int i = 0; i < m_nB_order; i++)
    {
		m_pdata_buf[i] = 0.0;
    }
	m_nFirIndex = 0;
}

/** \brief 

 */  
void CFilter_FIR::setPara(double B[], int nB_order)
{
	m_nB_order = nB_order;

	if (m_pB)
	{
		delete m_pB;
	}
	if (m_pdata_buf)
	{
		delete m_pdata_buf;
	}

    m_pB = new double[nB_order ];
    m_pdata_buf = new double[nB_order ];

    for(int i = 0; i < nB_order; i++)
    {
        m_pB[i] = B[i];
        m_pdata_buf[i] = 0.0;
    }	
}


/** \brief 滤波函数
 * 
 * \param data 传入输入数据 
 * \return 滤波后的结果 
*/  
double CFilter_FIR::filter(double data)
{
	int k;
	double fOut = 0.0;
    
	int i = 0;
	m_pdata_buf[m_nFirIndex%m_nB_order] = data;
	fOut = 0.0f;
	
	for (i = 0; i < m_nB_order; ++i)
	{
		fOut += m_pdata_buf[(m_nFirIndex +i+1)%m_nB_order]*m_pB[i];
	}
	
	m_nFirIndex++;
	return fOut;
}


/** \brief 滤波函数
 * 
 * \param data[] 传入输入数据,返回时给出滤波后的结果 
 * \param len data[] 数组的长度 
 * \return 
 */   
void CFilter_FIR::filter(double data[], int len)
{
   int k;
   double fOut = 0.0;
    for(k = 0; k < len; k++)
    {
		int i = 0;
		m_pdata_buf[m_nFirIndex%m_nB_order] = data[k];
		fOut = 0.0f;
		
		for (i = 0; i < m_nB_order; ++i)
		{
			fOut += m_pdata_buf[(m_nFirIndex +i+1)%m_nB_order]*m_pB[i];
		}
		m_nFirIndex++;

		data[k] = fOut;
    
	}
}
/** \brief 滤波函数
* 
* \param data_in[] 输入数据 
* \param data_out[] 保存滤波后的数据 
* \param len 数组的长度 
* \return 
*/  
void CFilter_FIR::filter(double data_in[], double data_out[], int len)
{
    int k;
    for(k = 0; k < len; k++)
    {
		int i = 0;
		m_pdata_buf[m_nFirIndex%m_nB_order] = data_in[k];
		data_out[k] = 0.0f;
		
		for (i = 0; i < m_nB_order; ++i)
		{
			data_out[k] += m_pdata_buf[(m_nFirIndex +i+1)%m_nB_order]*m_pB[i];
		}
		m_nFirIndex++;
    }
}

 IIR实现,验证过的

class CFilter_IIR_I  
{
public:
	CFilter_IIR_I();
	virtual ~CFilter_IIR_I();
	
private:
	double *m_pNum;
	double *m_pDen;
	double *m_px;
	double *m_py;
	int m_num_order;
	int m_den_order;
public:
	void reset();
	
	/*brief:注意:num数组为num_order个,den数组为den_order个
	*/
	void setPara(double num[], int num_order, double den[], int den_order);

	void resp(double data_in[], int m, double data_out[], int n);
	double filter(double data);
	void filter(double data[], int len);
	void filter(double data_in[], double data_out[], int len);
	
};


cpp文件

CFilter_IIR_I::CFilter_IIR_I()
{
    m_pNum = NULL;
    m_pDen = NULL;
    m_px = NULL;
    m_py = NULL;
    m_num_order = -1;
    m_den_order = -1;
}

CFilter_IIR_I::~CFilter_IIR_I()
{

}
/** \brief 将滤波器的内部状态清零,滤波器的系数保留 
 * \return
 */
void CFilter_IIR_I::reset()
{
    for(int i = 0; i < m_num_order; i++)
    {
        m_pNum[i] = 0.0;
    }
    for(i = 0; i < m_den_order; i++)
    {
        m_pDen[i] = 0.0;
    }
}

/** \brief 
 * 
 * \param num 分子多项式的系数,升序排列,num[0] 为常数项 
 * \param m 分子多项式的阶数 
 * \param den 分母多项式的系数,升序排列,den[0] 为常数项 
 * \param m 分母多项式的阶数 
 * \return 
 */   
void CFilter_IIR_I::setPara(double num[], int num_order, double den[], int den_order)
{
    delete[] m_pNum;
    delete[] m_pDen;
    delete[] m_px;
    delete[] m_py;
    m_pNum = new double[num_order ];
    m_pDen = new double[den_order ];
    m_num_order = num_order;
    m_den_order = den_order;
    m_px = new double[num_order ];
    m_py = new double[den_order ];
    for(int i = 0; i < m_num_order; i++)
    {
        m_pNum[i] = num[i];
        m_px[i] = 0.0;
    }
    for(i = 0; i < m_den_order; i++)
    {
        m_pDen[i] = den[i];
        m_py[i] = 0.0;
    }
}

/** \brief 滤波函数,采用直接I型结构 
 * 
 * \param data 传入输入数据 
 * \return 滤波后的结果 
 */   
double CFilter_IIR_I::filter(double data)
{
    m_py[0] = 0.0; // ????????
    m_px[0] = data;
    for(int i = 0; i < m_num_order; i++)
    {
        m_py[0] = m_py[0] + m_pNum[i] * m_px[i];
    }
    for(i = 1; i < m_den_order; i++)
    {
        m_py[0] = m_py[0] - m_pDen[i] * m_py[i];
    }
    for(i = m_num_order-1; i >= 1; i--)
    {
        m_px[i] = m_px[i-1];
    }
    for(i = m_den_order-1; i >= 1; i--)
    {
        m_py[i] = m_py[i-1];
    }
    return m_py[0];
}


/** \brief 滤波函数,采用直接I型结构 
 * 
 * \param data[] 传入输入数据,返回时给出滤波后的结果 
 * \param len data[] 数组的长度 
 * \return 
 */    
void CFilter_IIR_I::filter(double data[], int len)
{
    int i, k;
    for(k = 0; k < len; k++)
    {
        m_px[0] = data[k];
        data[k] = 0.0;
        for(i = 0; i < m_num_order; i++)
        {
            data[k] = data[k] + m_pNum[i] * m_px[i];
        }
        for(i = 1; i < m_den_order; i++)
        {
            data[k] = data[k] - m_pDen[i] * m_py[i];
        }
        // we get the y value now
        m_py[0] = data[k];
        for(i = m_num_order-1; i >= 1; i--)
        {
            m_px[i] = m_px[i-1];
        }
        for(i = m_den_order-1; i >= 1; i--)
        {
            m_py[i] = m_py[i-1];
        }
    }
}
/** \brief 滤波函数,采用直接I型结构 
 * 
 * \param data_in[] 输入数据 
 * \param data_out[] 保存滤波后的数据 
 * \param len 数组的长度 
 * \return 
 */  
void CFilter_IIR_I::filter(double data_in[], double data_out[], int len)
{
    int i, k;
    for(k = 0; k < len; k++)
    {
        m_px[0] = data_in[k];
        m_py[0] = 0.0;
        for(i = 0; i < m_num_order; i++)
        {
            m_py[0] += m_pNum[i] * m_px[i];
        }
        for(i = 1; i < m_den_order; i++)
        {
            m_py[0] -= m_pDen[i] * m_py[i];
        }
        for(i = m_num_order-1; i >= 1; i--)
        {
            m_px[i] = m_px[i-1];
        }
        for(i = m_den_order-1; i >= 1; i--)
        {
            m_py[i] = m_py[i-1];
        }
        data_out[k] = m_py[0];
    }
}
/** \brief 计算 IIR 滤波器的时域响应,不影响滤波器的内部状态 
 * \param data_in 为滤波器的输入,0 时刻之前的输入默认为 0,data_in[M] 及之后的输入默认为data_in[M-1] 
 * \param data_out 滤波器的输出 
 * \param M 输入数据的长度 
 * \param N 输出数据的长度 
 * \return 
 */ 
void CFilter_IIR_I::resp(double data_in[], int M, double data_out[], int N)  
{  
    int i, k, il;  
    for(k = 0; k < N; k++)  
    {  
        data_out[k] = 0.0;  
        for(i = 0; i < m_num_order; i++)  
        {  
            if( k - i >= 0)  
            {  
                il = ((k - i) < M) ? (k - i) : (M - 1);  
                data_out[k] = data_out[k] + m_pNum[i] * data_in[il];  
            }  
        }  
        for(i = 1; i < m_den_order; i++)  
        {  
            if( k - i >= 0)  
            {  
                data_out[k] = data_out[k] - m_pDen[i] * data_out[k - i];  
            }  
        }  
    }  
}  


IIR参考http://blog.csdn.net/liyuanbhu/article/details/38849897#comments

  • 2
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 17
    评论
下面是一个可以在CCS运行的c程序,用于比较FIRIIR滤波器的性能: ```c #include "DSP28x_Project.h" #include "DSP2833x_Mcbsp.h" #include "DSP2833x_Xintf.h" #include "DSP2833x_Spi.h" #include "DSP2833x_Gpio.h" #include "DSP2833x_Dma.h" #define FIR_LENGTH 51 #define IIR_LENGTH 4 float32 FIR_coeff[FIR_LENGTH] = {0.0, 0.002, 0.004, 0.006, 0.008, 0.01, 0.012, 0.014, 0.016, 0.018, 0.02, 0.022, 0.024, 0.026, 0.028, 0.03, 0.032, 0.034, 0.036, 0.038, 0.04, 0.042, 0.044, 0.046, 0.048, 0.05, 0.052, 0.054, 0.056, 0.058, 0.06, 0.062, 0.064, 0.066, 0.068, 0.07, 0.072, 0.074, 0.076, 0.078, 0.08, 0.082, 0.084, 0.086, 0.088, 0.09, 0.092, 0.094, 0.096, 0.098, 0.1}; float32 IIR_coeff[IIR_LENGTH] = {0.2, -0.4, 0.6, -0.8}; float32 FIR_buffer[FIR_LENGTH]; float32 IIR_buffer[IIR_LENGTH]; float32 FIR_filter(float32 input) { int i; float32 output = 0.0; FIR_buffer[0] = input; for(i = 0; i < FIR_LENGTH; i++) { output += FIR_coeff[i] * FIR_buffer[i]; } for(i = FIR_LENGTH - 1; i > 0; i--) { FIR_buffer[i] = FIR_buffer[i - 1]; } return output; } float32 IIR_filter(float32 input) { int i; float32 output = 0.0; IIR_buffer[0] = input; for(i = 0; i < IIR_LENGTH; i++) { output += IIR_coeff[i] * IIR_buffer[i]; } for(i = IIR_LENGTH - 1; i > 0; i--) { IIR_buffer[i] = IIR_buffer[i - 1]; } return output; } void main(void) { int i; float32 input_signal[1000]; float32 output_FIR[1000]; float32 output_IIR[1000]; InitSysCtrl(); InitPieCtrl(); DINT; InitPieVectTable(); for(i = 0; i < 1000; i++) { input_signal[i] = sin(2 * PI * i / 1000); output_FIR[i] = FIR_filter(input_signal[i]); output_IIR[i] = IIR_filter(input_signal[i]); } while(1); } ``` 在上面的程序中,我们定义了FIRIIR滤波器的系数以及缓冲区,并且实现了两个滤波器的函数。然后,我们使用一个正弦波作为输入信号,并分别使用FIRIIR滤波器对信号进行处理,得到两个输出信号。 在CCS中,可以通过以下步骤来调出原始信号的时域波形、原始信号的频谱、滤波后信号的时域波形以及滤波后信号的频谱的窗口: 1. 点击“File”菜单,选择“New” -> “CCS Project”来创建一个新项目。 2. 在“Project Name”中输入项目名称,选择合适的存储路径,勾选“Use default location”选项,并选择“C2000” -> “F2837xD” -> “Empty CCS Project”作为“Project Type”,然后点击“Finish”按钮。 3. 在“Project Explorer”窗口中右键点击项目名称,选择“New” -> “Source File”,输入文件名并选择“C Source File (.c)”类型,然后点击“Finish”按钮。 4. 将上面的c程序复制到新创建的c文件中。 5. 点击“Project”菜单,选择“Properties”。 6. 在左侧导航栏中选择“C/C++ Build” -> “TI C2000 Compiler” -> “Advanced Options”。 7. 在右侧“Predefined Symbols”中添加“F28379D”符号。 8. 在左侧导航栏中选择“Build” -> “Steps”。 9. 在右侧“Commands”中添加以下命令: ``` ${CG_TOOL_ROOT}/bin/cl2000 --advice:performance=all -g --diag_warning=225 --output_file="${ConfigName}/${TargetName}.out" "${InputFilePath}" --cmd_file="${BuildArtifactFileBaseName}.cmd" ${IncludeOptions} ${SourceOptions} ``` 10. 点击“Apply”按钮,然后点击“OK”按钮。 11. 点击“Project”菜单,选择“Build All”来编译项目。 12. 点击“Debug”菜单,选择“Debug Configurations”。 13. 在左侧导航栏中选择“Texas Instruments XDS110 USB Debug Probe”并点击“New launch configuration”按钮。 14. 在“Main”选项卡中,选择“Project”为刚刚创建的项目,选择“Connection”为“Texas Instruments XDS110 USB Debug Probe”。 15. 在“Target”选项卡中,选择“Device”为“F28379D”。 16. 在“Program”选项卡中,选择“Load Program”为“${ConfigName}/${TargetName}.out”。 17. 点击“Apply”按钮,然后点击“Debug”按钮。 18. 等待CCS连接到目标设备,并在“Debug”视图中打开“Expressions”窗口。 19. 在“Expressions”窗口中添加以下表达式:input_signal[0:999]、output_FIR[0:999]、output_IIR[0:999]。 20. 点击“Run”按钮,然后在“Expressions”窗口中查看相应的变量值。 21. 点击“Window”菜单,选择“Signal Processing” -> “Real-time Graph”来打开时域波形窗口。 22. 在时域波形窗口中,点击“Add Plot”按钮并选择“input_signal”、“output_FIR”和“output_IIR”变量,然后点击“OK”按钮。 23. 点击“Window”菜单,选择“Signal Processing” -> “Spectrum Analyzer”来打开频谱分析窗口。 24. 在频谱分析窗口中,点击“Add Plot”按钮并选择“input_signal”、“output_FIR”和“output_IIR”变量,然后点击“OK”按钮。 25. 点击“Run”按钮,然后在时域波形窗口和频谱分析窗口中查看信号的时域波形和频域特性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 17
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值