娇小w搡bbbb搡bbb,《第一次の人妻》,中国成熟妇女毛茸茸,边啃奶头边躁狠狠躁视频免费观看

關于MSP硬件I2C講解

發布者:老衛最新更新時間:2020-01-21 來源: eefocus關鍵字:MSP  硬件I2C 手機看文章 掃描二維碼
隨時隨地手機看文章

0.前言

對于大多數單片機來說,I2C成了一個老大難問題。從51時代開始,軟件模擬I2C成了主流,甚至到ARMCortex M3大行其道的今天,軟件模擬I2C依然是使用最廣的方法。雖然軟件模擬可以解決所有的問題,但是總感覺沒有充分發揮MCU內部的硬件資源。查閱了所有關于MSP430F5系列的圖書,沒有關于硬件I2C的應用代碼,自己通過調試摸索,把經驗總結之后和大家分享,希望大家喜歡。同時,I2C的使用可以分為等待法和中斷法,從理解的角度來說等待法思路清晰易于上手,從功耗的角度出發,中斷法可以靈活的進入低功耗模式,但是不易理解。本文先從等待法入手。


MSP430F5系列的硬件I2C使用大致會有以下問題:


【I2C地址設定】一般情況下I2C的7位地址被寫成了8位長度,最低位無效。例如AT24C02的I2C地址為0xA0,其實真正的7位地址為0x50。而MSP430正是需要填入這7位地址0x50。


【I2C停止位發送】在I2C讀操作過程中,讀取最后一個字節之后MCU應向從機發送無應答,MSP430F5系列的MCU發送無應答的操作將自動完成,這就以為在讀取最后一個字節內容時,應先操作停止位相關寄存器。


【 I2C起始位發送】如果仔細分析MSP430F5參考手冊,將會發現讀操作和寫操作發送I2C起始位時略有不同。寫操作時需要先向TXBUF中寫入數據,之后才可以等待TXSTT標志位變為0,而讀操作和寫操作稍有不同。


【AT24C02操作時序圖

1.初始化設置

1.1代碼實現 

void ucb0_config(void)  

{  

  P3SEL &= ~BIT2;                        // P3.2@UCB0SCL  

  P3DIR |= BIT2;  

  P3OUT |= BIT2;  

  // 輸出9個時鐘以恢復I2C總線狀態  

  for( uint8_t i= 0; i <9 ; i++)  

  {  

    P3OUT |= BIT2;  

    __delay_cycles(8000);  

    P3OUT &= ~BIT2;  

    __delay_cycles(8000);  

  }  

   

  P3SEL |= (BIT1 + BIT2);                // P3.1@UCB0SDAP3.2@UCB0SCL  

  // P3.1@ISP.1 P3.2@ISP.5  

   

  UCB0CTL1 |= UCSWRST;  

  UCB0CTL0 = UCMST+ UCMODE_3 + UCSYNC;  // I2C主機模式  

  UCB0CTL1 |= UCSSEL_2;                  // 選擇SMCLK  

  UCB0BR0 = 40;  

  UCB0BR1 = 0;  

  UCB0CTL0 &= ~UCSLA10;                  // 7位地址模式  

  UCB0I2CSA = EEPROM_ADDRESS;           // EEPROM地址  

  UCB0CTL1 &= ~UCSWRST;  

}  


1.2代碼分析

I2C從設備的地址一般有以下通俗說法——7位地址,寫地址(寫控制字)和讀地址(讀控制字)。1個I2C通信的控制字節(I2C啟動之后傳送的第一個字節)由7位I2C地址和1位讀寫標志位組成,7位I2C地址即7位地址,若讀寫標志位為讀標志(讀寫標志位置位)加上7位I2C地址便組成了讀地址(讀控制字),若讀寫標志位為寫標志(讀寫標志位清零)加上7位地址便組成了寫地址(寫控制字)。例如AT24C02的I2C7位地址為0x50,讀地址(讀控制字)為0xA1,寫地址(寫控制字)為0xA1。


在MSP430F5系列中,I2CSA地址寄存器應寫入7位地址,參照上面的例子應寫入0X50。至于I2C讀寫位的控制由CTL1寄存器完成,用戶無需干預。


在I2C設置開始之前,可以先通過SCL端口發送9個時鐘信號,該時鐘信號可以是I2C從機芯片從一種錯誤的通信狀態恢復,雖然這9個時鐘信號不起眼但是對于調試過程來說非常有用。例如在調試過程中,錯誤的發送了停止位,若再次啟動調試則I2C從設備仍處于一種錯誤的狀態,這9個時鐘信號可以把I2C從設備從錯誤的狀態“拉”回來。


