一阶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。

假设电路的输出阻抗很大(即不带任何负载),输入阻抗很小(理想情况)。可以得到以下公式:

V_o = \frac{1}{1+j\omega RC}V_i

电容的阻抗是Z_C = \frac{1}{j\omega C}

\omega = 2\pi f

截止频率f_{cut} = \frac{1}{2\pi RC},此频率下的信号,通过这个电路,输出电压和输入电压的关系式是V_o = \frac{1}{1+j}V_i

或者时域上的表达式:

V_o = V_i - RC\frac{dV_o}{dt}

上式离散后,可以得到:

V_o\left ( k \right )=\frac{V_i\left ( k \right )+\frac{RC}{T_s}V_o\left ( k-1 \right )}{1+\frac{RC}{T_s}}

假如要过滤掉10KHz以上的频率,可以选择fcut = 1K,并计算RC的值,代入上式。

1.2 波特图

用Octave或者Matlab可以得到传递函数的波特图:

 
  1. fcut =1000;

  2. RC=1/2/pi/fcut;

  3. %pkg load control %Octave用的读取control包

  4. y1 = tf(1,[RC,1])

  5. bode(y1)

以上波特图可见,在截止频率处(\omega =2\pi f,代入f=1k,可得截至角频率是6283 rad/s),信号会衰减到原来的0.707。这电路对频率大于截止频率的高频信号,具有比较强的衰减作用,同时对该信号有比较大的相位移动。

 

1.3 用C语言实现

C语言的实现1

 
  1. /**

  2. * @brief implement 1 order RC low pass filter

  3. * raw data filtered by a simple RC low pass filter@cufoff=5Hz

  4. * @param Vi : Vi(k)

  5. * @param Vi_p : Vi(k-1)

  6. * @param Vo : Vo(k)

  7. * @param Vo_p : Vo(k-1)

  8. * @note This example shows a simple way to report end of conversion

  9. * and get conversion result. You can add your own implementation.

  10. * @retval None

  11. */

  12. void LowPassFilter_RC_1order(float *Vi, float *Vo, float *Vo_p, float sampleFrq )

  13. {

  14. float CutFrq, RC, Cof1, Cof2;

  15.  
  16. //low pass filter @cutoff frequency = 5 Hz

  17. CutFrq = 5;

  18. RC = (float)1.0/2.0/PI/CutFrq;

  19. Cof1 = 1/(1+RC*sampleFrq);

  20. Cof2 = RC*sampleFrq/(1+RC*sampleFrq);

  21. *Vo = Cof1 * (*Vi) + Cof2 * (*Vo_p);

  22.  
  23. //update

  24. *Vo_p = *Vo;

  25. }

调用例子:

 
  1.  
  2. float b_ADCLoad1Volt, b_ADCLoad1VoltFltr, b_ADCLoad1VoltFltrPrv;

  3.  
  4.  
  5. LowPassFilter_RC_1order(&b_ADCLoad1Volt, &b_ADCLoad1VoltFltr, &b_ADCLoad1VoltFltrPrv, 1000.0);

C语言实现2:

 
  1.  
  2. //*********** Structure Definition ********//

  3. typedef struct {

  4. float Vi;

  5. float Vo_prev;

  6. float Vo;

  7. float Fcutoff;

  8. float Fs;

  9. } LPF_1orderRC_F;

  10. //*********** Structure Init Function ****//

  11. void LPF_1orderRC_F_init(LPF_1orderRC_F *v)

  12. {

  13. v->Vi=0;

  14. v->Vo_prev=0;

  15. v->Vo=0;

  16.  
  17. //low pass filter @cutoff frequency = 5 Hz

  18. v->Fcutoff=5;

  19.  
  20. // execute 1000 every second

  21. v->Fs=1000;

  22. }

  23.  
  24. //*********** Function Definition ********//

  25. float LPF_1orderRC_F_FUNC(LPF_1orderRC_F *v)

  26. {

  27. float RC, Cof1, Cof2;

  28.  
  29. RC = (float)1.0/2.0/PI/v->Fcutoff;

  30. Cof1 = 1/(1+RC*v->Fs);

  31. Cof2 = RC*v->Fs/(1+RC*v->Fs);

  32.  
  33. v->Vo = Cof1 * v->Vi + Cof2 * v->Vo_prev;

  34.  
  35. v->Vo_prev = v->Vo;

  36.  
  37. return v->Vo;

  38. }

  39.  
  40. LPF_1orderRC_F lpf_1orderrc_handle;

  41.  

调用方式:

 
  1. ...

  2. int main(void)

  3. {

  4. ...

  5. LPF_1orderRC_F_init(&lpf_1orderrc_handle); //初始化

  6. while(1)

  7. {

  8. ...

  9. if(flag_1ms==1)

  10. {

  11. lpf_1orderrc_handle.Vi = ADCresult; //假设ADCresult是ADC采样结果

  12. LPF_1orderRC_F_FUNC(&lpf_1orderrc_handle); //usage

  13. FilteredResult = lpf_1orderrc_handle.Vo; //FilteredResult存放滤波结果

  14. }

  15. }

  16. }

  17.  

 

 

 

 2、一阶RC高通滤波器的原理以及实现

2.1 原理推导

这是一节RC高通滤波器的原理图:

V_o = \frac{1}{1+\frac{1}{j\omega RC}}V_i

