單片機硬件和軟件是如何結合的,代碼如何控制硬件機器?


作者:不是真名
鏈接:https://www.zhihu.com/question/31752629/answer/53834585
來源:知乎
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。

目錄:
1. 二進制理論
2.數字電路的實現
3.CPU 對硬件的控制
4.最終章(解答樓主問題)

補充:
5.邏輯門的物理實現:MOSFET
6. 軟件控制硬件實例:SD CARD(待續)
7. I2C協議詳解(待續)
8. FPGA 與 ASIC(待續)

=========================================================

作為啃了幾年書本,燒過幾塊電池的工程狗,那我就來科普一下吧。

不算大神,唯手熟爾。

我們不妨從最底層開始往上走。

1. 二進制理論

眾所周知,電腦,手機以及其他大量的電子設備,都是基於復雜的數字電路進行工作的。而數字電路則通過循環往復地完成一系列的指令,來輸出我們想要的結果。

那究竟里面的工作原理是什么樣子的呢?

首先,我們需要一套數字理論。

上帝說,我們需要一個理論。於是萊布尼茨誕生了。
萊布尼茨提出了二進制,這成為了現代計算機理論的基礎。至於是老子啟發了他,還是他自己坐而悟道想出了二進制,其實已經不重要了。有了二進制,一切變得簡單起來:

我們可以只用1 和0 來代表所有數字,進行和十進制一樣的代數運算。雖然對於人腦來說,二進制非常不雅觀, 比如:

10001010101010101010 * 0101001101010 = 0101101001000001010011100110100。

但它對於計算機來說, 則最簡潔,最直觀,最高效。

1.1 二進制運算

每一位都只可能是1或者0,運算符號也就是加減乘除。雖然長,位數多,但速度極快!因為,但就每一位來說,運算之后,只會有幾種情況:
1 + 1 -> 0, 進一位(, 這個)
1 + 0 -> 1.
0 + 1 -> 1.
0 + 0 -> 0.

所以說,《三體》中,劉慈欣講到人肉計算機一說。單個運算單元只需要記住特定指令相對應的操作即可,甚至連加減乘除都不需要會。 但這個在現實里面並不可能完成。假設這個運算恆紀元的程序有10000條指令(但顯然這個條件都不成立,因為這個程序必然很復雜,涉及復雜的浮點運算和邏輯算法,甚至還有平方開放積分微分,10000條機器代碼都不夠塞牙縫的), 每條指令需要100個邏輯單元,每個單元的運算時間1秒鍾,那么整個程序就需要1000000s (11天13小時46分鍾)。。。所以可能程序還沒算完,亂紀元又來了,所有人來不及脫水都死了。這還不算發盒飯,上廁所時間。

1.2 二進制邏輯

而且,電腦可以理解是非對錯了。計算機以1表示“對”,“是”,“正確”。以0表示“錯”,‘否’,‘錯誤’。然后又引進了“或”,‘與’,‘否定’,等邏輯語句。

我們用 || 表示“或”,表示兩者有一個成立即成立(我是學工科的(1) || 我是學計算機的(0) = 我沒有女朋友(1))。
0 || 0 = 0
0 || 1 = 1
1 || 0 = 1
1 || 1 = 1
我們用&& 表示“與”,表示兩者都成立方可成立。(我是學工科的(1)&& 我是男的(1) = 我沒有女朋友(1))。
0 && 0 = 0
0 && 1 = 0
1 && 0 = 0
1 && 1 = 1

2. 數字電路的實現

2.1. 邏輯門
我們有了數字理論,那怎么才能做出邏輯電路呢?怎么才能用來運算呢?我們引入這些理想的邏輯門,靠他們來作運算。


這個就是與門,除非兩個輸入都是1,則輸出1, 否則輸出0.

 


 


這個就是或門,除非兩個輸入都是0,則輸出0,否則輸出1.

 



 

 

這個就是非門,它會對輸入取反(1變0,0變1 )


 

這個叫或非電路,除非兩輸入相同則輸出0,否則輸出1

 

現在,僅用一個理想原件,就可以做一次邏輯運算了!

那如何做代數運算?比如加法?

以上的電路就能完成2以內的加法了。
當兩個輸入都是0, 高位輸出0, 低位也是0 =》 0
當兩個輸入都是1, 高位輸出1, 低位也是0 =》 2
當輸入一個0一個1,高位輸出0, 低位也是1 =》 1

 

