Language

Showing posts with label DSP. Show all posts
Showing posts with label DSP. Show all posts

Monday, May 30, 2016

以頻率計數器來看 Undersampling

以頻率計數器來看 Undersampling

以頻率計數器來看 Undersampling

由於 blogspot 會被某些公司擋,我已經著手將這裡的文章慢慢的移到 GitHub Pages 上面,這篇文章可以在 這裡 看到

1 頻率計數器問題

想像一下你現在有一套嵌入式系統軟硬體,你只能偵測外部輸入是高或低電位(也就是 GPIO),你要測量外部的方波的頻率,你要怎麼達成呢?我想你能夠達成的就是,固定時間,比方說每隔 1 µs 「偵測」一次訊號位準是高或低,然後標定由低變高以及由高變低的地方,並且計算這個「由低變高」的週期,再轉換成頻率吧?你還能想到更簡單精準的方式嗎?歡迎來挑戰。

2 如何計算頻率?

Figure 1: 頻率計數

由圖 1 可以計算頻率,圖中黑色的方波是你要計算頻率的波形,而橘色的方波代表了你讀取外部 GPIO 值的時間點,綠色就是讀取到的值。\(T_0\) 是要計算的方波週期,從圖上的格子點來計算(假設一格是 1 µs),是 16 µs,\(T_s\) 是讀取 GPIO 的週期,是 4 µs,計算出來的頻率週期是 $Tc$,是 16 µs,就是訊號「看起來變回一週期同樣位置的」週期(為什麼強調這一點?因為要真正計算頻率,也是有點技巧的,這技巧叫做 frequency estimation,有機會再講,你的大腦比數學公式強多了,呵呵)

這裡 \(T_0 = T_c = 16 \mu s\) , 咦?可以精確的計算出來方波頻率呢。

我們改用頻率來看這些數值 \(F_0 = F_c = \frac{1}{T_0} = \frac{1}{T_c} = 62500 Hz = 62.5 kHz, F_s = \frac{1}{T_s} = 250000 Hz = 250 kHz\)

3 這跟取樣有什麼關係?

啊,這就是取樣啊,取樣就是這麼單純的一件事。「用同樣的頻率去觀察這個世界」,就是取樣的基本意義。上一篇文章「淺談取樣定理」就是在闡述這件事,所以,用固定的週期,去觀察 GPIO 的值,你說他跟取樣定理沒關係嗎?錯啦,他就是取樣定理的一個應用,所以取樣定理的 Nyquist rate 一樣會應用在這個過程中。所以 \(F_s \ge 2 * F_c\) 所以可以成功的取樣完整的訊號,等等,好像哪裡不對吧?先別說這個了,我們來看萬一你的計數頻率低於要偵測的頻率怎麼辦。

4 如果你的計數頻率低於要偵測的頻率呢?

如果你要計數的頻率低於要偵測的頻率,會發生什麼事呢?按照前面的流程,我們就畫一下波形來看看。

ZeroCrossingUnderSampling.jpeg

Figure 2: 頻率計數 Undersampling

2 就是 undersampling 的情況,一樣黑色方波是要計算頻率的波形,而橘色方波代表讀取外部 GPIO 值的時間點,綠色就是讀到的值。

\(T_0 = 4 \mu s, T_s = 6 \mu s, T_c = 12 \mu s\)

換算成頻率

\(F_0 = 250 kHz, F_s = 166.667 kHz, F_c = 83.333 kHz\)

哇,你說這怪怪的吧,我原本的頻率是 250 kHz,取樣後變成 83.333 kHz,你說,啊對,因為低於 Nyquist rate,所以無法取樣到正確的頻率,所以把這個資訊丟棄吧!不,這個資訊還是有用的,這個是低於 Nyquist rate 的時候,會看到的現象。在這裡,因為你在方波的正緣與負緣都取樣,所以其實真正的取樣率 $Fs = 333.333 kHz$,這就是上一節怪怪的地方(有看出來嗎?)我為什麼這麼做呢?因為在某些數位的計數器就是這麼做的,正緣與負緣都偵測一次,如果值改變了,就累計一次,沒改變就不累計。這種情況下的取樣頻率你要乘以二。

好啦,重點來了,\(F_s - F_0 = 333.333 - 250 = 83.333 kHz\) ,這巧合吧,你說。再次有圖有真相,我們來畫圖。

FrequencyAmbiguity.jpeg

Figure 3: Frequency Ambiguity

3 是我們常見的取樣圖形化分析方式1, \(F_0\) 是你觀察的訊號,他的頻率高於 \(\frac{F_s}{2}\) 。取樣後我們能看到的頻率範圍只有橘色所框住的 \([-\frac{F_s}{2}, \frac{F_s}{2}]\) 而已,所以高於 \(\frac{F_s}{2}\) 的我們就畫一條水平線,看他與橘色範圍的三角形交叉的點在哪裡,計算其頻率,那就是你取樣後的頻率。在我們這個例子中可以看到 $Fc < 0$,計算出來是 $Fc = F0 - Fs = 250 - 333.333 = -83.333 kHz$,先不看正負號,週期跟圖 2 算出來是一樣的吧?負號只是影響相位而已,不影響頻率。

5 結語

筆者發現每次寫部落格文章,最頭痛的就是畫出那精美的圖形,本來用 Python matplotlib 已經夠簡單了,不過還是要花點時間,所以部落格文章發表都拖很久,從這篇文章開始,筆者改用手繪!讓大家看到我醜醜的手寫字真是有點不好意思,不過這樣子可以發文章發得比較快一些。本篇就是承襲上一篇文章的取樣定理,在嵌入式系統或是數位設計常常會遇到的計數器問題上舉個例子,讓大家看看取樣定理是怎麼應用的,其實很常見啊,不是只有你在接收 ADC 傳進來的資料才會遇到喔!希望大家喜歡今天的文章!

Footnotes:

1

參見 Richard G. Lyons, "Understanding Digital Signal Processing," 3ed, Prentice-Hall, 2011.

Author: Albert Huang

Created: 2016-05-30 Mon 22:02

Validate

Wednesday, May 25, 2016

淺談取樣定理

淺談取樣定理

淺談取樣定理

由於 blogspot 會被某些公司擋,我已經著手將這裡的文章慢慢的移到 GitHub Pages 上面,這篇文章可以在 這裡 看到

1 來個取樣的思想實驗

想像你的房子剛好有個窗子,能看到窗外有個摩天輪,這個摩天輪有 360 個座位,以逆時針方向依序編號,但不巧,你的視角只能看到一台車。如果你固定兩個小時的整點觀察一次該摩天輪,發現每次都是編號第 180 的車,請問該摩天輪的轉速是多少?還是該摩天輪根本就沒轉呢?

