概述
目前,项目需要处理信号。目标信号是特定频率范围内的信号。高频视为干扰。而一阶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。
假设电路的输出阻抗很大(即不带任何负载),输入阻抗很小(理想情况)。可以得到以下公式:
电容的阻抗是。
而
截止频率,此频率下的信号,通过这个电路,输出电压和输入电压的关系式是
或者时域上的表达式:
上式离散后,可以得到:
假如要过滤掉10KHz以上的频率,可以选择fcut = 1K,并计算RC的值,代入上式。
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存放滤波结果
-
}
-
}
-
}
2、一阶RC高通滤波器的原理以及实现
2.1 原理推导
这是一节RC高通滤波器的原理图:
截止频率
写成时域上的表达式:
离散化后得到:
根据设定的截止频率,假如目标频率是50Hz,截止频率可以整定为0.5Hz,过滤低频分量,而不影响目标信号的采集。
2.2 波特图
传递函数可又频域函数转换得到,将带入频域公式。得到:
Octave绘制波特图:
-
fcut =0.5;
-
RC=1/2/pi/fcut;
-
pkg load control
-
y1 = tf([RC,0],[RC,1])
-
bode(y1)
高通滤波器对截至频率以上的信号无大影响,信号能正常经过滤波器。但是该滤波器对截至频率以下的信号,具有较大的影响。和截至频率相比,频率越小,衰减作用越明显。同时在相位图中可见,对频率越低的信号,相位移动也越大。
2.3 用C语言实现
C语言的实现1:
-
void HighPassFilter_RC_1order(float *Vi, float *Vi_p, float *Vo, float *Vo_p, float sampleFrq )
-
{
-
float CutFrq, RC, Coff;
-
//high pass filter @cutoff frequency = 0.5 Hz
-
CutFrq = 0.5;
-
RC = (float)1.0/2.0/PI/CutFrq;
-
Coff = RC/(RC + 1/sampleFrq);
-
*Vo = ((*Vi) - (*Vi_p) +(*Vo_p) )*Coff ;
-
//update
-
*Vo_p = *Vo;
-
*Vi_p = *Vi;
-
}
调用例子:
-
float b_ADCLoad1Volt, b_ADCLoad1VoltPrv, b_ADCLoad1VoltFltr, b_ADCLoad1VoltFltrPrv;
-
HighPassFilter_RC_1order(&b_ADCLoad1Volt, &b_ADCLoad1VoltPrv, &b_ADCLoad1VoltFltr, &b_ADCLoad1VoltFltrPrv, 1000.0);
调用时,1000是指每秒需要执行这个函数1000次。
C语言实现2:
-
#define PI 3.1415
-
//*********** Structure Definition ********//
-
typedef struct {
-
float Vi;
-
float Vi_prev;
-
float Vo_prev;
-
float Vo;
-
float Fcutoff;
-
float Fs;
-
} HPF_1orderRC_F;
-
//*********** Structure Init Function ****//
-
void HPF_1orderRC_F_init(HPF_1orderRC_F *v)
-
{
-
v->Vi=0;
-
v->Vi_prev=0;
-
v->Vo_prev=0;
-
v->Vo=0;
-
//high pass filter @cutoff frequency = 0.05 Hz
-
v->Fcutoff=0.05;
-
// execute 1000 every second
-
v->Fs=1000;
-
}
-
//*********** Function Definition ********//
-
float HPF_1orderRC_F_FUNC(HPF_1orderRC_F *v)
-
{
-
float RC, Coff;
-
RC = (float)1.0/2.0/PI/v->Fcutoff;
-
Coff = RC/(RC + 1/v->Fs);
-
v->Vo = (v->Vi - v->Vi_prev + v->Vo_prev ) * Coff;
-
//update
-
v->Vo_prev = v->Vo;
-
v->Vi_prev = v->Vi;
-
return v->Vo;
-
}
-
HPF_1orderRC_F hpf_1orderrc_handle;
调用例子:
-
...
-
int main(void)
-
{
-
...
-
HPF_1orderRC_F_init(&hpf_1orderrc_handle); //初始化
-
while(1)
-
{
-
...
-
if(flag_1ms==1)
-
{
-
hpf_1orderrc_handle.Vi = ADCresult; //假设ADCresult是ADC采样结果
-
FilteredResult = HPF_1orderRC_F_FUNC(&hpf_1orderrc_handle);//FilteredResult存放滤波结果
-
}
-
}
-
}
3 上机测试
板子上面MCU采用STM32F103C8,外扩了USB转UART模块,外扩了PIR+运放模块。
在STM32F103C8上面,PA7连接了某信号源。USART1和FT232模块连接,与电脑通信。
单片机对PA7的采样信号进行滤波处理,目的是把目标信号的直流部分和高频部分滤除,得到0.05Hz-5Hz以内的分量。
上位机使用了SerialChart-0.3.4,把信号波形显示。效果如下图。数据第一列是时间戳,第二列是原始数据,第三列是滤波后的数据。Chart中,蓝色是第二列原始数据,红色是第三列滤波后的数据。
可以看到,滤波器对直流信号有衰减作用。
最后
以上就是爱撒娇宝马为你收集整理的一阶RC滤波器的算法实现(低通和高通)的全部内容,希望文章能够帮你解决一阶RC滤波器的算法实现(低通和高通)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复