收藏 分享(赏)

巴特沃斯滤波器c语言.docx

上传人:HR专家 文档编号:11609466 上传时间:2020-08-25 格式:DOCX 页数:20 大小:310.93KB
下载 相关 举报
巴特沃斯滤波器c语言.docx_第1页
第1页 / 共20页
巴特沃斯滤波器c语言.docx_第2页
第2页 / 共20页
巴特沃斯滤波器c语言.docx_第3页
第3页 / 共20页
巴特沃斯滤波器c语言.docx_第4页
第4页 / 共20页
巴特沃斯滤波器c语言.docx_第5页
第5页 / 共20页
点击查看更多>>
资源描述

1、1. 模拟滤波器的设计 1.1巴特沃斯滤波器的次数 根据给定的参数设计模拟滤波器,然后进行变数变换,求取数字滤波器的方法,称为滤波器的间接设计。做为数字滤波器的设计基础的模拟滤波器,称之为原型滤波器。这里,我们首先介绍的是最简单最基础的原型滤波器,巴特沃斯低通滤波器。由于IIR滤波器不具有线性相位特性,因此不必考虑相位特性,直接考虑其振幅特性。 在这里,N是滤波器的次数,c是截止频率。从上式的振幅特性可以看出,这个是单调递减的函数,其振幅特性是不存在纹波的。设计的时候,一般需要先计算跟所需要设计参数相符合的次数N。首先,就需要先由阻带频率,计算出阻带衰减将巴特沃斯低通滤波器的振幅特性,直接带入

2、上式,则有最后,可以解得次数N为当然,这里的N只能为正数,因此,若结果为小数,则舍弃小数,向上取整。 1.2巴特沃斯滤波器的传递函数 巴特沃斯低通滤波器的传递函数,可由其振幅特性的分母多项式求得。其分母多项式根据S解开,可以得到极点。这里,为了方便处理,我们分为两种情况去解这个方程。当N为偶数的时候,这里,使用了欧拉公式。同样的,当N为奇数的时候,同样的,这里也使用了欧拉公式。归纳以上,极点的解为上式所求得的极点,是在s平面内,在半径为c的圆上等间距的点,其数量为2N个。为了使得其IIR滤波器稳定,那么,只能选取极点在S平面左半平面的点。选定了稳定的极点之后,其模拟滤波器的传递函数就可由下式求

