i2c課程設計--基于arm的i2c接口設計_第1頁
已閱讀1頁,還剩18頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、<p><b>  摘要: </b></p><p>  近年來,隨著計算機技術及集成電路技術的發(fā)展,嵌入式技術日漸普及,在通訊、網絡、工控、醫(yī)療、電子等領域發(fā)揮著越來越重要的作用。</p><p>  I2C是一種較為常用的串行接口標準,具有協議完善、支持芯片較多和占用I/O線少等優(yōu)點,主要在服務器管理中使用,可隨時監(jiān)控內存、硬盤、網絡、系統(tǒng)溫度等多個參數

2、,增加了系統(tǒng)的安全性,便于管理。目前比較流行的串行擴展總線中,I2C總線以其嚴格的規(guī)范和眾多支持I2C接口的外圍器件而獲得了廣泛的應用。</p><p>  因此,我們對I2C接口進行了必要的探究,通過UART(異步串行接口)發(fā)送字節(jié)數據,然后利用I2C串行接口對外部存儲器24C01進行讀寫,最后通過顯示器LCD1602顯示,正確驗證了I2C的通訊功能。</p><p>  關鍵字:

3、 I2C串行接口 UART 外部存儲器 顯示器LCD1602</p><p><b>  正文:</b></p><p>  設計原理與總體方案:</p><p>  本設計包含三個部分:UART發(fā)送數據部分、I2C讀寫存儲器部分、LCD1602顯示部分,下面分別介紹各部分原理。</p><p>&

4、lt;b>  異步串行接口</b></p><p>  UART是異步串行接口,LPC2000系列ARM7包含2個UART:UART0和UART1,UART0只有TXD(串行輸出)和RXD(串行輸入)兩個引腳,只需設置相應的寄存器即可實現基本的數據收發(fā)功能。</p><p>  1.2.I2C總線基本原理</p><p>  I2C總線系統(tǒng)是由SC

5、L(串行時鐘)和SDA(串行數據)兩根總線構成的,該總線有嚴格的時序要求。總線工作時, 由串行時鐘線SCL傳送時鐘脈沖, 由串行數據線SDA 傳送數據??偩€協議規(guī)定, 各主節(jié)點進行通信時都要有起始、結束、發(fā)送數據和應答信號,這些信號都是通信過程中的基本單元??偩€傳送是以幀為單位進行的, 每當發(fā)送完1 個字節(jié)后, 接收節(jié)點就相應給一應答信號。</p><p>  1.2.1. I2C總線數據傳輸中的接受/發(fā)送器&l

6、t;/p><p>  I2C總線系統(tǒng)中發(fā)送器與接收器來表明數據傳輸的發(fā)送方與接收方。</p><p>  發(fā)送器:總線上發(fā)送數據的器件。</p><p>  接收器:總線上接收數據的器件。</p><p>  1.2.2. I2C總線上數據的有效性</p><p>  I2C總線數據傳輸時,在時鐘線高電平期間數據線上必須保

7、持有穩(wěn)定的邏輯電平的狀態(tài),高電平為數據1,低電平為數據0。只有在時鐘線為低電平時,才允許數據線上的電平狀態(tài)變化,如圖1所示。</p><p>  圖1 I2C總線數據位傳送</p><p>  1.2.3. I2C總線數據傳送的起始、停止與應答</p><p>  I2C總線可以構成多主數據傳送系統(tǒng),但只有帶CPU的器件可以成為主器件。 主器件發(fā)送時鐘、啟動位、數

8、據工作方式,從器件則接收時鐘及數據工作方式,接收或發(fā)送則根據數據的傳送方向決定。I2C總線上數據傳送時的啟動、結束和有效狀態(tài)都由SDA、SCL的電平狀態(tài)決定,在I2C總線規(guī)程中啟動和停止條件規(guī)定如下:</p><p>  啟動條件:在SCL為高電平時,SDA出現一個下降沿則啟動I2C總線。 </p><p>  停止條件:在SCL為高電平時,SDA出現一個上升沿則停止使用I2C總線。

9、 </p><p>  啟動條件后總線為“忙”,在結束信號過后的一定時間總線被認為是“空閑”的。在啟動和停止條件之間可轉送的數據不受限制,但每個字節(jié)必須為8位。首先傳送最高位,采用串行傳送方式,但在每個字節(jié)之后必須跟一個響應位。主器件收發(fā)每個字節(jié)后產生一個時鐘應答脈沖,在這期間,發(fā)送器必須保證 SDA為高,由接收器將SDA拉低,稱為應答信號(ACK)。主器件為接收器時,在接收了最后一個字節(jié)之后不發(fā)應答信號,也稱為

