0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

用于ATtiny和ATmega的I2C總線

454398 ? 來(lái)源:wv ? 2019-10-24 10:09 ? 次閱讀

步驟1:

用于ATtiny和ATmega的I2C總線

I2C總線是一種簡(jiǎn)單的兩線連接,可以將多個(gè)設(shè)備鏈接在一起,并允許它們交換數(shù)據(jù)。在最簡(jiǎn)單的形式中,有一臺(tái)主設(shè)備與多個(gè)從設(shè)備進(jìn)行通信。所有設(shè)備都并行連接到I2C總線的兩條線。這兩條線稱為SCL和SDA。 SCL是時(shí)鐘線,由主設(shè)備控制。 SDA是雙向數(shù)據(jù)線。為了傳輸數(shù)據(jù),主機(jī)發(fā)送一個(gè)從機(jī)地址并結(jié)合一位讀/寫(xiě)標(biāo)志。如果需要寫(xiě)操作,則主機(jī)將繼續(xù)向被尋址的從機(jī)發(fā)送數(shù)據(jù)。如果請(qǐng)求讀取,則從站將響應(yīng)數(shù)據(jù)。為了協(xié)調(diào)事務(wù),SCL和SDA線由主機(jī)和從機(jī)操縱,以發(fā)出幾種情況的信號(hào)。其中包括START,STOP,ACK(確認(rèn))和NAK(未確認(rèn))。這些條件的詳細(xì)信息由驅(qū)動(dòng)程序處理。真正的極客可以在此Instructable末尾提供的鏈接中了解所有詳細(xì)信息。

電氣要求非常簡(jiǎn)單。主機(jī)和從機(jī)必須對(duì)Vcc使用相同的電平,必須接地,并且SCL和SDA線必須上拉至Vcc。上拉電阻的值是通過(guò)基于總線上總電容的計(jì)算精確確定的,但實(shí)際上幾乎可以是1.8K到10K之間的任何值。我從5.1K開(kāi)始使用較低的值,直到它起作用為止。除非您有很多設(shè)備或設(shè)備之間的電線很長(zhǎng),否則通常這不是問(wèn)題。

I2C總線上的標(biāo)稱數(shù)據(jù)速率為100Kbits/秒。也可以達(dá)到400Kbit/s,1Mbits/s或更高的速率,但是此Instructable中的驅(qū)動(dòng)程序不支持這些速率。所有I2C器件都將以100Kbit/s的速度工作。

ATtiny2313和ATmega168各自實(shí)現(xiàn)I2C總線的方式有所不同。 ATtiny2313使用通用串行接口(USI)硬件-也可以用于SPI總線。 ATmega168具有用于I2C總線的專用硬件,稱為雙線接口(TWI)。編寫(xiě)完驅(qū)動(dòng)程序后,這些差異對(duì)用戶幾乎都是透明的。軟件上的一個(gè)重要區(qū)別是:ATmega168 I2C驅(qū)動(dòng)程序是由中斷驅(qū)動(dòng)的,而ATtiny2313則不是。這意味著ATmega168程序不必等待I2C數(shù)據(jù)傳輸發(fā)生,而只需要在啟動(dòng)另一個(gè)傳輸之前等待,或者直到數(shù)據(jù)從讀取操作到達(dá)為止。 I2C地址的長(zhǎng)度為7位,因此每個(gè)示例都有一個(gè)唯一的地址,因此總線上最多可以有127個(gè)設(shè)備。如圖所示,此7位地址左移一位,最低有效位用于在該地址標(biāo)記對(duì)設(shè)備的讀取或?qū)懭?。因此,完整的從機(jī)地址是一個(gè)8位字節(jié)。實(shí)際地址部分地在設(shè)備內(nèi)部確定,并且不能更改(4個(gè)最高有效位),部分地由可以連接至設(shè)備引腳的位(3個(gè)最低有效位)確定,可以將其設(shè)置為高電平或低電平以進(jìn)行設(shè)置一個(gè)特定的地址。

聲音令人困惑,但是舉個(gè)例子可以清楚地說(shuō)明這一點(diǎn)。 PCA8574A數(shù)據(jù)表顯示,I2C地址的四個(gè)最高有效位始終為0111。接下來(lái)的三位由引腳AD0,AD1和AD2的設(shè)置確定。這些引腳可以接地或連接到正電源(5伏),分別代表0或1。因此,可能的地址范圍是38到3F十六進(jìn)制,如PCA8574數(shù)據(jù)表的另一幅圖所示。因此,通過(guò)更改地址位設(shè)置,可以同時(shí)在I2C總線上最多連接8個(gè)PCA8574A。每個(gè)都將僅響應(yīng)其特定的從站地址。如果需要更多的I/O端口,則可以使用PCA8574。 PCA8574和PCA8574A之間的唯一區(qū)別是PCA8574的I2C從設(shè)備地址范圍是20到27個(gè)十六進(jìn)制。

