色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

從IIC實測波形入手,去理解IIC的通信原理

FPGA之家 ? 來源:CSDN技術社區 ? 作者:碼農愛學習 ? 2021-04-09 18:07 ? 次閱讀

單片機的朋友都知道IIC通信這個工具,但好多人只是會用,內部的原理不求甚解,或是想要了解其原理,但卻對抽象的時序描述一頭霧水。本文將從實測的IIC波形入手,帶你看到真實的IIC樣子,進而去理解IIC的通信原理。

1IIC基礎知識

首先復習一下IIC基礎知識,這部分看不懂的請先帶著疑問,然后我們通過分析IIC的真實波形,這些疑問可能就豁然開朗了~

1.1 IIC是什么

IIC(Inter Integrated Circuit,集成電路總線)是一種由 PHILIPS 公司開發的兩線式串行總線,用于連接微控制器及其外圍設備。它是由數據線 SDA 和時鐘 SCL 構成的串行總線,可發送和接收數據。在 CPU (單片機)與IIC模塊之間、IIC模塊與IIC模塊之間進行雙向傳送。

IIC的一些特點:

IIC是半雙工,而不是全雙工

IIC是真正的多主機總線,(對比SPI在每次通信前都需要把主機定死,而IIC可以在通訊過程中,改變主機),如果兩個或更多的主機同時請求總線,可以通過沖突檢測和仲裁防止總線數據被破壞

起始和終止信號都是由主機發出的,連接到IIC總線上的器件,若具有IIC總線的硬件接口,則很容易檢測到起始和終止信號

在起始信號后必須發送一個7位從機地址+1位方向位,用“0”表示主機發送數據,“1”表示主機接收數據。

每當主機向從機發送完一個字節的數據,主機總是需要等待從機給出一個應答信號,以確認從機是否成功接收到了數據

起始信號是必需的,結束信號和應答信號,都可以不要

注:實際使用中,一般是單片機作為主機,其它器件作為從機,單片機先向器件發送信息表示要讀取數據,之后轉變傳輸方向,器件發送數據到單片機。

1.2 IIC物理連接

使用IIC通信的IIC器件有很多,比如陀螺儀加速度計MPU6050,EEPROM存儲芯片AT24C02等,通過IIC總線,可以與單片機之間進行數據傳輸。

IIC通信線只有只有兩根,數據線SDA的高低電平傳輸2進制的數據,時鐘線SCL通過方波信號提供時鐘節拍

多個IIC器件可以并聯在IIC總線上,每個器件有特定的地址,分時共享IIC總線

實際使用IIC當然還要連接電源以及共地哦

4bc7726c-990f-11eb-8b86-12bb97331649.png

1.3 IIC時序

網上查找IIC的基礎知識,可能會搜到這樣的時序圖:

4c0114a4-990f-11eb-8b86-12bb97331649.png

看起來好復雜的樣子,這時可能一部分人就放棄思考了。

1.3.1 IIC起始結束信號

好吧,換個簡單點的圖,你也可能會搜到這樣的圖:

4c3b7a22-990f-11eb-8b86-12bb97331649.jpg

這張圖看起來更簡單一些,描述了IIC的起始和停止條件:

起始:時鐘線SCL為高時,數據線SDA由高到低

停止:時鐘線SCL為高時,數據線SDA由低到高

注:SDA和SCL同時為高時,為IIC總線的空閑狀態

1.3.2 IIC應答

再來看下面這張圖:

4c6a89c0-990f-11eb-8b86-12bb97331649.jpg

這表示IIC的應答機制

下面的波形:SCL,主機產生的時鐘脈沖

上面的波形:SDA,主機發送的8位數據

中間的波形:SDA,從機在第9個時鐘信號進行拉低回應,表示收到了主機發來的數據,拉高則表示不應答

注:實際上,上面和中間是同樣的SDA線,這里只是分開示意。因為IIC應答是一種相互關系,單片機發數據給IIC器件,IIC器件要進行應答,表示收到了數據,同樣,單片機接收IIC器件的數據后,也要給IIC器件一個應答。

既然發送完都需要對方回應,那什么時候使用不應答呢?就是在讀取到本次數據后,如果不需要繼續讀取,則發送非應答,對方以為你沒收到這次數據,則就不會繼續發送了。

1.3.3 IIC完整傳輸時序

4fa7ff50-990f-11eb-8b86-12bb97331649.png

開始標志(S)發出后,主設備會傳送一個7 位的Slave 地址,并且后面跟著一個第8位,稱為Read/Write 位。

R/W 位表示主設備是在接受從設備的數據還是在向其寫數據。

然后,主設備釋放SDA 線,等待從設備的應答信號(ACK)。每個字節的傳輸都要跟隨有一個應答位。

應答產生時,從設備將SDA 線拉低并且在SCL 為高電平時保持低。

數據傳輸以停止標志(P)結束,然后釋放總線。但主設備也可以產生重復的開始信號去操作另一臺從設備,而不發出結束標志。

所有的SDA 信號變化都要在SCL 時鐘為低電平時進行,除了開始和結束標志

1.4 常用的數據收發方式(時序)

上面1.3小節是IIC的基礎時序,在實際使用中,一般是對某個IIC器件的某個寄存器進行讀寫操作,因此,對于寄存器的讀寫操作,還要遵循下面的組合時序邏輯。

1.4.1 寫一個字節

用于對IIC器件某個寄存器的配置,如對MPU6050的某些參數進行設置。

4fec4a0c-990f-11eb-8b86-12bb97331649.png

寫寄存器時,主設備除了發出開始標志和地址位,還要加一個R/W 位,0 為寫,1 為讀

在第9 個時鐘周期(高電平時),MPU6050 產生應答信號

主設備開始傳送寄存器地址,并接到應答

然后開始傳送寄存器數據,仍然要有應答信號

最后主設備發送停止信號。

1.4.2 連續寫多個字節

對連續地址的寫入,這個用的較少。

50364878-990f-11eb-8b86-12bb97331649.png

通信時序與上面的“寫一個字節”類似,上面是寫一個字節后就停止了,若要連續寫,則繼續寫即可,只要可以收到從機Ack。

1.4.3 讀一個字節

用于讀取IIC器件某個寄存器的數值。

50705d9c-990f-11eb-8b86-12bb97331649.png

首先由主設備產生開始信號,然后發送從設備地址位和一個寫數據位,等待應答

然后發送寄存器地址,才能開始讀寄存器

收到應答信號后,主設備再發一個開始信號,然后發送從設備地址位和一個讀數據位

然后,作為從設備的MPU6050 產生應答信號并開始發送寄存器中的數據

通信以主設備產生的拒絕應答信號(nACK)和結束標志(Stop)結束

拒絕應答信號(nACK)產生定義為SDA 數據在第9 個時鐘周期一直為高

1.4.4 連續讀多個字節

也是用于讀取IIC器件某個寄存器的數值,當某些數據一位字節不夠表示,或有一組連續的數據需要讀時,可以使用該模式。

50a7c2f0-990f-11eb-8b86-12bb97331649.png

通信時序與上面的“讀一個字節”類似,上面是讀一個字節后就nAck叫停,若要連續寫,則發送Ack,直到不需要繼續讀時再回復nAck。

復習了這么多,之前對IIC懵懵懂懂的是否依然犯迷糊,好了,現在從理論進入實踐,看看真實的IIC是什么樣子。

2初識IIC真實波形

下面這張圖(請橫屏觀看)是通過示波器抓取的IIC波形,可以看到:

時鐘線SCL是一種間歇性的方波(需要通信時才產生方波)

數據線SDA根據SCL提供的節拍,高電平代表數據1,低電平代表數據0

沒有數據傳輸時,SDA和SCL均為高電平狀態

起始信號后,數據是9個一組,包括8位的數據和另一方的1位回應

圖中紅色數字表示單片機發送的8位數據,黃色數字表示IIC器件回應的信號,低電平0表示器件收到了單片機發來的數據。