10、非應答信號(NOT ACK)。 當從器件不能再接收另外的字節(jié)時也會出現在種情況。I2C總線的數據傳送如圖2所示。</p><p>  圖2 I2C總線上的信號</p><p>  1.2.4. I2C總線數據傳送</p><p>  I2C總線上連接的每個器件都有自己唯一確定的地址,啟動條件后主機發(fā)送的第一個字節(jié)就是被讀寫的從器件地址,其中第8位為方向位,“0”(

11、W)表示主器件發(fā)送,“1”(R)表示主器件接收??偩€上每個器件在啟動條件后都把自己的地址與前7位相比較,如相同則器件被選中, 產生應答,并根據讀寫位決定在數據傳送中是接收還是發(fā)送。如圖所示為主器件發(fā)送和接收數據的過程,無論是主發(fā)、主收還是從發(fā)、從收都是由主器件控制。</p><p>  圖3主器件發(fā)送和接收數據的過程</p><p>  在主發(fā)送方式下,由主器件先發(fā)出啟動信號(S),接著發(fā)

12、從器件的7 位地址(SLA)和主器件發(fā)送的方向位“0”(W),即這個字節(jié)為SLA+W。被尋址的從器件在收到這個字節(jié)后,返回一個應答信號(A),在確定主從應答正常后,主器件向從器件發(fā)送字節(jié)數據,從器件每收到一個字節(jié)數據后都要返回一個應答信號,直到全部數據都發(fā)送完為止。在主接收方式下,主器件先發(fā)出啟動信號(S),接著發(fā)從器件的7位地址(SLA)和表明主器件接收的方向位“1”(R),即這個字節(jié)為SLA+R。在發(fā)送完這個字節(jié)后,SCL繼續(xù)輸出時

13、鐘,通過SDA接收從器件發(fā)來的串行數據。主器件每接收到一個字節(jié)后都要發(fā)送一個應答信號(A),當全部數據都發(fā)送或接收完畢后,主器件應發(fā)出停止信號(P)。</p><p>  1.3.LCD1602液晶顯示驅動原理</p><p>  1.3.1. LCD1602的引腳功能</p><p>  LCD1602液晶顯示器的引腳如圖4所示,其引腳功能如下:</p>

14、;<p> ?。?)RS:數據和指令選擇控制端,RS=0命令狀態(tài);RS=1數據</p><p> ?。?)R/W:讀寫控制線,R/W=0寫操作;R/W=1讀操作</p><p> ?。?)A:背光控制正電源 (4) K:背光控制地</p><p>  (5)E:數據讀寫操作控制位,E線向LCD模塊發(fā)送一個脈沖,LCD模塊與單片機間將進行一次數

15、據交換</p><p> ?。?)DB0~DB7:數據線,可以用8位連接,也可以只用高4位連接,節(jié)約單片機資源。</p><p> ?。?)VDD:電源端 VEE:亮度控制端(1-5V) VSS:接地端</p><p>  圖4 LCD1602液晶顯示器引腳圖</p><p>  1.3.2.LCD1602控制命令&

16、lt;/p><p>  表1 LCD控制命令</p><p>  指令3:光標和顯示模式設置。I/D:光標移動方向,高電平右移,低電平左移。S:屏幕上所有文字是否左移或者右移,高電平表示有效,低電平則無效。</p><p>  指令4:顯示開關控制。D:控制整體顯示的開與關,高電平表示開顯示,低電平表示關顯示。C:控制光標的開與關,高電平表示有光標,低電平表示無光標。

17、B:控制光標是否閃爍,高電平閃爍,低電平不閃爍。</p><p>  指令 6:功能設置命令。DL:高電平時為4位總線,低電平時為8位總線。N:低電平時為單行顯示,高電平時為雙行顯示。F:低電平時顯示5×7的點陣字符,高電平時顯示5×10的點陣字符。</p><p>  指令9:讀忙信號和光標地址。BF:為忙標志,高電平表示忙,此時模塊不能接受命令或者數據,如果為低電平

18、表示不忙。</p><p><b>  軟件設計</b></p><p>  2.1流程圖及部分初始化說明</p><p><b>  圖5 主程序流程圖</b></p><p>  圖6 lcd初始化及顯示函數流程圖</p><p>  圖7 UART接受數據流程圖&l

19、t;/p><p>  圖8 I2C讀寫24C01流程圖</p><p><b>  仿真設計</b></p><p><b>  仿真電路圖</b></p><p><b>  圖9</b></p><p><b>  仿真結果圖</b&

20、gt;</p><p><b>  圖10</b></p><p><b>  調試</b></p><p>  問題1:在進行仿真調試時,出現了發(fā)送亂碼的現象(如圖11)。</p><p>  原因: ADS調試時鐘頻率與proteus仿真設置頻率不一致。 </p><p&

21、gt;  問題2:在進行仿真調試時,I2C讀數據時,出現非應答位導致數據不能正常讀取(如圖12)。</p><p>  原因: ADS程序寫完24C01后沒有等待總線恢復,添加延時即可。</p><p>  圖11 調試出現亂碼情況</p><p>  圖12 讀取數據時出現非應答位情況</p><p><b>  結束語</

22、b></p><p>  本次課程設計是ARM嵌入式系統(tǒng)課程設計,是在我們學習了《ARM嵌入式系統(tǒng)》的基礎上的進一步實踐與拓展,該課程設計對各方面的知識進行了融合,具有一定的挑戰(zhàn)性。我們查閱了很多資料,并且借鑒了很多不同的想法,在老師的幫助下,我們順利完成了課程設計,對嵌入式系統(tǒng)的硬件、軟件有了更為深入的了解,為以后進行軟硬件設計打下了良好的基礎。</p><p><b>

23、  參考文獻</b></p><p>  [1]周立功主編.ARM嵌入式系統(tǒng)基礎教程[M].北京航空航天大學出版社,2008。</p><p>  [2]吳明輝,等.基于ARM的嵌入式系統(tǒng)開發(fā)與應用[M].北京:人民郵電出版社,2004。</p><p><b>  附錄:主程序</b></p><p>  

24、#include "config.h"</p><p>  #include "LCD1602.h"</p><p>  #include "UART.h"</p><p>  #include "I2C.h"</p><p>  #define Num 1<

25、;/p><p>  uint8 i=0,j=0,k=0, Addr=0;</p><p>  uint8 rcv_data[Num],read_data[Num],display_data[16];</p><p>  int main()</p><p><b>  {</b></p><p> 

26、 PINSEL0 = 0x55; //設置p0.0-p0.1為UART0,p0.2-p0.3為I2C</p><p>  PINSEL1 = 0; //設置p0.16-p0.24為GPIO</p><p>  IODIR = 0x7ff<<16; //p0.16-p0.24為輸出</p><p>  lcd_init();<

27、/p><p>  UART0_init();</p><p>  I2C_init(100000);</p><p><b>  while(1)</b></p><p><b>  { </b></p><p>  UART0_RcvStr(rcv_data,Num);<

28、;/p><p>  WriteC01(Addr,Num,rcv_data);</p><p>  DelayMs(100);////////////</p><p>  ReadC01(Addr,Num,read_data);</p><p><b>  if(i<15)</b></p><p>

29、;<b>  {</b></p><p>  display_data[i++]=read_data[0];</p><p>  display_data[i]='\0';</p><p><b>  }</b></p><p><b>  else</b>&l

30、t;/p><p><b>  {</b></p><p>  for(j=0;j<14;j++)</p><p><b>  {</b></p><p>  display_data[j]=display_data[j+1];</p><p>  display_data[

31、14]=read_data[0];</p><p>  display_data[15]='\0';</p><p><b>  }</b></p><p><b>  }</b></p><p>  DisText(0x80,display_data); Addr++;</

32、p><p><b>  }</b></p><p>  return(0);</p><p><b>  }</b></p><p>  /****************************************************************************</p

33、><p>  * File: lcd1602.h</p><p>  * 功能:向LCD輸出字符(一行只能顯示16個字符)</p><p>  ****************************************************************************/</p><p>  #include &quo

34、t;config.h"</p><p>  #define rs (1<<24)</p><p>  #define rw (1<<25)</p><p>  #define en (1<<26)</p><p>  #define busy (1<<23)</p>&l

35、t;p><b>  //檢查總線是否忙</b></p><p>  void ChkBusy()</p><p><b>  {</b></p><p>  IODIR=0x700<<16;</p><p><b>  while(1)</b></p&g