所以,大家也看到了,這個邏輯電路其實並不明白加法,它只是照部就搬的給我們了碰巧正確的結果——這就是我們常說的‘中文房間’的思想實驗。

我們有了2以內的加法,那么4以內也好解決了,8,16。。。以此類推,我們只要把數字電路互相疊加,就能得到很多功能,比如說加減乘除,求余等等數學運算,相應地,邏輯電路也會越來越復雜:


我們現在有了CPU,他可以完成簡單的運算,但是這還不夠。

 

我們要編程。

2.2. 編程
程序本身就是指令的集合。

所謂的編程就是將程序員所要實現的效果,用系統支持的指令寫下來。就好比給你一本唐詩三百首,讓你用里面的詩句組合(雜燴)成你想要表達的意思。

當我們安裝一個程序的時候,它本身實在硬盤里面的。 只有當我們啟動它的時候,系統才會到硬盤里,找到該程序,然后將其讀取到內存中。

將設我們還在使用一個幾十年前的電腦,這個電腦每次操作只操作的數字只有八個0或者1,也就是我們常說的8位系統。這些指令被存放到內存里面之后,CPU又會把它當下要執行的那一句放到寄存器里面,然后執行這條指令。一條接一條,循環往復。

假設我們有一個8位指令。CPU得到它之后,就會分析,這一個指令里面,哪一段是操作符,哪一段是數字。比如:0101 00 11,它會讀前四位,發現是加法(我瞎編的),然后讀5-6位發現是0,7-8位是3,所以輸出3。

CPU得到3之后,會把它放到寄存器里面,然后進行后續操作。

當然看似簡單,8位操作里面的數字電路也會是無比復雜了(這還只是幾十年前的科技,如今intel 64位處理器的復雜程度可見一斑)。

至此,我們已經可以編程了。我們的程序會是這樣子。

00101010
10101010
01001101
01010010

計算機誕生之初,程序的確是這樣的。但假如讓如今的程序員來干這種事情,肯定又得哭爹喊娘一頓了(誤)。所以,后來,出現了匯編語言。比如:
MOV R1, #0x1
MOV R2, #0x1
ADD R1, R2, R1
這是ARM的匯編指令,讀出來如下
在寄存器R1里面裝1,
在寄存器R2里面裝1,
計算R1 + R2 並將值放到R1里面。

這就是一個簡單的加法程序了。

但是呢,這種程序寫起來還是很不舒服,效率極低。
於是高級語言語言。
int a1 = 1;
int a2 = 2;
a1 = a1 + a2;

這是c語言里面的一個簡單加法。這個程序被我寫完之后,會被編譯出來——也就是有一個c的編譯器,將這個程序轉換成01010101 這樣的指令(往土了說,就是個翻譯機,把人類語言翻譯成1&0)。當我們運行這個程序的時候,電腦會把這些東西放到內存里面,然后逐行的讀取,然后一行行的運算。

好了,我們可以回歸問題了。

3. CPU 對硬件的控制

3.1. 對CPU的誤解

在我學習這些東西之前,我對CPU有一種誤解。我以為在電腦里面,只有CPU是活的。換句話說,整個電腦里面,事無巨細,都是CPU一手操辦的,就像一個勤奮的全棧工程師一樣。

其實,CPU更像是個產品經理。

舉個例子,我們的電腦里面有藍牙。藍牙里面其實也有一個CPU,更確切的說,是個MCU(Micro Control Unit),它負責將無線藍牙信號解碼成數字信號等一系列的操作,而CPU得工作只是協調MCU做相應的工作而已。