確定給定設(shè)備的地址可能會(huì)造成混淆,因?yàn)槟承?shù)據(jù)手冊(cè)認(rèn)為讀/寫(xiě)位是地址的一部分。仔細(xì)閱讀數(shù)據(jù)手冊(cè),并牢記從機(jī)地址的長(zhǎng)度為7位。讀/寫(xiě)位應(yīng)分開(kāi)處理。同樣,一個(gè)例子會(huì)有所幫助。我們將試驗(yàn)的24C16 EEPROM數(shù)據(jù)表中說(shuō),從機(jī)地址的前四個(gè)(最高有效位)是1010。接下來(lái)的三個(gè)位可以由A0,A1和A2確定。但請(qǐng)注意,數(shù)據(jù)手冊(cè)還涵蓋了尺寸較小的EEPROM 24C01至24C08。數(shù)據(jù)表中的圖顯示,這些地址位的設(shè)置隨著大小的增加而被忽略,而對(duì)于24C16則被完全忽略。也就是說(shuō),最后三位無(wú)關(guān)緊要,而24C16實(shí)際上使用所有I2C從地址50至57十六進(jìn)制。從機(jī)地址范圍實(shí)際上將尋址24C16中的不同部分。前256個(gè)字節(jié)位于地址50h,下一個(gè)256位于地址51h,依此類推,直到最后一個(gè)256位于57h-總共2K字節(jié)。由于我們也嘗試過(guò)的PCF8570 RAM的地址在此范圍內(nèi),因此24C16和PCF8570不能一起使用。

第2步:訂購(gòu)一些I2C設(shè)備

現(xiàn)在您已經(jīng)對(duì)I2C總線有所了解,并想使用它,為什么不訂購(gòu)

一些合適的設(shè)備包括I/O接口擴(kuò)展器(我最喜歡的),靜態(tài)Ram和EEPROM。還有很多,但是這是一個(gè)很好的開(kāi)始。我們將使用的AVR處理器是ATtiny2313和Atmega168(在Arduino中使用)。如果您不熟悉這些,請(qǐng)看看這個(gè)功能強(qiáng)大的Instructable,以了解它們并構(gòu)建您的Ghetto開(kāi)發(fā)系統(tǒng)。本Instructable中ATmega168的示意圖顯示了如何為該處理器實(shí)現(xiàn)Ghetto開(kāi)發(fā)系統(tǒng)。并行端口電纜與ATtiny2313的電纜相同。 (我尚未嘗試使用Ghetto開(kāi)發(fā)系統(tǒng)的USB版本,因此我不確定如何在其上訪問(wèn)I2C總線。與Arduino相同。)

這是Digikey的部件號(hào)。

Port Expander :

IC I2C I/O EXPANDER568-4236-5-ND

Ram:

IC SRAM 256X8 W/I2C568-1071-5-ND

EEPROM:

IC EEPROM串行16KCAT24C16LI-G -ND

步驟3:I2C驅(qū)動(dòng)程序

以下是I2C總線驅(qū)動(dòng)程序功能的說(shuō)明。這些是使用面向初學(xué)者的Atmel Apps Notes開(kāi)發(fā)的。沒(méi)有他們,我無(wú)法做得到這一基礎(chǔ)。使用WinAVR和gcc C編譯器進(jìn)行了開(kāi)發(fā)。

下面對(duì)每個(gè)處理器的時(shí)鐘速率限制進(jìn)行了說(shuō)明。由于我無(wú)法測(cè)試所有可能的處理器風(fēng)格/時(shí)鐘速率組合,因此我將堅(jiān)持實(shí)際測(cè)試并嘗試指出限制和限制。

以下是驅(qū)動(dòng)程序功能以及如何使用它們。請(qǐng)查看示例以獲取更多詳細(xì)信息,并查看完整程序中使用的功能。

對(duì)于ATtiny2313:

時(shí)鐘要求:

驅(qū)動(dòng)程序的設(shè)計(jì)時(shí)鐘頻率為1MHz(默認(rèn)頻率)對(duì)于ATtiny2313。如果要以其他速率運(yùn)行,則必須調(diào)整驅(qū)動(dòng)程序中的常數(shù)。如果需要幫助,請(qǐng)給我發(fā)電子郵件。您還可以從“資源”步驟中的鏈接中的Atmel應(yīng)用程序注釋中獲得一些提示。

USI_TWI_Master_Initialise()

此函數(shù)為I2C模式操作初始化USI硬件。在程序開(kāi)始時(shí)調(diào)用一次。它返回void并且沒(méi)有參數(shù)。

USI_TWI_Get_State_Info()

此函數(shù)返回I2C錯(cuò)誤信息,如果I2C事務(wù)期間發(fā)生錯(cuò)誤,則使用此函數(shù)。由于此函數(shù)僅返回錯(cuò)誤代碼,因此我使用函數(shù)TWI_Act_On_Failure_In_Last_Transmission(TWIerrorMsg)來(lái)閃爍錯(cuò)誤LED。錯(cuò)誤代碼在USI_TWI_Master.h中定義。調(diào)用方法如下:

TWI_Act_On_Failure_In_Last_Transmission(USI_TWI_Get_State_Info())

USI_TWI_Start_Read_Write()

此函數(shù)用于向I2C器件讀取和寫(xiě)入單個(gè)字節(jié)。它還用于寫(xiě)入多個(gè)字節(jié)。使用此功能有6個(gè)步驟。

1)在程序中聲明一個(gè)消息緩沖區(qū),以保存從站地址和要發(fā)送或接收的數(shù)據(jù)字節(jié)。

unsigned char messageBuf(MESSAGEBUF_SIZE);

2)將從地址作為緩沖區(qū)的第一個(gè)字節(jié)。向左移動(dòng)一位,然后在“讀/寫(xiě)”位中進(jìn)行“或”操作。請(qǐng)注意,對(duì)于讀操作,讀/寫(xiě)位將為1,對(duì)于寫(xiě)操作將為0。本示例適用于讀取。