那麼如果你增加觀察的頻率,固定每個小時的整點都觀察一次該摩天輪,發現這次不一樣了,每個小時觀察到的車輛編號是 0, 180, 0, 180 交替出現,那這代表什麼呢?恭喜你,至少確定排除摩天輪不轉的可能性。那麼該摩天輪的轉速到底是多少呢?每兩個小時觀察到他會轉一整圈,那麼是每小時半圈嗎?答案是:不一定。

這次我們換個角度來想,已知摩天輪每兩個小時轉一整圈,那麼你最少要用多快的觀察頻率,才能知道摩天輪的正確轉速?

如果你用跟摩天輪轉速相同的頻率,也就是每兩個小時觀察一次,那你會跟第一段的觀察結果一樣,看到每次都一樣的車輛編號,導致你根本就不知道他到底是有轉還是沒轉。那如果你用每個小時觀察一次,也就是兩倍於摩天輪轉速的頻率來觀察,那你會看到跟第二段一樣的結果,也就是每個小時剛好是相反的位置被觀察到,換算成轉速是每小時 0.5 圈,那如果變成四倍,也就是每 30 分鐘就觀察一次呢?摩天輪每兩個小時轉一整圈,那每 30 分鐘就是轉 1/4 圈了,那你會看到 0, 90, 180, 270, 0, 90, 180, 270,換算也是每小時 0.5 圈,看來你已經可以正確觀察到摩天輪轉速了,更高的觀察頻率應該也可以觀察到正確的轉速,你心裡想。可是最少要多少頻率才能觀察到正確轉速呢?

這次我們每一個半小時觀察一次,上一段我們知道每 30 分鐘,摩天輪會轉 1/4 圈,所以每 90 分鐘觀察,摩天輪會轉 3/4 圈的角度,也就是 360 * 3/4 = 270 個車輛,從 0 開始的話,會依序觀察到 0, 270, 180, 90, 0, 270, 180, 90, 0, …….,如果這次是你第一次觀察到的結果,你可能會很興奮的下結論說這個摩天輪每 4*90=360 分鐘轉一圈,而且方向是與編號方向相反方向的。可是我們已經知道摩天輪每兩個小時轉一圈啊,這個結果跟已知不合啊。所以低於轉速兩倍的觀察頻率看來也是不行,有興趣的讀者可以嘗試其他低於兩倍的觀察頻率,看看結果是如何?

那現在同樣的摩天輪,但你搬家了,變成只能看到摩天輪的地面,剛好在編號 0 的車輛上,有一個雷射光束,永遠指著地面,而你能夠觀察到地面的雷射光束位置。

高中數學告訴我們,雷射光束的位置與編號 0 的車子被轉的角度有一個關係,那個關係叫做 \(cos \theta\), 這裡假設摩天輪的半徑是 1,那在地面雷射光束的位置就是 \(cos \theta\) 了,所以地面位置用 +1 到 -1 來表示。

回到摩天輪觀察頻率,如果我們用每兩個小時觀察一次的頻率,我們會看到雷射光束一直都指在同一個地方,為了方便描述,我們就說他一直都是在 +1.0 的位置上。畫成圖就會像圖 1 所示。

SamplingRate_1.png

Figure 1: 取樣頻率等於訊號頻率

那如果我們每個小時觀察一次,雷射光束指的位置又會有什麼變化呢?如果我們在相同位置觀察到 0, 180, 0, 180, ……, 那麼第 0 輛車的位置就會在 +1.0, -1.0, +1.0, -1.0, …… 變化了,畫成圖的話就變成:

SamplingRate_2.png

Figure 2: 取樣頻率兩倍於訊號頻率

在訊號處理的領域上,我們習慣將取樣到的點與 X 軸連接起來,來表示它是取樣資料,就像下圖這樣:

SamplingRate_2_a.png

Figure 3: 週期為 2 hr,頻率 \(F = \frac{1}{2}\) cycles per hour 的正弦波,以 \(F_s = 1\) cycles per hour 來取樣(\(F_s = 2*F\))

在圖 3 我們引入了週期以及頻率的觀念,這裡我們用的頻率單位是 cycles per hour,也就是每小時的轉速,轉換成每秒的轉速就變成 \(\frac{1}{3600}\) cycles per second,也就是 \(\frac{1}{3600}\) Hz(Hz 這個單位一直到 1960 年代為了紀念赫茲(Heinrich Hertz) 以後才被廣泛使用,在此之前都是以更直接的 cycles per second 這種一目了然的單位來表示),正弦波的一個週期,就是上述的摩天輪轉一圈回到原點,所以會用 cycles 喔!

那麼如果我們回頭看剛剛那個以 1.5 小時取樣率的結果,畫成圖來看呢?注意算一下圖上的訊號週期就是 6 小時(X 軸的單位就是小時),與我們剛剛計算的結果是一樣的,也就是 360 分鐘轉一圈。

SamplingRate_1.5.png

Figure 4: Fs = 1.3333 * F

那我們如果取樣頻率更高一些呢?比方說四倍?我們來看一下結果:

SamplingRate_4.png

Figure 5: Fs = 4 * F

5 看起來就像是圖 3 的細緻版,只要每四點取一點,就會變成取樣率只有兩倍的那張圖。而這個「每 N 點取一點」也就是訊號處理 decimation 的基本觀念(不過當然不只有這樣,還需要做一些濾波的動作),但這就是基本的取樣率轉換的概念,在這篇文章裡面我們不詳談,有機會筆者再詳細說明。

SamplingRate_2_b.png

Figure 6: 週期為 \(\frac{2}{3}\) hr 的正弦波,以 \(F_s = 1\) cycles per hr 取樣

回到本文的第二段,為什麼看起來一樣的圖形,不一定代表一樣高的頻率訊號;圖 6 看起來跟圖 3 是完全一樣的圖形,但其實他的原始訊號頻率高三倍,不信我們將取樣率再高一些,變成 3 倍看看,如圖 7 所示。

SamplingRate_2_c.png

Figure 7: 週期為 \(\frac{2}{3}\) hr 的正弦波,以 \(F_s = 3\) cycles per hr 取樣

這是因為在數位訊號的領域上,不能表示真實的頻率,所有的頻率只剩下 [0, 1] 或是 \([0, 2\pi]\) ,前者稱為 normalized frequency, 單位是 cycles/sample,後者的單位則是 radian/sample,要轉換成真實的頻率,就需要把取樣率考量進來,變成 \([0, \frac{F_s}{2}]\) Hz,所以在數位訊號處理中,取樣率是個非常重要的參數喔!

而圖 6 取樣率是 1 cycles per hour,被取樣的訊號是 1.5 cycles per hour,最後得到的數位訊號是 1 cycles per hour,這個現象稱之為 alias,是我們一般要避免的,但有時候也會刻意採用這種取樣方式,筆者在下一篇文章會講相關的議題。

2 Nyquist Rate