截止频率f_{cut} = \frac{1}{2\pi RC}

写成时域上的表达式:

V_o = C\frac{d\left ( V_i - V_o \right )}{dt}R

离散化后得到:

V_o\left ( k \right )=\left ( V_i\left ( k \right )-V_i\left ( k-1 \right )+V_o\left ( k-1 \right ) \right )\frac{RC}{RC+T_s}

根据设定的截止频率,假如目标频率是50Hz,截止频率可以整定为0.5Hz,过滤低频分量,而不影响目标信号的采集。

RC = \frac{1}{2\pi f_{cut}}

2.2 波特图

传递函数可又频域函数转换得到,将s=j\omega带入频域公式。得到:

V_o = \frac{RCs}{RCs+1}V_i

Octave绘制波特图:

 
  1. fcut =0.5;

  2. RC=1/2/pi/fcut;

  3. pkg load control

  4. y1 = tf([RC,0],[RC,1])

  5. bode(y1)

 

 

高通滤波器对截至频率以上的信号无大影响,信号能正常经过滤波器。但是该滤波器对截至频率以下的信号,具有较大的影响。和截至频率相比,频率越小,衰减作用越明显。同时在相位图中可见,对频率越低的信号,相位移动也越大。

 

2.3 用C语言实现

C语言的实现1:

 
  1. void HighPassFilter_RC_1order(float *Vi, float *Vi_p, float *Vo, float *Vo_p, float sampleFrq )

  2. {

  3. float CutFrq, RC, Coff;

  4.  
  5. //high pass filter @cutoff frequency = 0.5 Hz

  6. CutFrq = 0.5;

  7. RC = (float)1.0/2.0/PI/CutFrq;

  8. Coff = RC/(RC + 1/sampleFrq);

  9. *Vo = ((*Vi) - (*Vi_p) +(*Vo_p) )*Coff ;

  10.  
  11. //update

  12. *Vo_p = *Vo;

  13. *Vi_p = *Vi;

  14. }

调用例子:

 
  1.  
  2. float b_ADCLoad1Volt, b_ADCLoad1VoltPrv, b_ADCLoad1VoltFltr, b_ADCLoad1VoltFltrPrv;

  3.  
  4.  
  5. HighPassFilter_RC_1order(&b_ADCLoad1Volt, &b_ADCLoad1VoltPrv, &b_ADCLoad1VoltFltr, &b_ADCLoad1VoltFltrPrv, 1000.0);

调用时,1000是指每秒需要执行这个函数1000次。

C语言实现2:

 
  1.  
  2. #define PI 3.1415

  3.  
  4.  
  5. //*********** Structure Definition ********//

  6. typedef struct {

  7. float Vi;

  8. float Vi_prev;

  9. float Vo_prev;

  10. float Vo;

  11. float Fcutoff;

  12. float Fs;

  13. } HPF_1orderRC_F;

  14. //*********** Structure Init Function ****//

  15. void HPF_1orderRC_F_init(HPF_1orderRC_F *v)

  16. {

  17. v->Vi=0;

  18. v->Vi_prev=0;

  19. v->Vo_prev=0;

  20. v->Vo=0;

  21.  
  22. //high pass filter @cutoff frequency = 0.05 Hz

  23. v->Fcutoff=0.05;

  24.  
  25. // execute 1000 every second

  26. v->Fs=1000;

  27. }

  28.  
  29. //*********** Function Definition ********//

  30. float HPF_1orderRC_F_FUNC(HPF_1orderRC_F *v)

  31. {

  32. float RC, Coff;

  33.  
  34. RC = (float)1.0/2.0/PI/v->Fcutoff;

  35. Coff = RC/(RC + 1/v->Fs);

  36. v->Vo = (v->Vi - v->Vi_prev + v->Vo_prev ) * Coff;

  37.  
  38. //update

  39. v->Vo_prev = v->Vo;

  40. v->Vi_prev = v->Vi;

  41.  
  42. return v->Vo;

  43. }

  44.  
  45. HPF_1orderRC_F hpf_1orderrc_handle;

调用例子:

 
  1. ...

  2. int main(void)

  3. {

  4. ...

  5. HPF_1orderRC_F_init(&hpf_1orderrc_handle); //初始化

  6. while(1)

  7. {

  8. ...

  9. if(flag_1ms==1)

  10. {

  11. hpf_1orderrc_handle.Vi = ADCresult; //假设ADCresult是ADC采样结果

  12.  
  13. FilteredResult = HPF_1orderRC_F_FUNC(&hpf_1orderrc_handle);//FilteredResult存放滤波结果

  14. }

  15. }

  16. }

  17.  

 

3 上机测试

板子上面MCU采用STM32F103C8,外扩了USB转UART模块,外扩了PIR+运放模块。

在STM32F103C8上面,PA7连接了某信号源。USART1和FT232模块连接,与电脑通信。

单片机对PA7的采样信号进行滤波处理,目的是把目标信号的直流部分和高频部分滤除,得到0.05Hz-5Hz以内的分量。

上位机使用了SerialChart-0.3.4,把信号波形显示。效果如下图。数据第一列是时间戳,第二列是原始数据,第三列是滤波后的数据。Chart中,蓝色是第二列原始数据,红色是第三列滤波后的数据。

可以看到,滤波器对直流信号有衰减作用。

  • 6
    点赞
  • 59
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值