国产毛片a精品毛-国产毛片黄片-国产毛片久久国产-国产毛片久久精品-青娱乐极品在线-青娱乐精品

電子工程網(wǎng)

標(biāo)題: STM32實(shí)現(xiàn)IIR濾波器,可用matlab生成的頭文件 [打印本頁(yè)]

作者: warmonkey    時(shí)間: 2011-1-30 19:51
標(biāo)題: STM32實(shí)現(xiàn)IIR濾波器,可用matlab生成的頭文件
matlab的fdatool是好東西,不過(guò)很多人不知道該怎么使用它生成的C頭文件。
趁著放假有時(shí)間,摸索了幾天,終于搞定。

該程序已經(jīng)用于心電采集實(shí)驗(yàn)
導(dǎo)聯(lián)aVF,帶寬1-25Hz

實(shí)驗(yàn)過(guò)程中圖片

file:///C:/Users/WARMON%7E1/AppData/Local/Temp/moz-screenshot-2.png
屏顯

不多說(shuō),切入正題
這里有個(gè)fdatool設(shè)計(jì)的IIR高通濾波器,采樣率400Hz時(shí)截止頻率1Hz。
設(shè)計(jì)定型之后,要做些調(diào)整。
以下說(shuō)明中的英文名詞有些可能對(duì)不上fdatool界面上的原文,請(qǐng)大家意會(huì)吧
第一步:
點(diǎn)擊菜單中的Edit->Convert Structure 選擇Direct Form I ,SOS,(必須是Direct Form I,  II不行)
一般情況下,按照默認(rèn)設(shè)置,fdatool設(shè)計(jì)都是由二階部分串聯(lián)組成的。
這種結(jié)構(gòu)的濾波器穩(wěn)定性比一個(gè)section的要好很多,其他方面的性能也好些。
如果不是的話(huà),點(diǎn)擊Convert to second order sections。
這時(shí),濾波器的結(jié)構(gòu)(structure)應(yīng)該顯示為 Direct Form I,second order sections
第二步:
選擇quantize filter,精度選擇single precision floating point (單精度浮點(diǎn))
之所以不用定點(diǎn)是因?yàn)樵肼曁螅膊蝗菀追(wěn)定。
點(diǎn)擊菜單中的Targets -> generate c header ,選擇export as:single precision floating point (單精度浮點(diǎn))
填寫(xiě)變量名稱(chēng)時(shí),把NUM改成IIR_B,DEN改成IIR_A,其他不用動(dòng),保存為iir_coefs.h

保存好的文件如下:
//一大堆注釋
//然后:
/* General type conversion for MATLAB generated C-code  */
#include "tmwtypes.h"
/*
* Expected path to tmwtypes.h
* C:\Program Files\MATLAB\R2010a\extern\include\tmwtypes.h
*/
/*
* Warning - Filter coefficients were truncated to fit specified data type.  
*   The resulting response may not match generated theoretical response.
*   Use the Filter Design & Analysis Tool to design accurate
*   single-precision filter coefficients.
*/
#define MWSPT_NSEC 9
const int NL[MWSPT_NSEC] = { 1,3,1,3,1,3,1,3,1 };
const real32_T IIR_B[MWSPT_NSEC][3] = {
{
     0.8641357422,              0,              0
  },
  {
                1,             -2,              1
  },
  {
     0.9949035645,              0,              0
  },
  {
                1,   -1.999938965,              1
  },
  {
     0.9985351563,              0,              0
  },
  {
                1,    -1.99987793,              1
  },
{
     0.9996337891,              0,              0
  },
  {
               1,    -1.99987793,              1
  },
  {
                1,              0,              0
  }
};
const int DL[MWSPT_NSEC] = { 1,3,1,3,1,3,1,3,1 };
const real32_T IIR_A[MWSPT_NSEC][3] = {
  {
                1,              0,              0
  },
  {
                1,   -1.938049316,   0.9401855469
  },
  {
                1,              0,              0
  },
  {
                1,   -1.989501953,   0.9900512695
  },
{
                1,              0,              0
  },
  {
                1,   -1.996887207,   0.9971923828
  },
  {
                1,              0,              0
  },
  {
                1,   -1.999084473,   0.9993286133
  },
  {
                1,              0,              0
  }
};