我們常常會聽到某訊號的 Nyquist rate 是多少?其實就是上一段直觀結論的數學版,一個 F 頻率的訊號,要用 \(F_s = 2*F\) 的取樣頻率來取樣,才能夠完整表示這個訊號,這個 \(F_s = 2*F\) 就是 Nyquist rate,有時候這又稱為取樣定理,或是 Shannon Sampling Theorem. 這裡的 Shannon 就是那個 Claude E. Shannon 啦。這起源於 19xx 年代,美國的電話公司開始數位化語音訊號,當時用的是 64kbps PCM(Pulse-Coded Modulation, 是一種用脈衝振幅來代表訊號大小的一個數位傳輸方式),為了節省頻寬,電話公司當然是要研究怎麼樣才能用最少的取樣頻率來傳遞語音訊號,Nyquist 採用的方式比較像是工程師直接量測與觀察得到的結論,而 Claude E. Shannon 則是後期利用取樣與 FFT 的關係,用數學式來描述,所以同樣內涵的取樣定理,有人稱之為 Nyquist Sampling Theorem,也有人稱之為 Shannon Sampling Theorem, 或是 Nyquist-Shannon Sampling Theorem,至於量測得到的結論,與數學式表示誰比較重要,我認為是兩者都重要,因為還沒有什麼理論是不需要實際驗證的,在理論能建構之前,大部分時候,也無法憑空想像出來,因為實驗就是了解上帝所創造的這個世界的方式。歸納永遠比演繹來得早,但歸納與演繹缺一不可;歸納能讓你了解系統現象,演繹則能讓你在腦海中從事思想實驗並大幅推廣。

3 取樣率與取樣頻寬

既然單一頻率的正弦波可以用他的 Nyquist Rate 來正確取樣,那麼所有頻率低於這個頻率的正弦波也可以用同樣的取樣率來取樣,所以我們一般會說 \(F_s \ge 2B\), \(F_s\) 是取樣率, B 是所需的訊號頻寬。

4 那我到底要多少取樣率呢?

是的,了解最低需要兩倍的取樣率之後,在訊號處理領域裡面,永遠都會再繼續問這個問題:到底要多少取樣率才夠呢?取樣率高有什麼好處與壞處?在市面上強調高取樣率的,最常見的就是音效卡,明明已經說了音樂到 20kHz 的頻寬就足夠,而 CD 取樣率也只有到 44.1kHz 而已,但你還是可以看到 96kHz 甚至 192kHz 取樣率的音效卡,那取樣率比 Nyquist rate 高這麼多有什麼用處呢?這有很多實作上的考量,先不談這個,你聽過錄製音樂的 CD 嗎?

5 說個 CD 取樣率 44.1 kHz 的小故事

一般會說人耳能夠聽到的範圍是 20 kHz,各位讀者現在也知道了只要兩倍的取樣率就足夠了,那為什麼 CD 的取樣率是 44.1 kHz 呢?那為什麼 DAT(錄音室比較常見的數位錄音帶)是 48 kHz 呢?根據維基百科,這要講到 1979 年 Sony 出了一台 PCM-1600 的裝置,可以在一般的卡帶上錄數位聲音,上面的取樣率就是 44100 Hz,因此 1980 年制定 CD 的標準的時候,就採用這個取樣率。那麼為什麼是 44100 Hz 而不是 40 kHz 呢?首先,要送進 ADC(Analog-to-Digigal Converter) 之前,要先經過一個低通濾波器,而真實世界的濾波器不會「嘎然而止」,而是會「漸漸停止」,這個「漸漸」就是 transition band,transition band 寬一點,濾波器比較容易設計,所以預留了 2.05kHz 的 transition band,那為什麼不是更多呢?當年電視是 PAL 與 NTSC 的時代,都是類比的,現在也幾乎看不到了,所以以當時的技術來說,44100 Hz 可以同時與 PAL 與 NTSC 相容,因為:

NTSC:

  • 245 * 60 * 3 = 44100
  • 245 active lines/field * 60 field/second * 3 samples/line = 44100 samples/second
  • 每個 field 245 條垂直掃描線(整張畫面的主動掃描線是 490 條,但全部有 525 條,但 NTSC 時代每次只更新半張畫面)
  • 每秒 60 field(所以每秒是 30 張)
  • 主要使用在北美
  • 北美交流電是 110V, 60Hz

PAL:

  • 294 * 50 * 3 = 44100
  • 294 active lines/field * 50 field/second * 3 samples/line = 44100 samples/second
  • 每個 field 294 條垂直掃描線(整張畫面的主動掃描線是 588 條,但全部有 625 條,一樣也是每次只更新半張畫面)
  • 每秒 50 fiels(所以每秒是 25 張)
  • 主要使用在歐洲
  • 歐洲的交流電是 110V, 50Hz

這個其實是相當好的工程範例,說明取捨(trade-off) 的藝術,也因此,當年 Sony 在標準會議上大獲全勝,於是 16 bits 44100 Hz 就 變成了 CD 的標準。1980 年代的日本在電子產業上真是強悍啊。

6 結語

對於數位訊號處理的初學者來說,取樣定理一直都是很難的一個題目,筆者一直都想寫個文章來談談取樣定理,也一直沒有太多心思來思考該如何淺顯的表達。本文的思想實驗是我認為很容易入門的方法,藉由這個思想實驗,讀者可以詳細了解取樣的動作,以及取樣會發生的效果,進而了解取樣定理所要描述的內容。取樣其實還有很多其他的題目可以探討,筆者希望這是一篇能夠讓讀者不至於懼怕取樣定理的一篇文章。

Author: Albert Huang

Created: 2016-05-25 Wed 23:33

Validate

Monday, March 3, 2014

漫談分貝(dB) 這一堆玩意兒

今天是 3 月 3 日, 恰好是發明電話的貝爾的生日, 所以今天我們來談以貝爾的姓氏命名的單位, Bel 以及 decibel(分貝或 dB)。剛開始接觸數位訊號處理或是通訊領域, 最常令人困惑的就是 dB 這個玩意兒, 它既不是一個單位, 也不怎麼直覺, 接下來就讓我們來看看這玩意兒吧。

分貝(dB, or decibel) 當初是拿來描述量測的電話線訊號衰減量, 在 1928 年貝爾系統公司(貝爾電報電話公司的相關企業)把原本使用的 Transmission Unit(TU) 改名為 decibel, 並且增加 Bel(1 Bel = 10 decibel), 用來紀念發明電話的貝爾(Alexander Graham Bell, March 3, 1847 – August 2, 1922),1 文章發布的今天剛好是他的生日。

分貝是拿來描述衰減量的, 只是一個相對單位而已, 就像一般講的數量級一樣, 一個數量級代表的是十倍, 而 1 Bel 就是 10 dB, 是由以 10 為基底的對數函數產生:

\begin{equation} L_{dB} = 10~\log_{10} \frac{P_1}{P_2} \end{equation}

要先記住上述衰減量是拿來描述功率衰減的, 我們也可以用 dB 描述振幅的衰減量, 而初學者很容易搞混計算功率以及振幅衰減的分貝公式。

