步驟1:
I2C總線是一種簡單的兩線連接,可以將多個設備鏈接在一起,并允許它們交換數據。在最簡單的形式中,有一臺主設備與多個從設備進行通信。所有設備都并行連接到I2C總線的兩條線。這兩條線稱為SCL和SDA。 SCL是時鐘線,由主設備控制。 SDA是雙向數據線。為了傳輸數據,主機發送一個從機地址并結合一位讀/寫標志。如果需要寫操作,則主機將繼續向被尋址的從機發送數據。如果請求讀取,則從站將響應數據。為了協調事務,SCL和SDA線由主機和從機操縱,以發出幾種情況的信號。其中包括START,STOP,ACK(確認)和NAK(未確認)。這些條件的詳細信息由驅動程序處理。真正的極客可以在此Instructable末尾提供的鏈接中了解所有詳細信息。
電氣要求非常簡單。主機和從機必須對Vcc使用相同的電平,必須接地,并且SCL和SDA線必須上拉至Vcc。上拉電阻的值是通過基于總線上總電容的計算精確確定的,但實際上幾乎可以是1.8K到10K之間的任何值。我從5.1K開始使用較低的值,直到它起作用為止。除非您有很多設備或設備之間的電線很長,否則通常這不是問題。
I2C總線上的標稱數據速率為100Kbits/秒。也可以達到400Kbit/s,1Mbits/s或更高的速率,但是此Instructable中的驅動程序不支持這些速率。所有I2C器件都將以100Kbit/s的速度工作。
ATtiny2313和ATmega168各自實現I2C總線的方式有所不同。 ATtiny2313使用通用串行接口(USI)硬件-也可以用于SPI總線。 ATmega168具有用于I2C總線的專用硬件,稱為雙線接口(TWI)。編寫完驅動程序后,這些差異對用戶幾乎都是透明的。軟件上的一個重要區別是:ATmega168 I2C驅動程序是由中斷驅動的,而ATtiny2313則不是。這意味著ATmega168程序不必等待I2C數據傳輸發生,而只需要在啟動另一個傳輸之前等待,或者直到數據從讀取操作到達為止。 I2C地址的長度為7位,因此每個示例都有一個唯一的地址,因此總線上最多可以有127個設備。如圖所示,此7位地址左移一位,最低有效位用于在該地址標記對設備的讀取或寫入。因此,完整的從機地址是一個8位字節。實際地址部分地在設備內部確定,并且不能更改(4個最高有效位),部分地由可以連接至設備引腳的位(3個最低有效位)確定,可以將其設置為高電平或低電平以進行設置一個特定的地址。
聲音令人困惑,但是舉個例子可以清楚地說明這一點。 PCA8574A數據表顯示,I2C地址的四個最高有效位始終為0111。接下來的三位由引腳AD0,AD1和AD2的設置確定。這些引腳可以接地或連接到正電源(5伏),分別代表0或1。因此,可能的地址范圍是38到3F十六進制,如PCA8574數據表的另一幅圖所示。因此,通過更改地址位設置,可以同時在I2C總線上最多連接8個PCA8574A。每個都將僅響應其特定的從站地址。如果需要更多的I/O端口,則可以使用PCA8574。 PCA8574和PCA8574A之間的唯一區別是PCA8574的I2C從設備地址范圍是20到27個十六進制。
確定給定設備的地址可能會造成混淆,因為某些數據手冊認為讀/寫位是地址的一部分。仔細閱讀數據手冊,并牢記從機地址的長度為7位。讀/寫位應分開處理。同樣,一個例子會有所幫助。我們將試驗的24C16 EEPROM數據表中說,從機地址的前四個(最高有效位)是1010。接下來的三個位可以由A0,A1和A2確定。但請注意,數據手冊還涵蓋了尺寸較小的EEPROM 24C01至24C08。數據表中的圖顯示,這些地址位的設置隨著大小的增加而被忽略,而對于24C16則被完全忽略。也就是說,最后三位無關緊要,而24C16實際上使用所有I2C從地址50至57十六進制。從機地址范圍實際上將尋址24C16中的不同部分。前256個字節位于地址50h,下一個256位于地址51h,依此類推,直到最后一個256位于57h-總共2K字節。由于我們也嘗試過的PCF8570 RAM的地址在此范圍內,因此24C16和PCF8570不能一起使用。
第2步:訂購一些I2C設備
現在您已經對I2C總線有所了解,并想使用它,為什么不訂購
一些合適的設備包括I/O接口擴展器(我最喜歡的),靜態Ram和EEPROM。還有很多,但是這是一個很好的開始。我們將使用的AVR處理器是ATtiny2313和Atmega168(在Arduino中使用)。如果您不熟悉這些,請看看這個功能強大的Instructable,以了解它們并構建您的Ghetto開發系統。本Instructable中ATmega168的示意圖顯示了如何為該處理器實現Ghetto開發系統。并行端口電纜與ATtiny2313的電纜相同。 (我尚未嘗試使用Ghetto開發系統的USB版本,因此我不確定如何在其上訪問I2C總線。與Arduino相同。)
這是Digikey的部件號。
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驅動程序
以下是I2C總線驅動程序功能的說明。這些是使用面向初學者的Atmel Apps Notes開發的。沒有他們,我無法做得到這一基礎。使用WinAVR和gcc C編譯器進行了開發。
下面對每個處理器的時鐘速率限制進行了說明。由于我無法測試所有可能的處理器風格/時鐘速率組合,因此我將堅持實際測試并嘗試指出限制和限制。
以下是驅動程序功能以及如何使用它們。請查看示例以獲取更多詳細信息,并查看完整程序中使用的功能。
對于ATtiny2313:
時鐘要求:
驅動程序的設計時鐘頻率為1MHz(默認頻率)對于ATtiny2313。如果要以其他速率運行,則必須調整驅動程序中的常數。如果需要幫助,請給我發電子郵件。您還可以從“資源”步驟中的鏈接中的Atmel應用程序注釋中獲得一些提示。
USI_TWI_Master_Initialise()
此函數為I2C模式操作初始化USI硬件。在程序開始時調用一次。它返回void并且沒有參數。
USI_TWI_Get_State_Info()
此函數返回I2C錯誤信息,如果I2C事務期間發生錯誤,則使用此函數。由于此函數僅返回錯誤代碼,因此我使用函數TWI_Act_On_Failure_In_Last_Transmission(TWIerrorMsg)來閃爍錯誤LED。錯誤代碼在USI_TWI_Master.h中定義。調用方法如下:
TWI_Act_On_Failure_In_Last_Transmission(USI_TWI_Get_State_Info())
USI_TWI_Start_Read_Write()
此函數用于向I2C器件讀取和寫入單個字節。它還用于寫入多個字節。使用此功能有6個步驟。
1)在程序中聲明一個消息緩沖區,以保存從站地址和要發送或接收的數據字節。
unsigned char messageBuf(MESSAGEBUF_SIZE);
2)將從地址作為緩沖區的第一個字節。向左移動一位,然后在“讀/寫”位中進行“或”操作。請注意,對于讀操作,讀/寫位將為1,對于寫操作將為0。本示例適用于讀取。
messageBuf(0)=(TWI_targetSlaveAddress 《 3)進行寫操作時,將要寫入的字節放入緩沖區的下一個位置。
4)以消息緩沖區和消息大小作為參數調用USI_TWI_Start_Read_Write函數。
temp = USI_TWI_Start_Read_Write (messageBuf,2);
5)可以測試返回值(在這種情況下為溫度)以查看是否發生錯誤。如果是這樣,則如上所述進行處理。請參閱程序中的示例。
6)如果請求讀取,則讀取的字節將位于緩沖區的第二個位置。
如果要寫入多個字節(例如,寫入存儲設備),則此可以使用相同的例程。設置緩沖區和調用例程略有不同。緩沖區中的第二個字節將是要寫入的起始存儲器地址。要寫入的數據將在后續字節中。消息大小將是包括所有有效數據的大小。因此,如果要寫入6個字節,則消息大小將為8(從站地址+內存地址+ 6個數據字節)。
USI_TWI_Start_Random_Read()
此函數用于從I2C設備讀取多個字節。 ,通常僅對某種內存有意義。使用此例程與上一個例程非常相似,但有兩個例外。
讀/寫位的設置無關緊要。調用此例程將始終導致讀取操作。
messageSize應該為2加上要讀取的字節數。
如果未發生錯誤,則數據將從第二個位置開始在緩沖區中。 》對于ATmega168:
時鐘要求:
驅動程序設計用于ATmega168的4MHz時鐘速率。示例代碼顯示了如何設置此時鐘速率。如果要以其他速率運行,則必須調整驅動程序中的常數。如果需要這樣做,請給我發送電子郵件。
TWI_Master_Initialise()
此函數將初始化TWI硬件以進行I2C模式操作。在程序開始時調用一次。它返回void并且沒有參數。確保在初始化后通過調用swi()來啟用中斷。
TWI_Get_State_Info()
此函數返回I2C錯誤信息,如果I2C事務期間發生錯誤,則使用此函數。由于此函數僅返回錯誤代碼,因此我使用函數TWI_Act_On_Failure_In_Last_Transmission(TWIerrorMsg)來閃爍錯誤LED。錯誤代碼在TWI_Master.h中定義,但已修改以在錯誤LED上發出信號。有關詳細信息,請參見示例代碼。調用方法如下:
TWI_Act_On_Failure_In_Last_Transmission(TWI_Get_State_Info())
請注意,通過確保I2C事務完成(如下所述),然后在全局狀態字中進行一點測試來完成錯誤檢查。 br》 TWI_Start_Read_Write()
TWI_Start_Random_Read()
這兩個功能與上述相應功能相同,但有一些例外。
它們不返回任何錯誤值。
讀取的數據為沒有轉移到緩沖區。這樣做將通過下面描述的功能完成。
調用TWI_Start_Random_Read時,messageSize應該是請求的數據字節數加1,而不是2。
ATmega168的I2C驅動程序是中斷驅動的。也就是說,啟動I2C事務,然后在主例程繼續運行時獨立執行。當主例程要從它啟動的I2C事務中獲取數據時,它必須檢查該數據是否可用。錯誤檢查的情況相同。在檢查錯誤之前,主例程必須確保I2C事務已完成。接下來的兩個函數用于這些目的。
TWI_Transceiver_Busy()
在檢查錯誤之前,調用此函數以查看I2C事務是否已完成。示例程序演示了如何使用此方法。
TWI_Read_Data_From_Buffer()
調用此函數可將數據從I2C驅動程序的接收緩沖區傳輸到消息緩沖區。此功能將確保在傳輸數據之前完成I2C事務。當此函數返回一個值時,我發現直接檢查錯誤位更加可靠。調用方法如下。消息大小應比所需的數據位數大一。數據將從第二個位置開始在messageBuf中。
temp = TWI_Read_Data_From_Buffer(messageBuf,messageSize);
第4步:構建!
首先下載文件I2C Schematics.zip。您可能需要在工作區中創建一個I2C文件夾,以保存原理圖和示例程序文件。將原理圖解壓縮到該目錄中。您會找到一個名為I2C Schematics的文件夾。打開名為tiny I2C.pdf的文件。此示意圖顯示了ATtiny2313 Ghetto開發系統和PCA8574A I/O端口擴展器(周圍帶有大虛線框)。端口擴展器電路建立在面包板上。看看照片,看看這些電路是什么樣的。它們確實非常簡單。
該原理圖的ATtiny2313部分只是帶有三個閃爍指示燈(LED1、2和3,以及R4、5和6)和一個掛鉤的按鈕(S1)的Ghetto開發系統。 ,以及其他一些細節。該細節是增加了跳線(JP4、5和6),可以將其刪除以允許連接I2C總線SCL和SDA線。跳線必須在適當的位置進行編程,然后將其卸下,以便可以連接SCL和SDA。照片顯示了跳線到位并被移除。這些跳線的位置由您決定,如果要使用I2C總線,只需將它們放在Ghetto開發系統上。必須斷開I2C總線,并設置跳線以進行編程。請注意,對于I2C總線,您只需要真正關心JP4和JP6。如果您想使用SPI總線,請放入JP5。PCA8574AI/O端口擴展器的面包板非常簡單。提供Vcc(+5伏)和Gnd(接地)連接,并將AD0、1和2接地(使I2C從地址38十六進制)。然后連接4個指示燈和4個DIP開關。 (如果沒有DIP開關,則可以使用電線。分別接地或懸空以分別打開或關閉信號。)最后,將上拉電阻(R11和12)從SDA和SCL連接到Vcc。這些顯示為3.3K,但是從1.8K到5.1K的任何值都可以工作(也許可以達到10K,但我沒有嘗試過)。對ATtiny2313進行編程后,就可以刪除跳線,并連接SDA和SCL進行測試。
現在用于ATmega168。這里唯一的麻煩是您可能尚未為此處理器構建Ghetto開發系統。如果是這樣,那么我提供的原理圖(MEGA I2C.pdf)將向您展示如何。這只是ATtiny2313版本的排列。如果您提前計劃,可以確保您的編程電纜可同時適用于兩個系統。主要區別在于添加了C2和C3。請參閱圖片中的這些位置,它們應該非常靠近芯片;其中之一實際上在芯片之下。這些特別有助于將噪聲排除在模數轉換器之外。除非計劃使用SPI總線,否則不需要插入跳線,因為該芯片上的I2C總線不需要它們。請注意,PCA8754A面包板將保持不變。您只需將SDA和SCL連接起來,就可以使用!容易嗎?
第5步:我們進行編碼和測試!
是時候構建驅動程序和示例程序了。我們將從剛構建的ATtiny2313和PCA8574A面包板開始。將文件I2C.zip下載到您的I2C工作目錄中并解壓縮。您將擁有一個名為I2C的新文件夾。在其中,您將找到USI I2C(用于ATtiny2313)和TWI I2C(用于ATmega168)。在USI I2C中,您會找到I_O端口文件夾。該文件夾包含我們第一個示例程序的代碼以及USI I2C驅動程序。
使用WinAVR將代碼編譯并加載到ATtiny2313中。深呼吸并打開電源。預期結果如下:
上電時,ATtiny2313的PD6端口上的LED 1閃爍兩次。
在按下按鈕(S1)之前,什么都不會發生。每次按下按鈕,將讀取開關,并且其設置將顯示在連接到PCA8574A的LED上。更改開關的值,按按鈕,LED將會改變。繼續這樣做,直到您克服了看到它起作用的快感。如果(上帝禁止!)事情沒有按預期進行,請仔細檢查接線。 I2C錯誤將通過LED3(PD4)閃爍來指示,這可能意味著您需要檢查SDA和SCL是否已連接到正確的引腳并被正確上拉。如果仍然無法解決問題,請閱讀本節的其余部分以了解有關調試的信息。
現在返回并讓我們看一下代碼。打開文件USI_I2C_Port.c。這是示例程序的代碼。 (USI_TWI_Master.c和USI_TWI_Master.h包含驅動程序-除非感到好奇,否則可以忽略它們。)使用該示例指導自己的I2C應用程序。
該程序通常向您展示如何初始化和使用I2C驅動程序。 ,包括設置從站地址和消息緩沖區的其余部分,以及從中獲取數據。您還將看到我如何反跳按鈕并設置while循環。該程序有一些細節值得一提。請注意,來自交換機的數據在寫入端口擴展器上的LED之前必須先反轉。另請注意,必須將端口擴展器上的輸入端口寫為高電平,以使其正常工作。這些細節在PCA8574A數據手冊中進行了描述。請務必仔細閱讀數據表!
更感興趣的是使用條件調試。在程序文件的開始附近是語句//#define DEBUG,并且在整個代碼中散布的是#ifdef DEBUG語句。只要未定義DEBUG(兩個斜杠使該行成為注釋并阻止其定義),就不會編譯#ifdef至#endif語句中的代碼。但是,如果事情沒有按您預期的那樣進行,請使用未注釋的#define DEBUG重新編譯并重新加載代碼。您將獲得更多的LED閃爍,您可以對其進行解碼,以跟隨程序的執行,并幫助您準確地找出問題所在。實際上,我建議您嘗試此操作以查看會發生什么。
您會看到隨著程序執行的進行,LED 2(PD5上的LED)將閃爍。從開關讀取的值在端口擴展器LED上顯示之前,將在LED 1(PD6)上閃爍。通過使用這些LED,您應該能夠在程序運行時對其進行跟蹤。
接下來,我們將與ATmega168一起工作。如果您僅對ATtiny2313感興趣,請跳過此部分。還在我這兒?好。移至TWI_I2C文件夾,將工作目錄更改為IO_Port,然后編譯并將TWI_I2C_Port.c加載到ATmega168中。從ATtiny2313斷開SDA和SCL線,然后將它們連接到ATmega168。連接電源和地面,然后加電。操作應該是一樣的!播放直到刺激消退,然后看一下代碼。
打開TWI_I2C_Port.c。該代碼幾乎完全相同,除了錯誤處理和容納中斷驅動的驅動程序。區別在于:
請注意,必須將時鐘設置為4MHz才能使I2C總線正常工作。
sei(); I2C驅動程序初始化后,該語句打開中斷。
要檢查錯誤,將測試特定的狀態位。
在讀取期間,必須調用TWI_Read_Data_From_Buffer函數將讀取的數據傳輸到消息緩沖區中。
在寫入期間,必須使用(TWI_Transceiver_Busy())來確保在檢查錯誤之前傳輸已完成。
最后兩個功能已在上面的驅動程序說明中進行了描述。除此之外,代碼與ATtiny2313幾乎相同。如果您想進行調試,則DEBUG的工作原理也相同。
步驟6:使用I2C內存
現在,我們已經學會了使用I2C總線讀寫I/O端口擴展器,讓我們繼續使用RAM和I2C存儲器EEPROM。主要區別在于可以使用單個I2C命令從存儲器讀取或寫入多個字節。
為準備好進行這些實驗,我們需要稍微修改硬件并在試驗板上建立幾個新電路。保留端口擴展器電路,因為我們將使用它來顯示一些內存值。從PCA8574A上卸下DIP開關,然后在那些引腳上放置閃爍指示燈。如果您沒有足夠的眨眼指示燈,請將P4到P7的指示燈移動到P0到P3。 (要顯示的值足夠小。)
現在看原理圖I2C Ram.pdf并將PCF8570連接到試驗板上。也看一下圖片。確保將引腳7連接到Vcc。從PCA8574A為SDA和SCL布線。不需要額外的上拉電阻。
如果您也對EEPROM感興趣,也可以使用24C16的I2C EEPROM.pdf構建該電路,但請注意,該示例使用ATmega168。這個電路真的很簡單。如上所述,應該忽略地址位。只需接通電源并接地即可。由于我們還沒有完成對Ram的實驗,因此請不要連接SDA和SCL。我們將通過連接到PCA8574A端口擴展器和PCF8570 Ram的ATtiny2313開始內存實驗。該程序將一些數字寫入Ram,然后將其讀回并顯示在Port Expander上。
將工作目錄更改為USI I2C下的RAM。使用生成文件來編譯和下載USI_I2C_RAM.c。請注意,I2C驅動程序文件與我們先前使用的文件相同。接通電源,LED 1(PD6)上將閃爍一次。數據將被寫入內存的前4個字節。按下按鈕,將讀取并顯示兩個字節。您應該在端口擴展器(P0)上看到一個LED指示燈,停頓兩秒鐘,然后在兩個LED指示燈(P0和P1)上點亮。再暫停兩秒鐘,指示燈應熄滅。再按一次按鈕可重新開始序列。調試與上述方法相似。
讓我們看一下代碼。打開USI_I2C_RAM.c。它看起來應該與之前的代碼非常相似。主要區別在于讀取和寫入內存的細節。在實際執行寫操作的調用之前,先查看消息緩沖區的加載方式。第一個字節是從機地址,其讀/寫位已適當設置。但是下一個字節是開始寫入數據的內存地址。然后是實際的數據字節,這些字節將從我們指定的地址開始依次加載到內存中。我們將消息大小指定為6。因此,我們從地址00開始寫入,并將值01、03、02和06寫入內存位置00至03。
要從內存中讀取數據,我們必須使用USI_TWI_Start_Random_Read。功能。消息緩沖區在第一個字節中獲取從機地址,在第二個字節中獲取起始地址。然后調用消息大小設置為要讀取的字節數加上2的函數。請注意,讀/寫位無關緊要,因為無論如何都將進行讀取。返回的數據將從消息緩沖區的第二個位置開始。讀入數據后,將其反轉以顯示在端口擴展器上,并一次向其寫入一個字節,并在兩個值之間暫停。最后,端口擴展器LED熄滅。對端口擴展器的寫入與前面的示例相同。有趣的是,您可以取消上面的#define DEBUG語句的注釋,并看到許多閃爍的LED。
在另一個成功的實驗后興奮不已,讓我們轉到ATmega168和EEPROM。將工作目錄更改為TWI I2C下的EEPROM。使用生成文件來編譯和下載TWI_I2C_EEPROM.c。請注意,I2C驅動程序文件與我們先前用于PCA8574A的文件相同。要測試程序,請斷開ATtiny2313的連接并連接ATmega168。將I2C總線掛在Ram上并加電。結果不同,因為我們現在正在寫入和讀取更多數據。初始化時,PD7上的LED 1應該閃爍。按下按鈕,數據將從存儲器中讀取并顯示。 PCA8574上的LED應按以下順序閃爍:P1,P0和P2(全部熄滅),P0和P1,P1和P2。最后,端口LED均應熄滅。再按一次按鈕即可重復。
哦,等一下,你說。該程序不是用于EEPROM嗎?由于我們正在訪問具有相同I2C地址的存儲設備,因此同一程序對Ram和EEPROM均有效。斷電,然后將SDA和SCL從Ram移至EEPROM,然后再次運行程序。它應該工作完全相同。請注意,由于EEPROM和Ram共享相同的地址,因此它們不能同時連接到I2C總線。 (其中一些聰明的人可能會考慮更改Ram上的可編程地址位,但這仍然行不通。24C16使用了可以為Ram編程的整個地址塊。)
好,讓我們來看一下最后一個程序。打開TWI_I2C_EEPROM.c。首先要注意的是,我已經說明了如何尋址完整的24C16 EEPROM。可以在8個不同的I2C從設備地址上以256字節塊的形式對其進行訪問。查看如何將MEMORY_ADDR定義為十六進制50的起始地址;這就是公羊工作的原因。如果要訪問24C16的其他塊,請使用我已指出的其他地址。看看我如何設置寫入內存。首先將設置了讀/寫位的從機地址放入緩沖區,然后將起始地址00放入,然后是16字節數據。調用函數TWI_Start_Read_Write以將消息大小設置為18寫入數據(如前所述)。按下按鈕時,我們使用TWI_Start_Random_Read和TWI_Read_Data_From_Buffer讀回數據。每第三個字節顯示在端口擴展器LED上。最后,LED熄滅以等待下一次按鈕按下。
您可能想知道為什么我選擇寫16個字節。如果仔細閱讀數據表,您會發現24C16只要接收到16個字節就執行寫周期,即使發送了更多字節也是如此。因此,這似乎是一個不錯的數字。如果選擇增加此值,則必須更改MESSAGEBUF_SIZE的大小。您還必須在TWI_Master.h中更改值TWI_BUFFER_SIZE。這是因為驅動程序從消息緩沖區復制了數據,以供中斷服務程序使用。結果恭喜!現在您可以在自己的項目中使用I2C總線了!
第7步:網絡資源
以下是用于實驗的零件的數據表鏈接。如果您什么都沒有,那么您肯定應該得到這些。端口擴展器,Ram,EEPROM和NXP作為I2C的創建者,NXP(Philips)有很多很棒的東西。 (他們喜歡在URL中使用方括號,所以我不能在此處正確包括它們。抱歉。)要進入I2C區域,請從“產品”列表中選擇“接口”。訪問它們提供的所有數據表和應用筆記,尤其是I2C總線描述和技術細節。
從Atmel獲得ATtiny2313和ATmega168數據表(數據手冊?)。
Atmel應用筆記在這里。看一下AVR310和AVR315,也獲取代碼。
在這里看看更多I2C內容。
步驟8:極客注意事項
對于想要了解詳細信息的真正極客,如果您查看Atmel Apps Notes和驅動程序代碼,請牢記以下幾點:
-尋址和命令I2C設備的方法不是規范的一部分!除了從機地址和讀/寫位以外,沒有指定命令,模式等,這些命令,模式等特定于給定設備。為清楚起見,請注意Atme中使用的方案
-
ATtiny
+關注
關注
3文章
128瀏覽量
19606 -
I2C總線
+關注
關注
8文章
391瀏覽量
61036 -
ATmega
+關注
關注
2文章
79瀏覽量
42852
發布評論請先 登錄
相關推薦
評論