2.寫單個字節

向I2C從設備寫入單個字節應該是最為簡單的一個操作,因為所有的控制權都在主機手中。寫單個字節實際包括了2個重要部分,一個便是寫寄存器地址,另一個便是寫寄存器內容。對于AT24C02而言,存儲內容的字節長度為一個字節,而對于容量更大的EEPROM而言,存儲地址可為兩個字節。


2.1 代碼實現

uint8_teeprom_writebyte( uint8_t word_addr, uint8_tword_value )  

{  

  while( UCB0CTL1& UCTXSTP );  

  UCB0CTL1 |= UCTR;                // 寫模式  

  UCB0CTL1 |= UCTXSTT;             // 發送啟動位  

   

  UCB0TXBUF = word_addr;           // 發送字節地址  

  // 等待UCTXIFG=1與UCTXSTT=0 同時變化等待一個標志位即可  

  while(!(UCB0IFG& UCTXIFG))  

  {  

    if( UCB0IFG& UCNACKIFG )      // 若無應答 UCNACKIFG=1  

    {  

      return 1;  

    }  

  }    

   

  UCB0TXBUF = word_value;          // 發送字節內容  

  while(!(UCB0IFG& UCTXIFG));     // 等待UCTXIFG=1  

   

  UCB0CTL1 |= UCTXSTP;  

  while(UCB0CTL1& UCTXSTP);       // 等待發送完成  

   

  return 0;  

}  


2.2 代碼分析

關于代碼出口的說明,關于I2C的讀寫函數,若返回值為0說明所有的操作正常,若返回值為非0說明操作有誤,例如1代表從機無應答。這種組合方式可能與各位的編程習慣有出入,一般認為返回1表示操作成功,而返回0表示操作失敗。這種方式的問題便是無法有效的表達錯誤原因,因為“0”只有一個,而非“0”卻有很多。


寫單個字節可以劃分為——從機寫地址發送、寄存器地址發送、寄存器內容發送。寄存器地址的發送由MSP430自動完成,這和軟件模擬的操作有所區別。請勿發送I2C從機地址,若操作AT24C02發送需要寫入的存儲字節的首地址即可。


在單字節和多字節寫操作過程中,尤其要注意UCTXSTT標志位的變化位置。UCTXSTT標志位會在從機接收完寫控制字節或讀控制字節之后變化,但是在寫控制字節發送之后,必須先填充TXBUF,再嘗試等待STT標志位復位,此時STT標志位和TXIFG標志位會同時變化。若從機沒有應答,那么NACK標志位也會發生變化。再次強調需要先填充TXBUF,在等待STT標志位復位。以下代碼將導致程序一直停留在while(UCB0IFG & UCTXSTT)處,具體的原因可查看MSP430參考手冊。

 

while( UCB0CTL1& UCTXSTP );  

UCB0CTL1 |= UCTR;                // 寫模式  

UCB0CTL1 |= UCTXSTT;             // 發送啟動位  

// 等待UCTXSTT=0同時變化,但是很遺憾該變化不會發送  

while(UCB0IFG& UCTXSTT);  

UCB0TXBUF = word_addr;           // 發送字節地址  


3.寫多個字節

3.1代碼實現

uint8_teeprom_writepage( uint8_t word_addr, uint8_t *pword_buf, uint8_t len)  

{  

  while( UCB0CTL1& UCTXSTP );  

  UCB0CTL1 |= UCTR;                // 寫模式  

  UCB0CTL1 |= UCTXSTT;             // 發送啟動位  

   

  UCB0TXBUF = word_addr;           // 發送字節地址  

  // 等待UCTXIFG=1與UCTXSTT=0 同時變化等待一個標志位即可  

  while(!(UCB0IFG& UCTXIFG))  

  {  

    if( UCB0IFG& UCNACKIFG )      // 若無應答 UCNACKIFG=1  

    {  

      return 1;  

    }  

  }    

   

  for( uint8_t i= 0; i < len; i++)  

  {  

    UCB0TXBUF = *pword_buf++;      // 發送寄存器內容  

    while(!(UCB0IFG& UCTXIFG));   // 等待UCTXIFG=1     

  }  

   

  UCB0CTL1 |= UCTXSTP;  

  while(UCB0CTL1& UCTXSTP);       // 等待發送完成  

   

  return 0;  

}  