第三步:
打開(kāi)iir_coefs.h把MWSPT_NSEC替換成IIR_NSEC,
NL、DL數(shù)組刪除掉,real32_T改成float ,
其中有一個(gè)#include "twmtypes.h",不要它了,刪掉
改完的文件如下:

#define IIR_NSEC 9
  //原來(lái)叫做MWSPT_NSEC


const float IIR_B[IIR_NSEC][3] = {
  //為什么改為float很明顯了吧
  {
    0.8641357422,              0,              0
  },
  {
                1,            -2,              1
  },
  {
    0.9949035645,              0,              0
  },
  {
                1,  -1.999938965,              1
  },
{
    0.9985351563,              0,              0
  },
  {
                1,    -1.99987793,              1
  },
  {
   0.9996337891,              0,              0
  },
  {
                1,    -1.99987793,              1
  },
  {
                1,              0,              0
  }
};

const float IIR_A[IIR_NSEC][3] = {
  {
                1,              0,              0
  },
  {
                1,  -1.938049316,  0.9401855469
  },
  {
                1,              0,              0
  },
  {
                1,  -1.989501953,  0.9900512695
  },
  {
                1,              0,              0
  },
  {
                1,  -1.996887207,  0.9971923828
  },
  {
                1,              0,              0
  },
  {
                1,  -1.999084473,  0.9993286133
  },
  {
                1,              0,              0
  }
};

保存文件,然后使用以下代碼進(jìn)行濾波
這段代碼是根據(jù)Direct Form I 2階IIR濾波的差分方程編寫(xiě)的
a0*y[n] = b0*x[n] + b1*x[n-1] + b2*x[n-2] - a1*y[n-1] -a2*y[n-2];

//iir_filter.c
#include "../platform.h"

//#include "iir_coefs.float.flat.h"
//#include "iir_coefs.float.sharp.h"
#include "iir_coefs_pass@2Hz_stop@0.8Hz.h"
#include "iir_filter.h"

static float y[IIR_NSEC][3];
static float x[IIR_NSEC+1][3];

//IIR_NSEC階直接型II IIR濾波器
//IIR_NSEC個(gè)二階biquad串聯(lián)
int16 iir_filter(int16 in)
{
      uint16 i;
      
      x[0][0] = in;
      
      for(i=0;i       {
         
        //  y[0] = x[0]*IIR_B[0] +x[1]*IIR_B[1] +x[2]*IIR_B[2]-y[1]*IIR_A[1]-y[2]*IIR_A[2];
          y[0] = 0;
         
          if(IIR_B[0] == 1) y[0]+=x[0];
          else if(IIR_B[0] == -1) y[0]-=x[0];
          else if(IIR_B[0] == -2) y[0]=y[0]-x[0]-x[0];
          else if(IIR_B[0] == 0);   
          else y[0] += x[0]*IIR_B[0];
         
          if(IIR_B[1] == 1) y[0]+=x[1];
          else if(IIR_B[1] == -1) y[0]-=x[1];
          else if(IIR_B[1] == -2) y[0]=y[0]-x[1]-x[1];
          else if(IIR_B[1] == 0);  
          else y[0] += x[1]*IIR_B[1];
         
          if(IIR_B[2] == 1) y[0]+=x[2];
          else if(IIR_B[2] == -1) y[0]-=x[2];
          else if(IIR_B[2] == -2) y[0]=y[0]-x[2]-x[2];
          else if(IIR_B[2] == 0);
          else y[0] += x[2]*IIR_B[2];
         
          if(IIR_A[1] == 1) y[0]-=y[1];
          else if(IIR_A[1] == -1) y[0]+=y[1];
          else if(IIR_A[1] == -2) y[0]=y[0]+y[1]+y[1];
          else if(IIR_A[1] == 0);
          else y[0] -= y[1]*IIR_A[1];
         
          if(IIR_A[2] == 1) y[0]-=y[2];
          else if(IIR_A[2] == -1) y[0]+=y[2];
          else if(IIR_A[2] == -2) y[0]=y[0]+y[2]+y[2];
          else if(IIR_A[2] == 0);
          else y[0] -= y[2]*IIR_A[2];
         
          if(IIR_A[0] != 1) y[0] /= IIR_A[0];
         
          y[2]=y[1];y[1]=y[0];
          x[2]=x[1];x[1]=x[0];
         
          x[i+1][0] = y[0];
      }
      
      if( x[IIR_NSEC][0]>32767)  x[IIR_NSEC][0]=32767;
      if( x[IIR_NSEC][0]<-32768) x[IIR_NSEC][0]=-32768;
      return  ((int16)x[IIR_NSEC][0]);     
      
}

//復(fù)位濾波器
void iir_reset(void)
{
    uint16 i,j;
   
    for(i=0;i     {
       for(j=0;j<3;j++)
       {
          x[j]=0;
       }
    }
   
    for(i=0;i     {
       for(j=0;j<3;j++)
       {
          y[j]=0;
       }
    }
}


//iir_filter.h
#ifndef _IIR_FILTER_H__
#define _IIR_FILTER_H__

int16 iir_filter(int16 x);
void iir_reset(void);

#endif

使用方法:
首先寫(xiě)好iir_coefs.h,然后調(diào)用iir_filter.c對(duì)數(shù)據(jù)流進(jìn)行濾波
一個(gè)偽代碼例子:
while(運(yùn)行中)
{
保存到SD卡(iir_filter(讀取ADC采樣值()));
}

這個(gè)函數(shù)比STM32 DSP庫(kù)中的函數(shù)要好很多,DSP庫(kù)中的2個(gè)IIR濾波函數(shù)都不能連續(xù)處理數(shù)據(jù)流。
記得在開(kāi)始濾波之前重置濾波器
iir_reset();


另:還可以用simulink導(dǎo)出代碼的方式解決,不過(guò)這個(gè)蛋疼的代碼既然弄出來(lái)了,就用著吧。。。





歡迎光臨 電子工程網(wǎng) (http://m.qingdxww.cn/) Powered by Discuz! X3.4
主站蜘蛛池模板: 四虎影永久在线高清免费 | 国产又爽又黄又刺激的软件 | 欧美一区二区三区国产精品 | 国产精品探花一区在线观看 | 日本卡通动漫影院网站 | 青青青青青青青青草 | 91小视频在线观看免费版高清 | 久久人人青草97香蕉 | 欧美自拍区 | 国产极品美女在线观看 | 成人性生交大片免费看中文 | 久久成人亚洲香蕉草草 | 国产美女视频国产视视频 | 男女黄网站 | 91精品视频网 | 两个人免费在线观看 | 亚洲精品中文字幕午夜 | 欧美精品一二三区 | 最近中文字幕无吗 | 国产精品久久久久久久专区 | 国产成人精品福利色多多 | 99精品在线观看 | 美国做受三级的视频播放 | 黄色免费网站视频 | 妈妈的朋友韩国三级 | 激情毛片| 亚洲国产成人久久99精品 | 亚洲黄色激情视频 | 狠狠操操操| 丝瓜草莓视频 | 96久久 | 欧洲三级网站 | 日韩精选在线 | 一级片韩国 | 99热在线播放| 日本不卡一区 | 成品人app软件下载 成品人app软件大全下载免费版 | 国产精品久久久久久久久久妇女 | 91精品视品在线播放 | 日韩国产免费一区二区三区 | 亚洲人人看 |