一阶RC滤波器的算法实现(低通和高通) | 您所在的位置:网站首页 › 低通滤波器参数设计原理 › 一阶RC滤波器的算法实现(低通和高通) |
目前,项目需要处理信号。目标信号是特定频率范围内的信号。高频视为干扰。而一阶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)以上波特图可见,在截止频率处( 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,过滤低频分量,而不影响目标信号的采集。 传递函数可又频域函数转换得到,将 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中,蓝色是第二列原始数据,红色是第三列滤波后的数据。 可以看到,滤波器对直流信号有衰减作用。 |
CopyRight 2018-2019 实验室设备网 版权所有 |