2010年5月6日 星期四

一個A/D 的系統應用問題(續篇-實驗結果)

好了~上回寫那個有關 A/D 系統應用問題,引起了廣大的迴響。

尤其是Eric 教授的許多在學理上的理論註解。

(老師還幫我建了許多數學模型分析~謝謝!

http://tw.myblog.yahoo.com/ericsu-blog/article?mid=447

http://tw.myblog.yahoo.com/ericsu-blog/article?mid=454

http://tw.myblog.yahoo.com/ericsu-blog/article?mid=468

我們搞工程的,就是比不上學術研究的嚴謹...這一點我們還是得跟老師多多請益!)

)

這一回我就先把一些實際的結果,先整理出來供大家參考參考這些數據。

測試條件:其實很簡單....譬如我如上回所舉的例子,有一個電瓶電壓為30 Volts 。

我們在系統應用上,該如何處理這個系統上的A/D 輸入信號?!

如果當我們在系統上忽然讀到 新的A/D 值為 40 Volts 時,(或許,真的在真實世界裡發生了!)

如果用我們傳統十根手指頭的韌體程式時,該如何處理?!...突然相差十度合理嗎?!

我們用一般所謂讀十次再取平均時,這樣的取樣誤差我們要不要當作合理時?!

因為在系統設計上,就顯得比較沒有學理上的數學支持了。

(這一點Eric 老師算是幫我找出他在學理上的意義的!)

換個角度,我們就用我們上回提到的 First Order Filter 來看這個結果,又將是如何?!

在這個實驗裡,還有一個很重要的先決條件:我們要在一般很傳統的8 bit MCU 上來跑這個結果。

因為這樣的First Order Filter,是要用到自然對數 (),不可避免的需要浮點運算的來求結果。

我們先將原始程式的基本數據整理如下:

(圖一)

上圖是我們先整理一般8051 的範例程式,我們將分別利用宣告float 與

一般整數運算方式來分別呈現實驗結果!---光會寫韌體程式還不夠,還需要額外的挑戰。

原始程式的大小是: 4169 Bytes...(我是隨便找我一個已經寫好的程式來測試的!)

(圖二)

是完成組譯後的詳細內容,這個檔案是許多玩8051 Keil C 的工程師們所比較沒有留意的地方,

其實這個檔案非常有用,等您看完我這一篇文章後,您就知道了。

我們可以看到:這個檔案是一般Small 小程式,也用到Keil C 的一些簡單的副程式庫。

(圖三)

我們也可以看到:我們所用到的Keil C 的程式庫佔我們的程式原始長度為 108H (264 Bytes)。

另外:還有一個很重要的副程式:printf()...這個我們常拿來作為PC 連線的Debug 用的,

他是35CH (860 Bytes) ,將近有1 K bytes 的長度,乖乖~

您看他幾乎常佔寫程式的第一、第二名大小!所以下回就別動不動就呼叫此函數。

這張圖裡所示的是依據各個副程式大小排列的!...

-----------------------------------------------------------------------------------
好~實驗一:

我們用浮點運算來作這個實驗,公式很簡單,就是我們上回推的那個公式,您就直接帶進程式裡就好了。

(

一般一階濾波的公式就是:

 Value(n) = Value(n-1)+ KF(RawValue - Value(n-1))

其中: Value(n) 就是我們要求的新值, 

 Value(n-1) 就是我們的上一個值,中間有個時間差(t)。

 RawValue 就是我們一般從A/D 裡讀到的原始值,就是未濾波值。

 KF 就是濾波常數。

Eric 教授的註解:

輸出(s)/輸入(s) = (1/tau)/(s+1/tau) <-- 轉移函數,s 為拉式轉換的變數

關於常數信號 E 輸出響應的數學式

S(t) = E*(1-exp(-t/tau)),tau 代表一階系統的時間常數。

但這是「類比系統的概念」,與數位低通濾波器的係數或頻寬間,似乎沒有明確而直接的關係。

)

其中那個Tau  (取樣時間為 15 ms, T 時間常數為 500 mSec)...

所以我們得到的自然對數為:0.02955447。

(圖一)

可以看到程式很簡單吧,就那麼一行而已:這是對C 語言來說的啦!

反正老闆找您來寫程式,不也是看您會寫C 嗎?!

