嵌入式的世界里面有幾個經典的協議:IIC,SPI,UART,CAN,1-WIRE,這些協議都是低速的,而且而是必須要掌握的內容,經常在使用和面試中出現。
現在應該是使用不成問題,但是細節里面的諸多細節要考慮,而且在每次使用的時候在看時序圖時仍有若干疑惑的地方,協議除了傳感器和MCU之間的通訊,其本身也可以傳輸數據,最終想實現的效果是可以在兩個MCU之間使用協議來傳輸自己的數據包。ElectronBot-數字舵機篇,就好像這篇文章里面寫的一樣,自己封裝,自己定義。這樣的優點就是若干個MCU可以組合在一起,真正的形成一種MCU傳感器網絡。當然看起來很美好,但是可能實現起來由于各種原因可能會鴿。
但是無傷大雅,一些疑惑是肯定要解的。
佳能 EF 鏡頭 SPI詳細協議
MCP3421-18bit ADC 調試,不過這個ADC寫的是真不錯
Seeed-XIAO-ESP32-C3-ADS1115測試
ADS1115-16Bit ADC 調試.上
Ti.ADS1115-15Bit差分ADC,TI的ADC也是補足了一些疑惑
這也是是之前寫的,感覺還是有點不求甚解了。
本來也想上示波器的,但是在家里面沒帶。
這次呢會使用一個ST家的傳感器(原因是便宜易得):
VL53L0X集成了領先的SPAD陣列(單光子雪崩二極管),并內嵌意法半導體第二代FlightSense專利技術。 VL53L0X的940 nm VCSEL發射器(垂直腔面發射激光器)完全不為人眼所見,加上內置的物理紅外濾光片,使其測距距離更長,對環境光的免疫性更強,對蓋片的光學串擾表現出更好的穩定性。
NXP現在是IIC的協議的標準文檔
而且各家呢,因為想變得有差異性,也會起一些自己的名字,但是大體上是換湯不換藥的。就是IIC這個名字和SDA,SCL上面有改動。
這個是一個傳感器的拓撲圖
以前問,IIC到底是幾根線,其實應該是一個2線的協議,這里就不加電源和中斷線了。
SDA 和 SCL 都是雙向線路都通過一個電流源或上拉電阻連接到正的電源電壓,當總線空閑時這兩條線路都是高電平連接到總線的器件輸出級必須是漏極開路或集電極開路才能執行線與的功能。
I2C 總線上數據的傳輸速率在標準模式下可達 100kbit/s 在快速模式下可達 400kbit/s 在高速模式下可達4Mbit/s 連接到總線的接口數量只由總線電容是 400pF 的限制決定。
下面的這個圖就是全文最精華的圖,數據究竟是什么時候傳的?
看綠色的框,永遠都是時鐘小于數據
數據的有效性在時鐘的HIGH時段,SDA線上的數據必須是穩定的。
只有當SCL線上的時鐘信號為LOW時,數據線的HIGH或LOW狀態才能改變(見圖上)。每傳輸一個數據位產生一個時鐘脈沖。
也就是另一個疑惑,時序圖里面這個互相交叉的線是什么意思,它在數據傳輸上的意思是,這個地方,進行了高低電平的變換,1是高,0是低,在時序上的意思是,在時鐘信號為LOW時,數據可以進行變化。
這個是MCP3421的時序圖
可以看到交叉是時鐘的LOW,在數據上的意思是,處于data和ACK的位置,自然是有不同的狀態。
我再換個說法重復一次上面的內容:
I2C總線進行數據傳送時,在SCL的每個時鐘脈沖期間傳輸一個數據位,時鐘信號SCL為高電平期間,數據線SDA上的數據必須保持穩定,只有在時鐘線SCL上的信號為低電平期間,數據線SDA上的高電平或低電平狀態才允許變化,因為當SCL是高電平時,數據線SDA的變化被規定為控制命令(START或STOP,也就是前面的起始信號和停止信號)。
數據有效傳輸在scl信號的高電平期間,sda數據線保持穩定,在scl為低電平時允許sda數據線變化。
數據傳輸必須帶響應,相關的響應SCL時鐘脈沖由主機產生,在響應的時鐘脈沖期間,發送器釋放 SDA 線(輸出高阻態使SDA線被上拉電阻拉高)。在響應的時鐘脈沖期間,接收器必須將 SDA 線拉低,使它在這個時鐘脈沖的高電平期間保持穩定的低電平。必須考慮建立和保持時間。
我覺得是應該是講明白了,以前這就是個疑惑沒有人告訴我。
接下來就是開始和停止:
啟動和停止條件所有事務都以START (S)開始,并以STOP (P)終止(參見圖上)。SDA線上的HIGH到LOW轉換(SCL為HIGH)定義了START條件。
SCL為HIGH時,SDA線上的LOW到HIGH轉換定義了一個停止條件。
這里的細節我覺得知道這些就可以了,在SDA拉低以后,這個通訊資源就相當于是獨占了。
下面說傳輸的數據格式:
這里也給一個中文的翻譯
byte組織:SDA上的數據傳輸是以8bit即一個字節為單位傳輸的,每一次傳輸的字節數沒有限制,每傳輸完一個字節后必須跟隨一個應答位。 以01001001(0X49)為例,其時序圖如下:
放在SDA線路上的每個字節必須是8位長。每次傳輸可以傳輸的字節數不受限制。每個字節后面必須跟一個確認位。數據首先以最高有效位(MSB)傳輸。
如果目標不能接收或傳輸另一個完整的數據字節,直到它執行了一些其他功能,例如服務內部中斷,它可以保持時鐘線SCL LOW以迫使控制器進入等待狀態。然后,當目標準備好接收另一個字節數據并釋放時鐘線SCL時,數據傳輸繼續進行。
看懂了嗎?這就是一次傳多個字節的奧秘,在時鐘線上,拉低向MCU說還沒有搞完,在準備了,好了以后就把線拉高,開始。
說說ACK,NACK信號:
確認發生在每個字節之后。確認位允許接收方通知發送方該字節已成功接收,并且可以發送另一個字節。控制器產生所有時鐘脈沖,包括確認第九時鐘脈沖。
確認信號的定義如下:在確認時鐘脈沖期間,發射機釋放SDA線,因此接收器可以將SDA線拉低,并在該時鐘脈沖的高電平期間保持穩定低電平。
就是這個圖
設置和保持時間也必須考慮在內。當SDA在第9個時鐘脈沖期間保持高電平時,這被定義為不確認信號。
然后控制器可以生成一個STOP條件來中止傳輸,或者一個重復的START條件來開始新的傳輸。
也就是說這個ack信號會影響之后的數據傳輸,也好理解,都沒有收到之后的發送都是無用功,就不發了。可以重新發,也可以停掉。
有五個條件會導致NACK的產生:
1. 總線上不存在具有傳輸地址的接收器,因此沒有設備響應確認。
2. 接收器無法接收或發送,因為它正在執行一些實時功能,還沒有準備好開始與控制器通信。
3. 在傳輸過程中,接收方接收到它不理解的數據或命令。
4. 在傳輸過程中,接收方不能再接收任何數據字節。
5. 控制器-接收器必須向目標發送器發出傳輸結束的信號。
下面說時鐘:
時鐘同步兩個控制器可以同時在空閑總線上開始傳輸,并且必須有一種方法來決定哪一個控制總線并完成傳輸。這是通過時鐘同步和仲裁完成的。
在單控制器系統中,不需要時鐘同步和仲裁。時鐘同步是使用I2C接口到SCL線的有線與連接來執行的。
這意味著SCL線上的HIGH到LOW轉換導致相關控制器開始計數其LOW周期,一旦控制器時鐘已變為LOW,它將SCL線保持在該狀態,直到時鐘達到HIGH狀態(見圖上)。
然而,如果另一個時鐘仍在其LOW周期內,則該時鐘的LOW到HIGH轉換可能不會改變SCL線的狀態。因此,SCL線由具有最長低電平周期的控制器保持低電平。低周期較短的控制器在此期間進入高等待狀態。
這個是我沒有看到過的東西,就是兩個時鐘信號對協議信號的影響,不過就記住我上面的黑色部分就好。
當所有相關的控制器都計算出它們的LOW周期時,時鐘線被釋放并變為HIGH。然后,控制器時鐘和SCL線的狀態之間沒有區別,并且所有控制器開始計數它們的HIGH周期。第一個完成其HIGH周期的控制器再次將SCL線拉至LOW。這樣,就會生成一個同步的SCL時鐘,其LOW周期由時鐘LOW周期最長的控制器決定,HIGH周期由時鐘HIGH周期最短的控制器決定。
一個IIC的信號周期的長短由兩個MCU時鐘信號來決定。
這里的多傳感器數據沖突我就不講了,目前好像還沒有用到。
接下來說數據傳輸,和上面有點一樣:
數據傳輸遵循圖上所示的格式,第二個字節有看頭
這個是MSB先行
在START條件(S)之后,發送一個目標地址。這個地址有7位長,后面跟著第8位數據方向位(R/W)——“0”表示傳輸(WRITE),“1”表示數據請求(READ)
由控制器產生的停止條件(P)。但是,如果控制器仍然希望在總線上進行通信,它可以生成重復的START條件(Sr),并在不首先生成STOP條件的情況下處理另一個目標。在這樣的傳輸中,讀/寫格式的各種組合是可能的。
接了個電話,思路都沒有了,撲街。。。
可能的數據傳輸格式有:
a,其實是A上面有一個橫杠,就是不響應的意思,下面丟失了。產生這個信號以后,主機發出了停止信號。
控制器-發射機發送到目標-接收機。傳輸方向沒有改變。目標接收方確認每個字節。
叨叨兩句吧,就是主機一直發數據,傳感器就應答收到了,像極了被罵的的我,是是是,對對對。
控制器在第一個字節之后立即讀取目標。在第一次確認的時刻,控制-發送者成為控制-接收者,目標-接收者成為目標-發送者。這個第一個確認仍然由目標生成。控制器生成后續確認。STOP條件由控制器生成,控制器在STOP條件之前發送一個不確認(a)。
這個呢就是讀取傳感器的值,瘋狂的拿,必要時候會說,拿到了。
組合格式。在傳輸過程中改變方向時,START條件和目標地址都是重復的,但是R/W位顛倒了。如果控制器-接收器發送一個重復的START條件,它在重復的START條件之前發送一個nottacknowledge (a)。
復合格式:傳輸改變方向的時侯,起始條件和從機地址都會被重復 但 R/ W 位取反,如果主機接收器發送一個重復起始條件,它之前應該發送了一個不響應信號 A。相當于是沒搭理,信號斷了,傳感器主動的找MCU。復合格式可以用于例如控制一個串行存儲器在第一個數據字節期間 要寫內部存儲器的位置在重復起始條件和從機地址后數據可被傳輸。
注:1. 例如,可以使用組合格式來控制串行存儲器。必須在寫入第一個數據字節期間寫入內部存儲器位置。重復START條件和目標地址后,即可傳輸數據。
2. 所有關于先前訪問的內存位置的自動遞增或遞減的決定,等等,都是由設備的設計者做出的。
3. 每個字節后面跟著一個確認位,由序列中的A或A塊表示。
4. pc總線兼容設備必須在接收到START或重復START條件時重置其總線邏輯,以便它們都預期目標的發送地址,即使這些START條件沒有按照正確的格式定位。
5. START條件緊跟著STOP條件(無效消息)是一種非法格式。然而,許多設備被設計為在這種條件下正常運行。
6. 連接到總線的每個設備都可以通過唯一的地址尋址。通常存在一個簡單的控制器/目標關系,但也可能有多個相同的目標可以同時接收和響應,例如在組廣播中。
說說尋址:I2C總線的尋址過程是通常在起始條件后的第一個字節決定了主機選擇哪一個從機例外的情況是可以尋址所有器件的廣播呼叫地址使用這個地址時 理論上所有器件都會發出一個響應但是也可以使器件忽略這個地址廣播呼叫地址的第二個字節定義了要采取的行動。
總有人不回答,媽的。
從機地址由一個固定和一個可編程的部分構成由于很可能在一個系統中有幾個同樣的器件從機地址的可編程部分使最大數量的這些器件可以連接到I2C總線上器件可編程地址位的數量由它可使用的管腳決定
例如:如果器件有 4 個固定的和 3 個可編程的地址位那么相同的總線上共可以連接8個相同的器件。
原來這些都是找過飛利浦買的
總結了I2C總線系統特性的規范要求,包括了強制和可選部分 Table 2 i2c總線協議特性的要求 M = 強制; O = 可選; n/a = 不適用
聽累沒有?估計沒有幾個看到這里的。
來看一個真實的協議信號
IIC的輸入輸出結構采用的是開漏的結構。開漏結構不能夠自主得到高電平,所以需要通過外部上拉電阻Rp來的實現IIC通信過程中的高電平。Rp的大小取決于IIC不同模式時的灌電流大小。 下面兩個圖是描述IIC獲得高低電平的情景。因為一條IIC總線上面可能會同時連接上多個設備,如果IIC使用的是推挽輸出的話容易引起短路。 IIC設備可以通過控制N-MOS管的開關來控制輸出信號的電平高低。當MOS管G極為低電平時MOS管截止IIC總線上面由于有上拉電阻的存在而為高電平;當MOS管G極為高電平時MOS管導通,IIC總線相當于直接接地為低電平。 IIC的輸入是通過TTL肖特基觸發器將數據傳輸到輸入數據寄存器當中,再提供給處理器處理。
由于種類的設備都有可能連接到IIC總線上面,比如說CMOS、NMOS等,所以IIC的高電平和低電平的標準是不一定的。高電平和低電平的值分別為0.7VDD和0.3VDD。
IIC的總線連接可以接受多主機的模式,也就是說一條IIC總線上面可以有多個設備可以作為主機來使用,但是在一次數據的傳輸過程中只能有一個設備作為主機。一條IIC總線上面誰是主機取決于總線上面的時鐘和數據信號由誰控制。
如果兩個MCU同時發起開始信號時(都試圖成為主機),這時候IIC的仲裁機制會發揮作用來判定誰成為主機。
IIC的仲裁機制得益于其開漏的輸入輸出結構。例如如圖所示,當SCL線上掛載的多個設備,其中的MCU2的SCL輸出低電平,那么這條IIC總線SCL就會被MCU2拉低,這也就是“與”的特性。 IIC上的仲裁主要是由兩部分組成SCL時鐘同步、SDA線仲裁。
如圖所示CLK1和CLK2都是連接在一條SCL線上的設備同時產生的時鐘信號,由于IIC總線存在“與”的特性,所以兩個設備高電平相同的部分形成了SCL最終的時鐘,也就是說同一條IIC總線上面的時鐘都是相同的。
那突然就理解了上面文章里面的時鐘是什么意思。
同樣SDA仲裁也是基于“與”的特性。如圖所示當兩個設備同時發出開始信號想要傳送數據時,在第一個和第二個周期內DATA1和DATA2的數據都是相同的,然后兩者繼續傳送數據,當在第三個時鐘周期時DATA2與SDA的數據不一致,這個時候設備2就會停止發送數據,轉而啟動接收模式。這樣SDA的數據就會與DATA1的數據保持一致,并且設備2停止發送數據也不會影響SDA的數據。
所示是示波器采集的IIC信號,得到這一段IIC包含的信息,主機向地址為0XA0 的設備寫入0X0C。
感謝夢源得文章,通了這次。
OKOK,看傳感器吧,不想寫了。
最大是400kHz
有中斷腳
XSHUT是可以控制功耗的引腳
上電和啟動順序有兩個選項可用于設備上電/啟動。
選項1:XSHUT引腳連接并從主機控制。此選項有助于優化功耗,因為VL53LOX可以在不使用時完全斷電,然后通過主機GPIO(使用XSHUT引腳)喚醒。
HW待機模式定義為AVDD存在且XSHUT處于低電平的時間段。
選項2:XSHUT引腳不受主機控制,通過上拉電阻連接到AVDD。如果XSHUT引腳不受控制,則上電順序如圖所示。在這種情況下,設備在FW啟動后自動進入SW STANDBY,不進入HW STANDBY。
SW是待機時刻。
也是IIC的接口,看時序圖吧,應該很好懂了
信息被封裝在8位數據包(字節)中,后面總是跟著一個確認位,Ac表示VL53LOX確認,Am表示主確認(主機總線主)。
內部數據是在SCL上升沿采樣SDA產生的。在SCL的高峰期,外部數據必須是穩定的。
例外情況是SDA下降或上升時的啟動(S)或停止(P)條件,而SCL較高。消息包含一系列字節,前面是開始條件,后面是停止或重復開始(另一個開始條件,但沒有前面的停止條件),然后是另一個消息。第一個字節包含設備地址(Ox52),還指定了數據方向。如果最低有效位很低(即Ox52),則消息是主向從機寫。如果設置了Isb(即Ox53),則消息是從從機讀取的主消息。
地址,MSB先行
寫,Ac是傳感器收到
當數據被從機接收時,它被一點一點地寫入串行/并行寄存器。從服務器接收到每個數據字節后,將生成一個確認,然后將數據存儲在當前索引尋址的內部寄存器中。
在讀取消息期間,當前索引所尋址的寄存器的內容在設備地址字節后面的字節中讀出。該寄存器的內容被并行加載到串行/并行寄存器中,并通過SCL的下降沿從設備中進行時鐘輸出。
讀
在每個字節的末尾,在讀和寫消息序列中,接收設備(即,用于寫的VL53LOX和用于讀的主機)發出確認。
消息只能由總線主機在讀取操作期間讀取完整字節后,通過發出停止條件或通過負確認(即不將SDA線拉低)來終止。
該接口還支持自動增量索引。傳輸完第一個數據字節后,索引自動加1。因此,主服務器可以連續地向從服務器發送數據字節,直到從服務器無法提供確認或者主服務器以停止條件終止寫通信。如果使用了自動增量特性,主機就不必發送地址索引來伴隨數據字節。
順序寫入
順序讀
32bit寄存器實列
這個是比較奇怪的,API的文檔不在數據手冊里面。
寫不動了。。。太多了。
-
總線
+關注
關注
10文章
2878瀏覽量
88052 -
I2C
+關注
關注
28文章
1484瀏覽量
123620 -
IIC協議
+關注
關注
0文章
16瀏覽量
3930
原文標題:IIC協議長文詳解-解惑版
文章出處:【微信號:TT1827652464,微信公眾號:云深之無跡】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論