給個場景:你打開了聽歌軟件,輸出設備是藍牙耳機。
軟件:哥,給我個耳機唄。
CPU:大妹子,耳機沒插,倒是有個藍牙耳機。
軟件:那哥,你告訴藍牙,俺要在他那里唱歌唄。
CPU:歐了。
CPU轉向藍牙。
CPU:嘿,那個傻大個,說你呢,瞅啥,俺大妹子要你給她干個活。
藍牙:哥,你等會兒。
藍牙:scanning devices.....
藍牙:searching for possible peripherals providing required service.....
藍牙:device BLEX00010EFD010 discovered.....
CPU: 啥玩樣兒啊,讓你干點事兒,咋這么墨跡呢?
藍牙:哥,這事兒費神,您和大妹子多擔待啊。
藍牙:bonding with BLEX00010EFD010.
藍牙:bonding succeeded.
藍牙:Bluetooth Service Linkage Established.
藍牙:哥,成了,叫大妹子開始吧。
CPU:真墨跡。
CPU轉向音樂軟件。
CPU:大妹子,開始吧。
軟件:哥,叫他唱“我是女生,可愛的女生”。
CPU:轉向藍牙。
CPU:傻大個,唱,“我是女生,可愛的女生”。
藍牙:check linkage lost?
藍牙:linkage quality good.
藍牙:signal to noise ratio: -20dB.
藍牙:transmission rate:1 Mb/s.
藍牙:我是女生,可愛的女生。。。。。

所以,在這個實例里面,CPU只是充當了協調&領導的角色。所以一個程序得以實現,其實仰仗於CPU能順暢,有效的發布指令,和得到結果。

而這些信息的通道就叫 BUS,或者叫總線。

3.2. 總線(BUS)
就像上網用網線一樣,電腦內部的通信也依賴於總線。這些總線傳輸數據,指令,地址等一系列的信息,是電腦完成各項計算和操作人物的物理基礎。在計算機內部,每一個硬件設備都以特定的方式與CPU想連。哪怕是外接設備,也可以通過USB,SD卡槽得以連接。

但單單有物理基礎還是不夠的,就像你只有電話線,只有網線,只有天線。

你還需要一些通訊協議。

4.3 通訊協議
誰都有嘴,但並不是誰和誰都可以用嘴高效正確地傳遞信息。(我就發現,一和女孩子講話,我就懵逼。) 而一門共同的語言就像是一個協議,確保雙方所言所聞都能被正確的處理。總線也一樣,也需要有一套既定的協議,得以讓信息能在CPU和MCU之間正常往來。比較常用的協議有SPI, I2C, UART, 等等。這些協議規定了,什么指令表明什么含義,什么時候可以發信息,有幾條數據線,電壓多少,頻率多少,等等。事無巨細,一律都有非常嚴謹統一的規定。

為了不讓看官厭煩,我也不會跟老學究老教授一樣說一堆,如果后面有空間,我可以舉幾個例子,這邊我暫且按下不表。

4. 最終章:總結暨對這個問題的直接回復
當程序員在電腦的終端寫下一行命令,比如說"turn off the bulb"(我們假設有個程序員在CPU上接出一根電線到一個小燈泡上面) 。從打下到執行有如下步驟。

我們的這句話會被編譯成若干個指令,就像(瞎編):
0101 0000(翻譯:CPU把0寫到內存里特定的位置),
00010101(翻譯:通過總線,用I2C,叫一下小燈泡的MCU),

然后小燈泡被叫了一下之后,自己到約定的這個內存為止去讀數字,發現是0,所以輸出0,這個0 就是個低電壓,可以理解成0V,然后0V和5V與邏輯之后,就是0V,所以小燈泡就關了。

當然,我上面也純屬扯淡,這個指令不可能用短短幾行代碼來完成。使用I2C協議本身可能就需要超過一百條代碼:通過吧某些地方的電壓拉低,某些地方的電壓拉高,來完成通信,有點類似黑幫片里面交易雙方互相閃車燈。

今天先寫這些,后面有時間會再補充一些內容。

看官們鼓勵一下把。

-------補充-------

5. 邏輯門的物理實現:MOSFET

有了理論上的邏輯門,現在需要做的,就是着手設計切實可用的邏輯元件。從最開始的陰極管到現在的晶體管(Transistors),在過去的大半個世紀,這些邏輯元件的實現經歷了數次更新迭代。無論在速度,穩定性上,都出現了質的飛躍。

今天,我們就來講一下MOSFET(metal–oxide–semiconductor field-effect transistor,金屬氧化物場效應晶體管),它是現如今電子行業用的最多的邏輯元件,比如說我們常聽到CMOS技術等等,就是基於MOSFET。

但是,在開始之前,我們必須先涉獵枯燥的,玄幻的,又非常重要的半導體理論。

5.1. 硅

一切都要從硅開始說起。

硅,其實並不稀奇。

地球上最多的元素:氧硅鋁鐵。這個我們都會背。