現在對IIC波形有沒有多了一些直觀的認識?下面再進入編程階段,看看程序是怎么控制這兩根線的。

3IIC軟件編寫邏輯

IIC通信可以使用單片機自帶的硬件IIC,它提供了固定的引腳接口和函數庫。也可以自己通過軟件編寫來實現IIC時序,這時就可以任選引腳,也方便其它硬件平臺的移植。

下面通過軟件IIC的編寫,從軟件角度理解IIC通信邏輯。

以下函數都是單片機在執行,即主機發出的動作,所以一定要從單片機的角度思考哦~

另外,不要看到程序就匆匆掠過,為幫助理解,我對代碼進行了一定的注解,仔細分析每條代碼,想想與IIC的邏輯如何對應起來,IIC邏輯還沒懂的,讀完本篇,分析過真實的IIC波形后,再來看看代碼,會有不一樣的體會。

起始IIC_Start()

//==================================//產生IIC起始信號//==================================void IIC_Start(void){ SDA_OUT(); //sda線輸出 IIC_SDA=1; delay_us(2); IIC_SCL=1; //時鐘線為高時 delay_us(2); IIC_SDA=0; //數據線由高到低 delay_us(4); IIC_SCL=0; //時鐘線拉低,鉗住IIC總線,準備發送數據}

最后一句SCL拉低,然后就準備產生時鐘信號,發送數據了。

停止IIC_Stop()

//==================================//產生IIC停止信號//==================================void IIC_Stop(void){ SDA_OUT(); //sda線輸出 IIC_SCL=0; //確保時鐘線為低時,數據線才能變化為0,否則這就可能成起始信號了! delay_us(2); IIC_SDA=0; delay_us(2); IIC_SCL=1; //時鐘線為高時 IIC_SDA=1; //數據線由低到高 delay_us(4); }

停止前也要確保SCL是拉低的狀態。

最后SDA和SCL都為高,即釋放IIC總線,IIC總線進入空閑狀態。

等待應答IIC_wait_Ack()

//==================================//等待應答信號到來//用于發送模式下,發送8位后,等待器件應答第9位//返回值:1,接收應答失敗// 0,接收應答成功//==================================u8 IIC_Wait_Ack(void){ u8 ucErrTime=0; SDA_IN(); //SDA設置為輸入 IIC_SDA=1;delay_us(1); //SDA先拉高,若被從機拉低則說明收到應答信號 IIC_SCL=1;delay_us(1); //SCL拉高,產生第9位的脈沖 while(READ_SDA) { ucErrTime++; if(ucErrTime》250) { IIC_Stop(); return 1; } } IIC_SCL=0;//時鐘輸出0 //SCL拉低,結束第9位的脈沖 return 0; }

在一定是時間內檢測SDA是否被從機拉低,被拉低則說明從機收到了數據。

產生應答IIC_Ack()

//==================================//產生ACK應答//用于讀取模式(SDA為in)讀了8位器件數據后,在第9位給出一個應答,我還要繼續讀//==================================void IIC_Ack(void){ IIC_SCL=0; //確保時鐘線為低時,數據線才能變化為0,否則這就可能成起始信號了! SDA_OUT(); //SDA由讀取改為發送 delay_us(2); IIC_SDA=0; //拉低SDA,表示應答 delay_us(2); IIC_SCL=1; //SCL先上升 delay_us(2); IIC_SCL=0; //SCL再下降,形成一個脈沖,應答才生效}

單片機在接收器件數據后,進行回應,表示接收到了器件的數據。

該函數用在連續讀取多個字節時,每讀完一個字節(8位),產生回應,表示還要進行讀,這時器件就可以繼續發數據了。

當單片機不需要繼續讀,如連續讀的最后一個字節,或只讀一個字節,單片機發送非應答信號,這時器件以為單片機沒有收到數據,接下來就不會再發數據了。

非應答函數如下,就是拉高SDA:

不產生應答IIC_nAck()