但是誰知道他的背後是一大堆副程式堆積起來的啦...組譯後的程式碼是:5811Bytes...

整整增加超過 1.5 K !   ---- 嘩...以現在MCU來說:

您光是一個簡單的副程式呼叫就用去整整一個小型的MCU 所有程式容量了。

(圖二)
 
我們再來看詳細內容:結果是:SMALL WITH FLOATING POINT ARITHMETIC 。浮點運算啦...

也看到帶進一大堆奇奇怪怪看不懂的副程式庫!全部都是來自C51FPS.LIB...您也別計較了,

因為您也不知道他裡面是什麼咚咚啊?Keil C 還算是公認比較好的組譯器...別家搞不好更慘。

(圖三)

哈~那個副程式庫已經超越Printf() 副程式庫,躍居第一名了:5DEH (1502 Bytes)...

對啊,寫程式大家誰不會啊~只要您能勇敢的拼命的用這些組譯器的副程式就好了。

想當然爾...程式變成他的執行效能也會備受矚目了,我們再來看執行效能結果:

(圖四)

上圖也是利用Keil C 的模擬環境來測試的,我們設定的頻率是 24.5 MHz ...

跑那個號稱最快的8051 :SliconLabs 的 8051 ~有些指令號稱是 1T 的啦!

副程式執行前的時間是 0.10714571 Sec

(怎麼用這個功能?!自己好好研究一下吧,不要留言問我了!)

(圖五)

副程式執行前的時間是 0.10717661 Sec ...總執行時間:約 30.9 uSec...您會覺得還好啦,

(東西沒有好不好的問題,只有在比較之下才知道自己的問題在哪?!

所以,待會往下看您就看到這個數據的所代表技術能力的指標了!))

如果換成一般 8051 的話:應該是還要乘以四以上...4T 或 12 T 的...也是留給您自己作實驗。

--------

接下來看結果:是利用UART 把結果show 在螢幕上:

(圖六)
 
我們可以看到隨著時間推演...我們量到的值會以自然對數特性往 40 Volts 移動,每一次是 15 mSec...

(圖七)

在 170 次之後,(約 15 msec x170 = 2.55 Sec) 就可以得到很接近的40 Volts 了...

所以,我們量到的數據是合理的,如果我們一直量到 40 Volts 的話...

所以我們一開始也不用急著去把這個值摒棄!

---------

好啦...我說過:這樣子寫韌體程式的話,老闆找您來幹嘛?! ...找大陸人寫就好了。

因為您不會幫老闆克服一些效能與成本問題,執行效能差,就怪MCU 速度差,程式容量小!

一天到晚一直在升級MCU...搞得老闆在產品上一直改版...搞得沒有競爭力...東西越賣毛利越低。

我們再來看我們所謂不要用十根手指頭寫的程式,用所謂的8 位元MCU 的思維模式,

一樣用自然對數的運算原理來求答案...(注意喔,原來用Float運算也是一種近似的推算的!)

實驗二:用 8 位元MCU 的思維模式寫韌體程式。

不知道原理?請再複習:http://chamberplus.myweb.hinet.net/ems_2.htm

(圖八)

我們就寫一個屬於我們自己的Fisrt Order Filter 副程式庫,,,結果是:組譯後程式:4405 Bytes。

還好吧!...其實我還是用一般C 在寫而已,如果我直接用組語寫這個副程式的話,應該還會再小!

(圖九)

看到沒,還是維持原來的SMALL 程式容量模式,根本無須動用 Keil C 的浮點副程式庫。

(圖十)

我們寫的First Order Filter 副程式容量為:7DH (125 bytes)...我說了,如果用組語寫會更小,

我還有包括負的方向耶...因為他有可能是一直讀到 20 Volts ,這個式子就會變成有符號的運算了。

再來看程式執行效能:

(圖十一)

執行副程式前的時間為:0.10714555 Sec 。

(圖十二)

執行副程式後的時間為:0.10714980 Sec 。總執行時間為:4.25 uSec ...

為原來浮點運算的 7.3 倍效能。您會不會覺得這個也沒什麼?!

東西就是要在比較之下才見真章,尤其是這一種單晶片的應用領域:

如果我們換算成外掛震盪器來算的話:可能要從原來 24.5 MHz 要提升到: 178 Mhz...

