總網頁瀏覽量

2020年6月27日 星期六

在台灣教育體制下之小時候對數學考試沒興趣,其數學能力就一定會一直爛嗎? 書讀越高越高尚?


看完「做工的人」六集電視劇,回想自己的一些歷程,有些感觸。

又是長篇大論,講講自己的古(雖然才剛滿29歲),算是給自己作個歷程回顧,看不爽的人就不要看。

自己老家住的是40幾年擁擠老舊的小公寓,再基層不過的勞工家庭。

自己在就讀國小高年級時期的數學科的表現被班導師徹底放棄,也因為自己喜歡熱血有趣的事物(三國志歷史、出師表、神奇寶貝扁扁、紙牌、橡膠玩偶、四驅車、電子雞、怪獸對打機、鋼彈、洛伊德、溜溜球、戰鬥陀螺、RPG、線上遊戲、遊戲王卡快樂快樂漫畫雜誌、各種漫畫和卡通、GB、GBA、WSC、哈利波特系列小說、魔戒小說、小王子)幾乎沒一樣不去玩(就算自己受到的家教方向是極度反對我去玩這些東西而有許多東西沒得買,但總是還是會能從同學那邊借到或A到可以玩的東西),而相對討厭死板的學校教學及考試內容,和教育方式嚴格的父親產生多次衝突,常被嗆說長大之後如果去做工很辛苦就不要抱怨父母沒栽培,所以從沒想過自己會走所謂讀書人的路。甚至在小時候曾想過要搞幫派,也幹過架,嗆聲叫囂之類的事情都幹過,所以更不可能想過自己會走理工領域的技術研發。小時候唯一會被老師特別誇獎優秀的科目似乎是作文和國文(國語),關於作文科目,通常老師還在講解寫作題目時我就已經將內容想得差不多或甚至寫完了。

在國三時期有所謂的「能力」分班(當然個人不不認同這種對於能力的狹隘定義),一開始被按照國一和國二的成績而被分在B組,國二暑假時還跑去加入籃球隊每天跟著練球,當時看著A組同學都在上整天的輔導課,好像還會覺得慶幸。後來也不知道是怎樣,在國三剛開學時的基測模擬考成績分數好像比一些A組的同學還高,所以就被調到所謂的「A組」,但也只是應該算是A組裡面的後段班、璞攏共而已,當時就覺得自己的風格和許多當時所謂成績較前段、多數就讀普通高中的多數同學們有點格格不入,也不太認同當時多數學校老師對於所謂「優秀」的標準,深深覺得教育制度根本就有問題,但當時年紀太輕,其實也講不出個所以然。

國中畢業後考上公立的高職,從此開始就讀技職體系,打從一入學開始就深刻感受到高職專業科目(至少是我接觸的電子工程領域的職科)的理論基礎內容內容對高中職階段的學生而言還真是深奧艱澀(到現在依然這樣覺得), 顯然國中多數老師就如同台灣社會多數的歧視與成見一樣,根本不了解高職體系。如果負責授課的高職老師本身不是很能理解這個階段學生的狀況和困難的話,其實很難把專業科目給教得「好」,因為很難讓這個年紀的學生去理解和愛上這些專業學科內容,坦白說這是造成許多同學會放棄走專業領域的原因之一,因為體驗不到專業技術開發的樂趣和成就感。自己在高職時期除了高一的數學和物理被當整套之外,也曾因為被老師誤會自己在上實習課的時候在打混,而被叫去走廊罰站過,其實當時也懶得去解釋什麼,因為就是不屑主流教育中的這一切。

幸好自己對於學校某些老師的教學方式以及主流教育體制內的作法一直有所質疑,另外也是因為在了解了台灣社會對於技職體系的嚴重成見和歧視後,就很想證明這些技職教育體系的學科內容其實相當專業,真的非常想要證明這些客觀事實,所以一直沒有放棄。高三時期去聽補習班高三班的基本電學和電子學課程之後,因為教學方式的不同,開始覺得這些專業科目內容真是有趣,就如同上述小時候的各項熱血玩物一樣有趣,自此逐漸熱愛專業科目和這些被賦予工程物理意義的數學(而不是台灣的大學教育之前的極度死板的數學考試給我的印象,甚至應該說這些只是算數考試),這時才知道台灣的大學以前的教育對於許多人來說根本是充滿著許多相當混帳的問題,這與許多學生在大學以前的學業表現一條龍、大學以後的表象一條蟲的普遍現象可能也有關。而自己顯然是適合較自由、較需要找到動力就會自動自律的大學學習模式的,國中小高中那種不斷硬逼且填鴨的方式完全不適合自己以及許多人。

