目前,项目需要处理信号。目标信号是特定频率范围内的信号。高频视为干扰。而一阶RC滤波器容易实现。但是网上资料往往没有详细的推导。因此在这里把笔记记下。本文的优势是比较详细,参数配置都有公式依据。
目录
1、一阶RC低通滤波器的算法实现
1.1 算法推导
1.2 波特图
1.3 用C语言实现
2、一阶RC高通滤波器的原理以及实现
2.1 原理推导
2.2 波特图
2.3 用C语言实现
3 上机测试
1、一阶RC低通滤波器的算法实现
1.1 算法推导
一阶RC滤波器的硬件电路如图:
图中输入电压是Vi,电阻R,电容C,输出电压为Vo。
假设电路的输出阻抗很大(即不带任何负载),输入阻抗很小(理想情况)。可以得到以下公式:
1.2 波特图
用Octave或者Matlab可以得到传递函数的波特图:
fcut =1000;
RC=1/2/pi/fcut;
%pkg load control %Octave用的读取control包
y1 = tf(1,[RC,1])
bode(y1)
以上波特图可见,在截止频率处(,代入f=1k,可得截至角频率是6283 rad/s),信号会衰减到原来的0.707。这电路对频率大于截止频率的高频信号,具有比较强的衰减作用,同时对该信号有比较大的相位移动。
1.3 用C语言实现
C语言的实现1
/**
* @brief implement 1 order RC low pass filter
* raw data filtered by a simple RC low pass filter@cufoff=5Hz
* @param Vi : Vi(k)
* @param Vi_p : Vi(k-1)
* @param Vo : Vo(k)
* @param Vo_p : Vo(k-1)
* @note This example shows a simple way to report end of conversion
* and get conversion result. You can add your own implementation.
* @retval None
*/
void LowPassFilter_RC_1order(float *Vi, float *Vo, float *Vo_p, float sampleFrq )
{
float CutFrq, RC, Cof1, Cof2;
//low pass filter @cutoff frequency = 5 Hz
CutFrq = 5;
RC = (float)1.0/2.0/PI/CutFrq;
Cof1 = 1/(1+RC*sampleFrq);
Cof2 = RC*sampleFrq/(1+RC*sampleFrq);
*Vo = Cof1 * (*Vi) + Cof2 * (*Vo_p);
//update
*Vo_p = *Vo;
}
调用例子:
float b_ADCLoad1Volt, b_ADCLoad1VoltFltr, b_ADCLoad1VoltFltrPrv;
LowPassFilter_RC_1order(&b_ADCLoad1Volt, &b_ADCLoad1VoltFltr, &b_ADCLoad1VoltFltrPrv, 1000.0);
C语言实现2:
//*********** Structure Definition ********//
typedef struct {
float Vi;
float Vo_prev;
float Vo;
float Fcutoff;
float Fs;
} LPF_1orderRC_F;
//*********** Structure Init Function ****//
void LPF_1orderRC_F_init(LPF_1orderRC_F *v)
{
v->Vi=0;
v->Vo_prev=0;
v->Vo=0;
//low pass filter @cutoff frequency = 5 Hz
v->Fcutoff=5;
// execute 1000 every second
v->Fs=1000;
}
//*********** Function Definition ********//
float LPF_1orderRC_F_FUNC(LPF_1orderRC_F *v)
{
float RC, Cof1, Cof2;
RC = (float)1.0/2.0/PI/v->Fcutoff;
Cof1 = 1/(1+RC*v->Fs);
Cof2 = RC*v->Fs/(1+RC*v->Fs);
v->Vo = Cof1 * v->Vi + Cof2 * v->Vo_prev;
v->Vo_prev = v->Vo;
return v->Vo;
}
LPF_1orderRC_F lpf_1orderrc_handle;
调用方式:
...
int main(void)
{
...
LPF_1orderRC_F_init(&lpf_1orderrc_handle); //初始化
while(1)
{
...
if(flag_1ms==1)
{
lpf_1orderrc_handle.Vi = ADCresult; //假设ADCresult是ADC采样结果
LPF_1orderRC_F_FUNC(&lpf_1orderrc_handle); //usage
FilteredResult = lpf_1orderrc_handle.Vo; //FilteredResult存放滤波结果
}
}
}