2011年3月5日 星期六

MCU 單晶片系統應用的數值方法

真的,我在部落格的文章中,除了賈老師所發表的短文文章外,

我是比較喜歡寫一些有技術性的文章,但事實上要寫技術性的文章,真的比較難,

因為除了真的要有一點深度或是要有真的真材實料才有辦法擠得出東西。

最重要的是,還要整理歸納與有系統的描述...當然最重要的是:

要有真實的使用經驗與範例,而實際上,大家出來工作這麼久了,

寫程式也都累積不少的時數了,那大家真的可以想想:我們到底在工作上可以寫出多少

像樣而真的有實際實戰的程式呢?!尤其是一些牽涉到核心演算法或是架構性的程式呢?

以前我說過了:我當初寫MP3 的系統韌體程式時,大概在構築整個系統架構程式外,

在四、五年的系統韌體程式撰寫工作時間內,大概有 85% (可能不只)以上的時間都是在

寫一些很直覺UI 人機介面或是只是很簡單的直覺式的程式,

像是USB 只是照表抄課式的程式撰寫。或是:人家要加一個LED 燈號顯示啊...

或是要一個支援什麼固定怠機時間關機功能等等...

尤其現在的韌體程式越來越大,動不動還要Android 作業平台...真正可以玩到一個真正的

核心價值的演算法或是架構性的程式技巧...應該都不容易,更何況:在程式撰寫的過程中,

您可以自己自行的加入一些比較有特殊技巧的東西?

不要說:人家前輩長官會透過工作教您的?或是自行進修,嘗試開發的程式技巧?

在學校中,老師也沒多少真正的職場工作實戰經驗,

學校也沒多少實際的產品開發流程與環境,所以也沒辦法教您什麼外面工作有用的程式技巧?

而外面公司絕大部分的工作,都是大家上工第一天,老闆或長官們就交付一個目標與功能,

就放牛吃草,自求多福...更何況還壓工作時程,讓您喘不氣來的天天巴不得

24 小時不睡覺的寫程式,Debug...哪來那麼多閒工夫研究這一種東西?

這種壓力當然除了時間壓迫性外,那一種無形的心理壓力更是有苦說不出,

工程師當然會過勞死。放心好了,新聞中的那些戰死職場的工程師不會是最後一位的啦。...

-----
之前我有提到那個有名的 3.14 的近似演算法,大家都給我很大的迴響,後來我又發表了:

A/D 轉換的一階濾波器計算方式,其實這些東西都不是我發明的,

也都是學校課本都有教過的,只是大家都在強大的工作壓力(加班生理與時程心理壓力)下,

都無法真實的展現應用而已。

後來,有一些讀者都會私底下跟我討論這些東西,其實,許多在程式中所採用的演算方式,

沒有固定一種最好的方式,許多數值分析方法,講求的是:快速與誤差小的方法,

當然就有許多各家理論,也有其適用的條件與方式,這些都是在學校課本有教的。

其實也輪不到我來評斷好壞,只是在許多自己本身的許多工作經驗中可以實際去嘗試與驗證,

然後分享給各位而已。

好了,在那個 3.14 的故事裡,我說了一個很簡單的程式語法:利用左移或右移方式來快速

求得近似值,所謂近似值,就是一種有誤差的計算方法...

我們在數值分析方法上,很強調一種結果:就是所謂的 Rounding Error ...

是一種近似產生誤差,我們可以視為一種循環累積誤差。

因為畢竟許多程式計算中會產生小數點,我們也不可能一直採用浮點運算,當然每一次計算

都會產生所謂的 Truncation Error (截去誤差)...

所以我們在採用近似計算方法過程中,就必須小心這一點。

所以,我們在數值分析方法與程式中,

會利用所謂的迭代(iteractive,有拼對嗎?)方式一直來逼近真實的答案值...所以,

在數值逼近計算中,我們會緊盯著一個收斂誤差值達到一個很小時,或是我們可以接受值時,

這個答案就是我們所要的答案了...不好意思,這些都是學校教的...不是我說的,

我也不是出來工作時才學到的,我說過:工作職場上,尤其台灣的高科技公司才不會教您這個!

我記得是我在大學時,一直想玩電腦(那時電腦不普遍),也想玩一些漂亮的電腦繪圖,

每一次可以看到電腦可以繪出漂亮圖形時,就很興奮,所以就自告奮勇的去找教授說:

有沒有什麼工作可以常常接觸電腦,還可以繪圖的工作?