如果說沒有貝爾實驗室和那一群伯樂(我忘記那些科學家的名字了),可能硅還是會很平凡的,作為砂石,存在這個星球上。

硅,基於我非常有限的高中化學知識:四價,共價鍵,非常穩定,不易得電子,不易失電子。

除了穩定,看似沒什么鳥用。但是,當少量的+3/+5價單質(如:Ga/As)被混入硅之后,我們就真的化腐朽為神奇了。

比如說,假如我們把0.1 Mol的As混入了1 Mol的Si之后,因為As為+5價,所以相比於Si,那個多出來的電子非常活躍,容易脫離原子核。這就導致一塊不帶電的混合物里面,有大量的(這里,大量只是相對於一塊Si單質)帶正電的原子核(+5As丟了一個電子)和同等量的游離電子(e)。我們稱這塊混合半導體為n-type(negative)。

到這里其實非常好理解。easy peasy。

同理,我們可以想象把0.1 Mol的Ga混入另外一個1 Mol的Si里面。這時候,那些牛逼的理論物理學家在這時候引入了穴的概念(Holes)。因為Ga特別容易得電子,導致有些Si的電子會被Ga偷取,留下了一些穴,而這些穴,就像+1的電子,也會不停的運動。我們稱這個半導體為p-type(positive)。

然后,當我們把一個p-type 和一塊n-type放在一起的時候,神奇到讓人無法相信的事情發生了。

(我覺得我可能都講不清楚~~~~~~~)

5.2. PN Junction(PN 結)

我們可以自己做一下思想實驗,接觸面兩邊鄰域的電子和穴會互相中和,導致這一塊區域(depletion region)的電子和穴非常稀少,而那些固定的原子核(包括帶+1的As和帶-1的Ga)並不會變化。他們會造成一個穩定的電場,阻止了其他地方的電子和穴涌入。於是一個動態穩定(dynamic equilibrium)形成了,如圖。

為了看官不頭疼,這里我省去若干章節。總而言之,言而總之。到這里,我們就得到了一個二極管。

 

當我們施加一個正向電壓的時候,depletion region會因為電壓的緣故變薄,大量的電子和穴得以穿過,造成很強的電流。而當我們施加一個反向電壓的時候,depletion region會變厚,電流無法通過。

wah lah ~

5.3. 場效應晶體管

有了這個理論,后面要做的就不難了。(Bazinga!寫到這里我已經徹底懵了,我是照着參考書寫的。)

一個MOSFET就長這樣。

為了便於理解它的工作原理,我們可以把它簡化成這樣:

當我們不給Gate這個電壓的時候,我們得到了兩個典型的PN Junction(Drain & Subtract, Subtract & Source),電流是無法流過的。

 

當我們給Gate施加一個正電壓的時候,Gate的上層帶正電,下層則帶了負電。但因為Gate是個不導電的金屬氧化物,所以它的下部會形成一個n type 通道(induced electron inversion layer)--電子可以直接從Source流到Drain。於是,我們得到了一個電流通路。

這就是我們的邏輯開關了。

最后,我們需要了解,MOSFET可以分為兩種,一種叫P-MOS, 一種叫N-MOS。我們上面的圖例其實是NMOS因為整個的載體為電子。很顯然,PMOS的載體就是穴,它的source和drain都是P-type。

在現實的使用中,兩者的區別就是:
High Gate Voltage Low Gate Voltage
PMOS 斷路 通路

NMOS 通路 斷路


 


5.4. CMOS (Complementary MOSFET BALABALA)邏輯電路

 

單個的MOSFET似乎並沒有神力,但當若干個mosfet組合到一起,我們就可以很輕松的得到各種我們想要的邏輯門。



 

 

這個圖例看起來很復雜,但其實是個紙老虎。首先,我們給Vdd通5V電源。

假設兩個輸入都是1, 即5V。對照5.3.的最后的表格
Q1: 通
Q2: 通
Q3: 斷
Q4: 斷 (Q1 和Q2 通導致Q5和Q6的Gate連到了5V,也即高電壓上)
Q5: 通
Q6: 斷
所以,輸出連接到了Vdd,也即5V,也即1.
同理,其他易證。

6. 軟件控制硬件實例:SD CARD
7. I2C協議詳解
8. FPGA 與 ASIC
 
來自


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM