打印
[STM32F1]

【转】STM32实现IIR工频陷波器

[复制链接]
1349|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
南国先生|  楼主 | 2016-12-24 12:19 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
工频干扰是由电力系统引起的一种干扰,中国大陆地区由50hz及其谐波构成的一种干扰,幅值约为ECG(心电信号的50%)。

        工频干扰可以用陷波器进行处理,过滤50hz信号。常用的工频陷波器主要有IIR和FIR两种,其中FIR具有良好的线性相位,但是在同等滤波效果的情况下,IIR的阶数要比FIR少很多,一个两阶的IIR滤波器的效果FIR要付出100多阶的代价,阶数大意味着运算量大,对于一个MCU单片机来说这是得不偿失的,所以采用IIR滤波器来实现工频滤波。
       IIR滤波器的设计方法有脉冲响应不变法和双线性变换法,如果你已经熟悉IIR滤波器的设计原理可以直接借用Matlab的Fdatool滤波器设计工具直接生成相关系数,这样省去了中间设计环节,再通过IIR滤波器的直接II型实现方式翻译成C语言格式并应用于STM32平台(重要:fs为采样频率,Fnotch为陷波频率)
            
按Designer键即可生成IIR滤波系数
            
导出滤波系数得到转移函数
            
这样再通过直接II型实现框图,翻译成C语言代码并烧录到主控MCU中运行
            
x0=ADC_ConvertedValueLocal;  //输入ADC采集到的信号  
          w0[0]=IIR_50Notch_A[0]*x0-IIR_50Notch_A[1]*w0[1]-IIR_50Notch_A[2]*w0[2];
          y0=IIR_50Notch_B[0]*w0[0]+IIR_50Notch_B[1]*w0[1]+IIR_50Notch_B[2]*w0[2];
          w0[2]=w0[1];
          w0[1]=w0[0];
前提是你的输入信号的时域采样率要和滤波器的频域采样率要保持一致,这样就涉及定时器触发ADC采样,用STM32的定时器来配置采样率,
附带Matlab平台仿真实现:
         clear all
         fs=250;           %数字滤波器的采样频率fs=1000hz
         f=50;              Phz的正弦信号
         t=0:1/fs:4;      %时间间隔,ADC采样频率250hz
         s=sin(2*pi*f*t);
         IIR_B=[0.90239774423695518,-0.55771247730967288,0.90239774423695518];
         IIR_A= [1,-0.55771247730967288,0.80479548847391036];
         w01=0;
         w02=0;
         w03=0;
         for i=1:1000
                w01=s(i)-IIR_A(2)*w02-IIR_A(3)*w03;
                y0(i)=IIR_B(1)*w01+IIR_B(2)*w02+IIR_B(3)*w03;
   
  
               w03=w02;
               w02=w01;
       end
   
      figure
      subplot(211)
      axis([1,1000,-1,1]);
      hold on
      plot(s);
      title('直接II型实现—原始信号时域');
      subplot(212)
      plot(y0,'r');
      title('直接II型实现—信号滤波之后');
附带一STM32实现IIR滤波器的源代码
http://www.51hei.com/f/IIR滤波器单片机实现蓝牙通讯.zip
*兴趣所致与各位分享,本人能力有限若有不足指出还望各位指正(●'??'●)
最后一句:懂者不傲,不懂者勤学

沙发
zhuotuzi| | 2016-12-24 13:07 | 只看该作者
话说这个一般用在什么情况呢

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

68

主题

160

帖子

3

粉丝