3.2 代碼分析

多字節寫函數和單字節寫函數相似,不做過多的解釋。


4.讀單個字節

單字節讀函數是4中讀寫函數中最為復雜的,復雜的原因在于讀最后一個字節之前就需要操作UCTXSTP標志位。


4.1 代碼實現

uint8_teeprom_readbyte( uint8_t word_addr, uint8_t *pword_value)  

{  

  UCB0CTL1 |= UCTR;                // 寫模式  

  UCB0CTL1 |= UCTXSTT;             // 發送啟動位和寫控制字節  

   

  UCB0TXBUF = word_addr;            //發送字節地址,必須要先填充TXBUF  

  // 等待UCTXIFG=1與UCTXSTT=0 同時變化等待一個標志位即可  

  while(!(UCB0IFG& UCTXIFG))  

  {  

    if( UCB0IFG& UCNACKIFG )      // 若無應答 UCNACKIFG=1  

    {  

      return 1;  

    }  

  }                         

   

  UCB0CTL1 &= ~UCTR;                //讀模式  

  UCB0CTL1 |= UCTXSTT;             // 發送啟動位和讀控制字節  

   

  while(UCB0CTL1& UCTXSTT);       // 等待UCTXSTT=0  

  // 若無應答 UCNACKIFG = 1  

  UCB0CTL1 |= UCTXSTP;             // 先發送停止位  

   

  while(!(UCB0IFG& UCRXIFG));     // 讀取字節內容  

  *pword_value = UCB0RXBUF;        // 讀取BUF寄存器在發送停止位之后  

   

  while( UCB0CTL1& UCTXSTP );  

   

  return 0;  

}  


4.2代碼分析

這段代碼給人一個錯覺,MSP430先發送了停止位,然后再讀取了一個字節內容。其實實際情況并不是這樣的。I2C讀操作時,主機讀取最后一個字節內容之后,應向從機發送無應答NACK(無應答區別于應答),之后主機發送停止位。MSP430為了完成這一組合動作,要求用戶提前操作UCTXSTP標志位,在讀取RXBUF之后做出發送NACK和I2C停止位的“組合動作”。

 

while(!(UCB0IFG& UCRXIFG));  

*pword_value = UCB0RXBUF;        // 讀取BUF寄存器在發送停止位之后  

UCB0CTL1 |= UCTXSTP;             // 發送停止位  


以上代碼可能導致后續的I2C操作無法進行。


5.讀多個字節

5.1代碼實現  

uint8_t eeprom_readpage(uint8_t word_addr, uint8_t *pword_buf, uint8_t len )  

{  

  while( UCB0CTL1& UCTXSTP );  

  UCB0CTL1 |= UCTR;                // 寫模式  

  UCB0CTL1 |= UCTXSTT;             // 發送啟動位和寫控制字節  

   

  UCB0TXBUF = word_addr;           // 發送字節地址  

  // 等待UCTXIFG=1與UCTXSTT=0 同時變化等待一個標志位即可  

  while(!(UCB0IFG& UCTXIFG))  

  {  

    if( UCB0IFG& UCNACKIFG )      // 若無應答 UCNACKIFG=1  

    {  

      return 1;  

    }  

  }    

   

  UCB0CTL1 &= ~UCTR;               // 讀模式  

  UCB0CTL1 |= UCTXSTT;             // 發送啟動位和讀控制字節  

   

  while(UCB0CTL1& UCTXSTT);       // 等待UCTXSTT=0  

  // 若無應答 UCNACKIFG = 1  

   

  for( uint8_t i= 0; i< len -1 ; i++)  

  {  

    while(!(UCB0IFG& UCRXIFG));   // 讀取字節內容,不包括最后一個字節內容  

    *pword_buf++= UCB0RXBUF;  

  }  

   

  UCB0CTL1 |= UCTXSTP;             // 在接收最后一個字節之前發送停止位  

   

  while(!(UCB0IFG& UCRXIFG));     // 讀取最后一個字節內容  

  *pword_buf = UCB0RXBUF;  

   

  while( UCB0CTL1& UCTXSTP );  

   

  return 0;  

}  


5.2代碼分析

讀單個字節和寫單個字節相似。唯一需要注意的是,寫操作需要先填充TXBUF,而讀操作不存在這個問題。試想一下,I2C寫操作時必定會向I2C從機寫入一個字節內容,所以先填充TXBUF也是合情合理的事情,填充TXBUF之后MSP430會進行一連串的動作——發送I2C起始位、I2C讀控制器和寫入從機的第一個字節。