自就讀大學開始,從大一的微積分以及大一下學期普通物理的電學和磁學開始,對這些數理科目大感興趣,會為了思考專業科目內容中的物理意義,而額外花大量時間、接近強迫症式鑽牛角尖的想破頭的去思考應付學科考試以外的數學式子背後所要呈現的觀念。在學科考試的方面(班上其實也有著學測數學科前標以上的幾位來自普通高中的同學),我的微積分的學期總成績接近滿分、海洋工程學院所舉辦的全學院同學參加的微積分競試是全學院排名第二高分(和班上來自普通高中的一位同學並列第二)、全學院的物理競試全學院特優(似乎是前五名、但詳細排名忘了),在後來大二的工程數學也考了幾次滿分(當然考試考高這種事並無法完全凸顯前述的興趣和這些對於物理意義的理解和成就感,有些東西是傳統的考試很難考得出來的),事實上,雖然這是一間國立科大,但是課程內容大部分都是相當數理性質的科目(如微積分、物理(I)(II)、工程數學(I)(II)、電路學(I)(II)、電子學(I)(II)、訊號與系統、機率與統計、通訊原理、數位通訊、電磁學(I)(II)、射頻電路設計、數位訊號處理等),所以大學階段的數學還真的算了不少,這是讓我大感興趣和成就感的(自己也感到很奇特的是在國小被老師放棄數學的人居然變成這樣)。另外也因為感受到光有學科其實在專業實務上是完全不足的,所以在大一暑假就開始加入實驗室做專題(雖然因為某些因素而換了幾次實驗室,但基本上大學階段因為寒暑假都在實驗室度過,所以大學階段幾乎沒放過寒暑假),學科方面讀到大學全系第一名畢業 (雖然成績這真的不一定能代表什麼。另外順帶一提,雖然學科成績是以傳統數理考試為主,但其實通常這個系的全系前幾名仍然大多都是來自高職的學生,努力還是有差的),還帶同學一起拿了不少全國專業競賽獎項。後來讀到所謂的名校碩士,畢業後去幹國內號稱底薪最高的公司的科技業工作。因為有著上述的求學經歷,所以花了自己許多時間去主動幫了不少人,用意只是希望他們不要被這個社會風氣文化之下的矛盾所誤導或阻礙。同時也因為這樣,所以不斷有機會讓我深入接觸學術界,所以也逐漸對許多所謂有社會地位的人開始有著深入的認識和了解。

一路走來至今,對於「人」的感想(綜合了觀察及理解台灣社會上相當普遍的勞工階級被壓榨的文化)

或許講到這裡有點跳tone ,但還是只想說

負心多是讀書人

許多人,書讀越高,掌握越多、得到越多,就只是越貪、越怕死、越沒膽、越自私、越務虛

社會的亂象是哪來的呢?主流教育體系內為何充滿著諸多矛盾和問題呢? 而如果有人覺得這個社會很幸福美好,是因為社會真的很美好,還是只是因為自己運氣好、還沒雖到,甚至也許自己就是既得利益的一群?

懂得去用心理解他人(包含理解在台灣的課業文化下成績表現不好的學生)和他人的職業(如基層的工人和其他任何從事辛苦職業的人),以及懂得回頭知恩圖報、回饋他人和社會的人,究竟有多少呢?

2020年6月15日 星期一

應用科學/工程領域的論文發表



就應用科學領域中,除了特殊的發展模式之外(如開源社群),有誰會真正將有商業價值的核心技術內容拿去發表成論文、公開自己公司團隊的know-how,把技術機密告訴人家,吃飽沒事幹地來增加自己的競爭對手?把記載自己公司核心know-how文章版權送給出版商,然後可能還要付錢給出版商才能出版/閱讀自己的論文?