messageBuf(0)=(TWI_targetSlaveAddress 《 3)進(jìn)行寫(xiě)操作時(shí),將要寫(xiě)入的字節(jié)放入緩沖區(qū)的下一個(gè)位置。

4)以消息緩沖區(qū)和消息大小作為參數(shù)調(diào)用USI_TWI_Start_Read_Write函數(shù)。

temp = USI_TWI_Start_Read_Write (messageBuf,2);

5)可以測(cè)試返回值(在這種情況下為溫度)以查看是否發(fā)生錯(cuò)誤。如果是這樣,則如上所述進(jìn)行處理。請(qǐng)參閱程序中的示例。

6)如果請(qǐng)求讀取,則讀取的字節(jié)將位于緩沖區(qū)的第二個(gè)位置。

如果要寫(xiě)入多個(gè)字節(jié)(例如,寫(xiě)入存儲(chǔ)設(shè)備),則此可以使用相同的例程。設(shè)置緩沖區(qū)和調(diào)用例程略有不同。緩沖區(qū)中的第二個(gè)字節(jié)將是要寫(xiě)入的起始存儲(chǔ)器地址。要寫(xiě)入的數(shù)據(jù)將在后續(xù)字節(jié)中。消息大小將是包括所有有效數(shù)據(jù)的大小。因此,如果要寫(xiě)入6個(gè)字節(jié),則消息大小將為8(從站地址+內(nèi)存地址+ 6個(gè)數(shù)據(jù)字節(jié))。

USI_TWI_Start_Random_Read()

此函數(shù)用于從I2C設(shè)備讀取多個(gè)字節(jié)。 ,通常僅對(duì)某種內(nèi)存有意義。使用此例程與上一個(gè)例程非常相似,但有兩個(gè)例外。

讀/寫(xiě)位的設(shè)置無(wú)關(guān)緊要。調(diào)用此例程將始終導(dǎo)致讀取操作。

messageSize應(yīng)該為2加上要讀取的字節(jié)數(shù)。

如果未發(fā)生錯(cuò)誤,則數(shù)據(jù)將從第二個(gè)位置開(kāi)始在緩沖區(qū)中。 》對(duì)于ATmega168:

時(shí)鐘要求:

驅(qū)動(dòng)程序設(shè)計(jì)用于ATmega168的4MHz時(shí)鐘速率。示例代碼顯示了如何設(shè)置此時(shí)鐘速率。如果要以其他速率運(yùn)行,則必須調(diào)整驅(qū)動(dòng)程序中的常數(shù)。如果需要這樣做,請(qǐng)給我發(fā)送電子郵件。

TWI_Master_Initialise()

此函數(shù)將初始化TWI硬件以進(jìn)行I2C模式操作。在程序開(kāi)始時(shí)調(diào)用一次。它返回void并且沒(méi)有參數(shù)。確保在初始化后通過(guò)調(diào)用swi()來(lái)啟用中斷。

TWI_Get_State_Info()

此函數(shù)返回I2C錯(cuò)誤信息,如果I2C事務(wù)期間發(fā)生錯(cuò)誤,則使用此函數(shù)。由于此函數(shù)僅返回錯(cuò)誤代碼,因此我使用函數(shù)TWI_Act_On_Failure_In_Last_Transmission(TWIerrorMsg)來(lái)閃爍錯(cuò)誤LED。錯(cuò)誤代碼在TWI_Master.h中定義,但已修改以在錯(cuò)誤LED上發(fā)出信號(hào)。有關(guān)詳細(xì)信息,請(qǐng)參見(jiàn)示例代碼。調(diào)用方法如下:

TWI_Act_On_Failure_In_Last_Transmission(TWI_Get_State_Info())

請(qǐng)注意,通過(guò)確保I2C事務(wù)完成(如下所述),然后在全局狀態(tài)字中進(jìn)行一點(diǎn)測(cè)試來(lái)完成錯(cuò)誤檢查。 br》 TWI_Start_Read_Write()

TWI_Start_Random_Read()

這兩個(gè)功能與上述相應(yīng)功能相同,但有一些例外。

它們不返回任何錯(cuò)誤值。

讀取的數(shù)據(jù)為沒(méi)有轉(zhuǎn)移到緩沖區(qū)。這樣做將通過(guò)下面描述的功能完成。

調(diào)用TWI_Start_Random_Read時(shí),messageSize應(yīng)該是請(qǐng)求的數(shù)據(jù)字節(jié)數(shù)加1,而不是2。

ATmega168的I2C驅(qū)動(dòng)程序是中斷驅(qū)動(dòng)的。也就是說(shuō),啟動(dòng)I2C事務(wù),然后在主例程繼續(xù)運(yùn)行時(shí)獨(dú)立執(zhí)行。當(dāng)主例程要從它啟動(dòng)的I2C事務(wù)中獲取數(shù)據(jù)時(shí),它必須檢查該數(shù)據(jù)是否可用。錯(cuò)誤檢查的情況相同。在檢查錯(cuò)誤之前,主例程必須確保I2C事務(wù)已完成。接下來(lái)的兩個(gè)函數(shù)用于這些目的。

TWI_Transceiver_Busy()

在檢查錯(cuò)誤之前,調(diào)用此函數(shù)以查看I2C事務(wù)是否已完成。示例程序演示了如何使用此方法。

TWI_Read_Data_From_Buffer()