結果,我的老師就教我去協助研究生跑數值分析程式,

然後再把結果,繪製在圖紙上....畢了業,也不覺得這些東西有什麼用?

更何況台灣的教育往往是跟工業界脫勾的。這也不能怪學校,

因為許多工業界是不懂得需要這樣的學術界東西,工程師們幾年就會把學校那一套

全還老師了。我們的高科技界總是喜歡外國人給他們什麼生意作時,

他們就找廉價工程師們幫他們代工!

至於您學校教的那一套?那是您個人造化...工作用不用得到?就不是那麼重要了。

----

好了,我現在就先看一個例子,再來舉一個例子,首先我們可以從上圖的程式中,

看到人家國外的引擎控制程式中,某一段計算Scaled RPM 的計算程式,

因為所謂 Scaled 代表的就是量化轉換,這個量化轉換,

當然就會牽涉所謂的累積誤差的近似計算...所謂 /25 或是 /12.5 就是會產生小數點。

在程式中我們當然不可能一路都宣告浮點變數一路往下計算吧...都算死了也不一定會對...

誤差總是有的啦,也會累積的...

您說:您開車只會開幾分鐘而已嗎?!而每一秒鐘行車電腦要算多少次?

所累積的誤差會跑到哪?!您在程式計算中您到底有沒有分析過這樣的問題

...您有沒有連基本的小學算數中的四捨五入觀念都沒有?

在程式中所謂的四捨五入就是那一段  ADD  D   #80H....您想過沒?

我在  3.14 的計算方法中,那一個左右移動的方法,當您有機會使用這一種計算技巧時,

一直除二過程中...其實就有最大0.5 的誤差存在與產生...

結果,您就一路一直去除小數點時,您有沒有想過這個  Rounding Error ?...

一路計算到最後,才發現答案好像就差麼一點?怎麼找程式BUG...就是找不到?

您說:您自己寫的韌體程式,您長官、老闆誰會體諒您?

...個人造孽,個人擔啊!...唉~......

好了,您覺得我這個例子跟您無關,我寫的程式好像沒用到?...那我舉一個更簡單的例子,

就是跟我上回提的那一個 A/D 一階濾波器的應用有關,在工程上採用A/D 的機會很多吧!

您看大家的單晶片微控器MCU 都一大堆都含有 A/D ,連現在 32 bits ARM 都有...

更何況都強調10 bits 甚至號稱 12 bits 呢?! ...那又怎樣?

您應用的數值方法與觀念不對...那麼高的Bits 數的A/D...

還不是一樣被您給Trucation 掉嗎?!結果一路的Rounding Error 產生!

人家客人玩我寫的一個在簡單不過的 LED 調光器,人家用的就是一種簡單的A/D 方法,

結果,您只要搭配一個簡單的 A/D 一階濾波器數值方法...那個感覺就是不一樣。

大家為何公認 iPhone 的人機介面那麼Smooth ?

我猜想其實都是在這些小細節上面花功夫的...

您說:當您在計算一些機械或自然界的現象時,您一路加減乘除...到了 100 %時,

才發現誤差是差了 1~ 2%...然後,就自作主張的最後補上去...

結果,最後那一下,就是會給人感覺跳一下。

被長官、客人釘時,才又自作聰明到處東補補、西補補的...補到最後,

不要說別人看不懂您的程式,連您自己都很心虛的...過了一陣子都看不懂了。

更不敢寫程式註解!您說:是不是?

-----
以上舉的例子其實在我們一般寫韌體程式很容易遇到的,

您說:韌體程式用不到數學計算方法的,那一些產品大概也不需要您念到大學或研究所

來寫啊...您說:現在寫一個跑馬燈的程式,完全用不到數學方法的...

這東西要賣給誰?您會寫程式很厲害嗎?!現在滿街都是啊。

也難怪這些高科技公司的老闆就一副老神在在,您一天不幹 16 小時,

還有一堆會寫這種程式的工程師可以用的啦...反正,現在講這些也沒用,

我們老是抱怨這個也沒用,也只能怪自己沒有好好的建立自己的核心價值...

只也能被替代的用。...

最後,也真的不知道要說什麼?就又附上另一段相同在國外引擎控制程式中的一段程式技巧,

就看大家看懂不懂他的意思吧:

看不懂的,可以留回應,大家再來討論吧!

謝謝大家的參與討論。。



 

沒有留言:

張貼留言