在應用科學領域,特別是多數的系統應用設計領域,以個人長期接觸的嵌入式系統應用和IoT領域來說,根本就是不適合用論文來作為主要KPI,因為性質極度不合適。這個領域的研究是要有許多專業實務經驗作為基礎而去發展的,其中許多技術細節相當關鍵,但根本無法透過論文發表的方式去詳細地展示出來,所以造成了許多期刊論文對於這些至關重要的技術細節,大多是屬於輕描淡寫、草草帶過的狀況,甚至有許多內容根本完全就是不專業。

再講個更直白的,大多數負責審查的學者教授很可能本身也沒有動手開發這些技術的實務經驗和能力,如果是如此,那這些「審查者」等同根本沒有能力去判斷內容的真偽和價值,所以搞到最後,所謂的論文發表就只是在比論文內容的包裝、比這些論文「看起來」是否漂亮好看、是否有放些外表看似高深美麗,但其實嚴重缺乏考慮實際技術細節內容、很表面的數學式(其實未必實際)。而論文中的核心內容實際上到底做得如何,除了作者本身以外根本沒人知道。

基礎科學領域或某些適合以純理論展現研究成果的領域的狀況可能是相反,因為距離商業市場端還有很大距離,所以適合透過發表研究成果來證明成就,且其內容如果涵蓋諸多數理推導,則較容易將其核心研究成果攤在論文之中以便讓研究者去檢視。

論文發表模式應該還是源自於古代歐洲的基礎科學研究。但直到了現代,我們整個國家就是搞不清楚狀況,不分領域,整個學界制度都是按照對論文的全盤接受(迷信)而去瞎比論文數量/績效。那應用科學領域的教育和產業競爭力競爭力就會出現很嚴重的問題,鳥事將會非常的多。說穿了只是將這種KPI拿來當成資源分配的遊戲規則罷了。當然也不是所有的應用科學/工程領域的論文都是毫無價值,但只能說上述這種狀況實在很多就是了,而且這些KPI決定了國家每年龐大經費的分配。

我們真的民主先進嗎?

2020年5月18日 星期一

【社會基層勞工議題】【送貨員的辛勞】


今天去便利商店,看到送貨員開著一台大貨車停在便利商店外,並且獨自一個人下來卸貨(光在台南擁擠的街道馬路上停好那麼大台的貨車,還要注意附近有無行人、腳踏車或機車就不是一件容易的事,我想在台灣多數的縣市角落大多都是一樣的狀況)。接下來將貨車後面的升降板升上去,透過熟練的手法將一大堆重量相當重的飲料箱疊到小推車上,並推入擁擠且空間狹小的便利商店,這樣急急忙忙的來來回回不曉得跑了多少趟,因為今天有下雨所以升降板上面看起來是有些濕滑的,在旁邊看了實在感到有點擔心,甚至有點想過去幫忙搬,但後來覺得自己不熟練可能反而只會耽誤到人家的工作於是作罷。
而便利商店裡面不但擁擠且人來人往,送貨員一個人從開大車、停大車、搬卸非常多貨物到升降梯上、將貨(放飲料的一堆箱子)放到推車上,再不斷的推入便利商店的倉庫擺放(還要閃過或者等待許多進去便利商店的客人),後續還要將便利商店的空箱子再推上貨車去。如果是一般人平常沒在搬送這些大量貨物的狀況下突然去做這些事,恐怕手早就痠到快廢了,更不可能繼續手握方向盤開著大車再急忙趕到下一間便利商店繼續送貨。
這些景象其實過去看了都一直覺得頗無奈,但今天在一旁從頭看到尾更是有很深的感觸,這些真的讓我覺得台灣許多大企業、大組織高層老闆對於基層勞工的壓榨和冷漠。光是要駕駛這類的大型貨車就是一件很難而且是絕對是攸關人命的事情,為了節省人事成本,將上述的事情全部都交給一個人做,讓要做這麼多事情的送貨員持續駕駛大貨車是安全的嗎? 送貨員在一個人獨自到處搬送這麼多貨物之後的體力、精神狀態有人顧慮嗎? 如果精神受到影響,繼續駕駛這大車的安全問題有人想過嗎? 這國家先進嗎? 大家希望這國家是先進的嗎? 如果希望,那這是一個先進國家該有的樣子嗎? 包含我自己每次搭乘公車、遊覽車,看到司機自己獨身一人居然要扛(承受)全車所有乘客的生命安危,也都會有這些感觸。
平常在便利商店隨手買的食物和飲料看似隨手可得,但其背後其實都有著許多基層勞工的辛勞付出(甚至可以說是冒著蠻多危險在做這些工作)。
所以請大家未來若在便利商店看到送貨員正在送貨時,請多禮讓出一條通道並體諒他們辛勞吧,至少讓他們順利推送貨物,他們真的很辛苦(包含一般網購物流業或搬家貨運等等的送貨員都是很辛苦)。當然也還有著太多其他職業的基層辛苦勞工有著這些類似的問題。
台灣有著太多辛苦默默努力的基層血汗勞工,完全沒有得到該有的基本保障和待遇,我們距離真正的先進恐怕其實還很遙遠。

2020年3月18日 星期三

【C# 應用程式】透過WMI API偵測COM Port裝置插拔狀態及取得裝置名稱的重點程式筆記(參考國外網路上網友分享的程式碼)


以下C# WMI範例程式code為參考自下方網路論壇資料並進行相關實作實驗,並加上自己的備忘註解: 
(1) https://hant-kb.kutu66.com/windows/post_650386 
(2) https://stackoverflow.com/questions/17563969/wmi-usb-monitor-multiple-events-fired?rq=1
(3) https://social.msdn.microsoft.com/Forums/zh-TW/c236cac4-a954-4a70-882d-bc20e2cc6e81/getting-more-information-about-a-serial-port-in-c?forum=winformsdesigner
(4) https://stackoverflow.com/questions/2837985/getting-serial-port-information/59508646#59508646
(5) https://cyfangnotepad.blogspot.com/2015/01/cnet-usb.html


個人本身不是什麼純軟體物件導向語言高手,只是過去有一些短暫的相關開發經驗,分享出來讓大家作個參考

程式執行(實驗)環境為Visual Studio IDE, 平台為.NET Framework
.

- 第一部分:主要是記錄如何用C#語言撰寫偵測USB裝置的insert/remove狀態事件

using System.Management;
//...
ManagementEventWatcher watcher = new ManagementEventWatcher();
WqlEventQuery query = new WqlEventQuery("SELECT * FROM Win32_DeviceChangeEvent WHERE EventType = 1");
//EventType = 1是對insert和remove都有反應; 
//EventType = 2是只有對insert有反應; 
//EventType = 3是只有對remove有反應
//以上可以視情況宣告為全域instances 方便一些應用

watcher.EventArrived += new EventArrivedEventHandler(watcher_EventArrived);
watcher.Query = query;
watcher.Start(); 
//如果要停掉watcher就呼叫watcher.Stop(); 不用時可以dispose()掉
//注意上述這些初始動作要在serial port init之前

static void watcher_EventArrived(object sender, EventArrivedEventArgs e)

{ 
  ... //看你想在EventHandler函式裡面做什麼應用
}



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


- 第二部分:主要是記錄如何用C#語言撰寫取得裝置管理員內的COM PORT裝置名稱,這邊以Prolific的PL2303 UART轉USB晶片的裝置為例合基本邏輯撰寫(這是許多人玩Raspberry pi或Arduino常會用到的UART/USB轉換的線材內的常見晶片,另外幾款這類用途的常見晶片就是CP210x、CH340、FT232R,不清楚這方面的朋友可參考小弟過去寫的這兩篇文章: USB_to_Serial轉換器或轉換線或轉換板  和  安裝PL2303 USB to Serial轉換線之驅動程式)

using System.Management;

//...

public string GetFullComputerDevices()

  ManagementClass processClass = new ManagementClass("Win32_PnPEntity");
  ManagementObjectCollection Ports = processClass.GetInstances();
  string ComPort_number = "No COM Port device recognized";

  foreach(ManagementObject property in Ports)
  {
       if (property.GetPropertyValue("Name").ToString().Contains("Prolific USB-to-Serial Comm Port");  //以顯示名稱為Prolific USB-to-Serial Comm Port的UART轉USB晶片PL2303為基底的裝置為例
   {
     ComPort_number = property.GetPropertyValue("Name").ToString(); 
     ComPort_number = ComPort_number.Substring(ComPort_number.IndexOf("COM")).TrimEnd(')'); //取得COMx的字串並將其放置到ComPort_number這個string變數
     
//微軟的String.Substring方法教學
//微軟的String.TrimEnd方法教學:
 
   }
  }    
  
  return ComPort_number; //回傳字串,如果都沒有就會回傳預設的"No COM Port device recognized"字串
}
   
注意! 除了在程式裡面using System.Management之外,還有一個步驟要做,否則會有錯誤: 專案 -> 加入參考參考管理員 -> 組件 -> 右上角搜尋: management -> 勾選System.Management -> 按下確定
(如果Visual Studio是英文版: project ->  Add Reference -> Reference Manager -> Assemblies -> search: System.Management -> choose(tick): System.Management -> press Enter)


最後,簡單利用上述重點,並搭配C#的一些基礎

整合實作一個簡單的PL2303的USB轉UART線裝置的插拔偵測與取得裝置名稱的應用程式

Demo影片如下:
(註解: GUI視窗程式下方淺藍色圖案只是一個測試效果)
程式背景圖片就用張西子灣照吧!



【若需要家教模式之技術輔導 可來信洽談合作方式: iws6645@gmail.com】
 

2020年3月11日 星期三

【UART應用】國外STM32臉書facebok社團討論小PO文之記錄整理:用UART傳送浮點數的方式



無意間在臉書上看到外國人的臉書社團STM32 ARM Cortex-M上面的這則老外們在討論的討論PO文(可能要加入該臉書社團才能看到)有點意思,是針對用UART傳送浮點數的方式的這個簡單但實用的議題,幾分鐘就能看完下面的留言討論,但是因為是簡單實用的討論所以就想說在此記錄一下。對於此層面的軟體程式邏輯來說,UART只是以byte為單位(Data framing中主要的資料部分)將資料送出的單元(當然如果要針對UART硬體更精確地來說,其實是將資料一個一個位元的進行串列傳送),所以這裡跟UART的關係並不算很直接,其實這議題算是有點偏向C語言的基礎

如果有嵌入式系統的C語言韌體開發背景的讀者,可以簡單看出該PO文的下面留言者(很多都是外國工程師)提出的留言建議的方式多數屬於下列兩種(也都是很直覺的方式),這邊將其整理並作一些解說:


1. 直接傳送浮點數值:使用union,讓浮點數值與uint8型態的資料作對應(casting/mapping), 然後一個一個byte透過UART送出

/* 將浮點數值與uint8型態的資料透過union在其內宣告,使它們共用一塊記憶體空間 */
typedef union{
float f_val;
uint8_t  uint_val[4];
} float_u; 

float_u value;
value.f_val =6.66; //6.66只是隨便舉個小數值的例子

/* Send Data via UART*/
UART_Transmit(value.uint_val);  /*此處的UART_Transmit函式也是類似pseudo code的簡單示意的範例,實際上就看你的嵌入式系統軟韌體開發環境的UART API函式是怎樣的狀況(實際形式),而此處的目的簡單來說就是用UART將浮點數值一個byte一個byte的方式送出去*/



2. 將浮點數值轉成字串並傳送這個字串:透過sprintf函式將浮點數值轉為字串,例如:
char buffer[4];
sprintf(buffer, "%.2f", 3.14);
然後再透過UART將資料傳送出去。接收端如果需要此值去做後續的運算,當然就需要再把字串轉變回數值之後再作運算
(如果相應的嵌入式系統軟韌體開發環境的printf若已直接串通UART, 就可直接用printf函式就好。這邊的討論應該是針對STM32的HAL_UART_Transmit函式來說,用sprintf將浮點數值轉換為字串並放置到某一段連續的buffer(或陣列),然後再透過此位址搭配HAL_UART_Transmit函式將該字串一個一個byte傳送出去)

【若需要家教模式之嵌入式系統技術輔導 可來信洽談合作方式: iws6645@gmail.com,亦可先點擊參考這篇介紹文章

2020年2月26日 星期三

【ADC應用】ADC之Step size(LSB size) voltage的計算: Vref該除以2^n還是該除以2^n – 1之簡略探討

歡迎透過合法的方式分享此文內容,若要轉載/轉貼,請明確貼出此原始連結並標示作者基本資訊請勿抄襲及非法轉貼(例如擷取內文但並未註明出處)

  • 前言
小弟不才,本身並不是ADCIC/IP設計專家。長期以來在嵌入式系統韌體與硬體整合應用設計系統的開發方面使用到ADC做各種感測器類比訊號擷取及轉換的應用,常在許多資料看到關於step size/LSB value/LSB size/LSB的實際公式算法有些微不同,故提出此討論。雖然這表面上看起來是個不起眼的小細節,但事實上,許多同行的資深工程師或資深教授都未必相當清楚 (除非過去是有ADC的相關開發經驗)

本文會以偏向軟韌體背景人員而非ADC IC設計工程人員的角度來作探討


: 在許多ADC IC或內建ADCsensor chipdatasheet所稱的step size/LSB value/LSB size/LSB通常指的都是step size voltage(階層電壓值)的意思,也就是輸入的類比電壓如果超過達到一倍的step size階層電壓值,ADC即輸出數位值1,以此類推,不熟的朋友請自行了解ADC基本應用基礎觀念,例如: https://en.wikipedia.org/wiki/Analog-to-digital_converter,參考內文的: “The change in voltage required to guarantee a change in the output code level is called the least significant bit (LSB) voltage”

平常我們單講LSB(Least Significant Bit)本身通常是數位二進制值的最低有效位的意思,而用在ADCdatasheet簡單來說單位數位值所對應的類比電壓值。例如一個8位元的ADC而LSB voltage(或者稱step size voltage)1V,要讓數位值從0b00000000變成0b00000001就是輸入的待轉換類比電壓要達1V以上。另外,step size voltage/LSB voltage常在datasheet常被簡稱為step sizeLSB(常見的敘述形式多種,可能會是這些: step size/LSB value/LSB size/LSB)


------

  • 本文重點

而關於本文要探討的主要部分為: 常見的step size之公式通常就是ADC之參考電壓Vref去除以量化位階,而這公式的常見形式有兩種,如下(暫時撇除量化誤差等誤差條件情況,單純探討原理層面):

Step size = Vref /(2^n)   第一種公式

Step size = Vref /(2^n - 1)   第二種公式

VrefADC的參考電壓
nADC的解析度位元數(文章以下內容皆同此)
而公式的分母項目為量化階層

裡所當然地,數位值的表示範圍是從0到2^n-1,這沒有疑慮。且當位元數多的時候,實際上使用第一種或第二種,都沒有太大的落差(除了這方面需要極度嚴謹的應用系統開發之外)。但這邊要探討的是step size較嚴謹的算法

成大資工wiki與一些市面上的MCU書籍即認為第二種公式才是正確,其內容主張: ADCstep size(LSB value)Vref/(2^n - 1)

圖片來源: 成大資工wiki網頁擷取畫面(http://wiki.csie.ncku.edu.tw/embedded/ADC)



但是,我們也可以在許多書籍或IC晶片廠的datasheetdatasheet裡面的看到ADCstep size(LSB value)的公式,是本文前面所歸類的第一種公式,也就是Vref/(2^n) ,如下:



可以從Analog devicesdatasheet看到數位滿格度的0b11111111是對應到(Vref減去1LSB/Step size電壓值)的類比電壓,而不是對應到Vref





Step size(LSB size)Vref/(2^10)也就是Vref/1024,

右邊是的Digital Output Code指的是ADC轉換並輸出的數位值 ,而1024/Vref等於Step size(LSB size)電壓值的倒數(1/LSB Size)。所以上面公式為

ADC轉換出來的數位值 =  VIN / Step size

1024可以看出仍然屬於第一種公式(沒有做本文章討論的所謂1”的動作)






其中,1024/Vref等於Step size(LSB size)電壓值的倒數(1/LSB Size),也就是每一階的電壓是多少的倒數

公式中的ADC是指ADC轉換並輸出的數位值所以上面公式為(意思與上述MCP3004/3008的部分一樣): 

ADC轉換出來的數位值 =  VIN / Step size

那從1024可以看出仍然屬於第一種公式(2^10 = 1024)








Arduino UNO板子的MCU晶片是上面提及過的Atmega328P,可看出這裡的寫法一樣是屬於第一種公式,也就是5/1024 (題外話: 它後面寫的4.9 mV僅是一個大約的數值,是不論用第一種或第二種公式去套用,答案都是4.88mV)






基本上雖然這章節在講ADCErrors,但框起來的這邊主要仍是在描述STM32 MCUADCLSB(即上述各datasheetStep sizeLSB size)的定義,基本上從4096(指的是STM32 12bits ADC2^12 = 4096)看起來仍然屬於第一種公式

但是在datasheet的某些部分(3.2 Errors due to the ADC environment)就用已經減14095在做一些該章節討論的相關計算,目前對這部分尚未清楚(或許這邊探討的狀況不同,尚未詳細研究)






這裡的LSB(即上述各datasheetStep sizeLSB size)
的定義,基本上從4096(STM32 ADC基本上是12bits ADC2^12 = 4096),仍然沒有做本文章討論的所謂"1"的動作,所以仍是屬於第一種公式



-        80X86 IBM PC and Compatible Computers: Assembly Language, Design, and Interfacing Volumes I & II (4th Edition), Author: Muhammad Ali Mazidi and Janice Gillispie-Mazidi
這是小弟大學時代的微算機原理科目課本,課本裡的4.4節以8位元的ADC0848 chip為講解範例,Step size一樣是Vref/256,仍然屬於第一種公式






上圖畫紅線的部分,說明1LSB(1個LSB voltage)是怎麼來的,12.5V tied to the Vref/2代表Vref為5V,而19.53mV是套用第一種公式而來(5/256,而不是5/255)


上圖畫紅線的部分,這裡又提到1個LSB(1個LSB voltage)的算法 ,也是屬於第一種公式的類型

-----------


這邊再假設一個極端的例子作為範例來思考,假設今天有一顆Vref5V、解析度為1bitADC(當然不可能有解析度這麼差的ADC產品,這邊只是故意舉極端的例子)。並且在圖表的部分仿照Analog devicedatasheet的方式來表示(橫軸為輸入的待轉換類比電壓,縱軸為在許多datasheet也稱為ADC code的已轉換出的數位值)

-> 若是套用第一種公式step size = 5/(2^1)= 2.5V




-> 若是套用第二種公式step size = 5/((2^1) – 1) = 5V


補充: 當然了,本例的上面這兩個圖不一定就是完全精確或完全實際情況的ADC transfer function畫法,僅按照前述Analog devicesdatasheet的在ADC transfer function方面的繪畫方式與邏輯來表現出這個例子的狀況

從這例子來看,第二種公式似乎不太合理,因為step size居然等於Vref的5V,而這邊的5V就是ADC的可輸入的類比full scale range(FSR)電壓值(題外話: 多數ADC允許差動輸入的方式輸入參考電壓),而5V以下的類比電壓就完全都區分不出來。基本上以此例來看,套用第二種公式的情況,似乎就失去了透過有限的數位位階去進行取樣/模擬/轉換那連續(無限多個值)的類比電壓的Analog to Digital的初衷和意義。



另外也從上面許多datasheet的內容做為結果論來看,在step size的計算方面或許應該是第一種公式才是比較正確的( Step size = Vref/(2^n) )

還有一些國外的相關議題討論文章:
> TI E2E™ support forums - Trying to find ADC non-linearity? Look under the carpet
mastering electronics design - An ADC and DAC Integral Non-Linearity (INL)

可以從上列這幾篇文章內容列出的的ADC transfer function圖看出,與ADC規格位元相對應的數位最大值,基本上對應到的類比輸入電壓,並不是對應到Vref/FSR電壓值(單從這點來說,與前述Analog devicesdatasheet的在ADC transfer function圖相同)。而從這點也可以推斷第一種公式較為正確



當然,若有ADC專家或高手能進一步對此說明或討論,則非常歡迎&感謝

------


  • 後記&補充

小弟過去的工程師專職工作都是在IC設計公司負責軟韌體開發,在某間公司時期也需要碰到一些電路的整合設計考量。但剛好都沒有負責到ADC相關的軟韌體,所以當時沒想到要去特別請教負責ADC相關的IC /IP的designer工程師這方面的問題。而最近透過朋友詢問相關專長的工程師,目前也都是得到第一種公式才是正確的公式的回覆。

【若需要嵌入式系統技術輔導課程 可來信洽談合作方式: iws6645@gmail.com,亦可先點擊參考這篇介紹文章