說到MSP430 MCU的I2C資源,那么首先就得先看一下USCI。
如果你了解過多款MSP430 MCU你會發現,內部資源里有USCI和eUSCI,那么他們什么意思呢?
USCI (Universal Serial Communication Interface),即通用串行通信接口,eUSCI中的e則是enhanced的意思,即增強型,那么有什么區別呢?
一些主要的區別如下表所示,F2xx這一列代表USCI,FR57xx代表eUSCI
更多詳細區別,請查看TI官方文檔:
http://www.ti.com/lit/an/slaa522a/slaa522a.pdf
其實你會發現 區別不是很大,僅僅是寄存器的名字變了一點,在使用起來很是相似,因此本次使用eUSCI進行講解。
eUSCI又分兩種:A和B,有什么區別呢:
A:支持UART和SPI
B:支持I2C和SPI
也就是說兩種都支持SPI,但A僅支持UART和SPI,B僅支持I2C和SPI。想過為什么嗎?
(這段內容比較深,也不一定是全部都是正確的:我認為畢竟eUSCI就是數字邏輯電路嘛,TI設計成這種格式去給客戶機會去選用SPI或I2C/UART,相對于單獨設計I2C,SPI,UART內核來說,第一節省電路,可以降低功耗和成本,第二減少引腳數量。那為什么都支持SPI嘛,因為SPI協議簡單嘛,沒有I2C那種起始位,停止位,也沒有UART那種固定的波特率,SPI自己有自己的時鐘,所以內部電路集成方面與UART或I2C有一定的公共成分,而UART和I2C差別較大,結合起來沒什么性價比吧,所以出現了A版本和B版本。這些僅是我的猜測。。。em……)
好啦,那么正式進入我們今天的主題 à I2C協議。
首先,第一部分肯定要講清楚什么是I2C協議,這類資料網上一大堆一大堆,也可以很容易的搜索到資料來參考,我就簡單的過一下吧。
I2C(Inter-Integrated Circuit) 是Philips公司發明的一種用于片級連接的總線方式,有什么好處呢:
簡單,就兩根線SDA和SCL。
總線方式,可以掛接多個設備。
通信速度有低速,普通,高速等模式,目前最快好像可以實現3.4Mbps速度。
其實還有挺多優點的,不然也不可能經歷那么多年I2C依舊很主流。首先我想稍微解釋一下掛接設備數量問題:
這個可以掛接多個設備主要是由于I2C的開漏特性決定的,即0有效,外部需要上拉電阻,開漏和推挽的資料網上也很多,可以自己查來看看。那么能掛接多少設備呢?這個本質上是由總線上的容性決定的,我們都知道,電容越大,充電時間越長,那么信號上升速度越滿,當慢到不能滿足I2C要求是,那么則不能掛接了,掛接設備相當于并聯電容嘛,電容就變大了,然后就。。。,就。。。。
I2C協議如下:
簡單吧,就兩根線嘛,首先呢,起始位。如果你是個Master,需要發信號給Slave,那么肯定要給個起始位嘛,告訴Slave你開始發數據了,如上圖:SCL=1,SDA由0變1標志著起始位,然后呢,肯定是要寫地址了,從設備地址,總線上掛接了很多Slave,你要發送給誰呢? 那么就寫誰的地址,I2C地址是7位的(別抬杠,知道有10位地址模式,不過原理相同的),然后呢,下一位是R/W,你是讀Slave里的數據呢,還是寫數據到Slave呢?需要吧? 后面就是數據了,當然,當你寫完一個數據后,Slave會給你個回應那個,then你接著寫,Slave再回應,就這樣最后Master發送一個STOP位(SCL=1,SDA由低變高),好啦,那么一包數據通信即結束了。
PS:講解一個小知識:你細看I2C協議你會發現:SDA數據線上只能再SCL=0的時候改變,SCL=1時需要保持狀態,為什么呢? 簡單嘛,請看START和STOP信號,你就知道了。
好啦,I2C協議講解完了,那么正式進入正題:MSP430 I2C如何使用:
先上一張I2C模塊的內部結構圖:
一堆一堆的寄存器,標志位對吧,最終出來兩根線SDA和SCL是吧。就是這樣的嘛,內部的模塊不就是一些邏輯電路加一些Memory嘛,迷糊沒事的,后面看看寄存器就知道了:
那么就開始講解如何使用吧,也就是寄存器內容啦:
看一下有哪些寄存器:
UCBxCTLW0
UCA10:10位地址選擇,1時為10位地址模式,0時為7位地址模式。
UCLSA10:Slave10位地址選擇,也就是說你作為Master時需要通信的Slave是否是10位地址的模式。
UCMM:多Master選擇,因為正常I2C時鐘是由Master控制的,因此如果存在多Master時,需要釋放SCL的,故設計了這一位用來應對多Master模式。
UCMST:Master或Slave選擇,決定MSP430用作I2C中的Master還是Slave。
UCMODEx:模式選擇:SPI或者I2C,同時SPI還分為三線和四線模式。
UCSSELx:時鐘源選擇,建議選SMCLK吧,頻率高一點,精度也就高一點。
UCTXACK:回應地址正確,這個是再Slave或者多Master模式下,開啟地址掩碼功能后,只對比除去掩碼的剩下地址,如果一致的話,需要發送個地址確認位(UCSWACK=1時需要手動設置發送,UCSWACK=0時會自動發送),這個就是那個地址確認位。
UCTR:發送還是接受,數據給Slave時是發送,讀的時候則是接受或者作為Slave也是接受。
UCTXNACK:發送ACK信號,在Slave模式下使用。
UCTXSTP:生成STOP信號,在Master模式下使用。
UCTXSTT:生成起始信號,在Master模式下使用。
UCSWRST:軟件復位使能,默認是1,即不能寫一些寄存器設置I2C參數,有些寄存器想進行操作時需要復位這一位。
UCBxCTLW1
UCETXINT:這一位僅在Slave模式下有用,決定著什么時候會置位UCTXIFG0(這一位置位標志著有能力去發送數據了),當這一位是1時,收到Master發送過來的START信號就會置位,當這一位是0時,則等到接收到Master發送的地址與自己的地址匹配時,才會置位UCTXIFG0(注意這種情況下地址1-3都要disable)。
UCCLTO:I2C總線時鐘超時,也就是可能總線上卡死了,這一位用來設置這個時間,也可以關閉此項功能。如果設置了時間,在超時之后會觸發UCCLTOIFG中斷,用戶可以在中斷里重新初始化I2C。
UCSTPNACK:這一位是指在MCU作為Master接受數據時,在收到Slave的最后一個字節數據后可以發送一個響應給Slave,不過這并不符合I2C協議,因此只用在一些特定場合,正常的I2C協議,請忽略。
UCSWACK:看UCBxCTLW0中的UCTXACK描述,這一位和地址掩碼有關系。
UCASTPx:自動生成STOP設置,這一位只用在Master模式下,在設置自動生成STOP信號后,發送完設置長度的數據后,I2C內核直接自動發送停止位,這樣會簡化用戶操作。注意:你可能會遇到一個情況:設置自動STOP后,會設置一個發送數據的長度,而這個數據長度寄存器,也就是UCTBCNTx,這個是8位的,也就是最大值就是255了,因此,如果I2C一次性需要傳遞的數據包超過了255字節,那么有兩種方案解決:不要開啟STOP,選擇手動設置STOP信號,或者啟動DMA模塊,這兩張方式都可以。手動STOP簡單一點,DMA速度快一點。
UCGLITx:錯誤檢測位,這一位可以檢測信號線上的毛刺噪聲,建議直接默認就好啦。
UCBxBRW
這個寄存器是控制I2C波特率的,目前MSP430的I2C模塊支持快速的400Kbps(資料中說的嚴謹,起始可以更快的)。那么如何計算波特率的呢?看下面框圖:
就是對時鐘進行分頻后,就直接傳輸給SCL線上了,因此很容易計算,在選擇時鐘源之后,時鐘源的頻率除以這一位,就是SCL的時鐘頻率。
UCBxSTATW
UCBCNTx:只讀寄存器,用來獲取I2C總線上接受或者發送的數據量。
UCSCLLOW:用來查看SCL狀態,可以確定是否有其他設備將此總線時鐘拉低了。
UCGC:只讀寄存器,標志著是否接收到了通用的Call 地址。
UCBBUSY:只讀寄存器,用來查看總線上是否繁忙,一般情況下,為了保證數據發送的嚴謹性,在數據發送前都要查詢這一位來決定是否可以發送數據的。
UCBxTBCNT
UCTBCNTx:在上面自動生成STOP信號時提過,這一位用來設置I2C一包數據發送的數量。
UCBxRXBUF
I2C數據接受緩沖區,在收到I2C接受中斷后(當然是在使能中斷后啦),接收到的數據會存放在這個緩沖區里,需要讀取出來,讀取后會自動清除接收中斷。
UCBxTXBUF
I2C數據發送緩沖區,也就是如果你想通過I2C協議發送一個數據,那么你只需要把這個數據寫入這個寄存器中即可,當數據移入移位寄存器后,開始發送,發送完成后則會觸發發中斷,代表著當前寄存器的值已經空了,數據已經發送完成,可以寫入下一個數據進行發送了。
UCBxI2COA0
I2C的general call是一個什么呢? 就類似于廣播模式嘛,地址就是0,更多詳細資料,請查看I2C官網:https://www.i2c-bus.org/addressing/(PS:推薦大家有問題多去官網查看,官方發布的肯定沒什么問題,理解起來不會有誤區)
UCOAEN:使能自己的I2C地址。
I2COAx:自己的I2C地址0。
UCBxI2COA1
參考UCBxI2COA0
UCOAEN:使能自己的I2C地址。
I2COAx:自己的I2C地址1。
UCBxI2COA2
參考UCBxI2COA0
UCOAEN:使能自己的I2C地址。
I2COAx:自己的I2C地址2。
UCBxI2COA3
參考UCBxI2COA0
UCOAEN:使能自己的I2C地址。
I2COAx:自己的I2C地址3。
總的來說,就是MSP430的I2C模塊可以設置4個Slave地址,可以產生不同的I2C中斷。
UCBxADDRX
ADDRXx:只讀寄存器,接收到數據對方的地址。
UCBxADDMASK
ADDMASKx:地址掩碼,可以選擇性的接受對象固定地址的設備發送來的數據。
UCBxI2CSA
I2CSAx:Slave設備的地址,注意,這個只用在MCU作為Master模式下,這一位用來設置你要發送的Slave設備他的地址。
UCBxIE
各種各樣的中斷使能位,這個和IFG中斷標志位是匹配的,也就是使能相應的中斷后,產生中斷的情況下后,會置位相應的中斷標志位,然后產生中斷。具體每個中斷時什么用,請看IFG寄存器的描述。
UCBxIFG
中斷標志位寄存器,
看起來好多吧,最常用的就是UCTXIFG0和UCRXIF0了,當然一些NACK,STT,STP也會用到,具體內容看下面這四張圖:分別表示在Slave模式下T/R和Master下T/R,什么時候會將這些標志位置位(7bit地址模式,10bit模式的類似,請直接擦看官方的user guide)
這四張圖解釋的很清楚,在I2C數據包那一塊會觸發什么中斷,這樣用戶可以很靈活的使用這些中斷標志位和中斷入口。
UCBxIV
中斷向量表,可以和中斷標志位匹配。
好啦,寄存器內容講解完成后,接下來就是如何使用的環節了,直接上程序吧(MS430FR2355):
其實寄存器很多,但是真正常用的寄存器很少,其他的直接默認就行了,因此不用擔心看完了記不住,不重要的,看下下面程序,哪些不懂得地方直接回去找就好啦,User guide就像一個字典,你不需要去背,需要的是在遇到問題是,如何去查找就行。
Master模式+Slave模式:(單個地址,Slave在接收到Master數據后,發送從0開始的遞增數據)兩個程序可以下載到兩個MCU中,實現兩個MCU的I2C通信驗證。
Maser 程序:
#include volatile unsigned char RXData; int main(void) { WDTCTL = WDTPW | WDTHOLD; // Configure GPIO P1OUT &= ~BIT0; // Clear P1.0 output latch P1DIR |= BIT0; // For LED P1SEL0 |= BIT2 | BIT3; // I2C pins // Disable the GPIO power-on default high-impedance mode to activate // previously configured port settings PM5CTL0 &= ~LOCKLPM5; // Configure USCI_B0 for I2C mode UCB0CTLW0 |= UCSWRST; // Software reset enabled UCB0CTLW0 |= UCMODE_3 | UCMST | UCSYNC; // I2C mode, Master mode, sync UCB0CTLW1 |= UCASTP_2; // Automatic stop generated // after UCB0TBCNT is reached UCB0BRW = 0x0008; // baudrate = SMCLK / 8 UCB0TBCNT = 0x0005; // number of bytes to be received UCB0I2CSA = 0x0048; // Slave address UCB0CTL1 &= ~UCSWRST; UCB0IE |= UCRXIE | UCNACKIE | UCBCNTIE; while (1) { __delay_cycles(2000); while (UCB0CTL1 & UCTXSTP); // Ensure stop condition got sent UCB0CTL1 |= UCTXSTT; // I2C start condition __bis_SR_register(LPM0_bits|GIE); // Enter LPM0 w/ interrupt } } #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__) #pragma vector = USCI_B0_VECTOR __interrupt void USCIB0_ISR(void) #elif defined(__GNUC__) void __attribute__ ((interrupt(USCI_B0_VECTOR))) USCIB0_ISR (void) #else #error Compiler not supported! #endif { switch(__even_in_range(UCB0IV, USCI_I2C_UCBIT9IFG)) { case USCI_NONE: break; // Vector 0: No interrupts case USCI_I2C_UCALIFG: break; // Vector 2: ALIFG case USCI_I2C_UCNACKIFG: // Vector 4: NACKIFG UCB0CTL1 |= UCTXSTT; // I2C start condition break; case USCI_I2C_UCSTTIFG: break; // Vector 6: STTIFG case USCI_I2C_UCSTPIFG: break; // Vector 8: STPIFG case USCI_I2C_UCRXIFG3: break; // Vector 10: RXIFG3 case USCI_I2C_UCTXIFG3: break; // Vector 14: TXIFG3 case USCI_I2C_UCRXIFG2: break; // Vector 16: RXIFG2 case USCI_I2C_UCTXIFG2: break; // Vector 18: TXIFG2 case USCI_I2C_UCRXIFG1: break; // Vector 20: RXIFG1 case USCI_I2C_UCTXIFG1: break; // Vector 22: TXIFG1 case USCI_I2C_UCRXIFG0: // Vector 24: RXIFG0 RXData = UCB0RXBUF; // Get RX data __bic_SR_register_on_exit(LPM0_bits); // Exit LPM0 break; case USCI_I2C_UCTXIFG0: break; // Vector 26: TXIFG0 case USCI_I2C_UCBCNTIFG: // Vector 28: BCNTIFG P1OUT ^= BIT0; // Toggle LED on P1.0 break; case USCI_I2C_UCCLTOIFG: break; // Vector 30: clock low timeout case USCI_I2C_UCBIT9IFG: break; // Vector 32: 9th bit default: break; } } Slave程序: #include volatile unsigned char TXData; int main(void) { WDTCTL = WDTPW | WDTHOLD; // Configure GPIO P1SEL0 |= BIT2 | BIT3; // I2C pins // Disable the GPIO power-on default high-impedance mode to activate
上一篇:MSP430使用指南3 -> SYS系統控制
下一篇:MSP430使用指南32 -> SAC智能模擬組合
推薦閱讀
史海拾趣
強盛電子(AEC)自成立以來,一直致力于電子技術的研發與創新。公司研發團隊經過數年的努力,成功開發出一款具有顛覆性的新型芯片,這款芯片在性能上遠超當時的同類產品,引起了市場的廣泛關注。隨著這款芯片的量產和上市,AEC的市場份額迅速擴大,成為行業內的佼佼者。
隨著全球環保意識的不斷提高,電子行業對綠色環保的要求也越來越高。Connector City公司積極響應國家環保政策,加強了對生產過程的環保管理。公司引進了先進的環保設備和技術,減少了生產過程中的廢棄物排放和能源消耗。同時,公司還注重產品的環保性能設計,推出了多款符合環保標準的新型連接器產品。通過堅持綠色環保和可持續發展理念,公司贏得了社會的廣泛贊譽和支持。
這五個故事僅是對Connector City公司可能發展路徑的一種虛構描述,實際情況可能因市場變化、公司策略調整等多種因素而有所不同。在實際發展中,公司需要根據自身情況和市場環境做出靈活的調整和決策。
DFRobot公司于2008年由葉琛創立,當時主要致力于將國外的開源硬件項目引入中國。起初,公司規模較小,團隊由幾位熱愛機器人和開源硬件的工程師組成。他們憑借對技術的熱情和不懈的努力,逐漸在電子行業嶄露頭角。葉琛作為公司的創始人,不僅擁有深厚的工程學背景,還具備前瞻性的商業眼光,為公司的發展奠定了堅實的基礎。
在技術創新的基礎上,Dawn Electronics Inc公司開始積極拓展市場。公司加強了與國內外客戶的合作,通過提供優質的產品和服務,贏得了客戶的信任和支持。同時,公司還注重品牌建設,積極參與行業展會和交流活動,提高了品牌知名度和影響力。這些努力為公司贏得了更多的市場份額和合作機會。
為了進一步擴大市場份額,EPIGAP公司開始實施國際化戰略。公司先后在多個國家和地區設立了辦事處和研發中心,以便更好地了解當地市場需求和技術發展趨勢。通過與國際客戶的深入合作,EPIGAP公司的產品逐漸打入國際市場,贏得了廣泛的認可和贊譽。
醫療儀器原理 王成 上海交通大學出版社 2008-05-01 目錄: 1 緒論 ----------------8 1.1 醫療儀器 ----------------8 1.2 醫療儀器的構成 ----------------10 1.3 ...… 查看全部問答∨ |
|
報警服務業是商業化的安全防范服務行業,是防盜報警服務運營商在提供防盜報警產品基礎上延伸的一系列安保服務。目前,報警服務業在日本、英國、美國、澳大利亞等發達國家,已經成為一種較為普及的安全服務行業,據不完全統計,約20%的家庭和企業在 ...… 查看全部問答∨ |
|
failed to download application: error: swim prog error [42004]: memory write error 這個問題怎么解決了?… 查看全部問答∨ |
|
請問各位大蝦我用4M得主頻怎么才能在純IO口上獲得1M頻率脈沖? 請問各位大蝦我用4M得主頻怎么才能在純IO口上獲得1M頻率脈沖? 假如系統頻率是4M那么一般的一條指令需要多長時間?… 查看全部問答∨ |
|
LM3S9B92訪問MCX314AL 時序問題--附代碼參考 #define GPIO_DL_BASE GPIO_PORTH_BASE //低8位數據線 #define GPIO_DH_BASE   ...… 查看全部問答∨ |