本應用筆記是探討MAX3108高性能通用異步接收器/發送器(UART)特性系列筆記中的第一篇,解釋了MAX3108和控制微處理器之間的基本接口。應用筆記簡要介紹了通過2、4或6引腳實現硬件連接;實現31個寄存器,可通過SPI或I2C接口訪問;和三種復位機制。下面詳細介紹了SPI和I2C接口以及偽代碼示例。
介紹
MAX3108為高性能通用異步收發器(UART),采用晶圓級封裝(WLP),理想用于低功耗便攜式設備。其高級功能范圍從單獨的 128 字發送和接收 FIFO 到廣泛的硬件介導流控制。然而,在應用利用這些特性之前,它必須與MAX3108及其31個內部寄存器進行可靠的通信。本應用筆記介紹了MAX3108通信的基本原理。有關偽代碼的軟件約定顯示在附錄中。
硬件連接
MAX3108與微處理器(μP)之間的通信通過2、4或6個引腳進行。兩個專用引腳IRQ和RST通常連接到微處理器 GPIO 引腳。IRQ是微處理器的輸入引腳。作為雙功能信號,IRQ既指示MAX3108復位何時完成,又在發生某些可編程UART事件時通知微處理器。RST是微處理器的輸出引腳。它可靠地強制MAX3108復位至已知狀態。盡管可以在不使用這些引腳的情況下實現功能應用程序,但最好連接它們,除非缺少 GPIO 引腳。
MAX3108實現31個寄存器,每個寄存器一個字節寬,可通過SPI或I2C接口訪問,該接口在硬件中選擇。由于其更大的帶寬和更簡單的實現,SPI接口更可取。將 SPI I2C 引腳連接到高電平可實現 SPI 接口。將其設置為低電平可實現I2C接口。
MAX3108 SPI接口直接連接到微處理器上常用的SPI硬件引擎時效果最佳。
微處理器 SPI 引腳 | MAX3108引腳 |
MISO | MISO/SDA |
MOSI | MOSI/A1 |
SCLK | SCLK/SCL |
SS | CS |
與其他SPI接口實現不同,即使MAX3108是SPI總線上唯一的器件,從選擇(SS)信號也必須連接到MAX3108。
同樣,I2C接口在直接連接到微處理器上的I2C硬件引擎時效果最佳。
微處理器I2C引腳 | MAX3108引腳 |
SCL | SCLK/SCL |
SDA | MISO/SDA |
與SPI接口不同,I2C接口依賴于總線上具有唯一I2C地址的每個外設。為幫助避免地址沖突,引腳MOSI/A1和%-overbar_pre%CS%-overbar_post%/A0上的硬件引腳搭接選項可將MAX3108 I2C外設地址固定為16種可能性之一。
重置
MAX3108具有三種復位機制,所有這些機制都使MAX3108處于已知狀態,需要后續寄存器設置負載。
第一種復位機制是在上電時自動復位。MAX3108要完成復位,無需時鐘。但是,1.8V電源必須啟動并運行。LDOEN 必須連接高電平,或者如果 LDOEN 連接為低電平,則必須將有效的 1.8V 電源連接到 V18 引腳。僅在復位期間,%-overbar_pre%IRQ%-overbar_post%引腳不是中斷指示器,而是復位完成指示器。一旦%-overbar_pre%IRQ%-overbar_post%引腳變為高電平,復位完成。如果MAX3108不存在或未上電,程序流可能會無限期地卡在環路中。如果這是一個問題,請添加一個計時器。如果 %-overbar_pre%IRQ%-overbar_post% 在 300μs 后仍未出現,您可以假設有問題。為避免在MAX3108完全就緒之前寫入寄存器,應用必須遵循以下步驟。
/* ** Wait for the MAX3108 to come out of reset */ // Wait for the IRQ pin to come up, as this // indicates that the MAX3108 reset is complete while (POLL_MAX3108_IRQ == 0);
第二種復位機制是通過MAX3108 RST引腳進行硬件復位。在這種情況下,手動將RST引腳脈沖為低電平,然后為高電平。與上電時自動復位一樣,%-overbar_pre%IRQ%-overbar_post%引腳表示復位完成。如上所述,為防止MAX3108缺電或未上電時無限期卡在環路中,增加一個延遲最小為300μs的定時器。偽代碼見下文。while
/* ** Perform a hardware reset */ SET_MAX3108_RESET_PIN_LOW; WAIT (1μs); SET_MAX3108_RESET_PIN_HIGH; // Wait for the IRQ pin to come up, as this // indicates that the MAX3108 reset is complete while (POLL_MAX3108_IRQ == 0);
第三種復位機制是軟件控制的復位,依賴于MAX3108的SPI或I2C訪問。與其他復位一樣,MAX3108寄存器需要在復位完成后重新加載。使用以下偽代碼調用重置。
/* ** Software reset of the MAX3108 */ MAX3108_Write (MAX3108R_MODE2, 0x01); MAX3108_Write (MAX3108R_MODE2, 0x00);
通過 SPI 接口
MAX3108與微處理器之間的通信通過%-overbar_pre%RST%-overbar_post%引腳、%-overbar_pre%IRQ%-overbar_post%引腳(均如上所述)以及應用微處理器和MAX3108寄存器之間的接口進行。該寄存器接口可以是SPI或I2C接口。有關SPI選項的詳細信息在此處,而有關I2C接口的詳細信息顯示在通過I2C接口部分。
SPI 接口是微處理器上常用的硬件接口。SPI接口的另一個優點是它的速度。MAX3108可支持高達26Mbps的SPI數據速率,比目前大多數微處理器SPI硬件更快。
MAX3108 SPI接口不僅支持單寄存器讀寫,還支持突發讀寫。這些突發事務提高了寄存器接口的效率,進一步推開了寄存器接口成為瓶頸的點。
與其他SPI方案不同,微處理器上SPI主硬件的SS信號必須連接至MAX3108 %-overbar_pre%CS%-overbar_post%/A0引腳。除了選擇SPI總線外設的傳統用途外,%-overbar_pre%CS%-overbar_post%/A0引腳還向MAX3108發出SPI事務邊界信號。%-overbar_pre%CS%-overbar_post%/A0的下降沿向MAX3108表示SPI接口上的下一個字節是MAX3108寄存器地址。%-overbar_pre%CS%-overbar_post%/A0的上升沿向MAX3108發出信號,表明SPI事務(單次讀取、單次寫入、突發讀取或突發寫入)已經結束。
SPI 事務本質上是雙向的。對于從微處理器寫入MAX3108的每個字節,MAX3108同時返回一個字節到微處理器。這些往往可以忽略;寄存器寫操作忽略MAX3108的返回字節。類似地,寄存器讀取返回其值,微處理器向MAX3108發送虛擬字節。這些虛擬字節不會降低接口速度,因為它們與有效的寄存器讀取或寫入數據同時發生。
單 SPI 寫入
單個寫入事務的偽代碼如下所示:
/* ** Write one byte to the specified register in the MAX3108 ** ** Arguments: ** port: MAX3108 register address to write to (0x00 through 0x1e) ** val: the value to write to that register ** ** return value: TRUE ** */ BOOL MAX3108_SPI_Write (unsigned int port, unsigned char val) { unsigned int dummy; // Indicate the start of a transaction SET_MAX3108_CS_PIN_LOW; // Write transaction is indicated by MSbit of the // MAX3108 register address byte = 1. SPI return // from the MAX3108 ignored dummy = SPI_SEND_BYTE (0x80 | port); // Now send the value to write, return value ignored dummy = SPI_SEND_BYTE (val); // Finally, indicate transaction completion SET_MAX3108_CS_PIN_HIGH; return TRUE; }
突發 SPI 寫入
MAX3108 SPI接口還支持突發寫入,適用于快速FIFO填充或快速寄存器負載。如果寄存器地址為零,則突發寫入將填充發送FIFO。這允許快速FIFO填充,無需切換MAX3108 %-overbar_pre%CS%-overbar_post%/A0線或為每個寫入FIFO字節發送寄存器地址。
對于任何其他MAX3108寄存器地址,寄存器地址隨著突發的每個后續字節自動遞增,從而允許快速寄存器填充。
突發寫入事務的偽代碼如下所示:
/* ** Write a burst of bytes to the MAX3108 ** ** Arguments: ** port: MAX3108 register address to write to ** len: number of bytes to send to MAX3108 registers ** ptr: pointer to the bytes to send ** ** return value: TRUE ** */ BOOL MAX3108_SPI_Puts (unsigned int port, unsigned int len, unsigned char *ptr) { unsigned int dummy; // Indicate the start of a transaction SET_MAX3108_CS_PIN_LOW; // Write transaction indicated by MSbit of the // MAX3108 register address byte = 1. SPI return // from the MAX3108 ignored dummy = SPI_SEND_BYTE (0x80 | port); // Covers the case where len==0 while (len--) { dummy = SPI_SEND_BYTE (*ptr++); // return value ignored } // Indicate transaction completion SET_MAX3108_CS_PIN_HIGH; return TRUE; }
注意,對于突發寫入事務,第一個字節是MAX3108寄存器地址,所有后續字節都是寄存器值寫入。最終寄存器寫入由CS A0引腳變為高電平表示。
SPI硬件引擎(通常基于DMA)也控制MAX3108 CSA0引腳,通常通過標有overbar_post overbar_pre SS的引腳。當CS A0 變低時,表示下一個 SPI 事務開始。CSA0必須保持較高的最短時間為100ns。此時確保MAX3108識別出交易已完成。
單 SPI 讀取
通過SPI讀取寄存器字節涉及發送寄存器地址,后跟虛擬字節。來自虛擬字節的SPI反饋是所選MAX3108寄存器的值。
單次讀取的偽代碼如下:
/* ** Read one byte from the specified register in the MAX3108 ** ** Arguments: ** port: MAX3108 register address to read from ** ** return value: the register value ** */ unsigned int MAX3108_SPI_Read (unsigned int port) { unsigned int dummy; unsigned int val; // Indicate the start of a transaction SET_MAX3108_CS_PIN_LOW; // Read transaction indicated by MSbit of the // address byte = 0. SPI return from the MAX3108 // ignored dummy = SPI_SEND_BYTE (port & 0x7f); // Now send a dummy byte to collect the // register value val = SPI_SEND_BYTE (0x00); // Finally, indicate transaction completion SET_MAX3108_CS_PIN_HIGH; return val; }
突發 SPI 讀取
MAX3108 SPI接口還支持突發讀取,適用于快速FIFO清空或快速寄存器掃描。如果寄存器地址為零,則突發讀取為空接收FIFO。這樣就可以快速進行FIFO轉儲,而無需切換MAX3108 %-overbar_pre%CS%-overbar_post%/A0線或為每個FIFO字節讀取發送寄存器地址。
對于任何其他MAX3108寄存器地址,寄存器地址隨著突發的每個后續字節自動遞增,從而允許快速寄存器掃描。
突發讀取事務的偽代碼如下:
/* ** Read a burst of bytes from the MAX3108 ** ** Arguments: ** port: MAX3108 register address to read from ** len: number of bytes to get from MAX3108 registers ** ptr: pointer to where to place the bytes ** ** return value: TRUE ** */ BOOL MAX3108_SPI_Gets (unsigned int port, unsigned int len, unsigned char *ptr) { unsigned int dummy; // Indicate the start of a transaction SET_MAX3108_CS_PIN_LOW; // Read transaction indicated by MSbit of the // address byte = 0. SPI return from the MAX3108 // ignored dummy = SPI_SEND_BYTE (port & 0x7f); // Covers the case where len==0 while (len--) { *ptr++ = SPI_SEND_BYTE (0x00); } // Indicate transaction completion SET_MAX3108_CS_PIN_HIGH; return TRUE; }
注意,對于突發讀取事務,第一個字節是MAX3108寄存器地址,所有后續字節都是假字節,其返回值為寄存器值。最終寄存器讀取由%-overbar_pre%CS%-overbar_post%/A0引腳變為高電平表示。
通過I2C接口
MAX3108寄存器和微處理器之間的通信也可以通過I2C接口進行。
I2C接口是微處理器上常見的硬件輔助接口。I2C接口的另一個優點是它只使用兩個引腳。I2C接口不是為每個外設單獨選擇片(如SPI接口),而是依賴于具有唯一I2C地址的每個外設。為避免與同一I2C總線上的其他I2C外設發生沖突,MAX3108可通過MOSI/A1和%-overbar_pre%CS%-overbar_post%/A0引腳的引腳搭接,對16個唯一的I2C外設地址進行引腳編程。在下面的偽代碼中,假定預處理器變量MAX3108_I2C_PERIPHERAL_ADDRESS使用適當的I2C寄存器寫入地址進行定義,該地址與同一總線上的任何其他I2C外設的地址是唯一的。
MAX3108不僅支持標準模式(100kbps)和快速模式(400kbps)I2C,還支持快速模式加(1Mbps)I2C。
MAX3108 I2C接口不僅支持單寄存器讀寫,還支持突發讀寫。這些突發事務提高了寄存器接口的效率,進一步推開了寄存器接口成為瓶頸的點。
單路I2C寫入
單個寫入事務的偽代碼如下所示:
/* ** Write one byte to the specified register in the MAX3108 ** ** Arguments: ** port: MAX3108 register address to write to ** val: the value to write to that register ** ** return value: TRUE – register successfully written ** FALSE – I2C protocol error of some kind ** */ BOOL MAX3108_I2C_Write (unsigned int port, unsigned char val) { // Indicate the start of a transaction and send the // MAX3108 write peripheral address (LSbit = 0) I2C_SET_START_CONDITION; I2C_SEND_BYTE (MAX3108_I2C_PERIPHERAL_ADDRESS); // Is anybody out there? if (!I2C_TEST_ACK) { I2C_SET_STOP_CONDITION; // no – close out the return FALSE; // transaction } // The MAX3108 is out there, now send the MAX3108 // register to write I2C_SEND_BYTE (port); // Possibly illegal MAX3108 register address? If (!I2C_TEST_ACK) { I2C_SET_STOP_CONDITION; return FALSE; } // Now send the byte to write I2C_SEND_BYTE (val); // Did the MAX3108 get confused? If (!I2C_TEST_ACK) { I2C_SET_STOP_CONDITION; return FALSE; } // The MAX3108 is OK with our write, make it so I2C_SET_STOP_CONDITION; return TRUE; }
突發I2C寫入
MAX3108 I2C接口還支持突發寫入,適用于快速FIFO填充或快速寄存器負載。如果寄存器地址為零,則突發寫入將填充發送FIFO。這允許快速FIFO填充,而無需為每個寫入FIFO字節產生I2C前導碼開銷。
對于任何其他MAX3108寄存器地址,寄存器地址隨著突發的每個后續字節自動遞增,從而允許快速寄存器填充。
突發寫入事務的偽代碼如下所示:
/* ** Write a burst of bytes to the MAX3108 ** ** Arguments: ** port: MAX3108 register address to write to ** len: number of bytes to send to MAX3108 registers ** ptr: pointer to the bytes to send ** ** return value: TRUE – register successfully written ** FALSE – I2C protocol error of some kind ** */ BOOL MAX3108_I2C_Puts (unsigned int port, unsigned int len, unsigned char *ptr) { // Indicate the start of a transaction and send the // MAX3108 write peripheral address (LSbit = 0) I2C_SET_START_CONDITION; I2C_SEND_BYTE (MAX3108_I2C_PERIPHERAL_ADDRESS); // Is anybody out there? if (!I2C_TEST_ACK) { I2C_SET_STOP_CONDITION; // no – close out the return FALSE; // transaction } // The MAX3108 is out there, now send the MAX3108 // register address I2C_SEND_BYTE (port); // Possibly illegal MAX3108 register address? If (!I2C_TEST_ACK) { I2C_SET_STOP_CONDITION; return FALSE; } while (len--) { // Now send the byte to write I2C_SEND_BYTE (*ptr++); // Did the MAX3108 get confused? if (!I2C_TEST_ACK) { I2C_SET_STOP_CONDITION; return FALSE; } } // The MAX3108 is OK with our write, make it so I2C_SET_STOP_CONDITION; return TRUE; }
注意,對于突發寫入事務,第一個字節是MAX3108 I2C外設地址,第二個字節是MAX3108寄存器地址,所有后續字節都是要寫入的寄存器值。最終寄存器寫入由 STOP 條件指示。
單路I2C讀取
通過I2C讀取寄存器字節包括發送MAX3108讀寄存器地址,然后I2C重啟條件,將I2C總線從寫(到MAX3108指定MAX3108寄存器)轉為讀(獲取寄存器值)。
單次讀取的偽代碼如下:
/* ** Read one byte from the specified register in the MAX3108 ** ** Arguments: ** port: MAX3108 register address to read from ** ** return value: the register value (0x00XX) ** 0xff00 is there was some error ** */ unsigned int MAX3108_I2C_Read (unsigned int port) { unsigned int val; // Indicate the start of a transaction and send the // MAX3108 write peripheral address (LSbit = 0) I2C_SET_START_CONDITION; I2C_SEND_BYTE (MAX3108_I2C_PERIPHERAL_ADDRESS); // Is anybody out there? if (!I2C_TEST_ACK) { I2C_SET_STOP_CONDITION; // no – close out the return 0xff00; // transaction } // The MAX3108 is out there, now send the MAX3108 // register address I2C_SEND_BYTE (port); // Possibly illegal MAX3108 register address? If (!I2C_TEST_ACK) { I2C_SET_STOP_CONDITION; return 0xff00; } // Now turn the I2C bus around by sending the MAX3108 // I2C peripheral read address (LSbit = 1) I2C_SET_RESTART_CONDITION; I2C_SEND_BYTE (MAX3108_I2C_PERIPHERAL_ADDRESS | 0x01); if (!I2C_TEST_ACK) { I2C_SET_STOP_CONDITION; return 0xff00; } // Now get the register value val = I2C_RECEIVE_BYTE; I2C_SEND_NACK; I2C_SET_STOP_CONDITION; return (val); }
突發I2C讀取
MAX3108 I2C接口還支持突發讀取,適用于快速FIFO清空或快速寄存器掃描。如果寄存器地址為零,則突發讀取為空接收FIFO。這允許快速FIFO轉儲,而不會產生與每個FIFO字節讀取的I2C前導碼相關的開銷。
對于任何其他MAX3108寄存器地址,寄存器地址隨著突發的每個后續字節自動遞增,從而允許快速寄存器掃描。
突發讀取事務的偽代碼如下所示:
/* ** Read a burst of bytes from the MAX3108 ** ** Arguments: ** port: MAX3108 register address to read from ** len: number of bytes to get from MAX3108 registers ** ptr: pointer to where to place the bytes ** ** return value: TRUE – if all read ** FALSE – if there was any error ** */ BOOL MAX3108_I2C_Gets (unsigned int port, unsigned int len, unsigned char *ptr) { // Indicate the start of a transaction and send the // MAX3108 write peripheral address (LSbit = 0) I2C_SET_START_CONDITION; I2C_SEND_BYTE (MAX3108_I2C_PERIPHERAL_ADDRESS); // Is anybody out there? if (!I2C_TEST_ACK) { I2C_SET_STOP_CONDITION; // no – close out the return FALSE; // transaction } // The MAX3108 is out there, now send the MAX3108 // register address I2C_SEND_BYTE (port); // Possibly illegal MAX3108 register address? If (!I2C_TEST_ACK) { I2C_SET_STOP_CONDITION; return FALSE; } // Now turn the I2C bus around by sending the MAX3108 // I2C peripheral read address (LSbit = 1) I2C_SET_RESTART_CONDITION; I2C_SEND_BYTE (MAX3108_I2C_PERIPHERAL_ADDRESS | 0x01); if (!I2C_TEST_ACK) { I2C_SET_STOP_CONDITION; return FALSE; } // Now get the register values while (len--) { *ptr++ = I2C_RECEIVE_BYTE; if (len) I2C_SEND_ACK; // all but last read else I2C_SEND_NACK; // last read only } I2C_SET_STOP_CONDITION; return TRUE; }
注意,對于突發讀事務,第一個字節是MAX3108 I2C外設寫地址,第二個字節是MAX3108寄存器地址,第三個字節是MAX3108 I2C外設讀地址,所有后續字節都是寄存器值。微處理器在要讀取更多寄存器時,以 ACK 條件響應每個字節讀取。NACK條件表示從MAX3108讀取的最終寄存器。
結論
按照本應用筆記提供的編碼指南,可以快速啟動并運行微處理器和MAX3108之間的接口。
本應用筆記中偽代碼例程的大部分翻譯都是特定于微處理器的。除中斷處理程序外,本系列中的其他特定代碼應用筆記詳細探討了MAX3108的特性,幾乎不需要轉換為特定的目標微處理器。它們將依靠本應用筆記中描述的讀、寫、獲取和放置基元來封裝微處理器特有的問題。
審核編輯:郭婷
-
處理器
+關注
關注
68文章
19293瀏覽量
229941 -
寄存器
+關注
關注
31文章
5343瀏覽量
120429 -
微處理器
+關注
關注
11文章
2263瀏覽量
82475
發布評論請先 登錄
相關推薦
評論