調(diào)用此函數(shù)可將數(shù)據(jù)從I2C驅(qū)動(dòng)程序的接收緩沖區(qū)傳輸?shù)较⒕彌_區(qū)。此功能將確保在傳輸數(shù)據(jù)之前完成I2C事務(wù)。當(dāng)此函數(shù)返回一個(gè)值時(shí),我發(fā)現(xiàn)直接檢查錯(cuò)誤位更加可靠。調(diào)用方法如下。消息大小應(yīng)比所需的數(shù)據(jù)位數(shù)大一。數(shù)據(jù)將從第二個(gè)位置開(kāi)始在messageBuf中。

temp = TWI_Read_Data_From_Buffer(messageBuf,messageSize);

第4步:構(gòu)建!

首先下載文件I2C Schematics.zip。您可能需要在工作區(qū)中創(chuàng)建一個(gè)I2C文件夾,以保存原理圖和示例程序文件。將原理圖解壓縮到該目錄中。您會(huì)找到一個(gè)名為I2C Schematics的文件夾。打開(kāi)名為tiny I2C.pdf的文件。此示意圖顯示了ATtiny2313 Ghetto開(kāi)發(fā)系統(tǒng)和PCA8574A I/O端口擴(kuò)展器(周圍帶有大虛線框)。端口擴(kuò)展器電路建立在面包板上。看看照片,看看這些電路是什么樣的。它們確實(shí)非常簡(jiǎn)單。

該原理圖的ATtiny2313部分只是帶有三個(gè)閃爍指示燈(LED1、2和3,以及R4、5和6)和一個(gè)掛鉤的按鈕(S1)的Ghetto開(kāi)發(fā)系統(tǒng)。 ,以及其他一些細(xì)節(jié)。該細(xì)節(jié)是增加了跳線(JP4、5和6),可以將其刪除以允許連接I2C總線SCL和SDA線。跳線必須在適當(dāng)?shù)奈恢眠M(jìn)行編程,然后將其卸下,以便可以連接SCL和SDA。照片顯示了跳線到位并被移除。這些跳線的位置由您決定,如果要使用I2C總線,只需將它們放在Ghetto開(kāi)發(fā)系統(tǒng)上。必須斷開(kāi)I2C總線,并設(shè)置跳線以進(jìn)行編程。請(qǐng)注意,對(duì)于I2C總線,您只需要真正關(guān)心JP4和JP6。如果您想使用SPI總線,請(qǐng)放入JP5。PCA8574AI/O端口擴(kuò)展器的面包板非常簡(jiǎn)單。提供Vcc(+5伏)和Gnd(接地)連接,并將AD0、1和2接地(使I2C從地址38十六進(jìn)制)。然后連接4個(gè)指示燈和4個(gè)DIP開(kāi)關(guān)。 (如果沒(méi)有DIP開(kāi)關(guān),則可以使用電線。分別接地或懸空以分別打開(kāi)或關(guān)閉信號(hào)。)最后,將上拉電阻(R11和12)從SDA和SCL連接到Vcc。這些顯示為3.3K,但是從1.8K到5.1K的任何值都可以工作(也許可以達(dá)到10K,但我沒(méi)有嘗試過(guò))。對(duì)ATtiny2313進(jìn)行編程后,就可以刪除跳線,并連接SDA和SCL進(jìn)行測(cè)試。

現(xiàn)在用于ATmega168。這里唯一的麻煩是您可能尚未為此處理器構(gòu)建Ghetto開(kāi)發(fā)系統(tǒng)。如果是這樣,那么我提供的原理圖(MEGA I2C.pdf)將向您展示如何。這只是ATtiny2313版本的排列。如果您提前計(jì)劃,可以確保您的編程電纜可同時(shí)適用于兩個(gè)系統(tǒng)。主要區(qū)別在于添加了C2和C3。請(qǐng)參閱圖片中的這些位置,它們應(yīng)該非??拷?a target="_blank">芯片;其中之一實(shí)際上在芯片之下。這些特別有助于將噪聲排除在模數(shù)轉(zhuǎn)換器之外。除非計(jì)劃使用SPI總線,否則不需要插入跳線,因?yàn)樵撔酒系腎2C總線不需要它們。請(qǐng)注意,PCA8754A面包板將保持不變。您只需將SDA和SCL連接起來(lái),就可以使用!容易嗎?

第5步:我們進(jìn)行編碼和測(cè)試!

是時(shí)候構(gòu)建驅(qū)動(dòng)程序和示例程序了。我們將從剛構(gòu)建的ATtiny2313和PCA8574A面包板開(kāi)始。將文件I2C.zip下載到您的I2C工作目錄中并解壓縮。您將擁有一個(gè)名為I2C的新文件夾。在其中,您將找到USI I2C(用于ATtiny2313)和TWI I2C(用于ATmega168)。在USI I2C中,您會(huì)找到I_O端口文件夾。該文件夾包含我們第一個(gè)示例程序的代碼以及USI I2C驅(qū)動(dòng)程序。

使用WinAVR將代碼編譯并加載到ATtiny2313中。深呼吸并打開(kāi)電源。預(yù)期結(jié)果如下:

上電時(shí),ATtiny2313的PD6端口上的LED 1閃爍兩次。

