FPGA實現IIC通訊(讀寫EEPROM)

2021-03-09 12:01:38

FPGA實現iic通訊(讀寫EEPROM)

實驗平臺:正點原子ALIENTEK開拓者FPGA開發板

1. IIC協定簡介

1.1 什麼是IIC協定

IIC即為Inter-Inegrated Circuit(積體電路匯流排),在上世紀八十年代左右由Philips公司(即現做的NXP半導體公司)設計出來的一種簡單、雙向、二進位制匯流排標準。其只需要兩根線(SDA傳輸線和SCL時鐘線)即可實現匯流排連線的器件間的通訊。SDA和SCL都是雙向I/O線,所以主要適用於資料量小,距離短的主從通訊,資料的傳輸速率在標準模式下可達100kbit/s,在快速模式下可達400kbit/s,在高速模式下可達3.4Mbit/s。

Alt
當兩個器件通訊時,用於啟動匯流排併產生時鐘的為主器件,此時匯流排上所有可被定址的都為從器件。所有的從器件都有其第一無二的裝置地址,主機傳送想要通訊的從機的裝置地址,所有的從器件將此地址與自身的裝置地址對照,對應的從器件則發出應答訊號,二者即開始通訊。這也意味著主機與從機不是固定的,而是取決於資料的傳輸方向。

1.2 硬體結構

SDA(序列傳輸線)和SCL(序列時鐘線)都是雙向I/O線,介面電路為開漏輸出,需通過上拉電阻接電源VCC,因此當匯流排空閒時兩根線都是高電平。
Alt

1.3 為什麼要使用IIC協定

通過上文可知IIC可以掛載多個裝置,這也是其最大的優點。在工業中有時我們並不需要讀出所有裝置的資料,這時就可以使用IIC匯流排,將多個感測器掛載在其上,只需要在需要的時候讀出對應裝置的資料。雖然其與其他的序列外設介面相比,通訊速度較慢,但是其大大節約了I/O資源;而且在傳輸過程中可以通過應答位來判斷是否成功通訊;這些優點導致IIC大面積應用。

1.4 IIC協定的時序特點

1.4.1 傳輸特點

由於IIC是由傳輸線和時鐘線所組成的,因此二者相互配合完成資料的傳輸。當時鍾線(SCL)為高電平時要求傳輸線(SDA)的資料穩定,此時從機開始接收主機資料或者主機接收從機的應答;當時鍾線(SCL)為低電平時傳輸線(SDA)的資料可變化,即更新資料以備下一次的接收。
Alt

1.4.2 時序特點

IIC傳輸主要由開始訊號、停止訊號、應答/非應答、讀、寫訊號五部分組成:
開始訊號
當時鍾線(SCL)為高電平期間,傳輸線(SDA)由高電平變為低電平即為起始訊號,時序圖如下圖所示:
在這裡插入圖片描述
終止訊號
當時鍾線(SCL)為高電平期間傳輸線(SDA)由低電平變為高電平即為終止訊號,時序圖如下圖所示:
在這裡插入圖片描述
應答/非應答
應答訊號與非應答都由接收方發出(需要注意在讀資料時,主機為接收方,因此要由主機傳送應答/非應答訊號),在時鐘線(SCL)為高電平期間,檢測傳輸線(SDA)的值,如果傳輸線(SDA)為低電平則為應答訊號,傳輸線(SDA)為高電平則為非應答訊號。
在這裡插入圖片描述
讀資料
讀資料的時序與應答/非應答的相同,都是在時鐘線(SCL)為高電平期間讀取傳輸線(SDA)的值,傳輸線(SDA)的高低電平即代表「1」或「0」,讀資料的時序如下圖所示:![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20210308164815695.png #pic_center =750x)
寫資料
通過上面的分析可知,從機在時鐘線(SCL)高電平期間讀取傳輸線(SDA)的資料,因此寫資料時需要在時鐘線(SCL)低電平期間改變傳輸線(SDA)的值來傳輸資料,時序圖如下:
在這裡插入圖片描述

1.4.3 完整時序

IIC寫時序
Alt

IIC寫時序變化
Alt
IIC讀時序
Alt

2. IIC協定實踐

2.1 設計思想

通過對讀寫過程分析可知,無論是讀或者寫過程都由開始訊號、傳送裝置地址(最後一位讀或者寫)、傳送儲存單元地址、傳送資料/讀資料、結束幾部分組成。因此用狀態機來完成此程式碼。
狀態機
在此我將讀寫操作寫在了一個驅動檔案裡,是考慮到如果讀寫分別寫在兩個檔案裡的話,在例化時對inout埠的例化會有困難(因為其還需要一個控制訊號),因此我寫在了一個檔案裡,由一個讀寫控制訊號來判斷是執行讀操作還是寫操作;在此次設計中我將開始訊號放在了傳送裝置地址裡,以便減少狀態。

2.2 RTL程式碼重要部分

驅動時鐘
由於IIC需要滿足不同的通訊速率,因此在此將其設定為引數,為了在時鐘線(SCL)的不同時刻對傳輸線(SDA)進行處理,因此將其進行四分頻,這樣驅動時鐘的4個週期就是時鐘線(SCL)的一個週期。

	parameter   CLK_FREQ   = 26'd50_000_000, //模組輸入的時脈頻率
    parameter   I2C_FREQ   = 18'd250_000     //IIC_SCL的時脈頻率
	
	assign  clk_divide = (CLK_FREQ/I2C_FREQ) >> 2'd2;

時鐘計數器
由於驅動時鐘是與時鐘線(SCL)相互對應的,因此驅動一個計數器來作為其他訊號的判斷依據。由於不同的狀態持續的時間不同,因此將計數器的自加放在狀態機的case語句中,這樣不同狀態可直接判斷計數器來判斷其他訊號的狀態。

傳輸線(SDA)資料的變化
通過驅動時鐘來驅動一個計數器,由於驅動時鐘的四個週期對應時鐘線(SCL)的一個週期,因此通過計數器的數值即可判斷時鐘線(SCL)是處於什麼位置,並根據此來判斷時鐘線(SCL)的上升沿和下降沿。
inout埠輸入輸出方向變化
在狀態機內部通過計數器來判斷時鐘線(SCL)的不同狀態,當其計數到相應時刻時將控制inout埠的 訊號更新到對應的狀態。

2.3 開發過程遇到的問題

從機無應答
在測試過程中出現了從機應答錯誤的情況,用SignalTap抓取波形圖發現起始訊號並沒有問題,通過上網查詢發現EEPROM在寫之間需要時間間隔,由於不知道需要等待多長時間,因此在狀態機中持續等待應答,等到應答正確後再狀態跳轉。
應答正常但讀出資料不對
更改後發現讀寫時序都正確,應答也正確但是讀出的資料不正確,通過查詢資料懷疑是EEPROM出問題,所以將裝置斷電使EEPROM進行上電,上電後恢復正常。
時鐘問題
將IIC和串列埠模組相連線,實現資料的迴環,將IIC模組的完成訊號作為串列埠的傳送使能訊號,由於IIC的完成訊號保持的時鐘是遠遠長於一個時鐘的,因此會造成串列埠持續傳送。所以在IIC模組中加了一個邊沿檢測程式,將電平訊號變為脈衝訊號後再將其輸出。

3. 程式碼下載

連結: IIC通訊原始碼.