3、得。 1.3巴特沃斯滤波器的实现(C语言) 首先,是次数的计算。次数的计算,我们可以由下式求得。 其对应的C语言程序为cppview plaincopy1. N=Ceil(0.5*(log10(pow(10,Stopband_attenuation/10)-1)/2. log10(Stopband/Cotoff); 然后是极点的选择,这里由于涉及到复数的操作,我们就声明一个复数结构体就可以了。最重要的是,极点的计算含有自然指数函数,这点对于计算机来讲,不是太方便,所以,我们将其替换为三角函数,这样的话,实部与虚部就还可以分开来计算。其代码实现为cppview plaincopy1. typed

4、efstruct2. 3. doubleReal_part;4. doubleImag_Part;5. COMPLEX;6. 7. 8. COMPLEXpolesN;9. 10. for(k=0;k=(2*N)-1);k+)11. 12. if(Cotoff*cos(k+dk)*(pi/N)0)13. 14. polescount.Real_part=-Cotoff*cos(k+dk)*(pi/N);15. polescount.Imag_Part=-Cotoff*sin(k+dk)*(pi/N);16. count+;17. if(count=N)break;18. 19. 计算出稳定的极点

5、之后,就可以进行传递函数的计算了。传递的函数的计算,就像下式一样这里,为了得到模拟滤波器的系数,需要将分母乘开。很显然,这里的极点不一定是整数,或者来说,这里的乘开需要做复数运算。其复数的乘法代码如下,cppview plaincopy1. intComplex_Multiple(COMPLEXa,COMPLEXb,2. double*Res_Real,double*Res_Imag)3. 4. 5. *(Res_Real)=(a.Real_part)*(b.Real_part)-(a.Imag_Part)*(b.Imag_Part);6. *(Res_Imag)=(a.Imag_Part)*

6、(b.Real_part)+(a.Real_part)*(b.Imag_Part);7. return(int)1;8. 有了乘法代码之后,我们现在简单的情况下,看看其如何计算其滤波器系数。我们做如下假设这个时候,其传递函数为将其乘开,其大致的关系就像下图所示一样。计算的关系一目了然,这样的话,实现就简单多了。高阶的情况下也一样,重复这种计算就可以了。其代码为cppview plaincopy1. Res0.Real_part=poles0.Real_part;2. Res0.Imag_Part=poles0.Imag_Part;3. Res1.Real_part=1;4. Res1.Imag

7、_Part=0;5. 6. for(count_1=0;count_1N-1;count_1+)7. 8. for(count=0;count=count_1+2;count+)9. 10. if(0=count)11. 12. Complex_Multiple(Rescount,polescount_1+1,13. &(Res_Savecount.Real_part),14. &(Res_Savecount.Imag_Part);15. 16. elseif(count_1+2)=count)17. 18. Res_Savecount.Real_part+=Rescount-1.Real_p

8、art;19. Res_Savecount.Imag_Part+=Rescount-1.Imag_Part;20. 21. else22. 23. Complex_Multiple(Rescount,polescount_1+1,24. &(Res_Savecount.Real_part),25. &(Res_Savecount.Imag_Part);26. 1Res_Savecount.Real_part+=Rescount-1.Real_part;27. Res_Savecount.Imag_Part+=Rescount-1.Imag_Part;28. 29. 30. *(b+N)=*(a

9、+N);到此,我们就可以得到一个模拟滤波器巴特沃斯低通滤波器了。2.双1次z变换 2.1双1次z变换的原理 我们为了将模拟滤波器转换为数字滤波器的,可以用的方法很多。这里着重说说双1次z变换。我们希望通过双1次z变换,建立一个s平面到z平面的映射关系,将模拟滤波器转换为数字滤波器。 和之前的例子一样,我们假设有如下模拟滤波器的传递函数。将其做拉普拉斯逆变换,可得到其时间域内的连续微分方程式,其中,x(t)表示输入,y(t)表示输出。然后我们需要将其离散化,假设其采样周期是T,用差分方程去近似的替代微分方程,可以得到下面结果然后使用z变换,再将其化简。可得到如下结果从而,我们可以得到了s平面到z

10、平面的映射关系,即由于所有的高阶系统都可以视为一阶系统的并联,所以,这个映射关系在高阶系统中,也是成立的。然后,将关系式带入上式,可得到这里,我们可以就可以得到与的对应关系了。 这里的与的对应关系很重要。我们最终的目的设计的是数字滤波器,所以,设计时候给的参数必定是数字滤波器的指标。而我们通过间接设计设计IIR滤波器时候,首先是要设计模拟滤波器,再通过变换,得到数字滤波器。那么,我们首先需要做的,就是将数字滤波器的指标,转换为模拟滤波器的指标,基于这个指标去设计模拟滤波器。另外,这里的采样时间T的取值很随意,为了方便计算,一般取1s就可以。 2.2双1次z变换的实现(C语言) 我们设计好的巴特

11、沃斯低通滤波器的传递函数如下所示。 我们将其进行双1次z变换,我们可以得到如下式子可以看出,我们还是需要将式子乘开,进行合并同类项,这个跟之前说的算法相差不大。其代码为。cppview plaincopy1. for(Count=0;Count=N;Count+)2. 3. for(Count_Z=0;Count_Z=N;Count_Z+)4. 5. ResCount_Z=0;6. Res_SaveCount_Z=0;7. 8. Res_Save0=1;9. for(Count_1=0;Count_1N-Count;Count_1+)10. 11. for(Count_2=0;Count_2=

12、Count_1+1;Count_2+)12. 13. if(Count_2=0)ResCount_2+=Res_SaveCount_2;14. elseif(Count_2=(Count_1+1)&(Count_1!=0)15. ResCount_2+=-Res_SaveCount_2-1;16. elseResCount_2+=Res_SaveCount_2-Res_SaveCount_2-1;17. for(Count_Z=0;Count_Z=N;Count_Z+)18. 19. Res_SaveCount_Z=ResCount_Z;20. ResCount_Z=0;21. 22. 23.

13、 for(Count_1=(N-Count);Count_1N;Count_1+)24. 25. for(Count_2=0;Count_2=Count_1+1;Count_2+)26. 27. if(Count_2=0)ResCount_2+=Res_SaveCount_2;28. elseif(Count_2=(Count_1+1)&(Count_1!=0)29. ResCount_2+=Res_SaveCount_2-1;30. else31. ResCount_2+=Res_SaveCount_2+Res_SaveCount_2-1;32. 33. for(Count_Z=0;Coun

14、t_Z=N;Count_Z+)34. 35. Res_SaveCount_Z=ResCount_Z;36. ResCount_Z=0;37. 38. 39. for(Count_Z=0;Count_Z=N;Count_Z+)40. 41. *(az+Count_Z)+=pow(2,N-Count)*(*(as+Count)*42. Res_SaveCount_Z;43. *(bz+Count_Z)+=(*(bs+Count)*Res_SaveCount_Z;44. 45. 到此,我们就已经实现了一个数字滤波器。3.IIR滤波器的间接设计代码(C语言)cppview plaincopy1. #i

15、nclude2. #include3. #include4. #include5. 6. 7. #definepi(double)3.1415926)8. 9. 10. structDESIGN_SPECIFICATION11. 12. doubleCotoff;13. doubleStopband;14. doubleStopband_attenuation;15. ;16. 17. typedefstruct18. 19. doubleReal_part;20. doubleImag_Part;21. COMPLEX;22. 23. 24. 25. intCeil(doubleinput)

16、26. 27. if(input!=(int)input)return(int)input)+1;28. elsereturn(int)input);29. 30. 31. 32. intComplex_Multiple(COMPLEXa,COMPLEXb33. ,double*Res_Real,double*Res_Imag)34. 35. 36. *(Res_Real)=(a.Real_part)*(b.Real_part)-(a.Imag_Part)*(b.Imag_Part);37. *(Res_Imag)=(a.Imag_Part)*(b.Real_part)+(a.Real_par

17、t)*(b.Imag_Part);38. return(int)1;39. 40. 41. 42. intButtord(doubleCotoff,43. doubleStopband,44. doubleStopband_attenuation)45. 46. intN;47. 48. printf(Wc=%lfrad/secn,Cotoff);49. printf(Ws=%lfrad/secn,Stopband);50. printf(As=%lfdBn,Stopband_attenuation);51. printf(-n);52. 53. N=Ceil(0.5*(log10(pow(1

18、0,Stopband_attenuation/10)-1)/54. log10(Stopband/Cotoff);55. 56. 57. return(int)N;58. 59. 60. 61. intButter(intN,doubleCotoff,62. double*a,63. double*b)64. 65. doubledk=0;66. intk=0;67. intcount=0,count_1=0;68. COMPLEXpolesN;69. COMPLEXResN+1,Res_SaveN+1;70. 71. if(N%2)=0)dk=0.5;72. elsedk=0;73. 74.

19、 for(k=0;k=(2*N)-1);k+)75. 76. if(Cotoff*cos(k+dk)*(pi/N)0)77. 78. polescount.Real_part=-Cotoff*cos(k+dk)*(pi/N);79. polescount.Imag_Part=-Cotoff*sin(k+dk)*(pi/N);80. count+;81. if(count=N)break;82. 83. 84. 85. printf(Pk=n);86. for(count=0;countN;count+)87. 88. printf(%lf)+(%lfi)n,-polescount.Real_p

20、art89. ,-polescount.Imag_Part);90. 91. printf(-n);92. 93. Res0.Real_part=poles0.Real_part;94. Res0.Imag_Part=poles0.Imag_Part;95. 96. Res1.Real_part=1;97. Res1.Imag_Part=0;98. 99. for(count_1=0;count_1N-1;count_1+)100. 101. for(count=0;count=count_1+2;count+)102. 103. if(0=count)104. 105. Complex_Mu

21、ltiple(Rescount,polescount_1+1,106. &(Res_Savecount.Real_part),107. &(Res_Savecount.Imag_Part);108. /printf(Res_Save:(%lf)+(%lfi)n,Res_Save0.Real_part,Res_Save0.Imag_Part);109. 110. 111. elseif(count_1+2)=count)112. 113. Res_Savecount.Real_part+=Rescount-1.Real_part;114. Res_Savecount.Imag_Part+=Res

22、count-1.Imag_Part;115. 116. else117. 118. Complex_Multiple(Rescount,polescount_1+1,119. &(Res_Savecount.Real_part),120. &(Res_Savecount.Imag_Part);121. 122. /printf(Res:(%lf)+(%lfi)n,Rescount-1.Real_part,Rescount-1.Imag_Part);123. /printf(Res_Save:(%lf)+(%lfi)n,Res_Savecount.Real_part,Res_Savecount.

23、Imag_Part);124. 125. Res_Savecount.Real_part+=Rescount-1.Real_part;126. Res_Savecount.Imag_Part+=Rescount-1.Imag_Part;127. 128. /printf(Res_Save:(%lf)+(%lfi)n,Res_Savecount.Real_part,Res_Savecount.Imag_Part);129. 130. 131. /printf(Theren);132. 133. 134. for(count=0;count=N;count+)135. 136. Rescount.

24、Real_part=Res_Savecount.Real_part;137. Rescount.Imag_Part=Res_Savecount.Imag_Part;138. 139. *(a+N-count)=Rescount.Real_part;140. 141. 142. /printf(There!n);143. 144. 145. 146. *(b+N)=*(a+N);147. 148. /-display-/149. printf(bs=);150. for(count=0;count=N;count+)151. 152. printf(%lf,*(b+count);153. 154

25、. printf(n);155. 156. printf(as=);157. for(count=0;count=N;count+)158. 159. printf(%lf,*(a+count);160. 161. printf(n);162. 163. printf(-n);164. 165. return(int)1;166. 167. 168. 169. intBilinear(intN,170. double*as,double*bs,171. double*az,double*bz)172. 173. intCount=0,Count_1=0,Count_2=0,Count_Z=0;

26、174. doubleResN+1;175. doubleRes_SaveN+1;176. 177. for(Count_Z=0;Count_Z=N;Count_Z+)178. 179. *(az+Count_Z)=0;180. *(bz+Count_Z)=0;181. 182. 183. 184. for(Count=0;Count=N;Count+)185. 186. for(Count_Z=0;Count_Z=N;Count_Z+)187. 188. ResCount_Z=0;189. Res_SaveCount_Z=0;190. 191. Res_Save0=1;192. 193. f

27、or(Count_1=0;Count_1N-Count;Count_1+)194. 195. for(Count_2=0;Count_2=Count_1+1;Count_2+)196. 197. if(Count_2=0)198. 199. ResCount_2+=Res_SaveCount_2;200. /printf(Res%d%lfn,Count_2,ResCount_2);201. 202. 203. elseif(Count_2=(Count_1+1)&(Count_1!=0)204. 205. ResCount_2+=-Res_SaveCount_2-1;206. /printf(

28、Res%d%lfn,Count_2,ResCount_2);207. 208. 209. else210. 211. ResCount_2+=Res_SaveCount_2-Res_SaveCount_2-1;212. /printf(Res%d%lfn,Count_2,ResCount_2);213. 214. 215. 216. /printf(Res:);217. for(Count_Z=0;Count_Z=N;Count_Z+)218. 219. Res_SaveCount_Z=ResCount_Z;220. ResCount_Z=0;221. /printf(%d%lf,Count_Z,Res_SaveCount_Z);222. 223. /printf(n);224. 225. 226. 227. for(Count_1=(N-Count);Count_1N;Count_1+)228. 229. for(Count_2=0;Count_2=Count_1+1;Count_2+)230. 231. if(Count_2=0)232. 233. ResCount_2+=Res_SaveCount_2;234. /printf(Res%d%lfn,Count_2,ResCount_2);235. 236. 237. elseif(Count_2=(Count_1+1)

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 网络科技 > 计算机原理

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报