在按下按鈕(S1)之前,什么都不會(huì)發(fā)生。每次按下按鈕,將讀取開(kāi)關(guān),并且其設(shè)置將顯示在連接到PCA8574A的LED上。更改開(kāi)關(guān)的值,按按鈕,LED將會(huì)改變。繼續(xù)這樣做,直到您克服了看到它起作用的快感。如果(上帝禁止?。┦虑闆](méi)有按預(yù)期進(jìn)行,請(qǐng)仔細(xì)檢查接線。 I2C錯(cuò)誤將通過(guò)LED3(PD4)閃爍來(lái)指示,這可能意味著您需要檢查SDA和SCL是否已連接到正確的引腳并被正確上拉。如果仍然無(wú)法解決問(wèn)題,請(qǐng)閱讀本節(jié)的其余部分以了解有關(guān)調(diào)試的信息。

現(xiàn)在返回并讓我們看一下代碼。打開(kāi)文件USI_I2C_Port.c。這是示例程序的代碼。 (USI_TWI_Master.c和USI_TWI_Master.h包含驅(qū)動(dòng)程序-除非感到好奇,否則可以忽略它們。)使用該示例指導(dǎo)自己的I2C應(yīng)用程序。

該程序通常向您展示如何初始化和使用I2C驅(qū)動(dòng)程序。 ,包括設(shè)置從站地址和消息緩沖區(qū)的其余部分,以及從中獲取數(shù)據(jù)。您還將看到我如何反跳按鈕并設(shè)置while循環(huán)。該程序有一些細(xì)節(jié)值得一提。請(qǐng)注意,來(lái)自交換機(jī)的數(shù)據(jù)在寫(xiě)入端口擴(kuò)展器上的LED之前必須先反轉(zhuǎn)。另請(qǐng)注意,必須將端口擴(kuò)展器上的輸入端口寫(xiě)為高電平,以使其正常工作。這些細(xì)節(jié)在PCA8574A數(shù)據(jù)手冊(cè)中進(jìn)行了描述。請(qǐng)務(wù)必仔細(xì)閱讀數(shù)據(jù)表!

更感興趣的是使用條件調(diào)試。在程序文件的開(kāi)始附近是語(yǔ)句//#define DEBUG,并且在整個(gè)代碼中散布的是#ifdef DEBUG語(yǔ)句。只要未定義DEBUG(兩個(gè)斜杠使該行成為注釋并阻止其定義),就不會(huì)編譯#ifdef至#endif語(yǔ)句中的代碼。但是,如果事情沒(méi)有按您預(yù)期的那樣進(jìn)行,請(qǐng)使用未注釋的#define DEBUG重新編譯并重新加載代碼。您將獲得更多的LED閃爍,您可以對(duì)其進(jìn)行解碼,以跟隨程序的執(zhí)行,并幫助您準(zhǔn)確地找出問(wèn)題所在。實(shí)際上,我建議您嘗試此操作以查看會(huì)發(fā)生什么。

您會(huì)看到隨著程序執(zhí)行的進(jìn)行,LED 2(PD5上的LED)將閃爍。從開(kāi)關(guān)讀取的值在端口擴(kuò)展器LED上顯示之前,將在LED 1(PD6)上閃爍。通過(guò)使用這些LED,您應(yīng)該能夠在程序運(yùn)行時(shí)對(duì)其進(jìn)行跟蹤。

接下來(lái),我們將與ATmega168一起工作。如果您僅對(duì)ATtiny2313感興趣,請(qǐng)?zhí)^(guò)此部分。還在我這兒?好。移至TWI_I2C文件夾,將工作目錄更改為IO_Port,然后編譯并將TWI_I2C_Port.c加載到ATmega168中。從ATtiny2313斷開(kāi)SDA和SCL線,然后將它們連接到ATmega168。連接電源和地面,然后加電。操作應(yīng)該是一樣的!播放直到刺激消退,然后看一下代碼。

打開(kāi)TWI_I2C_Port.c。該代碼幾乎完全相同,除了錯(cuò)誤處理和容納中斷驅(qū)動(dòng)的驅(qū)動(dòng)程序。區(qū)別在于:

請(qǐng)注意,必須將時(shí)鐘設(shè)置為4MHz才能使I2C總線正常工作。

sei(); I2C驅(qū)動(dòng)程序初始化后,該語(yǔ)句打開(kāi)中斷。

要檢查錯(cuò)誤,將測(cè)試特定的狀態(tài)位。

在讀取期間,必須調(diào)用TWI_Read_Data_From_Buffer函數(shù)將讀取的數(shù)據(jù)傳輸?shù)较⒕彌_區(qū)中。

在寫(xiě)入期間,必須使用(TWI_Transceiver_Busy())來(lái)確保在檢查錯(cuò)誤之前傳輸已完成。

最后兩個(gè)功能已在上面的驅(qū)動(dòng)程序說(shuō)明中進(jìn)行了描述。除此之外,代碼與ATtiny2313幾乎相同。如果您想進(jìn)行調(diào)試,則DEBUG的工作原理也相同。

步驟6:使用I2C內(nèi)存

現(xiàn)在,我們已經(jīng)學(xué)會(huì)了使用I2C總線讀寫(xiě)I/O端口擴(kuò)展器,讓我們繼續(xù)使用RAM和I2C存儲(chǔ)器EEPROM。主要區(qū)別在于可以使用單個(gè)I2C命令從存儲(chǔ)器讀取或?qū)懭攵鄠€(gè)字節(jié)。

為準(zhǔn)備好進(jìn)行這些實(shí)驗(yàn),我們需要稍微修改硬件并在試驗(yàn)板上建立幾個(gè)新電路。保留端口擴(kuò)展器電路,因?yàn)槲覀儗⑹褂盟鼇?lái)顯示一些內(nèi)存值。從PCA8574A上卸下DIP開(kāi)關(guān),然后在那些引腳上放置閃爍指示燈。如果您沒(méi)有足夠的眨眼指示燈,請(qǐng)將P4到P7的指示燈移動(dòng)到P0到P3。 (要顯示的值足夠小。)