//==================================//不產生ACK應答//用于讀取模式(SDA為in)讀了8位器件數據后,在第9位給出一個應答,我不想讀了//==================================void IIC_NAck(void){ IIC_SCL=0; //確保時鐘線為低時,數據線才能變化為0,否則這就可能成起始信號了! SDA_OUT(); //SDA由讀取改為發送 IIC_SDA=1; //拉高SDA,表示不應答 delay_us(2); IIC_SCL=1; //SCL先上升 delay_us(2); IIC_SCL=0; //SCL再下降,形成一個脈沖,不應答才生效}

IIC發送一個字節

//==================================//IIC發送一個字節//返回從機有無應答//1,有應答//0,無應答//==================================void IIC_Send_Byte(u8 txd){ u8 t; SDA_OUT(); //SDA發送模式 IIC_SCL=0; //拉低時鐘開始數據傳輸 for(t=0;t《8;t++) { IIC_SDA=(txd&0x80)》》7; //SDA高低電平表示數據1和0 txd《《=1; delay_us(2); //對TEA5767這三個延時都是必須的 IIC_SCL=1; //SCL先上升 delay_us(2); IIC_SCL=0; //SCL再下降,形成一個脈沖,發送一位數據生效 delay_us(2); }}

發送一個字節,就是分8次循環,產生8個時鐘信號,并將SDA賦值為0或1。

IIC讀取一個字節

//==================================//讀1個字節//ack=1時,發送ACK,ack=0,發送nACK //==================================u8 IIC_Read_Byte(unsigned char ack){ unsigned char i,receive=0; SDA_IN(); //SDA輸入模式 for(i=0;i《8;i++ ) { IIC_SCL=0; //SCL先下降,通過循環,形成時鐘脈沖 delay_us(2); IIC_SCL=1; //SCL上升 receive《《=1; if(READ_SDA) receive++; //讀取并組合記錄數據,++表示讀到1了,最低位置1 delay_us(1); } //讀取8位后,主機需要變為發送模式,在第9位進行應答或不應答 //此時CLK還是高電平狀態,不過下面的應答會先將CLK拉低的 if (!ack) { //讀1個字節,或讀多個字節讀到最后一個字節時,使用nACK //然后配合使用IIC停止信號 IIC_NAck();//發送nACK } else { //讀多個字節還沒讀完時,使用ACK,表示現在讀的ok,還要繼續讀 IIC_Ack(); //發送ACK } return receive;}

讀取一個字節,也是分8次循環,產生8個時鐘信號,并讀取SDA的高低電平信號,最后,根據要不要繼續讀下一個字節,發送第9位的Ack或nACK。

4真實IIC波形詳細分析

4.1 讀取從機數據(單字節讀)

下面這張圖(請橫屏觀看)展示IIC讀某個器件的寄存器的一個字節的真實波形(注:實際是讀了2個不同寄存器的值,每個寄存器讀了1個字節,所以,可以先只看前半部分哦~),我已對波形進行了詳細的注解,并留意一下顏色區分。

對照著圖,再來溫習一下各個信號的特點:

起始信號:時鐘線SCL為高時,數據線SDA由高到低

停止信號:時鐘線SCL為高時,數據線SDA由低到高

數據信號:連續的8位,每一個SCL脈沖時鐘對應的SDA,高電平為數據1,低電平為數據0

應答信號:第9位(數據信號后),由對方產生的回應,0為產生回應,1為不產生回應

上面這幅圖中,單片機先產生起始信號,然后發送7位器件地址+1位寫標志(綠色的0),并等待從機回應(從機拉低SDA表示收到數據),接著發送8位寄存器地址,并等待從機回應。然后,單片機先再次產生起始信號,發送7位器件地址+1位讀標志(綠色的1),并等待從機回應。從機收到讀的信號后,從機開始發送8位數據,主機接收到數據后,主機發送nAck不應答信號(圖中的Ack(1),主機將SDA拉高,從機則認為主機剛才沒有收到它發送的數據,從機將不再繼續發送),接著主機發送結束信號,讀取完成。

