什么是fir數(shù)字濾波器 什么叫FIR濾波器
Part 1: Basics
1.1 什么是FIR濾波器?
FIR 濾波器是在數(shù)字信號處理(DSP)中經(jīng)常使用的兩種基本的濾波器之一,另一個為IIR濾波器.
1.2 FIR代表什么?
FIR是有限沖激響應(yīng)(Finite Impulse Response)的簡稱.
1.3 FIR(有限沖激響應(yīng))中的有限該如何理解?
沖激響應(yīng)是有限的意味著在濾波器中沒有發(fā)反饋.
1.4 FIR 怎么發(fā)音?
有些人直接讀字母音 F-I-R; 也有人發(fā)做fir的音[:], fir是冷杉樹.
1.5 FIR 濾波器外有什么其他選擇?
DSP濾波器還有一類: IIR(無限沖激響應(yīng),Infinite Impulse Response). IIR濾波器使用反饋,因此當信號輸入后,輸出是根據(jù)算法循環(huán)的.
1.6 FIR濾波器與IIR濾波器比較?
每一種都有優(yōu)缺點.但總得來說, FIR濾波器的優(yōu)點遠大于缺點,因此在實際運用中,FIR濾波器比IIR濾波器使用的比較多.
1.6.1 相對于IIR濾波器, FIR濾波器有什么優(yōu)點?
相較于IIR濾波器, FIR濾波器有以下的優(yōu)點:
* 可以很容易地設(shè)計線性相位的濾波器. 線性相位濾波器延時輸入信號,卻并不扭曲其相位.
* 實現(xiàn)簡單. 在大多數(shù)DSP處理器, 只需要對一個指令積習循環(huán)就可以完成FIR計算.
* 適合于多采樣率轉(zhuǎn)換,它包括抽取(降低采樣率), 插值(增加采樣率)操作. 無論是抽取或者插值, 運用FIR濾波器可以省去一些計算, 提高計算效率. 相反,如果使用IIR濾波器,每個輸出都要逐一計算,不能省略,即使輸出要丟棄.
* 具有理想的數(shù)字特性. 在實際中,所有的DSP濾波器必須用有限精度(有限bit數(shù)目)實現(xiàn),而在IIR濾波器中使用有限精度會產(chǎn)生很大的問題,由于采用的是反饋電路,因此IIR通常用非常少的bit實現(xiàn),設(shè)計者就能解決更少的與非理想算術(shù)有關(guān)的問題。
* 可以用小數(shù)實現(xiàn). 不像IIR濾波器,F(xiàn)IR濾波器通??赡苡眯∮?的系數(shù)來實現(xiàn)。(如果需要,F(xiàn)IR濾波器的總的增益可以在輸出調(diào)整)。當使用定點DSP的時候,這也是一個考慮因素,它能使得實現(xiàn)更加地簡單。
1.6.2 相較于IIR濾波器, FIR濾波器的缺點是什么?
相比較于IIR濾波器, 有時FIR濾波器為了得到一個給定的濾波響應(yīng)特性,需要花費更多的存儲器或者計算. 當然,用FIR濾波器去實現(xiàn)某些響應(yīng)也是不實際的.
1.7 在描述FIR濾波器的時候,都要提到什么術(shù)語?
* 沖激響應(yīng) - FIR濾波器的沖激響應(yīng)實際上是FIR的系數(shù).
* 抽頭(Tap) - FIR的抽頭是系數(shù)或者延時對. FIR抽頭的個數(shù)(通常用N來表示)意味著:1)實現(xiàn)濾波器所需要的存儲空間, 2) 需要計算的數(shù)目, 3) 濾波器能濾掉的數(shù)量, 實際上,越多的抽頭意味著有更多的阻帶衰減, 更少的波紋,更窄的濾波等等.
* 乘累加 (MAC) - 在FIR方面考慮,MAC是指把延時的數(shù)據(jù)采樣與相應(yīng)的系數(shù)相乘,然后累加結(jié)果。通常,F(xiàn)IR每一個抽頭都需要一個MAC。大多數(shù)DSP微處理器實現(xiàn)MAC操作都是單指令周期。
* 躍遷帶(Transition Band) -在通帶和阻帶邊沿之間的頻帶。躍遷帶越窄,需要更多的抽頭去實現(xiàn)濾波器。也有說,小的躍遷帶就是一個sharp濾波器。
* 延時線- 一組存儲器單元,實現(xiàn)在FIR計算中的Z^-1延時。
* 環(huán)形緩存 - 一個特殊的緩存,是首尾相連的。通常由DSP微處理器實現(xiàn)。
Part 2: Properties
2.1 線性相位
2.1.1 FIR濾波器和線性相位之間有什么關(guān)系?
大多數(shù)的FIR濾波器是線性相位濾波器. 當需要設(shè)計線性相位濾波器時, 通常使用FIR濾波器.
2.1.2 什么是線性相位濾波器?
線性相位是指濾波器的相位響應(yīng)是頻率的線性函數(shù)(在+/-180度)。因此濾波器的延時后,所有的頻率相位相同。因而濾波器不會產(chǎn)生相位和延遲扭曲。在某些領(lǐng)域,比如數(shù)字解調(diào)器,沒有相位或者延遲扭曲是FIR濾波器相對于其他IIR和模擬濾波器的一個關(guān)鍵優(yōu)點
2.1.3 線性濾波器的條件是什么?
FIR濾波器經(jīng)常被設(shè)計成為線性相位的,當然不是必須要這么做。如果濾波器的系數(shù)是關(guān)于中心系數(shù)對稱的,也就是說第一個系數(shù)和最后一個系數(shù)相同,第二個系數(shù)和倒數(shù)第二個相同,那么FIR濾波器就是線性的。有奇數(shù)個系數(shù)的FIR濾波器,中心單獨的系數(shù)沒有對應(yīng)的。
2.1.4 什么是線性相位FIR濾波器的延時?
非常簡單的公式: 給定FIR濾波器有N個抽頭,那么延時是(N - 1) / (2 * Fs), 這里Fs是采樣頻率. 比如, 21抽頭的線性相位濾波器運行在1kHz, 那么延時就是(21 - 1) / (2 * 1 kHz)=10 微秒.
2.1.4 除了線性相位,還可以選擇什么?
當然是非線性的了。實際上,最流行的選擇是最小相位濾波器。最小相位濾波器,也叫最小延時濾波器,比線性相位濾波器具有更少的延時,當兩者的幅度響應(yīng)相同時以非線性相位特性。低通濾波器在它的沖擊響應(yīng)中心有最大的系數(shù)。而最小相位濾波器的最大系數(shù)在開始部分。
2.2 頻率響應(yīng)
2.2.1 什么是FIR濾波器的Z變換r?
對于N抽頭的濾波器, 系數(shù)為h(k), 那么輸出由:
y(n)=h(0)x(n) + h(1)x(n-1) + h(2)x(n-2) + ... h(N-1)x(n-N-1),
濾波器的z變換就是:
H(z)=h(0)z-0 + h(1)z-1 + h(2)z-2 + ... h(N-1)z-(N-1) , or
2.2.2 FIR濾波器的頻率響應(yīng)公式是什么?
H(z)中的變量z為連續(xù)的復數(shù)變量,可以描述為 z=r·ejw,這里r是幅度,w是z的角度。如果令r=1,H(z)就變成了濾波器頻率響應(yīng)H(jw)。這也就意味著替代z為ejw,得到了濾波器頻率響應(yīng)H(w)。
H(jw)=h(0)e-j0w + h(1)e-j1w + h(2)e-j2w + ... h(N-1)e-j(N-1)w , or
使用歐拉公式, e-ja=cos(a) - jsin(a), 我們可以把H(jw)寫成矩形表示:
H(jw)=h(0)[cos(0w) - jsin(0w)] + h(1)[cos(1w) - jsin(1w)] + ... h(N-1)[cos((N-1)w) - jsin((N-1)w)] , or
2.2.3 能用離散傅立葉變換(DFT)來計算FIR的頻率響應(yīng)么?
可以。對于N抽頭的FIR,可以得到N evenly-spaced points of the frequency response by doing a DFT on the filter coefficients.但是,為了得到任意頻率的頻率響應(yīng),需要使用上邊的公式。
2.2.4 FIR濾波器的DC增益指的是什么?
DC(0 Hz)輸入信號包含每個采樣都為1.0。通過延時線后,輸出是所有系數(shù)的和。因而,在DC處濾波器的增益就是所有系數(shù)之和。
可以通過上邊的公式進行驗證。問我們設(shè)w為0, cos項就一直為1,而sin項則一直為0。因此頻率響應(yīng)就變成了:
2.2.5 如何調(diào)整FIR濾波器的增益?
簡單地在系數(shù)上乘上因子.
2.3 數(shù)字性質(zhì)
2.3.1 FIR濾波器是固有穩(wěn)定的?
是的,因為沒有反饋,任何有限的輸入產(chǎn)生有限的輸出。
2.3.2 什么使FIR濾波器的數(shù)字性質(zhì)變好?
缺少反饋是關(guān)鍵。在計算機中實現(xiàn)FIR濾波器時,每個計算都產(chǎn)生數(shù)字錯誤。由于FIR濾波器沒有反饋,因此不能夠記住以前的錯誤。相反,IIR濾波器的反饋可能導致錯誤的積累。這個實際的影響就是,可以用更少的bit去實現(xiàn)與IIR濾波器相同精度的濾波器。比如,F(xiàn)IR濾波器通常用16位來實現(xiàn)的話,IIR濾波器就通常需要32位,或者更多。
2.4 為什么通常在多采樣率系統(tǒng)中采用FIR濾波器而不采用IIR濾波器?
因為只有一小部分的計算需要用減采樣或者插值濾波器來實現(xiàn)。
由于FIR濾波器不使用反饋,因而只有那些實際需要使用的輸出才需要計算。比如,在減采樣的時候(N個輸出中只有一個有效),那么其他的N-1輸出就不會進行計算。類似的,對于插值濾波器(在采樣點中插入0來提高采樣率),你不必實際地用FIR濾波器乘以系數(shù),求和得到,你只需要忽略和這些值有關(guān)的乘加(因為它們不會改變結(jié)果)。
相反,因為IIR濾波器使用反饋,每個輸入都必須使用,每個輸入必須計算,因為所有的輸入和輸出對濾波器的反饋都有影響。
2.5 有哪些特殊的FIR濾波器?
Aside from "regular" and "extra crispy" there are:
- 矩形 -矩形 FIR 濾波器是每個系數(shù)都是1.0的簡單的濾波器。因而對于N個抽頭的矩形濾波器,它的輸出僅僅是過去N個采樣之和。由于矩形FIR只能實現(xiàn)加法,因此當乘法器實現(xiàn)比較昂貴時,在硬件實現(xiàn)中會考慮。
- 希爾伯特變換(Hilbert Transformer) - 希爾伯特變換是把信號相移90度。它們經(jīng)常被用在給定實數(shù)部分,產(chǎn)生虛數(shù)部分。
- 差分(Differentiator) -差分器的幅度響應(yīng)是頻率的線性函數(shù)?,F(xiàn)在已經(jīng)不流行了,但是以前曾經(jīng)在FM解調(diào)器上使用過。
- Lth-Band - 也叫做“Nyquist"濾波器,這些濾波器是在多速率應(yīng)用中特殊的一類濾波器。主要的賣點是,每L個系數(shù)有一個為0,那么就將減少乘累加操作的實現(xiàn)(著名的半帶濾波器就是這一種)。
- Raised-Cosine - 這是一種特殊類型的濾波器,有時會用在數(shù)字數(shù)據(jù)應(yīng)用方面。(通帶上的頻率響應(yīng)是被上移一個常數(shù)的cos形狀)。
Part 3: Design
3.1 有哪些設(shè)計FIR濾波器的方法?
三種最流行的設(shè)計方法:
- Parks-McClellan: Parks-McClellan 方法( MATLAB里用Remez)是設(shè)計FIR濾波器中可能是使用最光的.method (inaccurately called "Remez" by Matlab) is probably the most widely used FIR filter design method. It is an iteration algorithm that accepts filter specifications in terms of passband and stopband frequencies, passband ripple, and stopband attenuation. The fact that you can directly specify all the important filter parameters is what makes this method so popular. The PM method can design not only FIR "filters" but also FIR "differentiators" and FIR "Hilbert transformers".
- Windowing:. In the windowing method, an initial impulse response is derived by taking the Inverse Discrete Fourier Transform (IDFT) of the desired frequency response. Then, the impulse response is refined by applying a data window to it.
- Direct Calculation: The impulse responses of certain types of FIR filters (e.g. Raised Cosine and Windowed Sinc) can be calculated directly from formulas.
3.2 如何實際地設(shè)計FIR濾波器?
當然是用FIR設(shè)計程序呀. 雖然可以使用手工親自的方法進行設(shè)計濾波器,但是使用FIR濾波器程序比較簡單.
Part 4: Implementation
4.1 實現(xiàn)FIR濾波器基本的方法是什么?
FIR濾波器的結(jié)構(gòu)上包含兩個東西:一個是采樣點延遲線,一個是系數(shù). 可以由以下方法實現(xiàn)FIR濾波器:
1. 把輸入的采樣點放入到延遲線中.
2. 把延遲線中的數(shù)與相應(yīng)的系數(shù)相乘并累加.
3. 移位, 使下一個輸入采樣能進入延遲線.
4.2 用C語言如何實現(xiàn)FIR濾波器?
為了展示眾多的方法和技巧,這里提供用C語言實現(xiàn)的FIR濾波器算法。
fir_algs_1-0.cC 源碼 |
fir_algs_1-0.zipC 源碼( MS Visual C++ 6.0 工程文件) |
包括以下功能模塊:
1. fir_basic: 實現(xiàn)基本的FIR濾波器
2. fir_circular: 說明環(huán)行buffer是如何實現(xiàn)FIR的。
3. fir_shuffle: 一些TI的處理器上使用的shuffle down技巧
4. fir_split: 把FIR濾波器展開為兩塊,避免使用環(huán)行緩存。
5. fir_double_z: 使用雙精度的延遲線,使可以使用一個flat buffer。
6. fir_double_h: 使用雙精度的系數(shù),使可以使用一個flat buffer。
4.3 用匯編如何實現(xiàn)FIR濾波器?
FIR濾波器的匯編算法是跟處理器對應(yīng)的,但是大多數(shù)普通的系統(tǒng)會使用一個DSP處理器提供的環(huán)行緩存。
1. 配置環(huán)行緩存。加載系數(shù)和延遲線指針。然后對每個采樣點執(zhí)行以下操作:
2. Store the incoming data in the delay line; increment the delay-line pointer.Digital
3. Clear the multiplier-accumulator.
4. Loop over all coefficients/delays; accumulate the values obtained by multiplying the coefficients by the delayed samples.
5. Round or truncate the result as the FIR output.
Alternatively, a "shuffle down" method is used in Texas Instruments' older fixed-point processors to implement circular buffers. The processor literally moves each sample delay values by one slot during each multiply-accumulate (via the "MACD" instruction).
Each DSP microprocessor manufacturer provides example FIR assembly code in its data books or its application handbooks, so be sure to look at those before you "reinvent the circular buffer".
4.4 如何測試以及實現(xiàn)的FIR濾波器?
Here are a few methods:
- Impulse Test: A very simple and effective test is to put an impulse into it (which is just a "1" sample followed by at lest N - 1 zeroes.) You can also put in an "impulse train", with the "1" samples spaced at least N samples apart. If all the coefficients of the filter come out in the proper order, there is a good chance your filter is working correctly. (You might want to test with non-linear phase coefficients so you can see the order they come out.) We recommend you do this test whenever you write a new FIR filter routine.
- Step Test: Input N or more "1" samples. The output after N samples, should be the sum (DC gain) of the FIR filter.
- Sine Test: Input a sine wave at one or more frequencies and see if the output sine has the expected amplitude.
- Swept FM Test: From Eric Jacobsen: "My favorite test after an impulse train is to take two identical instances of the filter under test, use them as I and Q filters and put a complex FM linear sweep through them from DC to Fs/2. You can do an FFT on the result and see the complete frequency response of the filter, make sure the phase is nice and continuous everywhere, and match the response to what you'd expect from the coefficient set, the precision, etc."
4.5 在實現(xiàn)FIR濾波器的過程中有什么有用的技巧?
FIR tricks center on two things 1) not calculating things that don't need to be calculated, and 2) "faking" circular buffers in software.
4.5.1 如何跳過不必要的計算?
First, if your filter has zero-valued coefficients, you don't actually have to calculate those taps; you can leave them out. A common case of this is "half-band" filter, which have the property that every-other coefficient is zero.
Second, if your filter is "symmetric" (linear phase), you can "pre-add" the samples which will be multiplied by the same coefficient value, prior to doing the multiply. Since this technique essentially trades an add for a multiply, it isn't really useful in DSP microprocessors which can do a multiply in a single instruction cycle. However, it is useful in ASIC implementations (in which addition is usually much less expensive than multiplication); also, some newer DSP processors now offer special hardware and instructions to make use of this trick.
4.5.2 How do I fake circular buffers in software?
When hardware support for circular buffers isn't available, you have to "fake" them. Also, since ANSI C has no construct to describe circular buffers, most C compilers can't generate code to use them, even if the target processor has them.
You can always implement a circular buffer by duplicating the logic of a circular buffer in software (and many have), but the overhead can be prohibitive; the circular-fake might take several instructions to implement, compared to just a single instruction to do the multiply-accumulate operation. Therefore you need to fake it.
Here are several basic techniques to fake circular buffers:
1. Split the calculation: You can split any FIR calculation into its "pre-wrap" and "post-wrap" parts. By splitting the calculation into these two parts, you essentially can do the circular logic only once, rather than once per tap. (See fir_double_z in FirAlgs.c above.)
2. Duplicate the delay line: For a FIR with N taps, use a delay line of size 2N. Copy each sample to its proper location, as well as at location-plus-N. Therefore, the FIR calculation's MAC loop can be done on a flat buffer of N points, starting anywhere within the first set of N points. The second set of N delayed samples provides the "wrap around" comparable to a true circular buffer. (See fir_double_z in FirAlgs.c above.)
3. Duplicate the coefficients: This is similar to the above, except that the duplication occurs in terms of the coefficients, not the delay line. Compared to the previous method, this has a calculation advantage of not having to store each incoming sample twice, and it also has a memory advantage when the same coefficient set will be used on multiple delay lines. (See fir_double_h in FirAlgs.c above.)
4. Use block processing: In block processing, you use a delay line which is a multiple of the number of taps. You therefore only have to move the data once per block to implement the delay-line mechanism. When the block size becomes "large", the overhead of a moving the delay line once per block becomes negligible.
評論