总体说来,定点数的优点在于运行速度比浮点数快,缺点是设计时比较麻烦,要通过malab在stm32上实现IIR的定点滤波程序,需要按照以下步骤来实现。
1.通过仿真确定内部状态值的范围,范围定的误差越小,精度越高,但容易出现饱和现象。
首先使用fdatool创建一个IIR滤波器,这里我们仍然设计一个2阶高通滤波,类型选切比雪夫I型,截止频率300Hz,量化方法采用浮点数,然后将该滤波器实例化,生成仿真模型,在仿真模型中添加一个正弦信号发生器、一个常量、一个示波器,然后将信号线连接好,如下图所示。
双击图中的sine wave模块,弹出设置对话框,由于我们的stm32的ADC输入电压范围在0~3.3V,输入信号是一个带直流偏置的正弦波信号,为了获得最大的摆幅,将直流信号设置到12位ADC的中间值2048,交流信号的幅值设置到2047,这样就可以满足ADC采集到最大摆幅值。因此Amplitude输入2047,频率先设置为1KHz。
点击OK,返回仿真主画面,进入Filter模块,添加一个示波器,用于观察各状态值,如图所示。
完成以上设置之后,再点击仿真运行,仿真完成之后可以看到内部各状态的最大值,由于输入的频率会影响内部状态值,因此需要将输入正弦波的频率从0改变到4KHz,这里只需要输入0、10、1000几个典型值即可,由于定点数表示的范围都是2的n次幂,因此通过观察得到状态值大概的范围如下。
在清楚了各状态的范围之后,就可以设置matlab量化参数了,回到fdatool界面,点击图中红色圈标记的图标,这个图标是滤波器数值量化方法。
点击后选择图中红色的”Fixed-point”,可以看到右侧金黄色圈住的三个选项,分别是Coefficients、Input/Output、FilterInternals,其中Coefficients表示IIR系数的定标,Input/Output表示输入、输出以及段输入输出定标,Filter Internals表示内部状态的定标。在c语言程序中IIR系数为16位有符号数,因此Coefficient word lenght 填入16根据分子、分母以及缩放因子值得大小,选择合适的定标位数,如分母的值是1、-2、1,分子的值是1、-1.7465710178967648、0.79152631529839501,因此分母和分子小数点位数填入14(s16,14的范围为[-2 2)),缩放因子值为0.039834401095698677和19.790259679335225,因此缩放值得小数点位填入10(s16,10的范围为[-32 32))。注:在生成的c头文件中会发现matlab计算出的分子、分母定标是按照缩放因子小数位定标的。