此圖后半部分是以相同方式讀了另一個寄存器的值。

另外,SCL信號都是由單片機產生,SDA信號由單片機和IIC器件(從機)共同產生,當需要對IIC器件的寄存器寫時,單片機產生SDA數據,當需要讀取IIC器件的寄存器數據時,改變傳輸方向,IIC器件產生SDA數據。

對于主機和從機什么時候控制SDA,還可以參考這個圖幫助理解:

4.2 讀取從機數據(多字節讀)

上面是單字節讀的波形,再來看看多字節的波形,前面的寫器件地址、寫寄存器地址1與單字節讀一樣,這張圖只顯示了后面不一樣的部分,主要區別在于單片機接收到數據1后,產生低電平的應答,從而可以繼續讀取數據2。

(注意,因為傳感器這次測得的數據不一樣,所以讀出的數據也不一樣哦~)

注:以上的IIC真實波形,是使用是硬件IIC,自己編寫的軟件IIC測得的波形,可能在兩個信號的前后延時時間上稍有差別,但整體的時序邏輯肯定是一樣的。

4.3 配置從機寄存器(單字節寫與多字節寫)

對于寄存器的配置,也就是IIC的寫寄存器操作,我就不放圖了,參考上面的“常用的數據收發方式(時序)”以及上面的IIC讀寄存器的真實波形,IIC的寫寄存器的真實波形,應該可以腦補出哦,哈哈~
編輯:lyn

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 單片機
    +關注

    關注

    6041

    文章

    44615

    瀏覽量

    637390
  • IIC
    IIC
    +關注

    關注

    11

    文章

    302

    瀏覽量

    38424

原文標題:從IIC實測波形入手,搞懂IIC通信