功率:

\begin{equation} L_{dB} = 10~\log_{10} \frac{P_1}{P_2} \end{equation}

振幅(如電壓、電流、聲壓):

\begin{equation} L_{dB} = 20~\log_{10} \frac{A_1}{A_2} \end{equation}

只要先記得分貝都是計算功率的公式, 再利用電路的基本公式: \(P=IV=\frac{V^2}{R}\), P 為功率, I 為電流, V 為電壓, R 為電阻, 那麼:

\begin{equation} L_{dB} = 10~\log_{10} \frac{P_1}{P_2} = 10~\log_{10} \frac{V_1^2}{V_2^2} = 20~\log_{10} \frac{V_1}{V_2} \end{equation}

而大部分功率都是振幅的平方倍, 所以都可以得到上述的式子, 因此振幅計算公式前面的常數是 20。

當倍數轉換成分貝讓乘法轉換成加法, 除法轉換成減法, 使得運算更為簡單, 其數值也不容易超過能夠表示的範圍。例如接收機的情況, 從發射機一路到接收機的各級增益, 按照順序列表:

  • 發射機 \(P_{TX} = 1W = 10\log_{10} \frac{1W}{1mW} = 10\log_{10} 1000 = 30 dBm\)
  • 發射天線增益 \(G_{TXANT} = 10 dBi\), 或 10 倍
  • 空氣中衰減 \(ATT_{channel} = -60 dB\), 或 1/1000000 倍
  • 接收機天線增益 \(G_{RXANT} = 10 dBi\), 或 10 倍
  • 接收機 LNA 增益 \(G_{RX} = 20 dB\), 或 10 倍

計算各級增益, 以 dB 來計算,只要算

\begin{equation} RSSI_{dB} = P_{TX} + G_{TXANT} + ATT_{channel} + G_{RXANT} + G_{RX} = 30 + 10 - 60 + 10 + 20 = 10 dBm \end{equation}

而用倍數來計算則會是這樣:

\begin{equation} RSSI = 1 * 10 / 1000000 * 10 * 10 = 0.001 \end{equation}

可以看出用倍數算會出現動態範圍比較大的整數或小數, 而 dB 值只要加加減減就出來了, 這在浮點運算的時候看不出好處, 但在定點運算上可以看出來上述的例子, dB 的計算只要給有號整數部分 8 個位元即可表示, 而線性尺度(linear scale, 也就是上述所稱的倍數) 的計算則會做到超過 20 位元的除法。

除了運算上會變得動態範圍變小以外, dB 公式中的對數函數也有將比較小的數值變化放大並將比較大的數值變化縮小的功用。

Resp_linear.png

Figure 1: 線性尺度

Resp_dB.png

Figure 2: dB 尺度

可以看得出來 320kHz 以下的變化原本在線性尺度看不太出來, 但在 dB 尺度看出來上下變化範圍有 10 dB 的大小, 這對訊號來說已經算是不小的影響。而線性尺度看起來差異很大(一半)的 400kHz 到 900kHz 的範圍, 在 dB 尺度上只有 4 dB 左右, 320kHz 變化 10 dB 在這個例子中, 因為那不是我們要的訊號, 所以影響不大, 但若發生在我們想要的頻譜上, 線性尺度可能就會看不太出來, 這個是 dB 尺度的優點。

以上就是對於 dB 簡單的介紹, 那麼我們常常看到 dB 後面還加上一些字母, 那是什麼意思呢?我們來看一些常用的 dB 家族。

分貝後面如果加上了其他的字母, 代表分母的參考量, 就會從相對值變成絕對值。

  • dBm 代表分母是 1mW, 所以 \(dBm = 10~\log_{10} \frac{P}{1mW}\)
  • dBW 代表分母是 1W, 所以 \(dBW = 10~\log_{10} \frac{P}{1W}\)

如果是分貝後面加上其他字母, 但是該字母被括號刮起來, 是代表訊號的種類。

  • dB(A) 代表聲壓, 是一個絕對單位, 參考訊號位準是 \(20~\mu~Pa\),2 是人耳所能聽到的下限, 又因為聲音是振幅, 所以計算公式為:
\begin{equation} L_p = 20~\log_{10}\frac{P_{rms}}{P_{ref}}, P_{ref} = 20~\mu~Pa \end{equation}

聲音用 dB 來表示是因為耳朵對於壓力變化大小是對數級的, 至於頻率變化也有類似的關係, 因此對於噪音計算定義了 octave band filter, 每一個 octave band 的中心頻率是下一個 band 的 2 倍或 1/2。3

dBi 是用來描述天線增益, 定義是最大的波束相對於理想均勻球體輻射樣式(isotropic) 的增益。

dBm/Hz 則是拿來描述功率密度(power spectral density), 意思就是每 1 Hz 所含的功率, 如果你有功率密度 -30 dBm/Hz, 在 10 MHz 寬度上都是平坦的, 其他地方的數值都小到可以忽略, 那麼總發射功率就是 \(-30 + 10 \log_{10} {10 \times 10^6} = 40 dBm = 10W\)

我們描述 SNR(訊雜比) 的時候也常常用 dB 來描述, 大部分的接收機, 比如說 Wifi, Bluetooth, LTE, WCDMA 等等都會顯示 SNRdB, 而筆者常常看到有人引用這個 SNR 值的時候, 忘記加上 dB, 這樣會造成非常大的誤解與巨大的差異, 舉例來說, 如果 SNR 是 60 dB, 而引用的時候說 SNR 是 60, 那麼這個意思就是 \(\frac{P_{signal}}{P_{noise}} = 60\) 了, 而 \(60~dB = 10^{\frac{60}{10}} = 1000000\), 差距有 \(\frac{1000000}{60} = 16666.7\), 有上萬倍的差異啊!筆者知道分貝對初學者來說, 是個不容易搞懂的數量, 因此寫了這篇文章, 希望大家在接觸訊號與通訊領域的時候, 看到 dB4 能夠不再那麼陌生。

Author: Albert Huang

Created: 2014-03-03 Mon 21:47

Emacs 24.3.1 (Org mode 8.2.1)

Validate

Tuesday, February 18, 2014

談談 ARM Cortex-M4F 上的 DSP 功能

1 談談 ARM Cortex-M4F 上的 DSP 功能

1 前言

從 ARM2 在 1986 年問世以來, ARM 的處理器一向以省電性聞名, 之後到了智慧型手持裝置的時代, 省電性更是非常迫切的需求, 到了 2005 年, 有 98% 的手機上面至少有一顆 ARM 的處理器。1 專精於數位訊號處理的工程師, 除了傳統的數位訊號處理器以外, 勢必要了解一下這樣的趨勢, 以及如何在自己的專案中評估使用 ARM 處理器的可能性, 本文將會針對與中低階 DSP 較為類似的 ARM Cortex-M4F 上的 DSP 功能來討論。