36、t;<p><b>  {</b></p><p><b>  IOCLR=rs;</b></p><p><b>  IOSET=rw;</b></p><p><b>  IOSET=en;</b></p><p>  if(!(IOPI

37、N & busy))break;</p><p><b>  IOCLR=en;</b></p><p><b>  }</b></p><p>  IODIR=0x7ff<<16;</p><p><b>  }</b></p><p&

38、gt;<b>  //寫函數</b></p><p>  void WrOp(uint8 dat)</p><p><b>  {</b></p><p>  ChkBusy();</p><p>  IOCLR=rs; // RS=0,RW=0</p><p> 

39、 IOCLR=rw; </p><p>  IOCLR=(0xff<<16); </p><p>  IOSET=(dat<<16);//送數</p><p><b>  IOSET=en;</b></p><p><b>  IOCLR=en;</b><

40、/p><p><b>  }</b></p><p><b>  //寫數據函數</b></p><p>  void WrDat(uint8 dat)</p><p><b>  {</b></p><p>  ChkBusy();</p>

41、<p>  IOSET=rs; // RS=1,RW=0</p><p><b>  IOCLR=rw;</b></p><p>  IOCLR=(0xff<<16); </p><p>  IOSET=(dat<<16);//送數</p><p><b>

42、;  IOSET=en;</b></p><p><b>  IOCLR=en;</b></p><p><b>  }</b></p><p>  //lcd初始化函數</p><p>  void lcd_init(void)</p><p><b>

43、;  {</b></p><p>  WrOp(0x38);// 8-bit mode - 2 line.</p><p>  WrOp(0x06);//光標加1</p><p>  WrOp(0x0C);//開顯示</p><p><b>  }</b></p><p&

44、gt;<b>  //顯示文本函數</b></p><p>  void DisText(uint8 addr,uint8 *p)</p><p><b>  {</b></p><p>  WrOp(addr);</p><p>  while(*p !='\0')WrDat(*(

45、p++));</p><p><b>  }</b></p><p>  /****************************************************************************</p><p>  * File: UART.h</p><p>  * 功能:通過串口輸入

46、字節(jié)數據。</p><p>  ****************************************************************************/</p><p>  #include "config.h"</p><p>  #define UART_BPS9600/* 定義通訊波特率 */&l

47、t;/p><p><b>  //初始化串口0。</b></p><p>  void UART0_init(void)</p><p><b>  { </b></p><p>  uint16 Fdiv;</p><p>  U0LCR = 0x83;// D

48、LAB = 1,可設置波特率</p><p>  Fdiv = (Fpclk / 16) / UART_BPS; // 設置波特率</p><p>  U0DLM = Fdiv / 256;</p><p>  U0DLL = Fdiv % 256;</p><p>  U0LCR = 0x03;</p&g

49、t;<p><b>  }</b></p><p>  //從串口接收 1 字節(jié)數據,使用查詢方式接收。</p><p>  uint8 UART0_RcvByte (void)</p><p><b>  { </b></p><p>  uint8 rcv_dat;</p

50、><p>  while ((U0LSR & 0x01) == 0); // 等待接收標志置位</p><p>  rcv_dat = U0RBR; </p><p>  return (rcv_dat);</p><p><b>  }</b></p><p>  //從串口接收字符串

51、。</p><p>  void UART0_RcvStr (uint8 *s, uint32 n)</p><p><b>  { </b></p><p>  for ( ; n>0; n--)</p><p><b>  { </b></p><p>  *s+

52、+ = UART0_RcvByte();</p><p><b>  }</b></p><p><b>  }</b></p><p>  /****************************************************************************</p>&l

53、t;p>  * File: I2C.h</p><p>  * 功能:讀寫外部存儲器24C01。</p><p>  ****************************************************************************/</p><p>  #include "config.h"</

54、p><p>  #define Write_C01 0xA0 </p><p>  #define Read_C01 0xA1 </p><p>  #define AA (1<<2) </p><p>  #define SI (1<<3) </p><p>  #def

55、ine STO (1<<4) </p><p>  #define STA (1<<5) </p><p>  #define I2CEN (1<<6)</p><p>  #define lastbyte 1</p><p><b>  //I2C初始化</b>&