文章出處:【微信號:zhuyandz,微信公眾號:FPGA之家】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    請問DS90UB903Q的IIC工作頻率必須為100KHz嗎?

    的實際工作與配置相同;使用示波器抓取IIC讀ID的波形,發現IIC在寫入8位地址0xB0后,沒有ACT信號芯片返回。 請問DS90UB903Q的I
    發表于 12-26 07:08

    IIC信號線需要增加上拉電阻,是因為IIC的IO是什么

    IIC通信中扮演著至關重要的角色,而上拉電阻的加入則是實現這種通信方式有效性和可靠性的關鍵。以下是對此現象的介紹: 一、IIC通信與開漏輸出
    的頭像 發表于 10-06 15:50 ?978次閱讀

    iic通訊的ardunio的文件下載

    里面很多iic通訊的ardunio的文件
    發表于 07-05 10:55 ?1次下載

    NSA2302iic通訊地址

    最近正在用NSA2302這個芯片,想問一下NSA2302的IIC通信地址是出廠時就設置好的嗎,還是買回來后需要自己燒寫,我使用數據手冊里給出的通信地址一直無法建立IIC
    發表于 07-04 09:55

    使用STM32F103的硬件IIC,出現BUSY重新初始化IIC之后,為什么會每次卡在設備地址發送不出去?

    使用STM32F103的硬件IIC,查詢的方式,進行通訊,出現BUSY之后,重新初始化IIC之后,之后為什么會每次卡在設備地址發送不出去啊。求教,求教
    發表于 05-28 06:43

    示波器如何捕獲和分析IIC波形

    示波器捕獲和分析IIC(集成電路間通信波形是一項重要的電子測量任務,特別是在嵌入式系統和微控制器的調試過程中。
    的頭像 發表于 05-20 15:08 ?3408次閱讀

    stm8的供電電壓是3.3V,IIC機的供電電壓是5V,請問這個IIC能正常通信嗎?

    請教一下,stm8的供電電壓是3.3V,IIC機的供電電壓是5V,請問這個IIC能正常通信嗎?是不是只要stm8的耐壓是5V就沒問題?
    發表于 05-07 08:01

    stm32f103z系列硬件IIC機不能用的原因?

    用了。 不知大家遇到過這種情況沒? 103ZE下的IIC波形如下,綠色波形IIC機的SD
    發表于 05-07 06:56

    stm8s103k與AT24C02的iic通信不穩定是什么原因導致的?

    stm8s103k與AT24C02的iic通信不穩定,有時可以讀取數據,有時讀不出 是什么原因? 有人與ADS1110用iic通信過嗎?
    發表于 04-30 07:33

    lis3dh使用IIC通訊,CS引腳懸空也能正常IIC通信嗎?

    芯片手冊上CS引腳接高電平是IIC通訊,接低電平是SPI通訊;接手的項目中,CS引腳是懸空的,IIC通訊能進行,我想知道懸空能IIC可靠通訊嘛?
    發表于 03-28 09:44

    巨霖科技將亮相IIC Shanghai并發表主題演講

    活動預告∣巨霖科技將亮相IIC Shanghai 并發表主題演講
    的頭像 發表于 03-27 09:50 ?440次閱讀
    巨霖科技將亮相<b class='flag-5'>IIC</b> Shanghai并發表主題演講

    STM32 IIC通信升級系統

    諸神,需求一套可以使用IIC通信升級固件的系統 1,STM32燒錄板,型號自定,盡量低成本,程序 2,STM32G031G8U6目標板示例程序 有人能做這項目嗎?或者大家有好的思路嗎? 如果能接請聯系425453660@qq.com 歡迎大家發表看法!
    發表于 03-20 12:40

    FPGA實現IIC協議的設計

    今天給大家帶來的是IIC通信IIC協議應用非常廣泛,例如與MPU6050進行通信,配置OV5640攝像頭、驅動OLED屏幕等等,都需要使用到IIC
    的頭像 發表于 03-04 10:49 ?1322次閱讀
    FPGA實現<b class='flag-5'>IIC</b>協議的設計

    GD32 MCU碰到IIC總線卡死怎么辦?

    大家在使用MCU IIC通信時,若碰到設備復位或者總線干擾等情況,可能會導致IIC總線卡死,表現上總線上SDA或者SCL其中一根線為低電平,IIC總線一直處于busy狀態。此時若代碼上
    的頭像 發表于 02-24 09:46 ?3971次閱讀
    GD32 MCU碰到<b class='flag-5'>IIC</b>總線卡死怎么辦?

    IIC總線為什么是半雙工?

    IIC(Inter-Integrated Circuit)總線是一種半雙工的串行通信接口。在I2C總線上,主設備和設備之間的數據傳輸是采用半雙工模式進行的。這意味著主設備和設備在不
    的頭像 發表于 02-02 16:37 ?4762次閱讀
    <b class='flag-5'>IIC</b>總線為什么是半雙工?
    主站蜘蛛池模板: 国产AV午夜精品一区二区入口| 在线播放国产视频| 国产探花在线精品一区二区| 国产av在线看的| 久久婷婷五月综合色情| 毛片免费观看视频| 免费视频网站嗯啊轻点| 男人插曲视频大全免费网站| 欧美白妞大战非洲大炮| 肉色欧美久久久久久久蜜桃| 手机在线观看无码日韩视频| 小萝ar视频网站| 亚洲中文字幕AV在天堂| 稚嫩挤奶h调教h| www黄色com| 国产99久久久欧美黑人刘玥| 久久永久免费视频| 人与人特黄一级| 王雨纯羞羞| 伊人22222| www.精品久久| 蜜桃麻豆WWW久久囤产精品免费| 日本少妇无码精品12P| 香港成人社区| 成年黄网站免费大全毛片| 国产女合集小岁9三部| 久久亚洲精品中文字幕| 亚洲精品第一综合99久久| 99re6热这里在线精品视频| 成电影人免费网站| 暖暖视频在线观看高清...| 中文视频在线| 久久久久久久久久综合情日本| 日韩欧美视频一区二区| 亚洲欧美日韩另类精品一区二区三区| 中文无码乱人伦中文视频播放| 好紧好湿太硬了我太爽了小说 | 美女伸开两腿让我爽| 一区二区乱子伦在线播放| 黄色xxxxxx| 色百度网址大全|