2011年6月4日 星期六

Introduction

註: 本文為中文翻譯,原文請見底下網址:

http://www.mikroe.com/eng/chapters/view/1/introduction-world-of-microcontrollers/

TOC Introduction Ch. 1 Ch. 2 Ch. 3 Ch 4. Ch. 5 Ch. 6 Ch. 7 Ch. 8 Ch. 9 App. A App. B App. C

Introduction: World of microcontrollers

在微控制器 (microcontrollers) 這個領域,我們今日所處的世界已經開始在發展積體電路科技 (Integrated Circuits)。這個發展使我們得以在一顆晶片上儲存數十萬顆電晶體。對微處理器 (microprocessors) 製造商來說,這只是一個前提,如果不使用積體電路把大量電晶體集中到一顆小小的晶片上,便不能稱為微處理器。記憶體、輸入/輸出線路 (input/output lines)、計時器 (timers) 和其它元件等,世界上第一部電腦就是加上這些外部周邊設備而產生的。由於封裝密度 (package destiny) 的進一步提高,使得打造包含處理器和周邊設備的積體電路這件事成為可能。這便是第一顆內含微處理器與周邊設備 ---- 我們後來把它稱為微控制器者,的發展沿革。

這一切是這麼開始的

1969 年,一個來自日本 BUSICOM 電子計算機製造公司的工程師團隊來到美國,請求根據他們的計畫為計算機設計一些積體電路。這個請求後來送到了Intel,當時由 Marcian Hoff 負責這項計畫。由於有過電腦 (PDP8) 的工作經驗,他想出了一個主意,建議改用完全不同的解決方案,而不是原先建議的設計。Marcian Hoff 提出的解決方案認為積體電路的運作應該由儲存在電路本身上面的程式來決定。這意味著系統的配置會比較簡單,不過卻需要更多的記憶體,遠超過日本工程師計畫中的提議。過了一段時間,即便日本工程師們試圖尋找更簡單的解決方案,Marcian Hoff 的想法還是贏得了勝利,於是第一顆微處理器就這麼誕生了。能把想法變成準備就緒 (ready-to-use) 的產品,Federico Faggin 的幫助很大。在聘用 Federico Faggin 9 個月之後,Intel 就從原始概念到成功開發出了這款產品。Intel 在 1971 年取得這塊積體電路的銷售權。在這之前,Intel 向 BUSICOM 購買了許可,而 BUSICOM 卻不知道這塊積體電路有多麼珍貴。在同一年,市場上出現了一個叫 Intel 4004 的微處理器。這是第一個 4 位元的微處理器,每秒可以執行 6000 條指令。在這之後不久,一家叫 CTC 的美國公司分別與 Intel 和德州儀器 (Texas Instruments) 合作要製造一個適用於終端機的 8 位元微處理器。儘管後來 CTC 放棄了這個計畫,Intel 和德州儀器公司還是繼續研發這顆微處理器;1972 年 4 月,第一顆 8 位元的微處理器上市,叫做 Intel 8008。8008 可以定址到 16KB 的記憶體,有 45 個指令而且每秒可以執行 30 萬條指令。8008 是今日所有微處理器的前身。Intel 不斷地開發改良 8008,並在 1974 年 4 月推出一個稱為 8080 的微處理器。8080 可以定址到 64KB 的記憶體,有 75 個指令,起價 360 美元。

另一家美國公司 Motorola 很快就意識到正在發生什麼事情,於是他們推出 8 位元微處理器 6800。Chuck Peddle 是 Motorola 的主要設計師。除了生產處理器外,Motorola 是第一家生產 6820 和 6850 等周邊晶片的公司。在此同時,許多企業認清了微處理器的重要性,紛紛起而效仿發展自己的微處理器。Chuck Peddle 後來引進 MOS 技術(金屬氧化半導體)到 Motorola 並且不斷的在微處理器這塊領域深耕。

譯註:6820 是 Peripheral Interface Adapter 用於 GPIO 和平行埠的控制晶片,而 6850 是Asynchronous Communications Interface Adapter 序列埠控制晶片。

在 1975 年 WESCON 的一場展覽會中,發生了一件微處理器史上的關鍵事件。MOS Technology 公司宣布即將販賣 6501 和 6502 微處理器,而且每顆只賣 25 美元,有興趣的客戶可以立即向他們購買。這是一個很轟動的事件,因為競爭對手賣的 8080 和 6800 要價 179 美元,而 MOS Technology 卻賣的這麼便宜,所以很多人認為這是一種詐欺。為了因應對手,Motorola 和 Intel 在第一天的展覽便降低了微處理器的價格,每顆只賣 69.95 美元。Motorola 指控 MOS Technology 和投靠 MOS Technology 的 Chuck Peddle 剽竊 6800 的技術。為此,MOS Technology 放棄了進一步製造 6501,不過仍持續生產 6502。6502 是一個 8 位元的微處理器,有 56 個指令,能夠直接定址到 64KB 的記憶體。由於價格低,6502 大受歡迎,它被安裝到諸如 KIM-1, Apple I, Apple II, Atari, Commodore, Acorn, Oric, Galeb, Orao, Ultra 等電腦上。不久,一些公司也開始製造 6502(Rockwell, Sznertek, GTE, NCR, Richoh, Commondore 都取得了許可)。1982 年 6502 生意興隆,該處理器以每年 1 千 5 百萬顆的速度在銷售!

其他公司也不想放棄這塊大餅。Frederic Faggin 離開了 Intel 並設立了自己的公司 Zilog Inc. 1976 年 Zilog 宣布 Z80 上市。在設計 Z80 微處理器的時候,Faggin 做了一個重要的決定。當時 8080 已經發展了一段時日,他意識到一件事,很多人會忠於 8080,因為重新改寫所有程式會花費非常多的經費。於是他決定新的處理器必須與 8080 兼容,也就是說 Z80 必須能夠執行所有為 8080 而編寫的程式。此外,因為添加了許多其它功能,使得 Z80 變成當時最強大的微處理器。Z80 能夠直接定址到 64KB 的記憶體,有 176 個指令,大量的暫存器,內建更新動態 RAM 記憶體 (dynamic RAM) 的功能,一個電源供應器,更高的運算速度等。Z80 獲得巨大的成功,大家都以 Z80 取代了 8080 的。當然,Z80 是當時最成功的商業 8 位元微處理器。除了 Zilog,市場上很快的出現了一些新的微處理器製造商,如 Mostek, NEC, SHARP 和 SGS。Z80 是許多電腦的心臟,例如 Spectrum, Parner, TRS703, Z-3 和 Galaxy。