56、lt;/p><p>  void I2C_init(uint32 fi2c)</p><p><b>  {</b></p><p>  if(fi2c>400000) fi2c = 400000;</p><p>  PINSEL0 = (PINSEL0 & 0xffffff0f) | 0x50;</p

57、><p>  I2SCLH = (Fpclk / fi2c+1) / 2;</p><p>  I2SCLL = (Fpclk / fi2c) / 2;</p><p>  I2CONCLR = STA | SI | AA;</p><p>  I2CONSET = I2CEN; </p><p&

58、gt;<b>  }</b></p><p><b>  //發(fā)送起始信號</b></p><p>  void I2C_Start(void)</p><p><b>  {</b></p><p>  I2CONSET = STA; &l

59、t;/p><p>  while(I2STAT!=0x08); </p><p>  I2CONCLR = STA; </p><p><b>  }</b></p><p><b>  //發(fā)送停止信號 </b></p><p>

60、  void I2C_Stop(void)</p><p><b>  {</b></p><p>  I2CONSET = STO; </p><p>  I2CONCLR = SI; </p><p><b>  }</b>

61、</p><p><b>  //寫一字節(jié)數據</b></p><p>  void WriteByte(uint8 data)</p><p><b>  {</b></p><p>  I2DAT = data;</p><p>  I2CONCLR = SI;

62、 </p><p><b>  }</b></p><p><b>  //寫地址</b></p><p>  void WriteAddr(uint8 Mode) </p><p><b>  {</b></p><p>  Wri

63、teByte(Mode);</p><p>  if(Mode==Read_C01) </p><p><b>  {</b></p><p>  while(I2STAT!=0x40); </p><p><b>  }</b></p><p><b&g

64、t;  else </b></p><p><b>  {</b></p><p>  while(I2STAT!=0x18); </p><p><b>  }</b></p><p><b>  }</b></p><p>

65、;<b>  //寫數據 </b></p><p>  void WriteData(uint8 data)</p><p><b>  {</b></p><p>  WriteByte(data);</p><p>  while(I2STAT!=0x28); </p>

66、;<p><b>  }</b></p><p><b>  //讀字節(jié)數據</b></p><p>  uint8 ReadByte(uint8 last) </p><p><b>  {</b></p><p

67、><b>  if(last) </b></p><p><b>  {</b></p><p>  I2CONCLR=AA;</p><p>  I2CONCLR=SI; </p><p>  while(I2STAT!=0x58); &

68、lt;/p><p><b>  }</b></p><p><b>  else</b></p><p><b>  {</b></p><p>  I2CONSET=AA; </p><p>  I2CONCLR=SI;

69、 </p><p>  while(I2STAT!=0x50); </p><p><b>  }</b></p><p>  return(I2DAT);</p><p><b>  }</b></p><p><b&g

70、t;  //寫24C01</b></p><p>  void WriteC01(uint8 StartAddr,uint8 CountByte,uint8 *i2c_buf)</p><p><b>  {</b></p><p>  uint8 i=0;</p><p>  I2C_Start(); &l

71、t;/p><p>  WriteAddr(Write_C01); </p><p>  WriteData(StartAddr); </p><p>  for(i=0;i<CountByte;i++)</p><p><b>  {</b></p>&l

72、t;p>  WriteData(i2c_buf[i]);</p><p><b>  }</b></p><p>  I2C_Stop();</p><p><b>  }</b></p><p><b>  //讀24C01</b></p><p&g

73、t;  void ReadC01(uint8 StartAddr,uint8 CountByte,uint8 *i2c_buf)</p><p><b>  {</b></p><p>  uint8 i=0;</p><p><b>  //設置讀指針</b></p><p>  I2C_Star

74、t(); </p><p>  WriteAddr(Write_C01); </p><p>  WriteData(StartAddr);</p><p>  I2C_Stop(); </p><p><b>  //開始讀數據</b></p><p>  I2C_Start(); <

75、/p><p>  WriteAddr(Read_C01);</p><p>  for(i=0;i<CountByte-1;i++)</p><p><b>  {</b></p><p>  i2c_buf[i]=ReadByte(!lastbyte);</p><p><b>  

76、}</b></p><p>  i2c_buf[i]=ReadByte(lastbyte);</p><p>  I2C_Stop(); </p><p><b>  }</b></p><p><b>  //延時函數 </b></p><p>  void

77、 DelayMs(uint8 dly)</p><p><b>  { </b></p><p><b>  uint8 i;</b></p><p>  for(; dly>0; dly--)</p><p>  for(i=0; i<1000; i++);</p>&

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 眾賞文庫僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論