6 單元測試

單元測試分為兩個部分。單字節寫函數和單字節讀函數分為一組,先使用單字節邪惡函數向某地址寫入某內容,在使用單字節讀函數讀出某內容,如果寫入的參數和讀出的內容相同,則測試通過。多字節寫函數和多字節度函數分為一組,測試過程相似,不同的是寫入的內容從一個變為了連續8個。請注意AT24C02的頁大小為8,若從頁首地址開始,最大的寫字節個數為8。

[1] [2]
關鍵字:MSP  硬件I2C 引用地址:關于MSP硬件I2C講解

上一篇:MSP430晶振配置詳解
下一篇:MSP430+DMA

推薦閱讀最新更新時間:2025-04-23 23:19

01:點亮LED 【MSP430F5529】
一:電路圖 開發板為TI的MSP-EXP430F5529LP LED1:P1.0 LED2:P4.7 LED負極接地,輸入為高電平,則點亮。輸入低電平,則熄滅。 二:端口初始化 LED1的初始化 /*LED1~P1.0 初始化*/ P1DIR |= BIT0; //初始化LED1的IO口P1.0,設置為輸出 P1OUT &= ~BIT0; //設置P1.0初始為低電平 LED2的初始化 /*LED2~P4.7 初始化*/ P4DIR |= BIT7; //初始化為輸出 P4OUT &= ~BIT0; //初始化低電平 三:點亮/熄滅
[單片機]
01:點亮LED 【<font color='red'>MSP</font>430F5529】
基于MSP430F5529的紅外循跡小車,
實現功能 第一功能:小車從A點開始出發,行駛到B點停止。 第二功能:小車從A點開始出發,然后沿跑道一直行駛。 下圖為黑色跑道,跑道為2mm的黑線,A、B、C、D四點為直徑4mm的黑圈。 設計方案 小車選用MSP430F5529做為主控芯片,TCRT5000紅外循跡模塊用來實現小車識別跑道功能,原理為紅外發射判斷黑白線以及區分黑線寬度,電機使用兩個直流電機,電機驅動模塊選用TB6612,來實現實時控制電機轉動的幅度與轉速。 設計電路 接線詳解 將MSP430F5529的P3.0、P3.1、P3.2引腳分別與3個TCRT5000模塊的DO端相連,芯片實時檢測這3個端口的電平,當發生電平跳變時,電機運行就會做出相對應的調整,
[單片機]
基于<font color='red'>MSP</font>430F5529的紅外循跡小車,
基于MSP430紅外循跡小車
1、P6簡單,是輸入嘛,肯定就是接受尋跡模塊紅外的返回值了,沒有什么疑義。 2、P4和P1共同控制電機,P1的存在是干什么的?這就與L298N的工作模式相關了,下面有個L298N的圖示,對照那個圖示來說。 輸出A和輸出B是連接電機的,電機串聯也好,并聯也罷,這無所謂。邏輯輸入端連接的是P4,也就是控制每個電機的正轉反轉,邏輯表下面也有,這也沒啥問題。 輸出通道A和B使能端,使能是啥意思?就是賦予權利,讓它可以工作唄,我們先不管P1,也就是不連接P1,在跳線帽連接的狀態下,A、B兩個使能端都是高電平的,或理解為3.3V,這時候輸出通道A和B是可以工作的,再配合上邊的P4的邏輯輸入,小車無論前進、倒退或轉彎都是全速前進的,
[單片機]
基于<font color='red'>MSP</font>430紅外循跡小車
基于CCS工程MSP430串口升級(三)
一、前文 第一次接觸MSP430的芯片,第一次使用CCS開發環境,花了將近一個星期的時間,才把MSP430串口升級做出來。 同樣分成BOOT(引導程序)、APP(主程序)、上位機(PC端工具),三個部分來講解。 二、正文 折騰這個功能的時候,遇到了很多問題,現在來一一描述 C和匯編語言混合編程 C語言嵌入匯編語言是asm(“xxx”);,這樣一開始編譯一直不過。 然后幾經百度谷歌后,發現在xxx前面加上制表符t,asm( xxx );,編譯就過了。 IAR沒有這個問題,CCS就這樣。看來CCS編譯器還有待改進。 匯編語言,#和&傻傻分不清 mov #0xEFFE,PC和mov &0xEFFE,PC 一開始搞不清楚,啥區
[單片機]
基于CCS工程<font color='red'>MSP</font>430串口升級(三)
MSP430FR6989功能介紹 首先看
單片機是一個集成電路芯片,是包括了CPU、隨機存儲器RAM、只讀存儲器ROM、多種I/O口和中斷系統、定時器/計數器等功能并將其集成到一塊硅片上構成的一個小而完善的微型計算機系統。一般把單片機也稱為Microcontroller,或MCU。 單片機的應用極其廣泛,大到汽車、工業,小到家電、個人消費電子品,里面都有單片機的身影。可以說凡是要進行控制和運算的應用,都有單片機的用武之地。 MSP430是由TI推出的16位的單片機,發展到現在MSP430已有多個系列共500多種型號。不同的MSP430系列集成了不同的外設,主要包括有Flash、RAM、定時器、GPIO、ADC、串行通信模塊等。 MSP430以低功耗而聞名,其低
[單片機]
<font color='red'>MSP</font>430FR6989功能介紹 首先看
msp430f149 4x4矩陣按鍵(薄膜)
main.c /******************************************************************** //DM430-A型開發板矩陣鍵盤控制程序,通過數碼管顯示按鍵值,采用逐行掃描 //4X4鍵盤接在P1口,通過控制IO口狀態變化,逐行掃描按鍵是否按下 //調試環境:EW430 V5.30 //作者:mmp //創客 P1口設置為按鍵插入口 更改引腳在Config.h文件中 有黑的地方插P1.0~P1.3 因為有上拉電阻 1 5 9 13 2 6 10 14 3 7 11 15 4 8 12 16 本程序按鍵布局 按照需求更改 case 0xee:key=1;b
[單片機]
基于msp430f2491的proteus仿真(實現流水燈)
實現P2口的流水燈 主函數 #include msp430x24x.h #define LED8PORT P2OUT //P2接8個LED燈 #define LED8SEL P2SEL //P2接8個LED燈 #define LED8DIR P2DIR //P2接8個LED燈 #define uchar unsigned char #define uint unsigned int //IAR軟件的延時函數 #define CPU_F ((double)8000000)//8M #define delay_us(x) __dela
[單片機]
基于<font color='red'>msp</font>430f2491的proteus仿真(實現流水燈)
MSP432P401R LaunchPad開箱入門
之前并沒有怎么接觸過TI的板卡,去年參加電賽并沒有使用過TI的板卡,只知道用TI的板子可以加分,小車類的題目必須要用這些板卡。今年電賽又因為疫情推遲了,最近快要開學了,回到學校,手頭剛好有申請來的MSP432P401R,想著還是拿來熟悉一下,以備不時之需,電賽用上了也穩賺不賠。 開箱 TI的板子包裝和平時淘寶買的一些板子還是不太一樣的,這個盒子還是挺方便的。 打開盒子,兩張簡易的說明書映入眼簾,左側是板卡,右側下方藏著數據線。把板卡拆出來看了看,和其他一些板卡相比,這個造型還是有一些奇怪的,上下兩面的排針排母也方便了拓展。 Out-of-box Demo 盒子里的手冊有這么一個Demo,看起來還有些意思,接下來就照著實
[單片機]
<font color='red'>MSP</font>432P401R LaunchPad開箱入門
小廣播
設計資源 培訓 開發板 精華推薦

最新單片機文章
何立民專欄 單片機及嵌入式寶典

北京航空航天大學教授,20余年來致力于單片機與嵌入式系統推廣工作。

 
EEWorld訂閱號

 
EEWorld服務號

 
汽車開發圈

 
機器人開發圈

電子工程世界版權所有 京B2-20211791 京ICP備10001474號-1 電信業務審批[2006]字第258號函 京公網安備 11010802033920號 Copyright ? 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
主站蜘蛛池模板: 永仁县| 郁南县| 黄骅市| 陕西省| 铁力市| 肇庆市| 信宜市| 鄄城县| 华容县| 沙湾县| 和静县| 呼图壁县| 诸暨市| 绥阳县| 乌什县| 鹤岗市| 石狮市| 长寿区| 宁陕县| 浑源县| 惠安县| 全椒县| 治县。| 保靖县| 崇州市| 蓬溪县| 平顶山市| 河源市| 鄂州市| 龙门县| 萍乡市| 通化县| 扎鲁特旗| 邯郸县| 罗定市| 南昌市| 门头沟区| 黔南| 久治县| 青海省| 仙居县|