Intel 在 1976 年發表 8 位元微處理器的升級版 8085。然而,Z80 實在是太好了,Intel 輸掉了這場戰爭。即使後來市場上出現了一些微處理器 (6809, 2650, SC/MP 等)。此時大局已定 (the die had been cast),因為沒有什麼重大的改良足以改變製造商的心意,因此 6502 和 Z80 以及 6800 仍然是當時 8 位元微處理器的主要代表產品。

微控制器 versus 微處理器

微控制器在許多地方不同於微處理器。第一個而且也是最大的不同點是它的功能。為了讓微處理器可用,必須在微處理器之外增加其它元件,例如記憶體。儘管微處理器是強大的計算機,它們的弱點就是沒辦法跟周邊設備通訊。

簡單的說,為了跟周邊設備溝通,微處理器必須使用專門的外部電路晶片。總之,微處理器純粹是電腦的心臟。時至今日,一路走來,始終如一。

image
Fig. 0-1 Microcontroller versus Microprocessor

而在另一方面,微控制器的設計則是全部合為一體。它的應用不需要其它專用的外部元件,因為周邊設備必需有的所有電路都已經內建了。微控制器節省了設計一台機器所需的時間和空間。

基本概念

你知道嗎,所有人可以分成兩種人 --- 熟悉二進制數字系統的人,跟不熟悉二進制數字系統的人。你不明白嗎?那代表你還是後者。如果你想改變情況,就讀一讀底下的文字,底下簡短描述一些本書會進一步用到的基本概念(只是為了確定我們之間有共識)。

數字的世界

數學是這麼好的科學!一切都是那麼合乎邏輯,就這麼簡單。整個宇宙可以只用 10 個數字的系統來描述。但是,是不是真的要這樣呢?我們是否確實需要 10 個數字的系統?當然不是,這只是習慣問題。記得學校教我們的,例如,數字 764 是什麼意思:4 個 1,6 個 10 和 7 個 100。嗯,簡單!可以用複雜一點的方法來表示嗎?當然可以:4 + 60 + 700。要更複雜點的嗎?當然有:4 * 1 + 6 * 10 + 7 * 100。可以讓數字看起來科學一點嗎?答案是肯定的:4 * 10^0 + 6 * 10^1 + 7 * 10^2。這實際上是什麼意思?為什麼我們要用這些數字:10^0,10^1 和 10^2?為什麼總是跟數字 10 有關?這是因為我們使用 10 種不同的數字(0,1,2,... 8,9)。換言之,因為我們用的是基底為 10 的數字系統 (base-10 number system),即十進制數字系統 (decimal number system)。

image


Fig. 0-2 The number 764 represented in three different ways

二進制數字系統

假如只用到 0 和 1 兩個數字的話,會發生什麼事?或者說,我們會因此而不知道某個東西是否為其它東西的 3 倍或 5 倍嗎?或者在比較數值大小時,我們會因此受到限制嗎?比如說,我們將因此只能指出某個東西裏存在著 (1),或者某個東西不存在著 (0),會這樣嗎?不會的,不會發生什麼特別的事,我們將繼續以同樣的方式使用數字,只不過它們看起來會有點不一樣而已。比如說:11011010。一本書裏有多少頁次包含了數字 11011010?要知道 11011010 這個數字是多少,就照著前一個例子同樣的邏輯計算,但是要用相反的順序。記住,這一切只跟數學的兩個數字 0 和 1 有關,即基底為 2 的數字系統(二進制數字系統)。

image
Fig. 0-3 The number 218 represented in binary and decimal system

顯然,數字是一樣的,只是表示方式不同。唯一的差別在於需要多少位數才能寫出一個數字。在十進制系統數字(2)用來表示數字 2,而在二進制系統則是使用兩個位數字(1 和 0)來表示數字 2。你現在同意世上的人分兩種人的這個想法了嗎?歡迎您來到二進制算術的世界。你知道二進制算術用在什麼地方嗎?

假如數值非常小 (比如兩個電壓值),除了嚴格控制的實驗室環境以外,即便最複雜的電子電路也不能準確地判定兩個 size 的大小(比如低於幾個伏特)。原因是電氣干擾和一種叫做 "真正的工作環境 (real working environment)”(無法預測的電壓源變化、溫度變化、內建元件的公差等)。想像一下,一部以十進制數字系統運算的電腦把 10 個數字這樣子識別出來:0=0V,1=5V 時,2=10V,3=15V,4=20V...9=45V!?有人說這是電池嗎?一個簡單很多的解決方案是使用二進位邏輯,其中 0 表示沒有電壓而 1 表示有電壓。寫成 0 或寫成 1,比寫成 "沒有電壓" 或 "有電壓" 簡單多了。這個稱之為 logic zero(0)和 logic one(1),電子產品完全遵照這種運作方式並以此輕鬆地執行所有那些無止盡的複雜的數學運算。電子產品在現實中應用這樣的數學 ---只用 0 和 1 來表示數字,並且唯一重要的目的是知道有沒有電壓。當然,我們說的是數位電子產品。

十六進制數字系統

在計算機發展初期,科學家就意識到人們在處理二進制數字有很多困難。由於這個原因,必須建立一個新的數位系統。這一次,新的數位系統使用 16 個不同的數字。前 10 個數字一樣,還是(0,1,2,3,... 9),但還需要 6 個數字。為了避免發明新的符號,於是使用 A, B, C, D, E, F 這 6 個英文字母。十六進制數字系統便建立起來了,由這 16 個數字組成:0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F。十六進制數字系統看似奇怪,它的目的是什麼呢?只要看看它與二進位數字搭配得多麼完美便知。