2 ARM Cortex-M4F 功能簡介

ARM Cortex-M4F 是 ARM Cortex-M 系列的處理器裡面功能最為強大的一個, 而 Cortex-M 系列的 M 是指 microcontroller, 下表列舉了部分的 Cortex-M 系列處理器的比較, 可以看出 Cortex-M4F 在指令集上有硬體乘法、硬體除法、飽和運算、數位訊號處理延伸指令以及浮點運算。

ARM Cortex-M 系列指令集支援2

ARM Cortex-M Thumb Thumb-2 硬體乘法器 硬體除法器 飽和運算 DSP 延伸功能 浮點 ARM 架構 核心架構
Cortex-M3 完整 完整 單一時脈 ARMv7-M Harvard
Cortex-M4 完整 完整 單一時脈 選項 ARMv7E-M Harvard

另外, Cortex-M4F 還有以下特點是數位訊號處理器程式設計師會注意的:

  • 沒有快取記憶體
  • 沒有記憶體管理單元(MMU)
  • 記憶體保護單元(MPU) 是選項功能
  • 中斷處理延遲最長 12 個時脈

在擁有 DSP 能力的處理器中, 有幾個分類:

  1. 數位訊號處理器(Digital Signal Processor)
  2. 數位訊號控制器(Digital Signal Controller)

第一種就是一般印象中的數位訊號處理器, 其特點就是架構完全針對數位訊號處理而優化, 是真正能夠持續的以單一時脈執行乘積累加運算, 亦即乘積累加所需的運算元會在下一個時脈就已經載入並執行運算, 而不用等待運算元從記憶體載入的時間, 發揮極致的運算能力, 但是設計複雜度比較高, 一般來說省電性不如微處理器或微控制器。這種有 TI TMS320C67x 定點與浮點 DSP 系列與很早期的 Motorola(現為 Freescale) DSP56300(這是 Steve Jobs 出走 Apple 時創立的 NeXT 公司在他們的工作站使用的 DSP56001 的下一代產品線, 是特殊的 24-bit DSP)。大部分的 DSP 只支援定點運算, 因為同樣的面積與功耗, 定點運算能夠提供更高的運算能力, 而且以訊號處理的應用而言, 不需要浮點數這麼高的動態範圍。當然, 浮點 DSP 還是有其優勢, 尤其是在一些必須縮短開發時間的應用上, 浮點數能力使得程式設計師不需要耗費太多精神與時間處理定點數運算。

第二種就是把微控制器整合數位訊號處理能力而成, 以傳統的微控制器為主, 擁有豐富的周邊支援與輸出入腳位。ARM Cortex-M4F 屬於這一個分類, 並且因為 ARM 架構被廣泛的支援, 使得 ARM Cortex-M4F 擁有豐富的工具可以應用。以 STMicroelectronics 公司的 STM32F 系列來說, 其 10ku 報價在 2 至 10 美元之間, 往下與 16-bit MCU 重疊, 往上與入門級 DSP 重疊。

3 DSP 運算的核心: 乘積累加(Multiply-and-Accumulate)

我們常常看到支援數位訊號處理能力的處理器都會強調其乘積累加(MAC, or Multiply-and-ACcumulate) 的能力, 這是因為在數位訊號處理演算法上, 大量的使用 MAC 運算。

不管是有限響應濾波器:

\begin{equation} y[n] = \sum_{k=0}^{N-1} h[k]x[n-k] \end{equation}

或是無限響應濾波器:

\begin{equation} y[n] = b_0 x[n] + b_1 x[n-1] + b_2 x[n-2] + a_1 y[n-1] + a_2 y[n-2] \end{equation}

還是快速傅利葉轉換中很重要的 butterfly 運算:

\begin{eqnarray} Y[k_1] & = & X[k_1] + X[k_2] \\ Y[k_2] & = & (X[k_1] - X[k_2])e^{-j\omega} \end{eqnarray}

這些都非常仰賴乘積累加的運算。

ARM Cortex-M4F 與乘法或乘積累加有關的指令集如下表2:

運算 指令意義 指令列表
16 * 16 = 32 Signed Multiply (SMUL) SMULBB, SMULBT, SMULTB, SMULTT
16 * 16 + 32 = 32 Signed Multiply and Accumulate (SMLA) SMLABB, SMLABT, SMLATB, SMLATT
16 * 16 + 64 = 64 16-bit Signed Multiply with 64-bit Accumulate (SMLAL) SMLALBB, SMLALBT, SMLALTB, SLMALTT
16 * 32 = 32 16-bit by 32-bit signed multiply returning 32 MSB, i.e. word (SMULW) SMULWB, SMULWT
(16*32) + 32 = 32 Q setting 16-bit by 32-bit signed multiply with 32-bit accumulate (SMLAW) SMLAWB, SMLAWT
(16*16) + (16*16) = 32 Q setting sum of dual 16-bit signed multiply (SMU-AD) SMUAD, SMUADX
(16*16) - (16*16) = 32 Dual 16-bit signed multiply returning difference (SMU-SD) SMUSD, SMUSDX
(16*16) + (16*16) + 32 = 32 Q setting dual 16-bit signed multiply with single 32-bit accumulator (SMLAD) SMLAD, SMLADX
(16*16) - (16*16) + 32 = 32 Q setting dual 16-bit signed multiply subtract with 32-bit accumulate (SMLSD) SMLSD, SMLSDX
(16*16) + (16*16) + 64 = 64 Dual 16-bit signed multiply with single 64-bit accumulator (SMLALD) SMLALD, SMLALDX
(16*16) - (16*16) + 64 = 64 Q setting dual 16-bit signed multiply subtract with 64-bit accumulate (SMLSLD) SMLSLD, SMLSLDX
32 * 32 = 32 Multiply MUL
32 + (32 * 32) = 32 Multiply accumulate MLA
32 - (32 * 32) = 32 Multiply subtract MLS
32 * 32 = 64 Long signed/unsigned multiply SMULL, UMULL
(32 * 32) + 64 = 64 Long signed/unsgiend accumulate SMLAL, UMLAL
(32 * 32) + 32 + 32 = 64 32-bit unsigned multiply with double 32-bit accumulation yielding 64-bit result UMAAL
32 + (32 * 32) = 32 MSB 32-bit multiply with 32-most-significant-bit accumulate SMMLA, SMMLAR
32 - (32 * 32) = 32 MSB 32-bit multiply with 32-most-significant-bit subtract SMMLS, SMMLSR
(32 * 32) = 32 MSB 32-bit multiply returning 32-most-significant-bits SMMUL, SMMULR

