版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、<p><b> 目錄</b></p><p><b> 1 設計要求2</b></p><p><b> 2 設計目的2</b></p><p> 3 器件EEPROM的介紹3</p><p> 3.1 EEPROM簡介3</p>&
2、lt;p> 3.2 EEPROM24XX系列功能概述3</p><p> 4 IIC協(xié)議的介紹3</p><p> 4.1 IIC協(xié)議總線特征3</p><p> 4.2 IIC協(xié)議工作原理3</p><p> 4.3 IIC協(xié)議總線基本狀態(tài)4</p><p> 4.4 尋址約定5<
3、/p><p> 5 EEPROM讀寫功能實現(xiàn)5</p><p><b> 5.1寫操作5</b></p><p> 5.1.1 字節(jié)寫操作6</p><p> 5.1.2 頁寫入操作6</p><p> 5.2 確認查詢7</p><p><b>
4、 5.3 讀操作7</b></p><p> 5.3.1 當前地址的讀操作8</p><p> 5.3.2 隨機讀操作8</p><p> 5.3.3 連續(xù)讀操作9</p><p> 6 具體設計過程10</p><p> 6.1 程序流程設計10</p><p&
5、gt; 6.2執(zhí)行結果13</p><p> 6.3 系統(tǒng)組成模塊結構及功能15</p><p> 6.3.1 函數(shù)定義15</p><p> 6.3.2 主函數(shù)設計17</p><p> 6.3.3 源程序19</p><p> 7 設計心得體會27</p><p>&
6、lt;b> 8 參考文獻28</b></p><p> IIC總線式EEPROM存儲器應用設計</p><p><b> 1 設計要求</b></p><p> 利用51單片機和IIC總線式EEPROM芯片24C02進行存儲器設計。按下KEYWRITE1鍵,向24C02存儲器寫入數(shù)據(jù)1和2;按下KEYWRITE2鍵,
7、向24C02存儲器寫入數(shù)據(jù)3和4;按下KEYREAD鍵,從24C02存儲器讀出剛寫入的數(shù)據(jù)數(shù)據(jù);寫入數(shù)據(jù)顯示在左兩位,讀出數(shù)據(jù)顯示在右兩位。</p><p><b> 如圖1.1所示。</b></p><p> 圖1.1 系統(tǒng)仿真運行圖</p><p><b> 2 設計目的</b></p><p
8、> 通過設計,了解IIC協(xié)議的基本原理,并對EEPROM讀寫功能的實現(xiàn)有個系統(tǒng)的概念,對其實現(xiàn)過程比較清楚。同時,在設計中,鞏固我們所學的理論知識。</p><p> 3 器件EEPROM的介紹</p><p> 3.1 EEPROM簡介</p><p> EEPROM (Electrically Erasable Programmable Read-
9、Only Memory),電可擦可編程只讀存儲器--一種掉電后數(shù)據(jù)不丟失的存儲芯片。 EEPROM 可以在電腦上或專用設備上擦除已有信息,重新編程。 EEPROM即電可擦寫可編程只讀存儲器,其可通過高于普通電壓的作用來擦除和重編程(重寫)。不像EPROM芯片,EEPROM不需從計算機中取出即可修改。在一個EEPROM中,當計算機在使用的時候是可頻繁地重編程的,EEPROM的壽命是一個很重要的設計考慮參數(shù)。EEPROM的一種特殊形式是閃存
10、,其應用通常是個人電腦中的電壓來擦寫和重編程。DRAM斷電后存在其中的數(shù)據(jù)會丟失,而EEPROM斷電后存在其中的數(shù)據(jù)不會丟失。 另外,EEPROM可以清除存儲數(shù)據(jù)和再編程。 </p><p> 3.2 EEPROM24XX系列功能概述</p><p> 1)每一個24XX 器件都支持雙向。</p><p> 2)線數(shù)據(jù)傳輸協(xié)議:如果器件被定義為發(fā)送器,則該器件
11、發(fā)送數(shù)據(jù)到總線;如果器件被定義為接收器,則該器件接收來自總線的數(shù)據(jù)。總線由主器件控制, 24XX 作為從器件。主器件提供串行時鐘(SCL),控制總線訪問和產生起始和停止條件。主器件和從器件皆可作為發(fā)送器或接收器,但必須由主器件決定采取何種工作模式。</p><p> 4 IIC協(xié)議的介紹</p><p> 4.1 IIC協(xié)議總線特征</p><p><b&
12、gt; 總線協(xié)議定義如下:</b></p><p> ? 只有在總線空閑時才可啟動數(shù)據(jù)傳輸。</p><p> ? 數(shù)據(jù)傳輸期間,在時鐘線為高電平時,無論何時,數(shù)據(jù)線都必須保持穩(wěn)定。在時鐘線為高電平時改變數(shù)據(jù)線將視為起始或停止條件。</p><p> IIC總線最主要的優(yōu)點是其簡單性和有效性。由于接口直接在組件之上,因此I2C總線占用的空間非常小
13、,減少了電路板的空間和芯片管腳的數(shù)量,降低了互聯(lián)成本??偩€的長度可高達25英尺,并且能夠以10Kbps的最大傳輸速率支持40個組件。I2C總線的另一個優(yōu)點是,它支持多主控,其中任何能夠進行發(fā)送和接收的設備都可以成為主總線。一個主控能夠控制信號的傳輸和時鐘頻率。當然,在任何時間點上只能有一個主控。</p><p> 4.2 IIC協(xié)議工作原理 </p><p> 以啟動信號ST
14、ART來掌管總線,以停止信號STOP來釋放總線;每次通訊以START開始,以STOP結束;啟動信號START后緊接著發(fā)送一個地址字節(jié),其中7位為被控器件的地址碼,一位為讀/寫控制位R/W,R. /W位為0表示由主控向被控器件寫數(shù)據(jù),R/W為1表示由主控向被控器件讀數(shù)據(jù);當被控器件檢測到收到的地址與自己的地址相同時,在第9個時鐘期間反饋應答信號;每個數(shù)據(jù)字節(jié)在傳送時都是高位(MSB)在前。</p><p> 4.
15、3 IIC協(xié)議總線基本狀態(tài)</p><p><b> 1)總線空閑(A)</b></p><p> 數(shù)據(jù)線和時鐘線同時為高電平。</p><p> 2)啟動數(shù)據(jù)傳輸(B)</p><p> 時鐘(SCL)為高電平時,SDA 從高電平變?yōu)榈碗娖奖硎酒鹗紬l件產生。起始條件必須先于所有的命令產生。</p>
16、<p> 3)停止數(shù)據(jù)傳輸(C)</p><p> 時鐘(SCL)為高電平時, SDA 從低電平變?yōu)楦唠娖奖硎就V箺l件產生。所有操作都必須以停止條件結束。</p><p> 4)數(shù)據(jù)傳送/數(shù)據(jù)有效 (D)</p><p> 數(shù)據(jù)線的狀態(tài)表明數(shù)據(jù)何時有效。在起始條件之后,數(shù)據(jù)線在時鐘處于高電平期間保持穩(wěn)定。必須在時鐘信號為低電平期間改變數(shù)據(jù)線。一個
17、數(shù)據(jù)位對應一個時鐘脈沖。數(shù)據(jù)的每次傳輸以起始條件開始,以停止條件結束。在起始條件和停止條件之間傳輸?shù)臄?shù)據(jù)字節(jié)數(shù)目由主器件決定</p><p> 5)確認信號(ACK)</p><p> 每一個被尋址的接收器在接收到每一字節(jié)數(shù)據(jù)后,應發(fā)送一個確認位。主器件必須提供一個額外的時鐘以傳輸確認位。在確認時鐘脈沖內,器件確認須拉低 SDA 線。在確認時鐘的高電平期間,SDA線以這種方式保持穩(wěn)定的
18、低電平。當然,還必須考慮建立時間和保持時間。讀操作期間,主器件必須發(fā)送一個結束信號給從器件,而不是在從器件輸出最后一個數(shù)據(jù)字節(jié)之后產生一個確認位。這種情況下,從器件(24XX)將釋放數(shù)據(jù)線為高電平,從而使主器件能夠產生停止條件。</p><p> 6)無應答信號(NACK)</p><p> 在時鐘的第9個脈沖期間發(fā)送器釋放數(shù)據(jù)總線,接收器不拉低數(shù)據(jù)總線表示一個 NACK,NACK有兩
19、種用途:a、一般表示接收器未成功接收數(shù)據(jù)字節(jié);b、當接收器是主控器時,它收到最后一個字節(jié)后,應發(fā)送一個NACK信號,以通知被控發(fā)送器結束數(shù)據(jù)發(fā)送,并釋放總線,以便主控接收器發(fā)送一個停止信號STOP。</p><p><b> 4.4 尋址約定</b></p><p> 1)不帶功能性地址輸入引腳的器件尋址</p><p> 在起始條件之后
20、,從主器件接收的第一個字節(jié)是控制字節(jié)。控制字節(jié)以4 位控制碼開始。對于24XX器件,這4 位設置為 ‘1010’以便進行讀/寫操作。隨后的3 位為存儲塊選擇位 (B2、 B1、 B0)。主器件用它們來選擇將要訪問的大小為 256 字的存儲塊。實際上,這些位是字地址中3 個最高有效位。控制字節(jié)的最后一位定義將要進行的操作。 設置為‘1’,選擇讀操作;設置為‘0’,選擇寫操作。在起始條件發(fā)生后,24XX 器件始終監(jiān)視SDA 總線。一旦接收到
21、 ‘1010’碼、存儲塊選擇位和 R/W 位,從器件輸出確認信號到 SDA 總線。在確認信號之后傳輸?shù)刂纷止?jié)。</p><p> 2)帶功能性地址輸入引腳的器件尋址</p><p> 在起始條件之后,從主器件接收的第一個字節(jié)是控制字節(jié)??刂谱止?jié)以4 位控制碼開始。在24XX</p><p> 器件,這4 位設置為 ‘1010’以便進行讀/寫操作。隨后的3 位
22、為片選位(A2、 A1、 A0)。片選位的不同組合允許在同一條總線上使用的24XX 器件達八個,并用于選擇訪問哪一個器件??刂萍拇嫫髦械钠x位必須與相應器件引腳A2、 A1 和 A0上的邏輯電平保持一致。實際上這些位是字地址中3 個最高有效位。起始條件發(fā)生之后,24XX 器件始終監(jiān)視SDA 總線。一旦接收到 ‘1010’碼、器件片選位和 R/W 位,從器件輸出確認信號到 SDA 總線。在確認信號之后傳輸?shù)刂纷止?jié)。</p>
23、<p> 5 EEPROM讀寫功能實現(xiàn)</p><p><b> 5.1寫操作</b></p><p><b> 寫數(shù)據(jù)過程:</b></p><p> 1)主控在檢測到總線空閑的狀況下,首先發(fā)送一個START信號掌管總線;</p><p> 2)發(fā)送一個控制字節(jié)(包括7位器件地
24、址碼和一位R/W);(某些器件的地址字節(jié)可能帶有其他功能)</p><p> 3)當被控器件檢測到主控發(fā)送的地址與自己的地址相同時發(fā)送一個應答信號(ACK);</p><p> 4)主控收到ACK后開始發(fā)送第一個數(shù)據(jù)字節(jié);</p><p> 5)被控器收到數(shù)據(jù)字節(jié)后發(fā)送一個ACK表示繼續(xù)傳送數(shù)據(jù),發(fā)送NACK表示傳送數(shù)據(jù)結束;</p><p
25、> 6)主控發(fā)送完全部數(shù)據(jù)后,發(fā)送一個停止位STOP,結束整個通訊并且釋放總線;寫數(shù)據(jù)時序。</p><p> 5.1.1 字節(jié)寫操作</p><p> 字節(jié)寫操作以來自于主器件的起始位開始, 4 位控制碼緊隨其后(圖3)。接下來的3 位是存儲塊尋址位(不帶地址輸入引腳的器件)或片選位(帶地址輸入引腳的器件)。然后主發(fā)送器將R/W 位(該位為邏輯低電平)發(fā)送到總線。從器件在第九
26、個時鐘周期產生一個確認位,主器件發(fā)送的第二個字節(jié)是地址字節(jié)或高位地址字節(jié)。24XX 器件會對每一個地址字節(jié)作出確認,并把地址位鎖存進器件內部的地址計數(shù)器。對于24XX00 器件,只使用地址字節(jié)的低4 位。高4 位可為任意值。送出最后一個地址字節(jié)后, 24XX 器件發(fā)出確認信號ACK。主器件在接收到該確認信號后即發(fā)送數(shù)據(jù)字,該數(shù)據(jù)字將被寫入已尋址的存儲器位置。24XX 器件再次發(fā)出確認信號,之后主器件產生停止條件,啟動內部寫周期。如果在
27、WP 引腳保持高電平時進行存儲器寫操作,器件會確認命令,但不會啟動寫周期,也不會寫入數(shù)據(jù),而會立即接受新的命令。寫命令為一個字節(jié),在發(fā)送寫命令后,內部地址計數(shù)器增加,指向下一個要尋址的位置。寫周期期間, 24XX 不會對命令進行確認。</p><p> ?。ㄗⅲ簣D中控制字節(jié)指器件地址碼和讀寫控制位;地址字節(jié)指器件內部的儲存器地址。下同。)</p><p> 5.1.2 頁寫入操作<
28、/p><p> 頁寫入操作時,被控器件完成一個寫字節(jié)操作后內部地址計數(shù)器自動加一。寫控制字節(jié)、字地址字節(jié)和首個數(shù)據(jù)字節(jié)以和寫操作字節(jié)基本相同的方式發(fā)送給 24XX 器件(見圖5.1 )。不同的是,主器件發(fā)送的是多至一整頁的數(shù)據(jù)字節(jié)(1),而不是停止條件,這些數(shù)據(jù)字節(jié)臨時存儲在片內頁緩沖器中。在主器件發(fā)送停止條件之后,這些數(shù)據(jù)將被寫入存儲器。每接收一個字,內部地址計數(shù)器加一。如果在停止條件產生前,主器件有超出一頁的數(shù)
29、據(jù)要發(fā)送,地址計數(shù)器將會翻轉,先前寫入的數(shù)據(jù)將被覆蓋。對于字節(jié)寫操作,一旦接收到停止條件,內部寫周期開始。在寫周期期間, 24XX 器件不會對命令作出確認。頁寫入操作在一頁內可以寫入任意個數(shù)的數(shù)據(jù)(最多為一頁),并且可以在此頁中的任意地址開始寫入。被尋址的數(shù)據(jù)只能在該頁內變動。如果在 WP 引腳保持高電平時進行存儲器寫操作,器件會確認命令,但不會啟動寫周期,也不會寫入數(shù)據(jù),而是立即接受新的命令。</p><p>
30、<b> 5.2 確認查詢</b></p><p> 在寫周期期間器件不會對命令作出確認,這可用來確定寫周期何時完成(這個特點可以優(yōu)化總線的吞吐量,使其最大化) 。如果主器件已經發(fā)出寫命令的停止條件,器件將啟動內部定時寫周期。可以隨時進行確認查詢。這包括在主器件發(fā)出起始條件后,再發(fā)送用于寫命令(R/W = 0)的控制字節(jié)。如果器件仍處在寫周期內,則不返回確認信號。一旦沒有返回確認信號,起
31、始位和控制字節(jié)必須重新發(fā)送。如果寫周期結束,器件返回確認信號,主器件就可以執(zhí)行下一個讀或寫命令。參見流程圖( 圖 6.3)。</p><p><b> 5.3 讀操作</b></p><p><b> 讀數(shù)據(jù)過程:</b></p><p> 1)主控在檢測到總線空閑的狀況下,首先發(fā)送一個START信號掌管總線;2)
32、發(fā)送一個控制字節(jié)(包括7位器件地址碼和一位R/W);(某些器件的地址字節(jié)可能帶有其他功能)</p><p> 3)當被控器件檢測到主控發(fā)送的地址與自己的地址相同時發(fā)送一個應答信號(ACK);4)主控收到ACK后釋放數(shù)據(jù)總線,開始接收第一個數(shù)據(jù)字節(jié);5)主控收到數(shù)據(jù)后發(fā)送ACK表示繼續(xù)傳送數(shù)據(jù),發(fā)送NACK表示傳送數(shù)據(jù)結束;6)主控發(fā)送完全部數(shù)據(jù)后,發(fā)送一個停止位STOP,結束整個通訊并且釋放總線;<
33、/p><p> 除了控制寄存器的R/W 位設置為‘1’外,讀操作與寫操作基本相同。有三種基本的讀操作:當前地址的讀操作、隨機讀操作和連續(xù)讀操作 。</p><p> 5.3.1 當前地址的讀操作</p><p> 當前地址的讀操作,被控器件內部儲存器地址計數(shù)器保留最后一次訪問的地址。24XX 內置一個自動加‘1’地址計數(shù)器,該計數(shù)器保留最后一次訪問的地址。因此,如
34、果先前對地址‘n’(n 為任意合法地址)進行讀或寫操作,則下一條讀操作命令將可能從地址n+1 訪問數(shù)據(jù)。接收到R/W 位設置為‘1’的控制字節(jié)后,24XX 發(fā)出確認信號,并發(fā)送 8 位數(shù)據(jù)字節(jié)。主器件不會對數(shù)據(jù)傳輸作出確認,但會產生停止條件,24XX 即停止數(shù)據(jù)發(fā)送(圖5.3)</p><p> 5.3.2 隨機讀操作</p><p> 隨機讀操作允許主器件以隨機方式訪問任意存儲器,主
35、控器件先發(fā)寫命令,然后發(fā)要讀的地址,然后發(fā)讀命令。執(zhí)行該指令前必須先設置地址字節(jié)。作為寫操作的一部分,通過發(fā)送字節(jié)地址給24XX 來完成地址字節(jié)的設置(R/W 設置為‘0’)。字節(jié)地址發(fā)送完后,主器件一接收到確認信號即產生起始條件。內部地址計數(shù)器設置完之后寫操作即被終止。主器件再次發(fā)送控制字節(jié),而該字節(jié)中 R/W 位設置為‘1’。之后24XX 會發(fā)出確認信號, 并發(fā)送8 位數(shù)據(jù)字節(jié)。主器件不會對數(shù)據(jù)傳輸作出確認,但會產生停止條件, 24
36、XX 即停止數(shù)據(jù)發(fā)送(圖5.4)。在隨機讀取命令之后,內部地址計數(shù)器加1 指向下一條地址。</p><p> 5.3.3 連續(xù)讀操作</p><p> 連續(xù)讀操作的起動過程和隨機讀操作相同,只是在24XX發(fā)送完第一個數(shù)據(jù)字節(jié)后,主器件發(fā)出確認信號,而在隨機讀操作中發(fā)送的是停止條件,在連續(xù)讀操作時被控器件完成一個讀字節(jié)操作后內部地址計數(shù)器自動加一。確認信號指示24XX 器件發(fā)送下一個連續(xù)
37、地址的數(shù)據(jù)字節(jié)(圖5.5)。在24器件向主器件發(fā)送完最后一個字節(jié)后,主器件不會產生確認信號,而是產生停止條件。為了可以進行連續(xù)讀操作, 24XX 器件內置了一個地址指針,在每次操作完成后該指針加1。地址指針允許一次操作連續(xù)讀取整個存儲器的內容。在達到最后一個地址字節(jié)后,地址指針將翻轉到地址 0x00。</p><p><b> 6 具體設計過程</b></p><p&g
38、t; 6.1 程序流程設計</p><p><b> 6.2執(zhí)行結果</b></p><p> ?。?)按下KEYWRITE1鍵,向24C02存儲器寫入數(shù)據(jù)1和2.寫入成功讀出11;寫入失敗讀出00。寫入數(shù)據(jù)顯示在左兩位,讀出數(shù)據(jù)顯示在右兩位。</p><p> 寫入成功如圖6.4所示:</p><p> 圖6.
39、4寫入數(shù)據(jù)1,2成功,讀出11</p><p> ?。?)按下KEYWRITE2鍵,向24C02存儲器寫入數(shù)據(jù)3和4;寫入成功讀出11;寫入失敗讀出00。寫入數(shù)據(jù)顯示在左兩位,讀出數(shù)據(jù)顯示在右兩位。</p><p> 寫入成功如圖6.5:</p><p> 圖6.5 寫入數(shù)據(jù)3,4成功,讀出11</p><p> (3)按下KEYREA
40、D鍵,從24C02存儲器讀出剛寫入的數(shù)據(jù)。</p><p> 成功讀取數(shù)據(jù)如圖6.6:</p><p> 圖6.6 讀出寫入的數(shù)據(jù)</p><p> 6.3 系統(tǒng)組成模塊結構及功能</p><p> 6.3.1 函數(shù)定義</p><p> 函數(shù)定義是對各個基礎函數(shù)的定義,并且設置需要運用的信息,便于調用<
41、;/p><p> #include<reg51.h></p><p> #include<intrins.h></p><p> #define uint unsigned int</p><p> #define uchar unsigned char</p><p> sbit Key
42、Write1=P1^0;//按鍵定義</p><p> sbit KeyWrite2=P1^1;</p><p> sbit KeyRead=P1^2;</p><p> #define WriteDeviceAddress 0xa0 //寫驅動地址指令</p><p> #define ReadDeviceAddress 0xa
43、1 //讀驅動地址指令</p><p> Start_Cond(); //寫開始信號</p><p> Write8Bit(WriteDeviceAddress); //寫驅動地址</p><p> Write8Bit(Addr); //寫從EEPROM中讀的開始地址</p><p> Start_Cond();
44、//寫開始信號</p><p> Write8Bit(ReadDeviceAddress); //寫讀數(shù)據(jù)指令</p><p> *nContent=Read8Bit(); //讀出內容</p><p> nContent++; //指針加1</p><p> Ack(); //發(fā)確認信號</p><
45、p> *nContent=Read8Bit(); //讀一字節(jié) </p><p> NoAck(); //沒有確認信號</p><p> Stop_Cond(); //發(fā)停止信號</p><p> return(0); //返回</p><p> Start_Cond(); //寫開始信號<
46、/p><p> Write8Bit(WriteDeviceAddress); //寫驅動地址</p><p> Write8Bit(Addr); //寫從EEPROM中寫的開始地址 </p><p> if(Addr%8==0) //每頁8字節(jié) //換頁</p><p> Stop_Cond(); //發(fā)停止信號&
47、lt;/p><p> uchar IICReadData[4];//AT24C02讀數(shù)據(jù)數(shù)組</p><p> uchar IICWriteData[4];//AT24C02寫數(shù)據(jù)數(shù)組</p><p> _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();/
48、/1個機器周期=12個時鐘周期,fosc=12MHz時,1個機器周期=1us</p><p> Init_Flash(0); //將AT24C02的第0頁初始化為FF</p><p> P2=0x1;// p2.0有效,選通數(shù)碼管左數(shù)第1位。</p><p> P0=table[showdata[0]];//顯示數(shù)據(jù)</p><p&g
49、t; P2=0x2;// p2.0有效,選通數(shù)碼管左數(shù)第2位。</p><p> P0=table[showdata[1]];//顯示數(shù)據(jù)</p><p> P2=0x4;// p2.0有效,選通數(shù)碼管左數(shù)第3位。</p><p> P0=table[showdata[2]];//顯示數(shù)據(jù)</p><p> P2=0x8;// p2
50、.3有效,選通數(shù)碼管左數(shù)第4位。</p><p> P0=table[showdata[3]];//顯示數(shù)據(jù)</p><p> if(KeyWrite1==0)//如果KeyWrite1鍵按下,則將'1'寫入2402的'0x80'地址中</p><p> Write_Flash(IICWriteData,0,2); //將da
51、t數(shù)組中的數(shù)據(jù)寫入AT24C02中地址從0開始</p><p> if(KeyWrite2==0)//如果KeyWrite2鍵按下,則將'2'寫入2402的'0x80'地址中</p><p> Write_Flash(IICWriteData,2,2); //將dat數(shù)組中的數(shù)據(jù)寫入AT24C02中地址從2開始</p><p>
52、 if(KeyRead==0)//如果KeyRead鍵按下,讀出2402的'0x80'地址中的數(shù)據(jù)</p><p> Read_Flash(IICReadData,0,4); //讀出AT24C02中從地址1開始依次往后16個字節(jié)放入dat數(shù)組中</p><p> 6.3.2 主函數(shù)設計</p><p> 主函數(shù)是程序的主流程,首先定義使用
53、到的常數(shù)、全局變量及函數(shù)原型說明,然后初始化圖形系統(tǒng),調用函數(shù) Write_One_Byte(char addr,char thedata) 完成字節(jié)寫入,調用Write_A_Page(char *buffer,char addr) 完成頁寫入,調用 Read_One_Byte(char addr) 完成隨機讀,調用Read_N_Bytes(char *buffer,char n,char addr) /*完成順序讀*/。</p&
54、gt;<p> void main()</p><p><b> {</b></p><p> Init_Flash(0); //將AT24C02的第0頁初始化為FF</p><p><b> while(1){</b></p><p> P2=0x1;// p2.0有
55、效,選通數(shù)碼管左數(shù)第1位。</p><p> P0=table[showdata[0]];//顯示數(shù)據(jù)</p><p> delay_ms(10);</p><p> P2=0x2;// p2.0有效,選通數(shù)碼管左數(shù)第2位。</p><p> P0=table[showdata[1]];//顯示數(shù)據(jù)</p><p&
56、gt; delay_ms(10);</p><p> P2=0x4;// p2.0有效,選通數(shù)碼管左數(shù)第3位。</p><p> P0=table[showdata[2]];//顯示數(shù)據(jù)</p><p> delay_ms(10);</p><p> P2=0x8;// p2.3有效,選通數(shù)碼管左數(shù)第4位。</p>&
57、lt;p> P0=table[showdata[3]];//顯示數(shù)據(jù)</p><p> delay_ms(10);</p><p> if(KeyWrite1==0)//如果KeyWrite1鍵按下,則將'1'寫入2402的'0x80'地址中</p><p><b> {</b></p>
58、<p><b> EA=0;</b></p><p> IICWriteData[0]=1;IICWriteData[1]=2;</p><p> showdata[0]=IICWriteData[0];showdata[1]=IICWriteData[1];</p><p> Write_Flash(IICWriteDa
59、ta,0,2); //將dat數(shù)組中的數(shù)據(jù)寫入AT24C02中地址從0開始</p><p> Read_Flash(IICReadData,0,2);</p><p> for(i=0;i<2;i++){if(IICWriteData[i]=IICReadData[i])showdata[i+2]=1;</p><p> else showdata[i
60、+2]=0;</p><p><b> }</b></p><p><b> EA=1;</b></p><p><b> }</b></p><p> if(KeyWrite2==0)//如果KeyWrite2鍵按下,則將'2'寫入2402的'
61、0x80'地址中</p><p><b> {</b></p><p><b> EA=0;</b></p><p> IICWriteData[0]=3;IICWriteData[1]=4;</p><p> showdata[0]=IICWriteData[0];showdata
62、[1]=IICWriteData[1];</p><p> Write_Flash(IICWriteData,2,2); //將dat數(shù)組中的數(shù)據(jù)寫入AT24C02中地址從2開始</p><p> Read_Flash(IICReadData,2,2);</p><p> for(i=0;i<2;i++){if(IICWriteData[i]==IIC
63、ReadData[i])showdata[i+2]=0;else showdata[i+2]=1;}</p><p><b> EA=1;</b></p><p><b> }</b></p><p> if(KeyRead==0)//如果KeyRead鍵按下,讀出2402的'0x80'地址中的數(shù)據(jù)&
64、lt;/p><p><b> {</b></p><p><b> EA=0;</b></p><p> Read_Flash(IICReadData,0,4); //讀出AT24C02中從地址1開始依次往后16個字節(jié)放入dat數(shù)組中</p><p> for(i=0;i<4;i++)&
65、lt;/p><p> {showdata[i]=IICReadData[i];}</p><p><b> EA=1;</b></p><p><b> }</b></p><p><b> }</b></p><p> 6.3.3 源程序 &l
66、t;/p><p> #include<reg51.h></p><p> #include<intrins.h></p><p> #define uint unsigned int</p><p> #define uchar unsigned char</p><p> sbit Ke
67、yWrite1=P1^0;//按鍵定義</p><p> sbit KeyWrite2=P1^1;</p><p> sbit KeyRead=P1^2;</p><p> #define WriteDeviceAddress 0xa0 //寫驅動地址指令</p><p> #define ReadDeviceAddress 0x
68、a1 //讀驅動地址指令</p><p> sbit AT24C02_SCL =P3^2;</p><p> sbit AT24C02_SDA =P3^4;</p><p> /*-------------------------------------------------------------</p><p><b>
69、; 功能:發(fā)起始信號</b></p><p> ------------------------------------------------------------*/</p><p> void Start_Cond()</p><p><b> {</b></p><p> AT24C02_
70、SCL = 0;</p><p><b> _nop_();</b></p><p> AT24C02_SDA = 1;</p><p><b> _nop_();</b></p><p> AT24C02_SCL = 1;</p><p><b> _n
71、op_();</b></p><p> AT24C02_SDA = 0;</p><p><b> _nop_();</b></p><p><b> }</b></p><p> /*-----------------------------------------------
72、--------------</p><p><b> 功能:發(fā)停止信號</b></p><p> ------------------------------------------------------------*/</p><p> void Stop_Cond()</p><p><b>
73、{</b></p><p> AT24C02_SCL = 0;</p><p><b> _nop_();</b></p><p> AT24C02_SDA = 0;</p><p><b> _nop_();</b></p><p> AT24C02_
74、SCL = 1;</p><p><b> _nop_();</b></p><p> AT24C02_SDA = 1;</p><p><b> _nop_();</b></p><p><b> }</b></p><p> /*-----
75、--------------------------------------------------------</p><p><b> 功能:發(fā)確認信號</b></p><p> ------------------------------------------------------------*/</p><p> void A
76、ck()</p><p><b> {</b></p><p> AT24C02_SCL = 0;</p><p><b> _nop_();</b></p><p> AT24C02_SDA = 0;</p><p> AT24C02_SCL = 1;</p
77、><p><b> _nop_();</b></p><p> AT24C02_SCL = 0;</p><p><b> _nop_();</b></p><p> AT24C02_SDA = 1;</p><p><b> }</b></
78、p><p> /*-------------------------------------------------------------</p><p><b> 功能:發(fā)無確認信號</b></p><p> ------------------------------------------------------------*/<
79、;/p><p> void NoAck()</p><p><b> {</b></p><p> AT24C02_SCL = 0;</p><p><b> _nop_();</b></p><p> AT24C02_SDA = 1;</p><p
80、><b> _nop_();</b></p><p> AT24C02_SCL = 1;</p><p><b> _nop_();</b></p><p> AT24C02_SCL = 0;</p><p><b> _nop_();</b></p>
81、;<p><b> }</b></p><p> /*-------------------------------------------------------------</p><p> 功能:寫一個字節(jié)數(shù)據(jù)</p><p> --------------------------------------------
82、----------------*/</p><p> bit Write8Bit(unsigned char input)</p><p><b> {</b></p><p> unsigned char i;</p><p> for (i=0;i<8;i++)</p><p>
83、;<b> { </b></p><p> AT24C02_SCL = 0;</p><p> input <<= 1;</p><p> AT24C02_SDA = CY;</p><p> AT24C02_SCL = 1;</p><p><b> }<
84、/b></p><p> AT24C02_SCL = 0;</p><p><b> _nop_();</b></p><p> AT24C02_SDA = 1;</p><p> AT24C02_SCL = 1;</p><p><b> _nop_();</b&
85、gt;</p><p> CY = AT24C02_SDA;</p><p> return(CY) ;</p><p><b> }</b></p><p> /*-------------------------------------------------------------</p>&
86、lt;p> 功能:讀一個字節(jié)數(shù)據(jù)</p><p> ------------------------------------------------------------*/</p><p> unsigned char Read8Bit()</p><p><b> {</b></p><p> un
87、signed char temp,rbyte=0;</p><p> for (temp = 8;temp != 0;temp--)</p><p><b> {</b></p><p> AT24C02_SCL = 0;</p><p><b> _nop_();</b></p>
88、;<p> rbyte = (rbyte << 1) | AT24C02_SDA;</p><p> AT24C02_SCL = 1;</p><p><b> _nop_();</b></p><p><b> }</b></p><p> return rby
89、te;</p><p><b> }</b></p><p> /*-------------------------------------------------------------</p><p> 功能:從EEPROM中給定一個地址連續(xù)讀NLEN個字節(jié)數(shù)據(jù)存放在以指針</p><p> nConten
90、t開頭的往下內容。</p><p> ------------------------------------------------------------*/</p><p> bit Read_Flash ( unsigned char *nContent, unsigned char nAddr, unsigned char nLen )</p><p>
91、;<b> {</b></p><p> unsigned char Addr;</p><p> Addr = nAddr;</p><p> Start_Cond(); //寫開始信號</p><p> Write8Bit(WriteDeviceAddress); //寫驅動地址</p>
92、<p> Write8Bit(Addr); //寫從EEPROM中讀的開始地址</p><p> Start_Cond(); //寫開始信號</p><p> Write8Bit(ReadDeviceAddress); //寫讀數(shù)據(jù)指令</p><p> while(--nLen)</p><p><b
93、> {</b></p><p> *nContent=Read8Bit(); //讀出內容</p><p> nContent++; //指針加1</p><p> Ack(); //發(fā)確認信號</p><p><b> }</b></p><p> *n
94、Content=Read8Bit(); //讀一字節(jié) </p><p> NoAck(); //沒有確認信號</p><p> Stop_Cond(); //發(fā)停止信號</p><p> return(0); //返回</p><p><b> }</b></p><p&
95、gt; /*-------------------------------------------------------------</p><p> 功能:初始化EEPROM子程序內容為FF</p><p> ------------------------------------------------------------*/</p><p> b
96、it Init_Flash ( unsigned int nPage ) // 8 Byte/1Page init 0xFF </p><p><b> {</b></p><p> unsigned char nLen;</p><p> unsigned char Addr;</p><p><b&
97、gt; nLen=8;</b></p><p> Addr=8 *nPage;</p><p> Start_Cond();</p><p> Write8Bit(WriteDeviceAddress);</p><p> Write8Bit(Addr);</p><p> for(;nLen!
98、=0;nLen--)</p><p><b> {</b></p><p> if(Write8Bit(0xff)) break; //if Write8Bit() Return 1 Write Flase</p><p><b> }</b></p><p> Stop_Cond();&
99、lt;/p><p> return(CY);</p><p><b> }</b></p><p> /*-------------------------------------------------------------</p><p> 功能:從EEPROM中給定一個地址連續(xù)寫NLEN個字節(jié)數(shù)據(jù)存放在以指針
100、</p><p> nContent開頭的往下內容。</p><p> ------------------------------------------------------------*/</p><p> bit Write_Flash ( unsigned char *nContent, unsigned char nAddr,unsigned c
101、har nLen)</p><p><b> {</b></p><p> unsigned char i,temp;</p><p> unsigned char Addr;</p><p> Addr = nAddr;</p><p> Start_Cond(); //寫開始
102、信號</p><p> Write8Bit(WriteDeviceAddress); //寫驅動地址</p><p> Write8Bit(Addr); //寫從EEPROM中寫的開始地址 </p><p> for(i = 0;i < nLen;i++)</p><p><b> {</b>&l
103、t;/p><p> if(Addr%8==0) //每頁8字節(jié) //換頁</p><p><b> {</b></p><p> Stop_Cond();</p><p><b> _nop_();</b></p><p> Start_Cond();</p
104、><p> Write8Bit(WriteDeviceAddress);</p><p> Write8Bit(Addr);</p><p><b> }</b></p><p> temp = *nContent;</p><p> if(Write8Bit(temp)) break;
105、//CY</p><p> nContent++;</p><p><b> Addr++;</b></p><p><b> }</b></p><p> Stop_Cond(); //發(fā)停止信號</p><p> return(CY);</p>
106、;<p><b> }</b></p><p> //共陰極數(shù)碼管真值表"0" "2" "3" "4" "5" "6" "7" "8" "9" "a" "b"
107、; "c" "d" "e" "f"</p><p> uchar code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xff};</p><p> uchar IICRe
108、adData[4];//AT24C02讀數(shù)據(jù)數(shù)組</p><p> uchar IICWriteData[4];//AT24C02寫數(shù)據(jù)數(shù)組</p><p> uchar showdata[4];</p><p> uchar i=0,j=0;</p><p> void delay_ms(uchar n)</p>&l
109、t;p><b> {</b></p><p> uchar i,j;</p><p> for(j=n;j>0;j--)</p><p><b> {</b></p><p> for(i=100;i>0;i--)</p><p><b>
110、; {</b></p><p> _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();//1個機器周期=12個時鐘周期,fosc=12MHz時,1個機器周期=1us</p><p><b> }</b></p><p>
111、<b> }</b></p><p><b> }</b></p><p> void main(void)</p><p><b> {</b></p><p> Init_Flash(0); //將AT24C02的第0頁初始化為FF</p>&
112、lt;p><b> while(1){</b></p><p> P2=0x1;// p2.0有效,選通數(shù)碼管左數(shù)第1位。</p><p> P0=table[showdata[0]];//顯示數(shù)據(jù)</p><p> delay_ms(10);</p><p> P2=0x2;// p2.0有效,選通數(shù)碼
113、管左數(shù)第2位。</p><p> P0=table[showdata[1]];//顯示數(shù)據(jù)</p><p> delay_ms(10);</p><p> P2=0x4;// p2.0有效,選通數(shù)碼管左數(shù)第3位。</p><p> P0=table[showdata[2]];//顯示數(shù)據(jù)</p><p> d
114、elay_ms(10);</p><p> P2=0x8;// p2.3有效,選通數(shù)碼管左數(shù)第4位。</p><p> P0=table[showdata[3]];//顯示數(shù)據(jù)</p><p> delay_ms(10);</p><p> if(KeyWrite1==0)//如果KeyWrite1鍵按下,則將'1'寫
115、入2402的'0x80'地址中</p><p><b> {</b></p><p><b> EA=0;</b></p><p> IICWriteData[0]=1;IICWriteData[1]=2;</p><p> showdata[0]=IICWriteData[
116、0];showdata[1]=IICWriteData[1];</p><p> Write_Flash(IICWriteData,0,2); //將dat數(shù)組中的數(shù)據(jù)寫入AT24C02中地址從0開始</p><p> Read_Flash(IICReadData,0,2);</p><p> for(i=0;i<2;i++){if(IICWriteD
117、ata[i]=IICReadData[i])showdata[i+2]=1;else showdata[i+2]=0;}</p><p><b> EA=1;</b></p><p><b> }</b></p><p> if(KeyWrite2==0)//如果KeyWrite2鍵按下,則將'2'寫
118、入2402的'0x80'地址中</p><p><b> {</b></p><p><b> EA=0;</b></p><p> IICWriteData[0]=3;IICWriteData[1]=4;</p><p> showdata[0]=IICWriteData[
119、0];showdata[1]=IICWriteData[1];</p><p> Write_Flash(IICWriteData,2,2); //將dat數(shù)組中的數(shù)據(jù)寫入AT24C02中地址從2開始</p><p> Read_Flash(IICReadData,2,2);</p><p> for(i=0;i<2;i++){if(IICWriteD
120、ata[i]==IICReadData[i])showdata[i+2]=0;else showdata[i+2]=1;}</p><p><b> EA=1;</b></p><p><b> }</b></p><p> if(KeyRead==0)//如果KeyRead鍵按下,讀出2402的'0x80&
121、#39;地址中的數(shù)據(jù)</p><p><b> {</b></p><p><b> EA=0;</b></p><p> Read_Flash(IICReadData,0,4); //讀出AT24C02中從地址1開始依次往后16個字節(jié)放入dat數(shù)組中</p><p> for(i=0;i
122、<4;i++)</p><p> {showdata[i]=IICReadData[i];}</p><p><b> EA=1;</b></p><p><b> }</b></p><p><b> }</b></p><p><
123、b> }</b></p><p> 7 設計心得體會 </p><p> 對于這次課程設計,我的感受很深,并且也收獲挺多的。</p><p> 在這次課程設計中,我基本上完成了本次設計的任務,使我學到了課本之外的東西,同時也讓我明白了,任何人在搞課程設計前,對自己搞的東西都不可能很懂,但是通過自己查資料,能一步一步弄懂的,在這其中得到的喜
124、悅也是不言而喻的。時間雖然很緊張,但是利用有限的時間完成課程設計,我心里無比的欣慰。</p><p><b> 8 參考文獻</b></p><p> 1.何立民.IIC總線應用系統(tǒng)設計.北京:北京航空航天大學出版社</p><p> 2.譚浩強.C語言程序設計(第三版) .北京:清華大學出版社</p><p>
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 眾賞文庫僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 單片機課程設計---單片機籃球計分器
- 虛擬存儲器課程設計
- 課程設計--請求頁式存儲器管理
- 單片機課程設計---單片機原理及應用
- 單片機課程設計-- 單片機原理及應用
- 課程設計---基于單片機的可存儲式電子琴設計
- 單片機課程設計-單片機課程設計---電子時鐘
- 單片機應用課程設計報告
- 課程設計---存儲器管理系統(tǒng)設計
- 單片機課程設計--單片機io口的應用
- 單片機課程設計-- 基于單片機的搶答器設計
- 基于單片機的計算器設計-單片機課程設計
- 單片機課程設計——計算器設計
- 單片機課程設計--- 比賽計分器設計
- 單片機課程設計
- 單片機課程設計
- 單片機課程設計
- 單片機課程設計
- 單片機課程設計--電子答題器
- 比賽計分器單片機課程設計
評論
0/150
提交評論