image
Fig. 0-4 Binary and Hexadecimal number

二進制系統四位數最大的數字是 1111,它對應的十進制數為 15,在十六進制系統只要用一個 F 就可以表示15。F 是十六進制系統中一個位數最大的數字。你知道這有多麼巧妙嗎?二進制 8 位元最大的數字 11111111正好是十六進制 2 位數最大的數字 FF。記住,計算機使用的是 8 位元的數字。

BCD碼

BCD 碼其實是十進制數的二進制編碼。BCD 碼讓電子電路得以使用十進制系統與周邊設備溝通,並且以周邊設備所知的二進位方式來表示數字。一個 BCD 碼包含 4 個位元的數字,可以代表 (0, 1, 2, 3 … 8, 9) 這 10 個數字。雖然 4 位元有 16 種組合,但 BCD 碼只用到前 10 種組合。

譯註:補充兩個BCD碼範例:

  • 將十進位數字 69 化成 BCD 碼,答案是:01101001 (BCD)
  • 將十進位數字 15 化成 BCD 碼,答案是:00010101 (BCD)

數制轉換

二進制是最常用的編碼系統,十進制是人最容易理解的編碼系統,而十六進制系統則介於兩者之間。因此,學習如何從某一種編碼系統轉換到另一種編碼系統是非常重要的一件事,也就是說,要學習如何把一串 0 和 1 組成的數字轉換成人們看得懂的數值。

二進制數轉換為十進制

二進制每個位數表示不同的值,其值取決於該位數所處的位置。此外,每個位置可以是 0 或者 1,根據位置,由右而左看,其值很容易就可以判定出來。要把二進制數字轉換成十進制,必須把對應的數字 (0 或 1) 做乘法運算,然後全部加總得到結果。二進制轉十進制這件神奇的事是行得通的 … 你懷疑嗎?看看這個例子:

110 = 1*2^2 + 1*2^1 + 0*2^0 = 6

必須指出,對於從 0 到 3 的十進制數你只需要二進制兩個位數。對於更大的數值,必須增加額外的二進制位數。因此,對於從 0 到 7 的數字,你需要 3 個位數,對於從 0 到 15 的數字,需要 4 個位數,依此類推。簡單來說,n 個位數的二進制數,其最大值可利用基底 2 的 n 次方計算而得,結果必須再減去 1。例如,如果 n=4:

2^4 - 1 = 16 - 1 = 15

因此,用 4 個位數的二進制數可以表示十進制數 0 到 15 之中的任何數字,總共可以表示 16 種不同的數值。

十六進制轉換為十進制

為了將一個十六進制數轉換為十進制,十六進制的每個位數必須根據其位置乘以 16 的次方,例如:

image  
Fig. 0-5 Hexadecimal to decimal number conversion

十六進制轉換為二進制

要把十六進制數字轉成二進制,不需要進行任何計算,因為只要使用 4 個位數的二進制就可以取代一個位數的十六進制。由於最大的十六進制數字相當於十進制數 15,因此我們需要使用 4 個位數的二進制數字來表示一個十六進制數字。 例如:

image  
Fig. 0-6 Hexadecimal to binary number conversion

 

image

標記數字

十六進制數字系統伴隨著二進制和十進制數字系統對我們來說是最重要的事。要把任何十六進制數轉換二進制是很容易的,而且也很好記。然而,這些轉換可能會造成誤解。例如,"必須算出組裝生產線上的 110 個產品的總數" 這句話是什麼意思?這取決於它是二進制,十進制或者是十六進制,其結果可能分別是 6,110 或 272 個產品!因此,為了避免誤解,我們得直接添加字首或字尾到數字上。字首為 $ 或 0x 以及字尾 h 用來標記十六進制的數字。例如,十六進制數 10AF 可能看起來如 $10AF、0x10AF 或是 10AFh。同樣的,二進制數通常以字尾 % 或 0b 標記之,而十進制數則是以字尾 D 標記之。

右邊這張比較表涵蓋了 0-255 在三種不同編碼系統中的寫法。

 

 

 

 

 

 

 

 

Bit

理論上,bit 是資訊最基本的單位 ... 讓我們暫時忘了這乾巴巴的解釋,來看看在它實際上是什麼。答案是沒什麼特別,bit 只是二進制的數位。好比十進制的系統,數字中的每個數位都有不同的意義(例如 444 中每個位數一樣都是 4,但數值卻是不同的),bit 的意義在於它在二進制數字中的位置。因此,探討個位數、10 位數等等是毫無意義的。相反的,在這裏有意義是 zero bit (最右邊的bit),first bit (從右邊算起第 2 個bit) 等。此外,由於二進制系統只用到兩個數 (0 和 1),一個 bit 的值不是 0 就是 1。

如果你發現某個 bit 的值為 4, 16, 或 64,不要混淆,這意味著該 bit 是以十進制表示的。簡單地說,因為我們習慣於十進制系統,所以這類表達變得很平常。"二進制的第 6 個 bit 相當於十進制的 64” 這樣的說法是正確的。不過,我們是人,積習總是難改 ... 如果用這樣表達概念: "數字: 11010…." 這怎麼可能聽得懂呢。

Byte

一個 Byte 由 8 個 bits 組成。就像十進制數字一樣,所有的數學算術都可以用在 Byte 上。一個 Byte 最左邊的 bit 擁有最大的值,所以稱之為最高有效位元 (Most Significant bit, MSb),而最右邊的 bit 擁有的是最小的值,所以稱之為最低有效位元 (Least Significant bit, LSb)。因為 8 個位元共可組出 256 種情況,所以一個 Byte 可以表示的數值最大是 255 (其中一個是 0)。

Nibble 用來表示半個 Byte。就看我們談論的是 Byte 的哪一半 (左邊或右邊),一個 Byte 分成 high nibble 和 low nibble。

