最近導師要求我將師兄寫的一篇關於fsk調製解調的MATLAB代碼用VS2013編成C語言,方便後續應用到工程實踐中。由於本人編程水平有限,並且C語言只有在大學的時候水水的學過一遍,所以此次代碼可能有許多疏漏,歡迎批評指正。
1.明確目標
本次要用C語言實現如下代碼功能:
recv_lowfilter = fir1(256,1.2*2*Br/fs);
這是一句MATLAB代碼,該句代碼的重點在於 fir1 這個函數。
2.明確功能
fir1 這個函數是MATLAB中的自帶函數,但是C語言中卻沒有該功能函數,因此,要首先弄清楚該函數實現的功能。所以,我去查找了MATLAB的官網。
此處爲該函數的連接:https://ww2.mathworks.cn/help/signal/ref/fir1.html
fir1 是根據窗函數法設計的有限長濾波器。本次我們只實現第一個句法,即只輸入兩個參數n和Wn,來實現一個濾波器。
我們可以來看一下參數列表:
輸入參數:n 是濾波器的階數,Wn是濾波器的截止頻率。
輸出參數:b是濾波器的參數,長度是n+1。
功能總結:就是輸入濾波器的階數和截止頻率,fir1函數會返回一個長度爲n+1的向量,該向量的組成爲濾波器的係數(B(z) = b(1) + b(2)z + … + b(n+1)z–n.)。
3.原理及實現流程
原理:
理想濾波器的衝擊響應是非因果的、無限長的,窗函數法是從時域出發,用因果的、有限長的衝擊響應去逼近非因果的無限長的理想濾波器。窗函數的作用相當於截取其中的一段。
其中hd(n)是理想的無限長的非因果的濾波器,w(n)是窗函數,h(n)是我們用窗函數逼近的濾波器,即我們所求。
fir1函數中,默認使用hamming窗,該窗的計算公式爲:
流程:
4.代碼
#include <stdio.h>
#include <math.h>
#include<vector>
#define PI 3.1415926f
using namespace std;
vector <double> fir1(int N, double w) //N=256,hamming,N爲階數256,濾波器長度是N+1=257
{
int a = N / 2; //這裏的N是階數,是長度-1
vector <int> n;
int i0;
for (i0 = 0; i0 <= N; i0++)
{
n.push_back(i0);
}
int len_n = n.size();
int i1;
vector <double> m;
for (i1 = 0; i1 < len_n; i1++)
{
double eps = 2.2204e-16;
m.push_back(n[i1] - a + eps);
}
int len_m = m.size();
vector <double> h;//ideal理想濾波器
int i2;
for (i2 = 0; i2 < len_m; i2++)
{
h.push_back(sin(w * m[i2]) / (PI * m[i2]));
}
vector <double> B;//hamming窗係數
int i3;
for (i3 = 0; i3 < N; i3++)
{
B.push_back(0.54 - 0.46*cos(2.0 * PI * i3 / (N - 1)));
}
//hd = h.* B
vector <double> hd;
int i4;
for (i4 = 0; i4 < N; i4++)
{
hd.push_back( h[i4] * B[i4]);
}
return hd;
}