此時,您有沒有覺得還是沒差了?!...當您的程式要反覆此類運算時,

您就知道這個比例上的差異在哪了。

那當然人家用一般MCU ,您就不得不用有支持 100 MHz 以上的ARM 了...

如果是同樣的Silicon Labs 的MCU...原來一塊美金的 3 xx 系列...您就得用 100 Mhz 的1xx系列

不好意思,他的單價也是七、八倍以上...而且還沒到  178 Mhz 呢!...

而且一高頻硬體電路就耗電,不好搞。

明明一棵簡單MCU可以做到的事,我為什麼要用那麼高檔得MCU 呢?!

那結果呢?

接下來看結果:是利用UART 把結果show 在螢幕上:

(圖十三)

我的程式只算到小數點下兩位就好了...本來就是近似的演算嘛!
 
我們可以看到隨著時間推演...我們量到的值一樣會以自然對數特性往 40 Volts 移動,

每一次是 15 mSec...

(圖十四)

相對於浮點運算的結果...一樣約在 170 次之前就可以求得一樣:39.94 Volts的值了。

這樣的結果應該還算可以接受吧!

重點是:我們用的是一般在簡單不過的MCU,用的也是最簡單的8 位元的計算方法,

只不過,我們會先在事前在計算紙上簡單用數學方法先推演一下,我們就賺到我們的系統價值了。

以一樣 170 次求得一樣的結果:(30.9-4.25)*170 = 4530.5 ~ 4.5mSec ...這可以做多少事啊!

-------------------------------------------------------------------------------------------------------------------------------------------------

好了...或許您會常聽到版主老是在講所謂的系統應用的競爭力與價值,

您也可能覺得是版主只是耍耍嘴皮子,或許您也會覺得自己該提昇自己的競爭力。

但是呢?也老是濛濛懂懂的不知該如何提升競爭力。..

寫韌體程式大家都會,更不用說用高階的C 語言寫程式,

當您看到我這一篇文章實驗之後...您覺得一樣用十根手指頭寫韌體程式,您的成就感來自於哪?!

這是一個非常簡單又常見的系統應用題目...當別人或代理商拿著跑  400 Mhz 的ARM 來推給您時,

您要想一想:因為這些代理商的FAE 也不會很懂寫程式的技巧,只是跟您說:您看:

178 MHz 是您原來 24.5 Mhz 的MCU 效能多了 7~8 倍耶。多好用啊。

是嗎?!是很好用...我可以拿來寫更多系統應用的附加價值,但對您來說也只是解決上述那個

簡單的浮點運算與一個也可以用數學方法克服的問題。

還是老話一句:人家用一般邏輯電路把太空船打上太空時,那時還沒有32 bits 100 Mhz 的MCU 。

而那時的確是有所謂的工程數學,數值分析...教我們用數學方法克服工程上的盲點。

這就是一再簡單又明顯的答案了。...您說呢?!


----------------

1. 一個A/D 的系統應用問題

3.一個A/D 的系統應用問題(續篇-精進版)

4.一個A/D 的系統應用問題(續篇-範例版)




 

3 則留言:

  1. 很棒的分享!加油!
    記得我教學生數學時,他們常會問我學這個做什麼?
    等到看到像您這樣的舉例時,又會嫌太煩。
    但換個角度想,或許這就是願意花時間又耐得住煩的人,他們競爭力的來由吧!

    回覆刪除
    回覆
    1. 年輕人不會想...當他們多一點工作經驗之後,發現又有新一代的工程師之後,
      他們才會再想到本身競爭力的問題,屆時才發現自己當初應該要好好的把這些年輕人當作很煩的事,才是自己能拉開競爭力的機會啊。
      ---這是自己本身的切身之痛,老師您下回上課時,您可以拿小弟我的慘痛經驗,好好的教導下一代吧!我也很樂意的分享。

      刪除
  2. 賈老師的真老公2012年3月28日 下午9:35

    喔...我指的是:以15 mSec 來看的話...500 mSec 也才算34 次而已...
    真的要趨近40 V 時,還是得要 170 次 = 約2.5 秒啊...
    太慢?!您就改時間常數...當然公式裡的時間常數就要配合啊。
     

    回覆刪除