一、基本概念
RAM(Random Access Memory)的全名為隨機存取記憶體,它相當於PC機上的移動存儲,用來存儲和保存數據的。它在任何時候都可以讀寫,RAM
通常是作為操作系統或其他正在運行程序的臨時存儲介質,它的一切都是最好的,唯一缺點斷電一切東西都沒有了。一般情況下,現在移動設備也多了,我
們叫它內存,更通常的叫運行內存。還有一個熟悉的詞DDR2或DDR3,後面還會學習到的。
ROM(Read Only Memory)的全名為唯讀記憶體,它相當於PC機上的硬盤,用來存儲和保存數據。ROM數據不能隨意更新,但是在任何時候都可以讀
取。即使是斷電,ROM也能夠保留數據。但是資料一但寫入後只能用特殊方法或根本無法更改,但這麼久了ROM已經有了很大的發展,不再是最初的摸樣
了。rom最初不能編程,出廠什麼內容就永遠什麼內容,不靈活。後來出現了prom,可以自己寫入一次,要是寫錯了,只能換一片,自認倒黴。人類文明不
斷進步,終於出現了可多次擦除寫入的EPROM,每次擦除要把芯片拿到紫外線上照一下,想一下你往單片機上下了一個程序之後發現有個地方需要加一句
話,為此你要把單片機放紫外燈下照半小時,然後才能再下一次,這麼折騰一天也改不了幾次。歷史的車輪不斷前進,偉大的EEPROM出現了,拯救了一
大批程序員,終於可以隨意的修改rom中的內容了,這一段話就説出了ROM的發展歷程。
狹義的EEPROM:這種rom的特點是可以隨機訪問和修改任何一個字節,可以往每個bit中寫入0或者1。這是最傳統的一種EEPROM,掉電後數據不丟
失,可以保存100年,可以擦寫100w次。具有較高的可靠性,但是電路複雜/成本也高。它的改寫是由高電壓或者由控制端的邏輯電平來完成的。因此目前的
EEPROM都是幾十千字節到幾百千字節的,絕少有超過512K的。我們也就發現了EEPROM的確可以實現隨意讀寫,EEPROM的全稱是“電可擦除可編程只讀
存儲器”,即Electrically Erasable Programmable Read-Only Memory。可介紹的這兩種都不存在大容量並且也十分昂貴,那我們平時見到的幾十G的存儲設備是
什麼?flash就應運而生了。flash屬於廣義的EEPROM,因為它也是電擦除的rom。但是為了區別於一般的按字節為單位的擦寫的EEPROM,我們都叫它
flash。flash做的改進就是擦除時不再以字節為單位,而是以塊為單位,一次簡化了電路,數據密度更高,降低了成本。上M的rom一般都是flash。
ROM的應用
flash分為nor flash和nand flash。nor flash數據線和地址線分開,可以實現ram一樣的隨機尋址功能,可以讀取任何一個字節。但是擦除仍要按塊來擦。
nand flash同樣是按塊擦除,但是數據線和地址線複用,不能利用地址線隨機尋址。讀取只能按頁來讀取。NOR Flash的讀取,用户可以直接運行裝載在NOR
FLASH裏面的代碼。NAND Flash沒有采取內存RAM的隨機讀取技術,它的讀取是以一次讀取一塊的形式來進行的,通常是一次讀取512個字節,採用這種
技術的Flash比較廉價。用户不能直接運行NAND Flash上的代碼,因此好多使用NAND Flash的開發板除了使用NAND Flah以外,還作上了一塊小的NOR
Flash來運行啓動代碼。nandflash引腳上覆用,因此讀取速度比nor flash慢一點,但是擦除和寫入速度比nor flash快很多。nand flash內部電路更簡單,因此數
據密度大,體積小,成本也低。因此大容量的flash都是nand型的。小容量的2~12M的flash多是nor型的。nor flash可以進行字節尋址,所以程序可以在nor
flash中運行。嵌入式系統多用一個小容量的nor flash存儲引導代碼,用一個大容量的nand flash存放文件系統和內核。
二、I2C總線
這個在我轉載的一篇文章裏面有很詳細的描述,就不在提及了。有一個問題是無論UART還是I2C都是串行按位傳輸數據,區別在哪?還有SPI傳輸,下面
分別總結一下三者的特點。
UART:兩線,一根發送一根接收,可以全雙工通信,數據異步傳輸,對雙方的時序要求比較嚴格,在多機通信上面用的最多。按照標準波特率完成雙
向通訊,速度慢,之前提到採集一位數據就需要16個時鐘週期,適合遠距離傳輸,比如IEEE488定義並行通行狀態時,規定設備線總常不得超過20米,並且
任意兩個設備間的長度不得超過2米;而對於串口而言,長度可達1200米。UART需要固定的波特率,就是説兩位數據的間隔要相等,
I2C:能用於替代標準的並行總線,能連接的各種集成電路和功能模塊。I2C是多主控總線,所以任何一個設備都能像主控器一樣工作,並控制總線。
總線上每一個設備都有一個獨一無二的地址,根據設備它們自己的能力,它們可以作為發射器或接收器工作。多路微控制器能在同一個I2C總線上共存,當
然在任何時間點上只能有一個主控。一般用於同一板卡上芯片之間的通信,較少用於遠距離通信。
SPI:SPI接口和UART相比,多了一條同步時鐘線,對通信雙方的時序要求不嚴格不同設備之間可以很容易結合,而且通信速度非常快。一般用在產品
內部元件之間的高速數據通信上面,如大容量存儲器flash等。高速同步串行口,3~4線接口,收發獨立、可同步進行。
I2C總線是由PHILIPS公司開發的兩線式串行總線,多用於連接微處理器及其外圍設備。I2C總線的主要特點是接口方式簡單,兩條線可以掛多個參與通
信的器件,即多機模式,而且任何一個器件都可以作為主機,當然同一時刻只能一個主機。
從原理上來講,UART屬於異步通信,比如電腦發送給單片機,電腦只負責把數據通過TXD發送出來即可,接收數據是單片機自己的事情。而I2C屬於同步
通信,SCL時鐘線負責收發雙方的時鐘節拍,SDA數據線負責傳輸數據。I2C的發送方和接收方都以SCL這個時鐘節拍為基準進行數據的發送和接收。
從應用上來講,UART通信多用於板間通信,比如單片機和電腦,這個設備和另外一個設備之間的通信。而I2C多用於板內通信,比如單片機和我們本章要
學的EEPROM之間的通信。
在硬件上,I2C總線是由時鐘總線SCL和數據總線SDA兩條線構成,連接到總線上的所有的器件的SCL都連到一起,所有的SDA都連到一起。I2C總
線是開漏引腳並聯的結構,因此我們外部要添加上拉電阻。對於開漏電路外部加上拉電阻的話,那就組成了線“與”的關係。總線上線“與”的關係,那所有接
入的器件保持高電平,這條線才是高電平。而任意一個器件輸出一個低電平,那這條線就會保持低電平,因此可以做到任何一個器件都可以拉低電平,也就
是任何一個器件都可以作為主機,如圖14-1所示,我們添加了R63和R64兩個上拉電阻。
圖14-1 I2C總線的上拉電阻
雖然説任何一個設備都可以作為主機,但絕大多數情況下我們都是用微處理器,也就是我們的單片機來做主機,而總線上掛的多個器件,每一個都像電話機
一樣有自己唯一的地址,在信息傳輸的過程中,通過這唯一的地址可以正常識別到屬於自己的信息,在我們的KST-51開發板上,就掛接了2個I2C設備,一
個是24C02,一個是PCF8591。
我們在學習UART串行通信的時候,知道了我們的通信流程分為起始位、數據位、停止位這三部分,同理在I2C中也有起始信號、數據傳輸和停止信號,如
圖14-2所示。
圖14-2 I2C時序流程圖
從圖上可以看出來,I2C和UART時序流程有相似性,也有一定的區別。UART每個字節中,都有一個起始位,8個數據位和1位停止位。而I2C分為
起始信號,數據傳輸部分,最後是停止信號。其中數據傳輸部分,可以一次通信過程傳輸很多個字節,字節數是不受限制的,而每個字節的數據最後也跟了
一位,這一位叫做應答位,通常用ACK表示,有點類似於UART的停止位。
下面我們一部分一部分的把I2C通信時序進行剖析。之前我們學過了UART,所以學習I2C的過程我儘量拿UART來作為對比,這樣有助於更好的理解。
但是有一點大家要理解清楚,就是UART通信雖然我們用了TXD和RXD兩根線,但是實際一次通信,1條線就可以完成,2條線是把發送和接收分開而已,而
I2C每次通信,不管是發送還是接收,必須2條線都參與工作才能完成,為了更方便的看出來每一位的傳輸流程,我們把圖14-2改進成圖14-3。
圖14-3 I2C通信流程解析
起始信號:UART通信是從一直持續的高電平出現一個低電平標誌起始位;而I2C通信的起始信號的定義是SCL為高電平期間,SDA由高電平向低電平變
化產生一個下降沿,表示起始信號,如圖14-3中的start部分所示。
數據傳輸:首先,UART是低位在前,高位在後;而I2C通信是高位在前,低位在後。第二,UART通信數據位是固定長度,波特率分之一,一位一位固
定時間發送完畢就可以了。而I2C沒有固定波特率,但是有時序的要求,要求當SCL在低電平的時候,SDA允許變化,也就是説,發送方必須先保持SCL是
低電平,才可以改變數據線SDA,輸出要發送的當前數據的一位;而當SCL在高電平的時候,SDA絕對不可以變化,因為這個時候,接收方要來讀取當前
SDA的電平信號是0還是1,因此要保證SDA的穩定不變化,如圖14-3中的每一位數據的變化,都是在SCL的低電平位置。8為數據位後邊跟着的是一位響應
位,響應位我們後邊還要具體介紹。
停止信號:UART通信的停止位是一位固定的高電平信號;而I2C通信停止信號的定義是SCL為高電平期間,SDA由低電平向高電平變化產生一個上升沿,表
示結束信號,如圖14-3中的stop部分所示。
14.2 I2C尋址模式
上一節介紹的是I2C每一位信號的時序流程,而I2C通信在字節級的傳輸中,也有固定的時序要求。I2C通信的起始信號(Start)後,首先要發送一個從
機的地址,這個地址一共有7位,緊跟着的第8位是數據方向位(R/W),‘0’表示接下來要發送數據(寫),‘1’表示接下來是請求數據(讀)。
我們知道,打電話的時候,當撥通電話,接聽方撿起電話肯定要回一個“喂”,這就是告訴撥電話的人,這邊有人了。同理,這個第九位ACK實際上起到的就
是這樣一個作用。當我們發送完了這7位地址和1位方向位,如果我們發送的這個地址確實存在,那麼這個地址的器件應該回應一個ACK‘0’,如果不存在,
就沒“人”迴應ACK。