現(xiàn)在看原理圖I2C Ram.pdf并將PCF8570連接到試驗(yàn)板上。也看一下圖片。確保將引腳7連接到Vcc。從PCA8574A為SDA和SCL布線。不需要額外的上拉電阻。

如果您也對(duì)EEPROM感興趣,也可以使用24C16的I2C EEPROM.pdf構(gòu)建該電路,但請(qǐng)注意,該示例使用ATmega168。這個(gè)電路真的很簡(jiǎn)單。如上所述,應(yīng)該忽略地址位。只需接通電源并接地即可。由于我們還沒(méi)有完成對(duì)Ram的實(shí)驗(yàn),因此請(qǐng)不要連接SDA和SCL。我們將通過(guò)連接到PCA8574A端口擴(kuò)展器和PCF8570 Ram的ATtiny2313開(kāi)始內(nèi)存實(shí)驗(yàn)。該程序?qū)⒁恍?shù)字寫(xiě)入Ram,然后將其讀回并顯示在Port Expander上。

將工作目錄更改為USI I2C下的RAM。使用生成文件來(lái)編譯和下載USI_I2C_RAM.c。請(qǐng)注意,I2C驅(qū)動(dòng)程序文件與我們先前使用的文件相同。接通電源,LED 1(PD6)上將閃爍一次。數(shù)據(jù)將被寫(xiě)入內(nèi)存的前4個(gè)字節(jié)。按下按鈕,將讀取并顯示兩個(gè)字節(jié)。您應(yīng)該在端口擴(kuò)展器(P0)上看到一個(gè)LED指示燈,停頓兩秒鐘,然后在兩個(gè)LED指示燈(P0和P1)上點(diǎn)亮。再暫停兩秒鐘,指示燈應(yīng)熄滅。再按一次按鈕可重新開(kāi)始序列。調(diào)試與上述方法相似。

讓我們看一下代碼。打開(kāi)USI_I2C_RAM.c。它看起來(lái)應(yīng)該與之前的代碼非常相似。主要區(qū)別在于讀取和寫(xiě)入內(nèi)存的細(xì)節(jié)。在實(shí)際執(zhí)行寫(xiě)操作的調(diào)用之前,先查看消息緩沖區(qū)的加載方式。第一個(gè)字節(jié)是從機(jī)地址,其讀/寫(xiě)位已適當(dāng)設(shè)置。但是下一個(gè)字節(jié)是開(kāi)始寫(xiě)入數(shù)據(jù)的內(nèi)存地址。然后是實(shí)際的數(shù)據(jù)字節(jié),這些字節(jié)將從我們指定的地址開(kāi)始依次加載到內(nèi)存中。我們將消息大小指定為6。因此,我們從地址00開(kāi)始寫(xiě)入,并將值01、03、02和06寫(xiě)入內(nèi)存位置00至03。

要從內(nèi)存中讀取數(shù)據(jù),我們必須使用USI_TWI_Start_Random_Read。功能。消息緩沖區(qū)在第一個(gè)字節(jié)中獲取從機(jī)地址,在第二個(gè)字節(jié)中獲取起始地址。然后調(diào)用消息大小設(shè)置為要讀取的字節(jié)數(shù)加上2的函數(shù)。請(qǐng)注意,讀/寫(xiě)位無(wú)關(guān)緊要,因?yàn)闊o(wú)論如何都將進(jìn)行讀取。返回的數(shù)據(jù)將從消息緩沖區(qū)的第二個(gè)位置開(kāi)始。讀入數(shù)據(jù)后,將其反轉(zhuǎn)以顯示在端口擴(kuò)展器上,并一次向其寫(xiě)入一個(gè)字節(jié),并在兩個(gè)值之間暫停。最后,端口擴(kuò)展器LED熄滅。對(duì)端口擴(kuò)展器的寫(xiě)入與前面的示例相同。有趣的是,您可以取消上面的#define DEBUG語(yǔ)句的注釋,并看到許多閃爍的LED。

在另一個(gè)成功的實(shí)驗(yàn)后興奮不已,讓我們轉(zhuǎn)到ATmega168和EEPROM。將工作目錄更改為TWI I2C下的EEPROM。使用生成文件來(lái)編譯和下載TWI_I2C_EEPROM.c。請(qǐng)注意,I2C驅(qū)動(dòng)程序文件與我們先前用于PCA8574A的文件相同。要測(cè)試程序,請(qǐng)斷開(kāi)ATtiny2313的連接并連接ATmega168。將I2C總線掛在Ram上并加電。結(jié)果不同,因?yàn)槲覀儸F(xiàn)在正在寫(xiě)入和讀取更多數(shù)據(jù)。初始化時(shí),PD7上的LED 1應(yīng)該閃爍。按下按鈕,數(shù)據(jù)將從存儲(chǔ)器中讀取并顯示。 PCA8574上的LED應(yīng)按以下順序閃爍:P1,P0和P2(全部熄滅),P0和P1,P1和P2。最后,端口LED均應(yīng)熄滅。再按一次按鈕即可重復(fù)。