以上都是定點運算3, 並且每一個指令都能夠在一個時脈執行完畢, 或許你會問:「我只想寫 C 語言, 而且已經有函式庫, 為什麼還需要了解指令集呢?」如果你不碰數位訊號處理應用, 或許可以不用了解這一顆處理器的指令集, 但就像作業系統的程式設計師必須要了解處理器關於作業系統的指令集一樣, 數位訊號處理工程師必須在了解所有 DSP 指令集後, 想盡辦法像國稅局一樣榨乾這顆處理器, 一滴都不能剩。尤其是函式庫提供的定點運算都只有 Q31 與 Q15 的選擇, 如果你有其他特殊的需求, 就得自己寫數位訊號處理程式碼。在 C 語言的優化過程中, 使用指令集的 intrisincs 是不可避免的。

ARM Cortex-M4F 也有符合 IEEE-754 規範的浮點運算單元, 而單精確浮點數在訊號處理演算法上扮演很重要的角色, 下表列舉了單精確浮點數的運算與時脈數:

單精度浮點運算 指令 執行時脈
加/減 VADD.F32, VSUB.F32 1
乘法 VMUL.F32 3
乘積累加 VMLA.F32, VMLS.F32, VNMLA.F32, VNMLS.F32 3
Fused MAC VFMA.F32, VFMS.F32, VFNMA.F32, VFNMS.F32 3
平方根 VSQRT.F32 14
除法 VDIV.F32 14

可以看出浮點數的乘法比較花時間, ARM Cortex-M4F 有提供 fused MAC 指令以增加精確度。

接下來, 我們來看實際上拿 ARM Cortex-M4F 寫數位訊號處理程式的時候的效能, 以下是一般標準的 FIR 濾波器的程式碼:

void fir(q31_t *in, q31_t *out, q31_t *coeffs, 
         int *state, int numTaps, int blkSize)
{
    int sample;
    int k;
    q63_t sum;                  /* Q2.62 in 64-bit acccumulator */
    int idx = *state;

    for (sample=0; sample<blkSize; sample++)
    {
        state[idx++] = in[sample];
        sum = 0;
        for (k = 0; k < numTaps; k++)
        {
            sum += (q63_t) coeffs[k] * state[idx]; /* 1. Fetch coefficient and sample. 2. Perform MAC */
            idx--;                         /* Pointer update for circular addressing */
            if (idx < 0)
            {
                idx = numTaps - 1; 
            }
        }
        out[sample] = (q31_t) (sum >> 31u); // Convert Q2.62 to Q1.31
    }
    *state = idx;
}

參考更早之前的 FIR 濾波器運算式:4

\begin{equation} y[n] = \sum_{k=0}^{N-1} h[k]x[n-k] \end{equation}

h[k] 就是 coeffs[k], x[n-k] 就是 state[idx], numTaps 就是 N, out[sample] 則是 y[n].

在最內側的迴圈中包含了:

  • 載入係數與輸入取樣
  • 執行乘積累加運算
  • 循環定址的指標更新

在現代 DSP5 中, 上述運算可以在一個或兩個時脈內執行完畢, 如:

    do          x0,FirLoop
     mac    x1,y1,a     x:(r0)+,x1  y:(r4)+,y1
FirLoop

這個迴圈指令是 zero overhead loop, 而且只需一個時脈指令就能完成上述三項最內側迴圈需要完成的事項。這是數位訊號處理器的能力, 而且也需要使用組合語言來優化, 那我們來看 ARM Cortex-M4F 用 C 語言能夠達到的速度:

動作 時脈數
載入 coeffs[k] 2
載入 state[idx] 1
乘積累加 1
idx-- 1
循環定址 4
迴圈 overhead 3
總共 12

從上述表格中可以看出, 即便 ARM Cortex-M4F 這類數位訊號控制器擁有一個時脈就可以完成的乘積累加指令, 加上其他額外的執行成本, 就增加到 12 個時脈才能完成一個乘積累加。有一些 C 語言優化的方式:

  • Circular addressing alternatives
  • Loop unrolling
  • Caching of intermediate variables
  • Extensive use of SIMD and intrinsincs(還是用上指令集)

如果用上這些, 並且輸入以及係數是 16-bit 的情況下, 是可以達到平均每個乘積累加 1.625 個時脈的程度。6如果需要的精確度是 32-bit 的情況下, 可能會需要更多時脈, 但已經與數位訊號處理器差距不算遠了, 當然若與同樣擁有 SIMD 能力的數位訊號處理器並且優化相比, 還是差上一大截, 但是搭配 ARM 廣泛的周邊與軟體資源, 這樣的效能已經很吸引人。

在數位訊號處理程式上, ARM 提供了 CMSIS(Cortex Microcontroller Software Interface Standard) DSP 函式庫, 在實際開發時只需要呼叫這些函數即可, 但要善用這個函式庫, 還是需要對於數位訊號處理基本概念有認識才行。

另外, 在使用 ARM Cortex-M4F 的累加器的時候, 需要注意的是, 累加器不會自動作飽和動作, 因此做定點運算的時候, 必需自行預留累加的空間, 或是先將數值預先縮小以避免溢位。

4 結語

從 ARM7 問世開始, ARM 這間公司展現的企圖就是除了 32-bit microprocessor 以外, 還要開始蠶食 8-bit/16-bit MCU 的市場, 經過了一陣子的努力之後, 繼續推出了 ARM Cortex-M 系列展現強烈的企圖心, 如今採用的公司漸漸增多, 侵蝕了部分 16-bit MCU 的市場, MCU 程式設計師必須要看清這個趨勢, 學習 ARM 系列架構來接受這個潮流變化。Cortex-M 系列最高接的 Cortex-M4F 提供了數位訊號處理能力, 成為數位訊號控制器, 在省電性主導的地方, 與 16-bit DSP 相比互有優劣, 但 Cortex-M4F 提供了 32-bit 浮點運算, 讓開發時間能夠縮短, 千萬不可小看 ARM 在數位訊號控制器上的未來性。本文只討論了 ARM Cortex-M4F 的 DSP 能力以及在新的 DSP 專案中使用 ARM Cortex-M4F 的可能性, 筆者將在後續的文章中陸陸續續介紹如何使用 Cortex-M4F 來做實際的數位訊號處理應用。

Footnotes:

2

ARM® Cortex™-M4 Processor Technical Reference Manual Revision r0p1, http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0439d/index.html

3

有關於定點數 Q format 可以參考我之前寫的「定點數表示法」, http://alberthuang314.blogspot.tw/2012/08/blog-post.html

4

有關於 FIR 有限響應濾波器的概念可以參考我之前寫的「淺談動平均濾波器」, http://alberthuang314.blogspot.tw/2012/08/blog-post_24.html

5

這還是 Motorola DSP56300 的組合語言, 是將近二十年前的產品。

6

Kishore Dasari, Designing with the Cortex-M4, https://www.arm.com/files/pdf/DSPConceptsM4Presentation.pdf

Author: Albert Huang

Created: 2014-02-18 Tue 22:05

Emacs 24.3.1 (Org mode 8.2.1)

Validate

Friday, November 2, 2012

在 SoC debug 的藝術

今天要談一下, 在 SoC(System-on-Chip) debug 的藝術, 首先我先界定一下何謂 SoC, Wikipedia 對於 "System on a chip" 的解釋是 "A system on a chip or system on chip (SoC or SOC) is an integrated circuit (IC) that integrates all components of a computer or other electronic system into a single chip." 對於在 SoC 上面寫程式與 debug, 我認為最大的特點是:

  • 任何地方都有可能會錯

讀者可能會想, 我在任何地方寫程式的特性也是這樣啊, 但是 SoC 還有一個很致命的缺點, 即便是處理器已經驗證過, 都仍然有可能會發生指令集的錯誤, 尤其是組合語言程式設計師每個人的寫法都不一樣, 很有可能會踩到之前沒有驗證過的指令集組合而發生錯誤!

是的, 在 SoC 上寫程式, 驗證工具不管做得再好, 都只是減少錯誤發生的機率而已, 實際上遇到的問題, 還是要有這樣的心態來面對會比較正確。因為在一般的情況下, 我們會把 CPU/DSP 當做已經驗證沒有問題來寫程式, 但是在 SoC 上面, CPU/DSP 非常有可能會因為在新的設計上, 某個或某些組合的 CPU/DSP instruction 在某一級 pipeline 發生問題, 而導致錯誤的結果。即便是大廠如 AMD, 經過了很多的驗證程序之後, 還是有可能出現問題, 如: AMD processor incorrectly updates the stack pointer

在這樣的 SoC 上面寫程式與 debug, 需要有一些藝術與技巧, 筆者就來分享一下我的經驗。筆者分享的是筆者在通訊 SoC 晶片上發展的經驗, 但我想很多部分都可以類推到其他系統晶片上。一般說來, 在這樣的 SoC 上面會出現的錯誤來源有幾個:

  • 自己的程式
  • CPU/DSP instruction 的邏輯錯誤
  • CPU/DSP instruction 的時序錯誤
  • IC 硬體區塊的錯誤
  • IC 內部 Bus 傳輸錯誤
  • IC 與 IC 之間外部 Bus 傳輸錯誤
  • 別家晶片上對於通訊訊號或協定上的錯誤

由於通訊基頻系統大部分都含有一顆或多顆 DSP 負責基頻訊號處理, 所以 DSP programmer 常常身負驗證各個 functional block 的責任, 或是在使用的過程中由奇特的現象來發現驗證團隊之前沒有發現到的錯誤。不管錯誤來源有多少, 解錯誤的首要, 就是先把整個系統以及演算法的原理搞清楚, 清楚之後, 就要依據錯誤出現的現象, 猜測問題出現的點, 然後設計實驗來確認錯誤發生的地方。猜測問題發生的點, 依靠的是對於這個系統的直覺, 而這個直覺是透過你對系統的了解與經驗累積而來的。另外, 就是需要重建錯誤發生時所發生的事情。如果有 simulator 可以使用, 那麼常常在 simulator 上就可以觀察到錯誤的前後發生的事情, 但是像是通訊訊號或協定上的錯誤, 則常常需要有時序上的事件紀錄來重建錯誤發生當時的原貌, 或是有時候沒有現成的分析工具, 就要自己寫一些程式來記錄與觀察變數的變化與事件的流程; 而選擇觀察的物件, 也反映了你對於系統的了解程度。

第一個就是要確定自己的程式沒有問題, 程式可能出錯的來源有兩種: 一種是程式設計師自己寫錯, 另一個是 CPU/DSP instructions 出錯導致程式有錯。前者有很多的程式設計相關書籍都有提到如何避免, 以筆者的經驗, 在寫任何 DSP 程式, 特別是組合語言之前, 一定要先想好怎麼測試自己所寫的程式, 以及怎麼樣算是測試成功及失敗。這部分的觀念, 筆者後來發現軟體業界早已經講了很多, 讀者有興趣的話可以參考 TDD(Test Driven Development) 的觀念。TDD 的導入也能夠幫助我們找到第二、三個 CPU/DSP 指令集上的錯誤。

程式出錯另一個來源就是 CPU/DSP 指令集上的錯誤, 可以略分成兩種: 一種是指令集邏輯上的錯誤, 另一種是指令集時序上的錯誤。一般來說如果 CPU/DSP 有 test pattern 的話, 前者邏輯上的錯誤應該都已經抓完, 剩下的時序上的錯誤, 也就是指令前後組合的問題, 由於樣本數太大, 一般都只能隨機測試, 所以後者時序上的錯誤是 DSP programmer 比較容易遇到的地雷。如果 DSP programmer 是用組合語言撰寫程式, 而不是 C 語言, 那麼踩到地雷的機會更大。如果有編譯器的話, 通常編譯器就可以當作是一個測試的程式, 可以抓到某些編譯器 codegen 愛用的組合語言時序組合的 bug, 但是組合語言程式設計師每個人愛用的組合語言寫法都不同, 就很容易在某個人的寫法上就踩到地雷。而時序上的錯誤其實也是比較難抓的問題, 通常只能依靠 DSP programmer 在使用上的時候, 發現某些奇特的現象, 把搜尋範圍縮小之後才能夠找到。上一節講的 TDD 就能夠幫助 programmer 找到那些奇特的現象在哪裡。另外, 一般來說, 通訊 SoC 的計畫時程短則三年, 長則五年以上, 要求把整本 DSP 架構讀得滾瓜爛熟不也是很合理的嗎? 對於 CPU/DSP 架構的熟悉程度, 也會幫助你可以很快的找到指令時序上的錯誤。

前三項都確定沒問題之後, 接下來要排除的錯誤才是困難的開始, 在此, 筆者建議大家一定要維持寫實驗記錄或是工作記錄的習慣, 筆者常常遇到一解就是一兩週的 bug, 常常解到後來需要與一兩週之前的結果一起比較才能判斷錯誤在哪裡, 因此工作記錄非常重要, 而且有了工作記錄之後, 每天回家才不會心裡一直掛念這件事。要排除這邊的錯誤, 通常是已經有一個錯誤發生了, 這個錯誤也許要做很多次才能重複, 但是一定要確定如何能夠重複這個錯誤, 這點很重要, 因為接下來你會需要一直讓這個錯誤發生才能夠 debug. 讓錯誤發生是一個「點」, 要找出錯誤發生真正的原因(root cause), 常常需要其他的「點」, 讓你連成數條線才能夠把搜尋範圍變小找到真正發生的原因。

找 root cause 的過程, 我個人覺得就像是 binary search 一樣, 不斷的找一個點做判斷, 決定要往左跑, 還是往右跑。當然, 有的時候還是會判斷錯誤, 跑錯方向, 所以就要回溯到當初的切割點, 知道當時的實驗資料是什麼, 為什麼做這樣的判斷, 才能對整個問題有更全面性的了解。這時候仰賴的還是當初的實驗記錄, 所以實驗記錄很重要吧!

