I2C接口


I2C是一種多向控制總線,它是由PHILIPS公司在二十世紀八十年代初設計出來的,利用該總線可實現多主機系統所需的裁決和高低速設備同步等功能,是一種高性能的串行總線。I2C總線只用兩根雙向傳輸線就可以將128個不同的設備互連到一起。這兩根線一根是時鍾線SCL,一根是數據線SDA。外部硬件只需要接兩個上拉電阻,每根線上一個。所有連接到總線上的設備都有自己的地址。

I2C總線上傳輸的數據是通過在時鍾線(SCL)高電平期間所對應的數據線(SDA)上的電平來判別的。在SCL線拉高期間對應到SDA線的電平,如果為高則這位數據為1,反之則為0。只有在SCL線為低電平期間,SDA線才可以更新下一位數據。

除了傳送的數據以外,I2C總線在每一幀數據傳送之前,還會有一個啟動信號,以通知從機准備接收數據。在數據傳送結束之后,也會有一個停止信號,以通知從機數據傳輸結束。在SCL為高電平期間,若對應的SDA線上有一個由高變低的電平下降沿,表示這是一個啟動信號。同樣,在SCL為高電平期間,若對應的SDA線上有一個由低變高的電平上升沿,表示這是一個停止信號。當已經有一個啟動信號之后,在沒有停止信號出現之前若再次出現啟動信號,則表示該信號是一個重新啟動信號,它主要用於在主機不放棄總線控制的情況下啟動新的傳送。

在啟動信號之后緊接着的是地址幀,所有的地址包均為9位,包括7位地址位、1位READ/WRITE控制位(即方向位,表明是主機寫從機還是從機寫主機)與1位應答位。如果READ/WRITE為1,則執行讀(從機寫主機)操作;否則執行寫(主機寫從機)操作。從機被尋址后,必須在第九個SCL(ACK)周期通過拉低SDA作出應答。

地址幀發送后,緊接着就要發送數據幀。所有在I2C總線上傳送的數據包長度為9位,包括8位數據位及1位應答位。在數據傳送中,主機產生時鍾及START與STOP狀態,接收器響應接收。應答是由從機在第9個SCL周期拉低SDA實現的,如果接收器在第9個SCL周期使SDA為高,則發出的是NACK信號。NACK信號是接收器在完成了最后數據的接收,或者由於某些原因無法接收更多數據時,才在收到最后字節后發出去通知發送器的。

I2C總線上一個完整的傳輸過程將包含地址包和數據包。發送主要由START狀態、SLA+R/W、至少一個數據包及STOP狀態組成。一個典型的數據傳送的過程可用下圖來描述。

LPC824在硬件上完整支持I2C接口規范,並配有4個I2C接口(具體引腳取決於開關矩陣SWM的配置),它們具有以下特性。

(1)獨立的主機、從機和監控器功能。
(2)支持多主機和帶從機功能的多主機。
(3)硬件支持多個I2C從機地址。
(4)可以通過一個位屏蔽或一個地址范圍選擇性驗證一個從機地址,從而響應多個I2C總線地址。
(5)通過軟件輔助支持10位尋址。
(6)支持SMBus。
(7)支持I2C總線規格達到超快速模式(高達1兆赫)。

LPC824提供一個基於片上ROM的I2C API,以配置和操作I2C接口。

下圖是I2C接口的功能框圖。 

 

在LPC824中,一共有四組I2C接口,分別為I2C0/1/2/3。I2C0組接口引腳是固定的(PIO0_10和PIO0_11),通過開關矩陣使能,支持超快速模式。I2C1/2/3這三組接口的引腳都是可移動的,可被分配至任何引腳。除PIO0_10和PIO0_11引腳以外,其他組的引腳不是開漏引腳,也不支持超快速模式,所有的引腳均支持400 kHz比特率。下表給出了這些引腳各自的SWM配置寄存器。

從上表中可以看出,I2C0接口的引腳是固定的,通過PINENABLE0寄存器來使能(詳見“開關矩陣SWM”一章)。其他三組I2C接口的共8個引腳可以被分配到任意一個物理引腳上,涉及到PINASSIGN9、PINASSIGN10共2個配置寄存器,接下來就分別給出這兩個寄存的具體結構。

下表給出的是引腳分配寄存器PINASSIGN9的全部位結構,其字節地址為0x4000C024。 

(1)第0到7位為SCT_OUT5功能分配引腳,可選范圍從PIO0_0到PIO0_28一共29根引腳,默認為未分配狀態。
(2)第8到15位為I2C1_SDA功能分配引腳,可選范圍從PIO0_0到PIO0_28一共29根引腳,默認為未分配狀態。
(3)第16到23位為I2C1_SCL功能分配引腳,可選范圍從PIO0_0到PIO0_28一共29根引腳,默認為未分配狀態。
(4)第24到31位為I2C2_SDA功能分配引腳,可選范圍從PIO0_0到PIO0_28一共29根引腳,默認為未分配狀態。

下表給出的是引腳分配寄存器PINASSIGN10的全部位結構,其字節地址為0x4000C028。 

(1)第0到7位為I2C2_SCL功能分配引腳,可選范圍從PIO0_0到PIO0_28一共29根引腳,默認為未分配狀態。
(2)第8到15位為I2C3_SDA功能分配引腳,可選范圍從PIO0_0到PIO0_28一共29根引腳,默認為未分配狀態。
(3)第16到23位為I2C3_SCL功能分配引腳,可選范圍從PIO0_0到PIO0_28一共29根引腳,默認為未分配狀態。
(4)第24到31位為ADC_PINTRIG0功能分配引腳,可選范圍從PIO0_0到PIO0_28一共29根引腳,默認為未分配狀態。

下表給出了I2C接口用到的全部寄存器描述。

由於LPC824的I2C接口功能很完善,所以涉及到的寄存器較多,它一共使用了18個寄存器來進行控制,應用上有些復雜。下面給出了上述寄存器對應的結構體定義。 

typedef struct {
__IO uint32_t CFG;
__IO uint32_t STAT;
__IO uint32_t INTENSET;
__O uint32_t INTENCLR;
__IO uint32_t TIMEOUT;
__IO uint32_t CLKDIV;
__I uint32_t INTSTAT;
__I uint32_t RESERVED0;
__IO uint32_t MSTCTL;
__IO uint32_t MSTTIME;
__IO uint32_t MSTDAT;
__I uint32_t RESERVED1[5];
__IO uint32_t SLVCTL;
__IO uint32_t SLVDAT;
__IO uint32_t SLVADR0;
__IO uint32_t SLVADR1;
__IO uint32_t SLVADR2;
__IO uint32_t SLVADR3;
__IO uint32_t SLVQUAL0;
__I uint32_t RESERVED2[9];
__I uint32_t MONRXDAT;
} LPC_I2C0_Type;

為了將4個I2C的基址指針強制轉換為上述結構體,還要加上下面的定義。

#define LPC_I2C0_BASE 0x40050000UL
#define LPC_I2C1_BASE 0x40054000UL
#define LPC_I2C2_BASE 0x40070000UL
#define LPC_I2C3_BASE 0x40074000UL
#define LPC_I2C0 ((LPC_I2C0_Type *) LPC_I2C0_BASE)
#define LPC_I2C1 ((LPC_I2C0_Type *) LPC_I2C1_BASE)
#define LPC_I2C2 ((LPC_I2C0_Type *) LPC_I2C2_BASE)
#define LPC_I2C3 ((LPC_I2C0_Type *) LPC_I2C3_BASE)

I2C接口涉及到的寄存器較多,后面會對它們進行具體分析。

--待續--


免責聲明!

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



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