哦,等一下,你說(shuō)。該程序不是用于EEPROM嗎?由于我們正在訪問(wèn)具有相同I2C地址的存儲(chǔ)設(shè)備,因此同一程序?qū)am和EEPROM均有效。斷電,然后將SDA和SCL從Ram移至EEPROM,然后再次運(yùn)行程序。它應(yīng)該工作完全相同。請(qǐng)注意,由于EEPROM和Ram共享相同的地址,因此它們不能同時(shí)連接到I2C總線。 (其中一些聰明的人可能會(huì)考慮更改Ram上的可編程地址位,但這仍然行不通。24C16使用了可以為Ram編程的整個(gè)地址塊。)

好,讓我們來(lái)看一下最后一個(gè)程序。打開(kāi)TWI_I2C_EEPROM.c。首先要注意的是,我已經(jīng)說(shuō)明了如何尋址完整的24C16 EEPROM??梢栽?個(gè)不同的I2C從設(shè)備地址上以256字節(jié)塊的形式對(duì)其進(jìn)行訪問(wèn)。查看如何將MEMORY_ADDR定義為十六進(jìn)制50的起始地址;這就是公羊工作的原因。如果要訪問(wèn)24C16的其他塊,請(qǐng)使用我已指出的其他地址??纯次胰绾卧O(shè)置寫(xiě)入內(nèi)存。首先將設(shè)置了讀/寫(xiě)位的從機(jī)地址放入緩沖區(qū),然后將起始地址00放入,然后是16字節(jié)數(shù)據(jù)。調(diào)用函數(shù)TWI_Start_Read_Write以將消息大小設(shè)置為18寫(xiě)入數(shù)據(jù)(如前所述)。按下按鈕時(shí),我們使用TWI_Start_Random_Read和TWI_Read_Data_From_Buffer讀回?cái)?shù)據(jù)。每第三個(gè)字節(jié)顯示在端口擴(kuò)展器LED上。最后,LED熄滅以等待下一次按鈕按下。

您可能想知道為什么我選擇寫(xiě)16個(gè)字節(jié)。如果仔細(xì)閱讀數(shù)據(jù)表,您會(huì)發(fā)現(xiàn)24C16只要接收到16個(gè)字節(jié)就執(zhí)行寫(xiě)周期,即使發(fā)送了更多字節(jié)也是如此。因此,這似乎是一個(gè)不錯(cuò)的數(shù)字。如果選擇增加此值,則必須更改MESSAGEBUF_SIZE的大小。您還必須在TWI_Master.h中更改值TWI_BUFFER_SIZE。這是因?yàn)轵?qū)動(dòng)程序從消息緩沖區(qū)復(fù)制了數(shù)據(jù),以供中斷服務(wù)程序使用。結(jié)果恭喜!現(xiàn)在您可以在自己的項(xiàng)目中使用I2C總線了!

第7步:網(wǎng)絡(luò)資源

以下是用于實(shí)驗(yàn)的零件的數(shù)據(jù)表鏈接。如果您什么都沒(méi)有,那么您肯定應(yīng)該得到這些。端口擴(kuò)展器,Ram,EEPROM和NXP作為I2C的創(chuàng)建者,NXP(Philips)有很多很棒的東西。 (他們喜歡在URL中使用方括號(hào),所以我不能在此處正確包括它們。抱歉。)要進(jìn)入I2C區(qū)域,請(qǐng)從“產(chǎn)品”列表中選擇“接口”。訪問(wèn)它們提供的所有數(shù)據(jù)表和應(yīng)用筆記,尤其是I2C總線描述和技術(shù)細(xì)節(jié)。

從Atmel獲得ATtiny2313和ATmega168數(shù)據(jù)表(數(shù)據(jù)手冊(cè)?)。

Atmel應(yīng)用筆記在這里。看一下AVR310和AVR315,也獲取代碼。

在這里看看更多I2C內(nèi)容。

步驟8:極客注意事項(xiàng)

對(duì)于想要了解詳細(xì)信息的真正極客,如果您查看Atmel Apps Notes和驅(qū)動(dòng)程序代碼,請(qǐng)牢記以下幾點(diǎn):