除了解單一錯誤以外, 有的時候會需要解多重錯誤。筆者碰觸到的大部分是通訊或訊號處理的問題, 穩定度很重要, 多重錯誤常常會表現在穩定度上, 所以我們常常要記錄錯誤率, 才能知道自己是否已經解完所有的錯誤, 或是剛剛解掉的那個錯誤是否佔的比例最大。另外, 我覺得在這樣的系統上 debug, 還要「大膽的假設,小心的求證」, 有的時候, 我們需要處理的是通訊 physical layer 或是 protocol layer 的問題, 需要猜測對方怎麼做, 這時候就需要大膽的假設, 然後小心的求證。有的時候, 錯誤的可能是另一家公司的晶片, 因此「大膽的假設,小心的求證」是必要的。在這個情況下, 考驗的就是你對整個通訊系統以及原理的掌握程度了。另外, 晶片內部的錯誤, 也是需要「大膽的假設,小心的求證」, 因為這時候, 能夠觀察的工具變少了, 有時候需要猜測。還有, 對已知事物的掌握程度, 也會影響到猜測的精準度, 比如說各個硬體的規格, 使用到的演算法的原理, 通訊 physical layer or protocl layer 的原理, 通訊系統的規格, CPU/DSP instruction set, 等等, 都能夠提昇猜測的效率。對已知事物掌握程度高, 才能夠專心的面對未知的事物。

在此, 筆者試圖將我的經驗整理成幾點原則:

  • 先想清楚 test plan
  • 熟悉 CPU/DSP 架構
  • 熟悉待測物的功能、規格、演算法
  • 確保知道如何重複產生 bug
  • 知道 bug 發生點之後, 嘗試往前一級測試問題
  • 紀錄所有測試數據以及判斷的依據, 以便回頭仔細檢視

身為一個使用組合語言的通訊 DSP 程式設計師, 除了通訊演算法以外, debug 大概就佔掉絕大多數的時間, 真正寫 code 反而是這些工作裡面佔比例最少的。因此, debug 的效率與正確性, 對於程式甚至是晶片的品質, 有著決定性的影響。每個人都有每個人的方法, 筆者在這一篇文章裡, 試圖分享我個人的方法與經驗, 希望能對即將跨入或剛剛跨入這一個領域的工程師有點幫助, 而在這個領域很有經驗的工程師也歡迎大家一起交流心得。


--

Friday, August 31, 2012

再談指數濾波器

上週我們在動平均濾波器一篇文章中提到了「指數平均濾波器」, 這是一個簡單又有效的濾波器, 今天我們再來詳談一下指數平均濾波器的應用。 全文 PDF

Friday, August 24, 2012

淺談動平均濾波器

動平均濾波器 (moving average filter) 可說是世界上使用最廣泛的一種濾波器了; 在股市裡面, 每天都可以看到動平均濾波器的應用, 股價趨勢圖裡面的週線、月線與年線, 都是長度不等的動平均輸出圖形。我們在實作訊號處理的時候, 也很常應用這個簡單又有效率的動平均濾波器。 由於它應用廣泛, 許多程式設計師也許沒有修過數位訊號處理的課程, 不熟悉數位訊號處理分析方式, 但是又需要寫這樣的程式。因此, 在這一篇文章中, 筆者將會儘量以實例來介紹動平均濾波器的概念, 幾種不同的實作方式以及優缺點。

詳全文請點: 全文 PDF

Saturday, April 7, 2012

LaTeX PSTricks 訊號處理範例: z-Transform


上一篇的 moving average filter y(n) = (15/16)*y(n-1) + (1/16)*x(n) 的
z-transform 有一個 pole 在 z=(15/16, 0) 的點上, 要畫這個 z-Transform 在
z-plane 上的表示圖, 可以用下列的 PSTricks 來表示。




\usepackage{pstricks}
\usepackage{pst-sigsys}





圖形如下表示:
http://farm6.staticflickr.com/5238/7053583759_5fbddb20fc.jpg





\begin{center}
\begin{pspicture}[showgrid](-2,-2)(2,2)
\pscircle[linecolor=gray](0,0){1} % unit circle
\pspole(0.9375,0){z1}
\nput{0}{z1}{$(\frac{15}{16},0)$}
\end{pspicture}
\end{center}





--

LaTeX PSTricks 訊號處理範例: Moving Average Filter


今天要介紹的是如何用 PSTricks 來繪製訊號處理的 functional diagram, 假設
我們要描述的訊號處理方程式是: y(n) = (15/16)*y(n-1) + (1/16)*x(n). 這是
一個動平均濾波器, y(n) 是目前的輸出值, x(n) 是目前的輸入值, y(n-1) 則是上一次的輸出值,
那他的 functional diagram 會是如下圖所示:
http://farm6.staticflickr.com/5320/6907485526_81ef0d8ab5.jpg



上述圖形使用了 PSTricks 以及 PSTricks 的 pst-sigsys 套件,所以要在 preamble 的部份如下宣告:




\usepackage{pstricks}
\usepackage{pst-sigsys}





描述這個濾波器的 LaTeX source code 如下:




\begin{center}
% To describe y(n) = (15/16)*y(n-1) + (1/16)*x(n)
\begin{pspicture}(-2,-1)(10,2)
\pssignal(0,1){x}{$x(n)$}
\pscircleop[oplength=0.25,operation=times](2,1){op1}
\pssignal(2,0){coefx}{$\frac{1}{16}$}
\pscircleop[oplength=0.25](4,1){op2}
\pssignal(8,1){y}{$y(n)$}
\dotnode(6,1){ydot}
\psblock(6,0){delay}{$z^{-1}$}
\pscircleop[oplength=0.25,operation=times](4,0){op3}
\pssignal(3,0){coefy}{$\frac{15}{16}$}
\nclist{->}{ncline}{x,op1,op2,y}
\nclist{->}{ncline}{coefx,op1}
\nclist{->}{ncline}{ydot,delay,op3,op2}
\nclist{->}{ncline}{coefy,op3}
\end{pspicture}
\end{center}






--

Thursday, January 26, 2012

超便宜的 TI C6670 EVM, 只要 USD$599!


參考連結: http://www.ti.com/tool/tmdxevm6670
這是 TI 的 TMS320C6670 EVM 的連結,這一顆 DSP 擁有四個 C66x 的核心,每一個核心都可執行 SIMD 指令,可以同時執行 8 組 32-bit 指令。TI 稱呼這個叫做 static VLIW, i.e. Very Long Instruction Word. 另外, C6670 有 Turbo encoder/decoder coprocessor、Viterbi decoder coprocessor、CDMA 用的 RAKE 加速器,還有 FFT coprocessor 等,頗適合拿來實作 WCDMA/CDMA2000/LTE 等各種 cellular communication 的基地台。當然,要拿來其他通訊模式也非常 powerful. 這麼強大的一顆 DSP, EVM 含 emulator 只要 USD$599 喔!



--
My Emacs Files At GitHub