|
看了一些書,沒能完全理解。不理解就只能照抄別人的東西,這個沒意思。于是,拋開所有的書,站在設計者的角度,來自己設計一下。(個人見解啊) 首先,不是說什么I2C總線,而是先確定是由兩條線來實現兩個器件之間的通訊。 第二,因為兩個器件都要有對數據的處理,因此兩個器件都會有微處理器也即你必須將主從器件都當作微處理器來對待,所以,在設計時,必須對兩個器件的端口要一同考慮,對各器件的內部也要考慮處理程序,而不是象現在的教科書上對主器件說得多,而對從器件說得太少。 第三,根據第二條,我們在設計時必須同時考慮到主從器件四個端口的工作,包括時序圖中也應該有四個端口的狀態,而不應該在時序圖中只考慮線上狀態。 第四,就是確定一次傳輸一字節,而且做到雙向傳輸。 以上是在設計總線時的幾個原則,都很重要。其中第二條,關系到總線標準或者說是規格問題,不同的處理方式,就會產生不同的標準,進而關系到這個標準之下的所有的器件的設計及生產標準。 好了,依據以上,我們現在開始設計。 一、傳輸方式設計 設計的第一步,是先確定采用兩條線的方式,能否實現傳輸,以及傳輸的方式也就是標準。這是這個總線的核心,就象發動機的核心機一樣,確定了這個核心之后,才能在這個基礎上完成其它的要求,比如尋址、區分數據與命令。另外,可以實現通訊的傳輸方式可能有多種,你要根據后續功能需要來確定最優方式。 傳輸設計的第一步,是對器件的初始值的確定。其它的初始值這里不考慮,只考慮四個端口的工作方式。我們知道有四種方式,我們可以采取窮舉法,這里先設定四個端口均設置為準雙向方式,這個方式下,每條傳輸線上的值就是兩個端口輸出值的“與”,即兩個端口同時輸出高電平,線上才是高電平,這個很重要,我們知道器件要檢測傳輸線的電平狀態變化的。 我們再確定兩條線的工作分工,這個分工,我們在以下的設計中確定。 啟動信號 然后器件開始工作,第一步當然是主器件要告訴從器件:我準備要向你傳輸了。那就發一個信號吧?我們先看看發一個從低到高的電平,對方能不能感覺到變化:如果對方輸出的是高,那么線上就會從低電平變化為高電平,這個就有變化,能行;如果對方輸出的是低電平,那線上依然是低電平,這個就行不通了。這就確定了一個可行方案:確定兩條線中的一條線來做傳輸啟動信號,初始設置主器件端為低電平,從器件端為高電平。當然,這個不是I2C的標準。我們在后面的設計中可以理解為什么I2C不采用這個方案。 我們再來看看I2C的方案即第二個方案,確定由一條線做啟動,兩端口初始設置均為高電平,主器件發低電平,線上則變為低電平,從器件就檢測到了變化。 前面說過,主從器件均作為微處理器看待,從器件在設計中,在待機時,一是要將此端口設為高電平,二是要不斷檢測這個端口的狀態,一旦檢測到了變化,則立即轉入接收狀態。 這里有個問題,按說另一條線即數據線的狀態對這個啟動是沒有影響的,它兩端的電平是不需要初始化的,但我看現在的程序中都進行了初始化,有必要么?還有現在的程序中開頭就進行了時鐘線的兩端拉高然后再拉低,這個已經在初始化時拉高過,以及每一次傳輸完成后都進行了拉高,有必要再拉高一次么?有興趣的可以實驗驗證一下,如果真是這樣,那程序就可以減減肥了,這也是我們在做程序應用時,從設計角度充分理解其原理的原因。 這里思考一下:從機檢測到也就是接收到信號并完成接收準備工作后,要不要對主器件做一個應答說我準備好了?有沒有必要?I2C是沒有的,這個在I2C里面是對的,但如果做其它的總線設計,則是必須考慮到的。 傳輸字節 首先確定是一次傳輸一個字節即八位,這個沒說的。然后是先高位后低還是先低后高的確定,這個理論上都可以,你自己定就是了。I2C選擇的是從高到低。如果你選擇先低后高,那就不是I2C總線標準了,你自己得另外起個名字。 然后確定用哪條線來傳,這個先確定采用另一條線來專門傳送字節,給這條線起個名字“數據線”。 先傳送第一位,將其值放在數據線上,并告訴從器件可以讀數據了,然后從器件讀,放一位就告訴一次并讓對方讀一次,這個“告訴”的工作,就分給那條“啟動”線了,這個時候我們可以給這條線起個名字叫“時鐘線”。怎么讀?什么時候讀?這個就要考慮在發送數據之前的四個端口的電平初始值設計了。首先數據線接收端口必須輸出高電平,這樣發送端的變化才能直接影響數據線電平的高低。 然后就是時鐘線兩端的初始電平設計。因為從器件要跟著主器件的端口電平變化來區分位數變化,故其端口應輸出為高。主器件理論上在這一步設為高或低是都可以的,考慮到后面的其它工作,I2C確定的是低電平。這里從器件還要做的一件事是不斷檢測時鐘線電平。 初始設置完成了,根據前面的分析,數據第一位在時鐘線低時放在數據線上,穩定后(這就是延時的來由)主器件拉起時鐘線電平以告訴從器件可以讀第一位數據了。從器件在一定時間內讀取,主器件認為在這個時間內已經讀取了數據線上的電平,然后拉低電平,穩定后在數據線上放上第二位,再重復至所有八位傳輸完成。 應答 從器件收完八位數,主器件就停下,需要確認從器件是否收到了這一字節數據,那么從器件就要給個答復。這個信號必須由從器件發出。再次強調在理解這個總線的原理時必須同時考慮從器件。 我們知道在主器件發送數據時,從器件的兩個端口輸出的都是高電平,那么理論上,我們可以讓任一條線上從器件的端口輸出低電平來告訴主器件,這時只需要主器件對應端口輸出高電平就行了,然后主器件對此線的電平進行檢測,如果是低電平,則判斷收到了從器件的應答信號,否則主器件就認為從器件沒能完成這段字節的接收(這個情況主器件就要另外處理了)。 I2C是選擇的哪種方式?自己查。 傳輸結束 這個是主器件的事,它說傳完了,得告訴從器件,也就是說,這個信號,得主器件來發出。 既然是主器件發信號,那從器件的接收端必須設置為高電平輸出。但這時,從器件也有了一個條件,知道主器件已經發完一段數據了,有可能會發終止信號,也有可能繼續發送數據(這種總線設計方案,有沒有繼續發送數據的可能,需要在后面的設計中從理論上論證)。在接收終止信號這點上,從器件與啟動時的準備是有區別的。這種條件上的區別,在總線設計時是必須考慮到的。 做不同的事,就要有不同的信號或者說是對不同狀態的判斷。前面已經用了幾種了,我們得找一種與前不同的狀態。前面放數據位時,是主器件讓時鐘線在低位;應答時,數據線是從器件讓其在低位。那么,我們在終止時,主從器件讓時鐘線在高位,主器件讓數據線在低位(這個時候,從器件端口輸出高與低,有沒有關系,可以再思考一下),是不是跟其它情況有區別?當然有了,就用它了。 以上,完成了主器件向從器件的數據傳輸,包括啟動、字節傳輸、從器件的應答、主器件決定傳輸結束。到此為止,可以說,核心機已經完成了。
形成總線標準 以下,就是驗證這個核心機能否完成其它的功能:
其它說明 兩線方式有很多種,I2C的方式,屬非固定波率方式,也就是說節拍沒有固定時間間隔,甚至節拍沒說要固定一致,就是說你一會快一會慢也是可以滿足要求的。這點,對我們后面的驗證及實踐很重要。 時序圖中一定要有四端口的時序圖,然后才是四端口的時序“與”之后的線上時序圖,不然理解起來真的困難,反正我是被現在的時序圖弄暈了。 四、驗證方法 對I2C驗證的最好方法,當然是用兩片單片機來實現,這種方法,你可以徹底了解這個總線。 第二種簡易方法,不用邏輯分析儀而是很直觀地用LED,就是自己搭建電路,將時鐘線(注意是時鐘線上電平,下數據線同)的狀態送到另外的端口接一個LED,數據線的狀態送到另外八個端口接LED,你可以延時設定每過2秒送一位數據,這樣你連從器件的應答都可以同步觀測到了,結束也可以觀測到了,起始狀況、數據傳輸各位是否正確等等,可以立即發現你的程序的問題,比邏輯分析儀還直觀迅速。這種方式,也可以延伸到固定波特率傳輸,當然不能照抄。 PS1:實現一種功能,辦法是很多的,“標準”只是辦法之中的一種,它不能在你心中成為對你的約束,否則就是對人類智能的侮辱。 PS2:學習別人的方法,才是人才的做法,不然就是機器。 PS3:實在不想寫了,交差。 PS4:信了你的邪,這就三千多字了?我已經在偷懶啊,破底線了!!! PS5:有興趣將后面論證的東西補充一下,就是一篇不錯的論文。
|