-尋址和命令I(lǐng)2C設(shè)備的方法不是規(guī)范的一部分!除了從機(jī)地址和讀/寫(xiě)位以外,沒(méi)有指定命令,模式等,這些命令,模式等特定于給定設(shè)備。為清楚起見(jiàn),請(qǐng)注意Atme中使用的方案

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • ATtiny
    +關(guān)注

    關(guān)注

    3

    文章

    128

    瀏覽量

    19534
  • I2C總線
    +關(guān)注

    關(guān)注

    8

    文章

    384

    瀏覽量

    60664
  • ATmega
    +關(guān)注

    關(guān)注

    2

    文章

    79

    瀏覽量

    42738
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    優(yōu)秀實(shí)踐:I3C共享總線上的I2C器件

    電子發(fā)燒友網(wǎng)站提供《優(yōu)秀實(shí)踐:I3C共享總線上的I2C器件.pdf》資料免費(fèi)下載
    發(fā)表于 09-06 09:49 ?0次下載
    優(yōu)秀實(shí)踐:<b class='flag-5'>I3C</b>共享<b class='flag-5'>總線</b>上的<b class='flag-5'>I2C</b>器件

    I2C總線協(xié)議的工作原理和尋址格式

    I2C(Inter-Integrated Circuit)總線協(xié)議,即集成電路總線協(xié)議,是一種用于連接微控制器及其外圍設(shè)備的串行總線協(xié)議。
    的頭像 發(fā)表于 05-27 15:47 ?1172次閱讀

    什么是I2C協(xié)議 I2C總線的控制邏輯

    在實(shí)際使用過(guò)程中,I2C比較容易出現(xiàn)的一個(gè)問(wèn)題就是死鎖 ,死鎖在I2C中主要表現(xiàn)為:I2C死鎖時(shí)表現(xiàn)為SCL為高,SDA一直為低。
    發(fā)表于 03-12 09:17 ?654次閱讀
    什么是<b class='flag-5'>I2C</b>協(xié)議 <b class='flag-5'>I2C</b><b class='flag-5'>總線</b>的控制邏輯

    藍(lán)牙串口通訊總線——I2C/SPI/UART

    嵌入式工程師在做串口通信調(diào)試工作的時(shí)候,會(huì)經(jīng)常用到I2C、SPI、UART這3條總線,I2C、SPI、UART這三種通信總線在嵌入式領(lǐng)域很常見(jiàn),目前主流的SOC芯片都內(nèi)置了這三種
    的頭像 發(fā)表于 01-22 09:41 ?1024次閱讀
    藍(lán)牙串口通訊<b class='flag-5'>總線</b>——<b class='flag-5'>I2C</b>/SPI/UART

    關(guān)于I2C總線的6個(gè)問(wèn)題分析

    I2C總線上的上拉電阻范圍是多少? 回答: 總線電容是走線部分、連接部分、管腳部分的電容的總和。總線電容限制了上拉電阻(Rp) 的最大值,因?yàn)?b class='flag-5'>
    發(fā)表于 12-25 09:19 ?1043次閱讀

    I2C總線信號(hào)與測(cè)試案例(一)

    I2C bus是Inter-IC bus的縮寫(xiě),意思是IC器件之間的通訊總線I2C 總線的特點(diǎn)如下
    的頭像 發(fā)表于 11-20 15:45 ?1506次閱讀
    <b class='flag-5'>I2C</b><b class='flag-5'>總線</b>信號(hào)與測(cè)試案例(一)

    分享I2C總線規(guī)范

    電子發(fā)燒友網(wǎng)站提供《分享I2C總線規(guī)范.pdf》資料免費(fèi)下載
    發(fā)表于 11-18 10:49 ?0次下載
    分享<b class='flag-5'>I2C</b><b class='flag-5'>總線</b>規(guī)范

    I2C串行總線組成及工作原理

    電子發(fā)燒友網(wǎng)站提供《I2C串行總線組成及工作原理.ppt》資料免費(fèi)下載
    發(fā)表于 11-16 09:23 ?1次下載
    <b class='flag-5'>I2C</b>串行<b class='flag-5'>總線</b>組成及工作原理

    I2C與SPI與UART:如何布局這些通用總線

    如果您要為項(xiàng)目構(gòu)建開(kāi)發(fā)板或使用通用MCU,則會(huì)發(fā)現(xiàn)許多用于通信其他活動(dòng)組件的協(xié)議。USB和以太網(wǎng)之類的標(biāo)準(zhǔn)已內(nèi)置在大多數(shù)控制器中,用于與計(jì)算機(jī)外圍設(shè)備一起使用。盡管如此,仍使用I2C,SPI
    的頭像 發(fā)表于 11-08 17:33 ?796次閱讀
    <b class='flag-5'>I2C</b>與SPI與UART:如何布局這些通用<b class='flag-5'>總線</b>

    I2C總線—電平轉(zhuǎn)換

    我們先來(lái)看一張圖,熟悉I2C的人一看,這不是I2C的level shifter電路嘛,在Philip的I2C標(biāo)準(zhǔn)里面有,沒(méi)有啥復(fù)雜的。
    的頭像 發(fā)表于 11-02 12:32 ?3837次閱讀
    <b class='flag-5'>I2C</b><b class='flag-5'>總線</b>—電平轉(zhuǎn)換

    I2C總線原理詳解

    I2C兩線式串行總線通訊協(xié)議,它是由飛利浦開(kāi)發(fā)的,主要用于連接微控制器及其外圍設(shè)備之間,它是由數(shù)據(jù)線SDA和信號(hào)線SCL構(gòu)成的,可發(fā)送和接收數(shù)據(jù)即在MUC和I2C設(shè)備之間,
    發(fā)表于 10-18 17:20 ?1946次閱讀
    <b class='flag-5'>I2C</b><b class='flag-5'>總線</b>原理詳解

    I2C讀寫(xiě)時(shí)序分析和實(shí)現(xiàn)思路

    上篇推文對(duì)I2C總線的特性進(jìn)行了介紹和描述。對(duì)于開(kāi)發(fā)者而言,最重要的是編碼I2C的讀寫(xiě)時(shí)序驅(qū)動(dòng)。本篇推文主要總結(jié)和分享I2C總線主機(jī)端通信的
    發(fā)表于 10-01 16:54 ?1363次閱讀
    <b class='flag-5'>I2C</b>讀寫(xiě)時(shí)序分析和實(shí)現(xiàn)思路

    I2C總線能掛多少設(shè)備 I2C架構(gòu)

    I2C總線能掛多少設(shè)備? 理論上: 7-bit address :2 的 7 次方,能掛 128 個(gè)設(shè)備。 10-bit address :2 的 10 次方,能掛 1024 個(gè)設(shè)備。
    的頭像 發(fā)表于 09-28 14:20 ?2499次閱讀
    <b class='flag-5'>I2C</b><b class='flag-5'>總線</b>能掛多少設(shè)備 <b class='flag-5'>I2C</b>架構(gòu)