image
Fig. 0-8 High and Low nibbles

邏輯電路

你是否曾經想過,在一些數位積體電路中,微控制器或處理器的電子是長什麼樣子?執行複雜數學運算和做決策的電路長得又是如何? 你知道嗎?它們的電路看似複雜,其實只包括了一些稱之為 "邏輯電路 (logic circuits)” 或 "邏輯閘 (logic gates)” 的元素而已。

這些元素建基於 19 世紀中的英國數學家 George Boole --- 比真空管的發明還要來得早!簡單來說,主要想法是透過代數功能 (algebraic functions) 來表示邏輯形式。這個想法很快就被轉化為實際的產品,在今日被稱為 AND,OR 和 NOT 邏輯電路。其運作原理稱為布林代數 (Boolean Algebra)。除了變成指令的形式以外,由於微控制器的一些指令跟邏輯閘 (logic gates) 的運作方式是一樣的,因此這裡將討論邏輯電路的運作規則。

AND Gate

AND Gate 有兩個或多個 inputs 和一個 output。讓我們假定 AND Gate 只有兩個 inputs,只有在兩個 inputs (A 和 B) 皆為 1 時,AND Gate 才會得到邏輯 1 的 output。image

這張表顯示 inputs 和 outputs 是彼此相依的。

當有超過兩個 inputs 時,AND Gate 的運作原則還是一樣:只有所有 inputs 都是 1 時才會得到值為 1 的 output。其它任何 inputs 的組合都會讓它的 output 為 0。

 

image在程式中使用時,logic AND 的運算是由指令執行的,這我們後面會討論,目前這樣就足以記住程式中的logic AND 跟兩個暫存器 (registers) 有關。

 

 

 

OR Gate

image 跟前面的例子很類似,OR Gate 有兩個或多個 inputs 和一個 output。只要 inputs (A 或 B) 其中一個為1時,output 就會得到 1。假如所有 inputs 都是 0,那麼 output 將會是 0。

 

 

 

image 跟 logic AND 的運算一樣,在程式中,logic OR 的運算執行於兩個暫存器 (registers) 相對應的位元 (bits) 之間。

 

 

 

 

NOT Gate

image 這個邏輯閘只有一個 input 和一個 output。它的運作原理非常簡單。當 input 為 0 時,output 會是 1,反之則相反。這意味著這個邏輯閘會反轉訊號。它有時候稱作反轉器 (inverter)。

 

 

image Logic NOT 的運算執行於一個 byte 時,得該 byte 反轉後的結果。假如 byte 被當成是一個數字,反轉後的值其實就是該數的補數,即一個數字加上其補數後,就會得到 8 bit 的最大值 (255)。

 

 

 

EXCLUSIVE OR Gate

image 相較於其它邏輯閘,EXCLUSIVE OR(XOR) Gate 稍微複雜。XOR Gate 是前面討論過的所有邏輯閘的組合。只有 inputs 皆為不同的狀態時 (互斥),output 才會是 1。

 

 

image 在程式中,XOR Gate 通常用來比較兩個 bytes。減法也可以達到同樣的目的 (假如 XOR Gate 運算結果為0,那兩個 bytes 就是相等的)。XOR Gate 的優點是這種邏輯運算在「從小數減去大數」的情況下不會有什麼危險。

 

 

 

暫存器 (Register)

暫存器或 memory cell 是可以記憶一個 byte 的狀態的電子電路。

image
Fig. 0-17 Register

特殊功能暫存器 (Special Function Register)

除了沒有特別用途與預定功能的暫存器外,每個微控制器都有一些由製造商預先定義好功能的暫存器。它們的位元 (bits) 被連接(實實在在地)到內部電路,如計時器 (Timers),A/D 轉換器 (A/D converter),振盪器 (oscillator) 和其他電路,這意味著它們直接指揮微控制器的運作。想像一下,有 8 個開關,它們指揮微控制器內部一些較小的電路,沒錯!特殊功能暫存器(SFRs)就是在做這回事!

image
Fig. 0-18 Special Function Register

輸入/輸出埠 (Input/Output Ports)

為了讓微控制器有用,微控制器必須連接額外的電路,比如周邊設備。每個微控制器都有一個或多個連接到微控制器的腳位 (pins) 的暫存器 (稱作 "port")。為什麼要 Input/Output?因為你可以如你所願地改變腳位的功能。例如,假設你希望設備可以切換 3 個 LED 燈號,同時監測 5 個感測器 (sensors) 或按鈕 (push-buttons) 的邏輯狀態,那麼某些 ports 就必須做一些設定,這樣才可以得到 3 個 output (連接到 LEDs) 和 5 個 inputs (連接到 sensors)。這些動作是透過軟體完成的,這意味著腳位功能可以在程式執行的時候動態調整。

image
Fig. 0-19 Input / Output ports

Input/Ooutput (I/O) 腳位一個很重要的規格,是它們可以處理的最大電流 (maximum current)。對於大多數微控制器而言,從一支腳位獲得的電流便足以推動 LED 或類似低電流的設備 (10-20mA)。假如微控制器有很多 I/O 腳位,那麼一個腳位的最大電流會降低一些。簡單的說,假如微控制器有超過 80 支腳位,你不可能期待所有腳位都可以輸出最大的電流。另一種說法是,data sheet 裏面提到的微控制器的最大電流,是由所有I/O 腳位共同分享的。

腳位的另一個重要功能是它們可以有提升電阻 (pull-up resistors)。提升電阻連接腳位與正電壓,當腳位設置成輸入而且連接到機械開關 (mechanical switch) 或按鈕的時候,提升電阻的效果是明顯的。較新的微控制器本身具有提升電阻,而且可以透過軟體設定。

通常,每個 I/O port 受另一個 SFR 的控制,這表示暫存器的每個位元決定了微控制器對應腳位的狀態 (或稱方向)。例如,把邏輯 1 寫到SFR 控制暫存器,相稱的 pin 腳位就會自動設成輸入 (input)。這意味著可以讀出送到該腳位的電壓,讀出的結果將會是邏輯 0 或 1。反之,把 0 寫到 SFR 控制暫存器,對應的 pin 腳位就會自動設成輸出 (output),該腳位便會根據其狀態輸出適當的電壓 (0V 或 5V)。

記憶體單元

記憶體是微控制器的一部份,用來儲存資料。解釋記憶體最簡單的方式是拿有很多抽屜的檔案櫃來比較。假設抽屜都有清楚的標示,那麼便很容易辨識與存取它們。要取得抽屜的內容很簡單,只要讀取抽屜上面的標籤就行了。

image 每個記憶體位址對應到一塊記憶體空間。透過位址就可以得知任何一塊記憶體空間的內容。記憶體可讀也可以寫。微控制器裏面有很多種記憶體。

 

 

 

 

 

 

 

 

 

 

Read Only Memory (ROM)

ROM (Read Only Memory) 是用來永久保存要被執行的程式。可以寫入多少程式就看記憶體有多大。程式可以寫多大,取決於這塊記憶體。現在的微控制器通常使用 16 位元定址,這意味著它們最多可以定址到 64KB 的記憶體,即 65535 塊記憶體空間。當一個新手,你的程式會很少超過幾百個指令。ROM 分很多種。

Masked ROM。含有這類 ROM 的微控制器是預留給大製造商的。程式是由製造商載入到晶片中。如果是大規模的生產,價格會非常低廉。不必在意它...

One Time Programmable ROM (OTP ROM)。假如微控制器有這種記憶體,你可以載入程式到這塊記憶體,不過程式的載入過程是「單程票 (one-way-ticket)」,這意味著只能做一次。假如程式載入完畢後才發現程式有錯,你唯一可以做的事就是丟掉這顆晶片,然後把正確的程式載入到另一顆晶片裏。

image UV Erasable Programmable ROM (UV EPROM)。這種記憶體的特性與生產過程跟 OTP ROM 完全一樣。不過,在這類微控制器的包裝上側有可辨識的 "窗口"。這個窗口使得內部的晶片表面得以接收紫外燈 (UV Lamp) 的照射,紫外燈對 ROM 的清除與寫入非常有效。要安裝這個窗口工程非常複雜,也影響價格。從我們的觀點來看,很不幸的 --- 不值得...

 

 

 

Flash memory。這種記憶體是 80 年代在 Intel 實驗室中發明的,它被視為 UV EPROM 的接班代表者。由於 Flash memory 的內容可以寫入與清除,而且幾乎不限次數,所以有 Flash ROM 的微控制器是學習、實驗與小量生產最理想的選擇。由於它的普及,今日大多數微控制器都是用 Flash 製造的。所以,如果你要購買微控制器,要找的種類肯定是 Flash 莫屬!

Random Access Memory (RAM)。一旦電源關閉,RAM (Random Access Memory) 的內容就會被清掉。RAM 是用來保存微控制器運作中的暫時和中介的資料。例如,如果程式執行一個加法運算 (不管是加什麼),就必須要有個暫存器用來代表所謂的 "sum"。為此,RAM 其中一個暫存器就被稱作 "sum",並且用來保存加法運算的結果。

Electrically Erasable Programmable ROM (EEPROM)。EEPROM 可以在執行階段改變內容(類似 RAM),而且即便電源關閉,其內容仍然可以永久保存 (類似 ROM)。因此,EEPROM 常用來保存執行階段所產生的需要永久保存的值。例如,如果你設計了一個電子鎖或警報,讓使用者可以設定與輸入組會是很好的一件事,但假如每次電源關掉後密碼就不見了,那就不妙了。理想的解決辦法是使用內嵌 EEPROM 的微控制器。

中斷 (Interrupt)

大部份程式在執行的時候都會使用中斷。微控制器主要的目的是對周圍的變化做出反應。換句話說,當某個事件發生時,微控制器就做些事情... 例如,當你按下遙控器 (remote controller) 的按鈕時,收到訊號的微控制器就會登記這個事件並回應這個命令,例如改變頻道,調高或降低音量等。假如微控制器大部份的時間都在無止盡的處理按鈕事件而不做點別的... 將是不切實際的。

微控制器已經從電腦進化過程中學到竅門。微控制器把 "等待某件事" 委託給 "專家" 處理,而不是不斷的檢查每個腳位或位元。"專家" 只對某件值得它關注的事有反應。

通知中央處理器 (central processor) 這類事件的訊號 (signal) 稱為中斷 (INTERRUPT)。

中央處理器 (CPU)

正如名稱所示,CPU 是微控制器內部負責監測與控制所有行程 (processes) 的單元。CPU 包含幾個較小的子單元,其中最重要的是:

  • 指令解碼器 (Instruction Decoder) 是 CPU 的一部分,它負責辨識指令並以此為基礎執行其它電路。每個微控制器家族 (microcontroller family) 的指令集都不一樣,指令集揭示了指令解碼器的能力。
  • 算述邏輯單元 (Arithmetical Logicall Unit, ALU) 對資料執行數學與邏輯運算。
  • 累加器 (Accumulator) 是與 ALU 的運算緊密相關的 SFR。累加器用來保存應當執行運算 (加法,位移/搬移等) 的所有資料。它也保存準備用於進一步處理的資料。SFRs 其中一個叫做 Status Register(PSW) 的暫存器跟累加器非常親密。Status Register 顯示了儲存在累加器中的數字的狀態 (數字大於零或小於零等)。 

 

image
Fig. 0-22 Central Processor Unit - CPU 

匯流排 (Bus)

實際上,匯流排由 8, 16 或者更多線路 (wires) 組成。匯流排有兩種:address bus 與 data bus。Address bus 是由必要足夠多的線路組成的,以作記憶體的定址使用。Address bus 用來讓 CPU 傳輸 address 給記憶體。Data bus 與資料長度一樣寬,以我們的情況而言是 8 位元或更寬。Data bus 是用來連接微控制器內部的所有電路。

序列通訊 (Serial Communication)

對短距離到數米的距離而言,微控制器與周邊之間經由 input/output ports 的並列連線 (Parallel connections) 是理想的解決方案。然而,在其它情況下 --- 當必須建立兩個設備間的通訊時,使用並列連線是不太可能的 --- 不在話下,因為成本高。在這些場合,序列通訊 (serial communication) 是最好的解決方案。

今天,跟標準電腦設備一樣,大多數微控制器都內建許多種不同的序列通訊系統。該用哪一種序列通訊取決於許多因素,其中最重要的是:

  • 微控制器要與多少設備交換資料?
  • 資料交換的速度要有多快?
  • 設備之間的距離為何?
  • 需不需要同時發送與接收資料?

關於序列通訊,最重要的事其中之一是得嚴格注意所用的通訊協定 (Protocol)。通訊協定是一組規則,為了讓設備正確地互相交換資料而必須遵守的通訊協定。幸運的是,微控制器會自動處理這些事情,所以 programmer/user 的工作就簡化了,只需要做寫入 (要傳送的資料) 與讀取 (收到的資料) 等簡單的工作。

image
Fig. 0-23 Serial communication

Baud Rate

Baud rate 一詞通常用來表示每秒傳送的位元 (bits per second, bps)。

必須指出,Baud rate 指的是 bits,不是 bytes!在傳送每個 byte 的時候,協定通常需要一起傳送一些控制位元 (control bits)。這意味著在序列資料串流 (serial data stream) 中一個 byte 可能會由 11 個位元組成。例如,假如 baud rate 是 300 bps,那麼每秒最多可傳輸 37 bytes 而最少可以傳輸 27 bytes 的資料,這一切取決於所用的連線種類以及通訊協定。

最常用的序列傳輸系統是:

image I2C (Inter Integrated Circuit) 是當微控制器間距離很短而且特定的新一代積體電路 (接收器和傳送器通常都在同一張印刷電路板上) 會用的通訊系統。I2C 的連線經由兩個導體建立起來:一個是傳輸資料用,而另一個是訊號同步用 (clock signal)。從圖中可以看出,其中一台設備永遠是 master,在通訊開始前,它對一個 slave晶片 (從屬的) 執行定址。以這種方式,一個微控制器可以與 112 台不同的設備通訊。Buad rate 通常是100Kb/sec (標準模式) 或 10Kb/sec (低速率模式)。最近已經出現 3.4Mb/sec 的系統。走 I2C bus 通訊的設備,其間的距離限制在數米之內。

SPI (Serial Peripheral Interface Bus) 是一個使用最多 4 個導體 (通常是3個) 的序列通訊系統:一個用於資料接收,一個用於資料傳送,一個用於訊號同步,而一個 (可選擇的) 則用於選擇欲通訊的設備。SPI 是全雙工連線,這意味著資料的收送是同時進行的。SPI 最高速率高於 I2C。

UART (Universal Asynchronous Receiver/Transmitter) 這種連線是非同步的,這意味著不會用到一根特別用來做時脈訊號 (clock signal) 的線路。在某些情況下,這個特色至關重要(例如無線電波或紅外線遠端遙控)。由於只用到一條通訊線,為了保持必要的同步,接收器和發送器都得使用相同預先定義好的運作速率。這是一種非常簡單的傳送資料的方式,因為基本上它代表 8 位元的資料會從並列轉成序列格式。UART 的 Baud rate 不超過 1Mbit/sec。

振盪器 (Oscillator)

來自振盪器 (oscillator) 的脈波使微控制器所有電路得以和諧和同步的運作。振盪器通常用石英振盪器(quartz crystal) 或陶瓷諧振器 (ceramic resonator) 來產生穩定的頻率。此外,微控制器也可以使用沒有穩頻功能的振盪器 (例如 RC oscillator)。必須說這是很重要的一點,指令並不是照振盪器的速率在執行,而是比它慢幾倍在執行。這是因為指令是分成好幾個步驟執行的。對於某些微控制器而言,每個指令的執行週期是一樣的,而其他微控制器則不是所有指令執行週期都相同。因此,如果有一個使用石英振盪器頻率 20Mhz 的系統,它一個指令的執行時間不會是 50nS,而是 200, 400 或 800nS,取決於所用的微控制器(MCU)類型!

電源供應電路 (Power supply circuit)

關於微控制器電源供應電路,有兩件值得注意的事情:

Brown-out 是一種潛在的危險狀態,發生於微控制器被關閉的當下或是因為電子干擾而導致電壓掉到界限以外的情況。由於微控制器是由許多使用不同運作電壓準位的電路所組成的,電壓不足 (Brown-out) 會造成微控制器產生不受控制的表現。為了防止這件事情,微控制器通常內建 Brown-out reset 的電路。當電路準位掉到界限以下時,這個電路就會立即重置 (reset) 機器。

Reset pin 通常被標記為 MCLR(Master Clear Reset),它做的事是微控制器的外部重置 (external reset)的工作,觸動辦法是對 MCLR 腳位給邏輯 0 或1,這取決於所用的微控制器類型。假使微控制器沒有內建 Brown-out 電路,可以用一個簡單的外部電路連接到這個腳位以設計 Brown-out reset 機制。

計時器/計數器 (Timers/Counters)

微控制器採用石英振盪器以供運作。雖然它不是最簡單的解決方法,卻有很多使用它的理由。那就是,這種振盪器的頻率有精確的定義而且非常穩定,它產生的脈衝永遠是相同的寬度,這使得它們很適合於時間的測量。這種振盪器用在石英手錶。如果有必要測量兩個事件之間的時間,計算來自振盪器的脈衝數便足以得知。這正是 Timer 做的事。

image
Fig. 0-27 Timers/Counters

大多數的程式使用這些微型的電子 "秒錶 (stopwatches)"。這些 Timers 一般是 8 或 16 位元的 SFRs,每來臨一個脈衝,其內容便自動遞增。一旦暫存器溢位時就會產生中斷!

如果 Timer 暫存器是使用石英振盪器運作的,那麼便可能測量兩個事件之間的時間(假如在測量開始時暫存器的值是 T1,而結束時為 T2,那麼所用的時間將等於 T2-T1)。如果暫存器使用的是來自外部來源 (external source) 的脈衝,那麼這樣的 Timer 便變成了 Counter (計數器)。

這只是計時器內部運作的一個簡單的解釋。

Timer 是怎麼運作的?

實際上,來自石英振盪器的脈衝是每一個機器週期 (machine cycle) 來一次,或者脈衝是來自通過預除器 (prescaler) 的電路,prescaler 會遞增 Timer 暫存器的內容。如果一個指令(一個機器週期)為期 4 個石英振盪器週期,那麼嵌入一個頻率為 4MHz 的石英振湯器,Timer 的內容將每百萬秒改變一次(每微秒)。

image
Fig. 0-28 Timer Operation

以上述這種方式測量短暫的時間間隔 (最多 256 微秒) 是很簡單的,因為 255 是一個暫存器可以儲存的最大的數值。這個明顯的缺點很容易克服,可以用這幾種方法:使用慢一點的振盪器、較多位元的暫存器、prescaler 或中斷。前兩個解決方案有一些弱點,因此,最好使用 prescaler 或中斷。

使用 prescaler 計時

prescaler 是一個透過預先決定的係數 (factor) 用來減少頻率的一個電子設備,意思是為了在 prescaler 的輸出產生一個脈衝,有必要把 1, 2, 4 或更多的脈衝放到它的輸入。這種電路內建於微控制器,而且其除率 (division rate) 可以在程式裏改變。當有必要測量較長的時間週期的時候就會用到 prescaler。

prescaler 通常由 timer 和 watchdog timer 共同分享,這意味著它不能被這兩者同時使用。

image
Fig. 0-29 Using prescaler in timer operating

使用中斷計時

如果 timer 暫存器由 8 個位元組成,那麼可以寫入的最大數值為 255 (16 位元暫存器的話是 65535)。如果超過了這個數值,timer 會被自動重設,而且將再次從 0 開始計數。這種情況稱為溢位 (overflow)。如果程式裏面有啟用,這類溢位事件可以引發中斷,這帶來了完全新的可能。例如,用來計數秒數、分鐘或天數的狀態暫存器,其內容可以在中斷函式裏改變。整個過程(除了中斷常式外)是在背景裏自動完成的,這使得微控制器的主電路得以執行其它運算。

image
Fig. 0-30 Using the interrupt in timer operation

這張圖說明了中斷計時的用法。藉由指定 prescaler 給 timer,主程式干預造成的任意一段期間的延遲將可輕易的獲得。

計數器 (Counters)

如果 Timer 是用來計算供應到微控制器的輸入腳位的脈衝,那麼 timer 便變身為 counter。顯然,電子電路是相同的,唯一不同的是,在這種情況下,被計數的脈衝是通過 ports 而來,而脈衝持續時間 (寬度) 大部份是沒有定義的。這就是為什麼他們不能用來衡量時間的原因,但是可以用來衡量其它東西:裝配線上的產品,旋轉軸(axis rotation),乘客數量等(取決於所用的感測器)。

看門狗計時器 (Watchdog Timer)

Watchdog Timer 是連接到微控制器內部一個完全獨立的 RC 振盪器的 timer。

如果 watchdog timer 有啟用,那麼每當它計數到極限時,微控制器就會重置 (reset),而且程式會從第一個指令開始執行。重點是要用一個特定的命令以防止這種情況發生。整個概念基於這樣的事實,每個程式其實在執行許多或長或短的迴圈。

如果把重設 watchdog timer 的指令放在程式適當的位置,此外,指令也規律地執行,那麼 watchdog timer便不會影響程式的執行。如果因為任何原因(在工作界通常是電子干擾)Program Counter 被卡在某個沒有 return 的記憶體位置,watchdog 就不會被清除,而該暫存器的值將不斷遞增直到達極限!重置就發生了 (reset occurs)!

image
Fig. 0-31 Watchdog Timer

A/D 轉換器 (A/D Converter)

外部訊號通常從根本上與微控制器所知的 (1 和 0) 不一樣,因此,他們必須經過轉換以使微控制器得以理解它們。類比數位轉換器是一個轉換連續訊號為離散數位數值的電路。該模組用來將某些類比值轉換成二進制數值,並將結果轉發給 CPU 作進一步的處理。換句話說,這個模組用於輸入腳位的電壓測量(類比值)。測量結果是一個數字(數位值),之後在程式裏使用與處理。

image
Fig. 0-32 A/D Converter

內部架構 (Internal Architecture)

所有微控制器都使用 Harvard 和 von-Neumann 兩種基本設計模型的其中一種。

簡單地說,它們是 CPU 與記憶體間兩種不同的資料交換方式。

von-Neumann 架構

image 使用這種架構的微控制器只有一個記憶體區塊和一個 8 位元的data bus。由於所有的資料交換都是使用這 8 條線路,所以這條 data bus 負荷大、通訊速度慢,而且效率低。CPU 可以從記憶體讀出指令或讀/寫記憶體。這兩者不能同時發生,因為指令跟資料使用的是同一條匯流排。例如,如果某支程式的一行 code 說,叫作 "SUM" 的 RAM 暫存器應該加 1 (指令:incf SUM),那麼微控制器將執行下列操作:

1. 讀出指明該做什麼事的指令 (在這個情況下,是遞增的 "incf" 指令)

2. 進一步讀出同一個指令指明的該處理的資料 (在這個情況下,是 "SUM" 暫存器)

3. 在遞增數值後,結果應該寫回暫存器("SUM" 暫存器的位址)

所有這些運算使用的都是同一條 data bus。

Harvard 架構

image 使用這種架構的微控制器有兩個不同的 data buses。一個是 8 位元寬並且連接 CPU 與 RAM。另一個由許多線路組成 (12,14或 16條) 並連接 CPU 與 ROM。因此,CPU 可以同時讀取指令與存取資料記憶體 (在 RAM裏面)。由於所有的 RAM 暫存器是 8 位元寬,所以微控制器內的所有資料都是以相同格式交換。此外,程式寫人資料時,只有 8 位元才考慮。換句話說,程式中的資料可以不斷變化,但你能影響的將只是 8 位元寬的資料。為這些微控制而編寫的程式,在編譯為機器語言後將被儲存在微控制器內部的 ROM。然而,這些 ROM 並沒有 8 位元而只有 12, 14 或 16 位元的記憶體位置。剩餘的 4,6 或 8 個位元,則是指令本身的指示,以指示 CPU 該對 8 位元的資料做什麼事。

這種設計的優點如下:

1. 程式裏所有資料都是 8 位元寬。由於讀取程式指令的 data bus 有許多線路(12, 14 或 16 條),利用這些多餘的位元,可以同時讀出指令和資料。因此,所有指令都是在一個指令週期裏執行完畢。唯一的例外是 jump 指令,執行 jump 指令要兩個指令週期。

2. 程式 (ROM) 和暫時的資料 (RAM) 是分開的,由於這一個事實,CPU 可以同時執行兩條指令。簡單地說,當 RAM 的讀或寫正在進行時,下一個指令便會從另一條 bus 讀出來。

3. 使用 von-Neumann 架構的微控制器,使用者永遠不曉得某支程式要佔用多少記憶體。基本上,每個指令佔用兩個記憶體位置(一個包含應該做什麼的資訊,而另一個則包含該處理哪個資料的資訊)。但是,這並不是一個硬性規定,只是最常見的情況而已。在 Harvard 架構的微控制器上,program bus 比一個 byte 來的寬,這允許每個 Word 可以包含指令和資料。換句話說:一個 Word 一個指令。

指令集

image 微控制器理解的指令稱為指令集。當你以組語語言編寫程式,你其實是在 "講故事",以該被執行的順序指派指令。在這個過程中,主要的限制是可用的指令數。微控制器製造商信守下列策略:

 

 

 

 

RISC (Reduced Instruction Set Computer) 在這種情況下,微控制器只認識與執行很基本的運算(加、減、複製等)。所有其他更複雜的運算則透過結合這些指令(例如,乘法是透過執行連續的加法運算)。限制是顯而易見的(試著只用簡短的幾句話解釋給別人知道要怎麼到其它城市的機場)。不過,也有一些很大的優勢。首先,這種語言容易學習。此外,微控制器是非常快的,所以不可能看到所有算術運算的 "巧妙手法"。使用者只能看到這些運算的最終結果。最後,如果你用對字眼,要解釋機場在哪裏也不怎麼困難。例如,左,右,公里等。

CISC (Complex Instruction Set Computer) 是 RISC 的相反!認識超過 200 條不同的指令,CISC 微控制器可以做很多事而且非常快。然而,使用者要理解這豐富語言提供的所有指令,這不容易...

如何做出正確的選擇

好吧,你是初學者,而你必須做出決定以繼續與微控制器相處的冒險旅程。恭喜您的選擇!但是,它不是如所見的那麼容易選擇正確的微控制器。問題不在有限範圍的設備,而是相反的!

在你開始設計一些基於微控制器的設備前,想一下這些問題:我需要多少輸入/輸出線路?相較於只是切換繼電器的開關,是否需要執行其它運算?是否需要一些專門的模組,如序列通信,A/D 轉換等。當你建立一張清楚的想像時,選擇範圍便大大地減少,那麼便是考慮價格的時候。你的計劃是要生產許多設備嗎?數百台?數百萬台?無論如何,你懂意思了吧...

如果你是第一次考慮這所有的事情,那麼一切似乎有點混亂,令人困惑。為此,一步一步走。首先,選擇製造商,即你可以容易取得的微控制器系列。之後,研究一個特定的 model。依你所需盡可能的學習,但不要進入細節。解決一個具體的問題,然後將會發生令人難以置信的事 ---- 你將能夠處理屬於該系列的任何微控制器。

記得學習騎腳踏車這檔事:一開始經歷很多次不可避免的傷痕,你學會設法保持平衡,並且輕易便學會騎其它腳踏車。當然,正如永遠不會忘記怎麼騎腳踏車,你將永遠不會忘記編程的技巧!

PIC microcontrollers

如果你是初學者,Microchip Technology 公司設計的 PIC microcontrollers 可能是正確的選擇。原因是...

這個微控制器真名是 PICmicro (Peripheral Interface Controller),不過稱為 PIC 比較好。它的第一個原型是通用儀器 (General Instruments) 公司在1975年設計的。這顆晶片叫做的 PIC1650 用途完全不同。大約 10 年後,在增加 EEPROM 記憶體後,這顆晶片變成了一個真正的 PIC microcontroller。時至今日,Microchip Technology 聲稱已經製造了5億顆 PIC ...

為了讓您更容易理解其受歡迎的原因,我們將簡要地介紹一些重要的事情。

image

所有 PIC microcontrollers 都使用 harvard 架構,這意味著 PIC 的 program memory 透過超過 8 條線路的 bus 連接 CPU。根據 bus 的寬度,區分為 12, 14 位和 16 位元的微控制器。上表顯示這三大類型微控制器的主要特點。

如表格所示,除了 PIC24FXXX 和 PIC24HXXX 等 "16位元怪物" 之外,所有 PIC microcontrollers 都用 8 位元 harvard 架構,而且屬於三大類型的其中一種。因此,根據 program word 的大小,總共有三種類型的微控制器,即 12, 14 或 16 位元的微控制器。由於擁有相似的 8 位元核心,它們都使用相同的指令集和基本的硬體骨架連接到或多或少周邊。

為了避免繁瑣的解釋和關於不同微控制器有用的特色的無止盡的故事,本書描述一個屬於 "中高階 (high middle class)" 的特定 model 的運作。它是 PIC16F887,一個夠強大,值得關注,而且簡單到足以向每個人介紹的微控制器。

0 意見: