I2C從機(jī)掛死分析和解決方法

I2C幾乎是嵌入系統(tǒng)中最為通用串行總線,MCU周邊的各種器件只要對速度要求不高都可以使用。優(yōu)點(diǎn)是兼容性好(幾乎所有MCU都有I2C主機(jī)控制器驳遵,沒有也可以用IO模擬)怨喘,管腳占用少津畸,芯片實(shí)現(xiàn)簡單。I2C協(xié)議雖然簡單必怜,實(shí)際使用過程中小毛病還不少肉拓。今天先來看一個(gè)平日最為常見的問題:I2C從機(jī)掛死。

很多事情不難而且經(jīng)常碰到棚赔,每次自認(rèn)為懂了但最終讓你站出來說清楚的時(shí)候卻總是不能自圓其說帝簇,很難受。所以我決定寫博客的時(shí)候就想盡量把內(nèi)容寫清楚詳細(xì)甚至是透徹靠益,希望讓每一個(gè)閱讀博文的同學(xué)都能看得明明白白丧肴,學(xué)會(huì)一點(diǎn)小知識(shí)。如果還有不清楚的可以留言交流.

I2C規(guī)范與特性

I2C是什么胧后,我相信99%的同學(xué)能點(diǎn)到這篇博文對I2C也有了一定的了解芋浮,這里附上一份I2C鼻祖NXP (前Philips半導(dǎo)體)的一份權(quán)威手冊:I2C-bus specification and user manual v.6

描述一下I2C最重要的幾個(gè)特性,為了后面描述問題和解決方案作一些鋪墊壳快。

  1. I2C是由兩根線(時(shí)鐘SCL + 數(shù)據(jù)SDA)組成的多主多從串行同步通信總線纸巷。
  2. 規(guī)范要求接入I2C的器件,SCL時(shí)鐘和SDA數(shù)據(jù)線都必須是雙向開漏結(jié)構(gòu)的眶痰,通過總線上的上拉電阻拉到邏輯高電平瘤旨。這樣的結(jié)構(gòu)可以實(shí)現(xiàn)線與(&)功能。
  3. 一般情況下I2C的SDA只有在SCL為低電平的時(shí)候才能改變竖伯,為高電平的時(shí)候需要保持存哲。對應(yīng)到芯片設(shè)計(jì)上則是上升沿采樣,下降沿變化七婴。


  4. 兩個(gè)例外情況由主機(jī)發(fā)出的總線起始條件START(SCL為高時(shí)SDA由高變低)和停止條件STOP(SCL為高時(shí)SDA由低變高)


掛死 = 掛了 + 死機(jī)

掛死這個(gè)詞應(yīng)該來源于英文hangs : To cause (a computer system) to halt so that input devices, such as the keyboard or the mouse, do not function.

前面提到因?yàn)?strong>線與&結(jié)構(gòu)祟偷,是I2C總線設(shè)計(jì)上最關(guān)鍵的特征,用了這種結(jié)構(gòu)才能實(shí)現(xiàn)

  • 多主機(jī)仲裁同步
  • 慢從機(jī)同步快主機(jī)

因?yàn)檫@個(gè)特性打厘,只要總線上任何一個(gè)器件拉低了SDA或者SCL修肠,其他器件都無法拉高它們,看到的都是低電平户盯。如果有器件不釋放總線嵌施,則整個(gè)總線上的通訊都會(huì)被暫停饲化,我們成為I2C bus hangs:I2C總線掛死

因?yàn)镮2C主機(jī)一般是可編程的器件,受我們控制艰管,如果主機(jī)主動(dòng)拉低了總線滓侍,我們可以通過調(diào)試代碼了解原因,也可以很方便的通過復(fù)位I2C外設(shè)或者復(fù)位芯片來退出這種狀態(tài)牲芋。而I2C從機(jī)往往不帶RESET引腳撩笆,如果掛死了總線即使整個(gè)系統(tǒng)復(fù)位都無法解除,僅重新上下電才可以恢復(fù)缸浦。很多系統(tǒng)上是不可接受的夕冲,因此我們需要更加小心的處理I2C從機(jī)掛死的情況,下面分析也是針對I2C從機(jī)掛死來寫的裂逐。

SDA掛死

先來看下哪些情況下I2C從機(jī)會(huì)需要拉低SDA線歹鱼。

  1. 主機(jī)向從機(jī)寫數(shù)據(jù)或地址時(shí),從機(jī)如果發(fā)出ACK應(yīng)答卜高,則會(huì)第9個(gè)CLK的期間拉低SDA
  2. 主機(jī)讀數(shù)據(jù)的時(shí)候弥姻,從機(jī)會(huì)在bit為0時(shí)對應(yīng)的CLK期間拉低SDA

那什么情況I2C從機(jī)又可能鉗住SDA線呢?我們先來看一個(gè)典型的I2C主機(jī)發(fā)起對某一器件地址讀操作掺涛,讀到的數(shù)據(jù)為10011000b庭敦,MSB在先也就是0x98。在圖中地址字節(jié)第9個(gè)CLK期間從機(jī)拉低SDA表示對地址進(jìn)行應(yīng)答薪缆,在返回的數(shù)據(jù)字節(jié)的第2秧廉,3,6拣帽,7疼电,8幾個(gè)CLK器件從機(jī)拉低SDA輸出邏輯0電平。


根據(jù)上面講的I2C協(xié)議SCL為高的時(shí)候减拭,SDA電平應(yīng)保持蔽豺,而等到SCL為低后(也就是下降沿后)才能發(fā)生改變。如果在上面幾個(gè)CLK的前半個(gè)周期SCL拉高后主機(jī)不再拉低呢拧粪?從機(jī)會(huì)有什么動(dòng)作修陡?YES,從機(jī)會(huì)持續(xù)拉低著SDA既们,直到見到下一個(gè)他應(yīng)該輸出高電平的下降沿濒析。

最常見的情況就是主機(jī)在通訊的過程中產(chǎn)生了復(fù)位正什。由于復(fù)位動(dòng)作通常會(huì)立刻執(zhí)行啥纸,外設(shè)狀態(tài)機(jī)都恢復(fù)到默認(rèn)狀態(tài),也就發(fā)不出完整的CLK了婴氮。那么等到主機(jī)復(fù)位完成回來后斯棒,SCL為高盾致,SDA被從機(jī)拉低。主機(jī)無法發(fā)起START起始條件荣暮,不能開始下一次與從機(jī)的通訊庭惜,這稱為SDA掛死。

要想辦法恢復(fù)穗酥,我們先得知道從機(jī)什么時(shí)候會(huì)釋放SDA护赊。由于剛剛的SCL下降沿沒有給出來,恢復(fù)總線要做的第一件事情就是在想辦法用GPIO在SCL線上模擬一個(gè)下降沿砾跃,讓從機(jī)狀態(tài)機(jī)繼續(xù)走下去骏啰。只發(fā)一個(gè)下降沿并不一定能將SDA釋放,因?yàn)槲覀儾⒉磺宄?dāng)主機(jī)復(fù)位異常發(fā)生時(shí)刻從機(jī)到底處于圖中哪一個(gè)狀態(tài)抽高,所以需要逐個(gè)CLK去探測判耕,直到見到SDA被釋放了,我們才終止并且發(fā)送STOP條件告訴從機(jī)這次坑爹的通訊結(jié)束了翘骂。

網(wǎng)上通常的傳授的方法是模擬9個(gè)連續(xù)的CLK壁熄,但是我更喜歡上面的方法,一是速度快碳竟,二是具備可確定性草丧。發(fā)送9個(gè)CLK我主要擔(dān)心從機(jī)在最后一個(gè)CLK時(shí)又拉低了SDA,還是需要用到上面的方法來釋放瞭亮。

通過模擬幾種情形來實(shí)際體會(huì)一下(從機(jī)對SDA的操作紅色表示):

如果在地址字節(jié)第9個(gè)CLK拉高后主機(jī)復(fù)位方仿。在模擬的第一個(gè)時(shí)鐘低電平期間就可以看到SDA的釋放,隨后主機(jī)先拉低SDA统翩,再模擬一個(gè)STOP結(jié)束條件仙蚜。



在數(shù)據(jù)字節(jié)第2個(gè)CLK拉高后主機(jī)復(fù)位,在第二個(gè)模擬的時(shí)鐘低電平期間才看到SDA釋放



在數(shù)據(jù)字節(jié)第6個(gè)CLK拉高后主機(jī)復(fù)位厂汗,在第三個(gè)模擬的時(shí)鐘低電平期間才看到SDA釋放

通過以上三種情況的分析委粉,想必你已經(jīng)非常清楚改如何處理了,最后附上一個(gè)程序處理流程圖:

SCL掛死

I2C從機(jī)主動(dòng)拉低SCL線在規(guī)范中是一個(gè)合法的行為娶桦,稱之為Clock Stretching(時(shí)鐘擴(kuò)展贾节,我一般叫他時(shí)鐘同步)。通常是主機(jī)請求數(shù)據(jù)( 收或者發(fā))后從機(jī)需要一些時(shí)間處理衷畦,且沒有多余Buffer可以接收接或者提供接下來的數(shù)據(jù)的時(shí)候從機(jī)則會(huì)拉低SCL一段時(shí)間直到有新的數(shù)據(jù)準(zhǔn)備好栗涂。

SCL掛死(也就是前面所說一直拉低SCL)這種情況在標(biāo)準(zhǔn)I2C從器件上基本不會(huì)出現(xiàn),因?yàn)橹灰酒€在正常工作buffer總算有準(zhǔn)備好的時(shí)候祈争,自然就就釋放SCL了斤程。往往是使用用戶使用MCU作為I2C從機(jī)時(shí),程序設(shè)計(jì)上的問題導(dǎo)致MCU無法讀取&填充buffer而導(dǎo)致菩混,重點(diǎn)分析MCU I2C中斷服務(wù)程序忿墅。

  1. I2C中斷服務(wù)程序被意外屏蔽
  2. 中斷服務(wù)程序中陷入了一些標(biāo)志位查詢的while(flag != xxx)死循環(huán)
  3. I2C功能系統(tǒng)被意外禁止
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末扁藕,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子疚脐,更是在濱河造成了極大的恐慌亿柑,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,817評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件棍弄,死亡現(xiàn)場離奇詭異望薄,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)呼畸,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,329評論 3 385
  • 文/潘曉璐 我一進(jìn)店門式矫,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人役耕,你說我怎么就攤上這事采转。” “怎么了瞬痘?”我有些...
    開封第一講書人閱讀 157,354評論 0 348
  • 文/不壞的土叔 我叫張陵故慈,是天一觀的道長。 經(jīng)常有香客問我框全,道長察绷,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,498評論 1 284
  • 正文 為了忘掉前任津辩,我火速辦了婚禮拆撼,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘喘沿。我一直安慰自己闸度,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,600評論 6 386
  • 文/花漫 我一把揭開白布蚜印。 她就那樣靜靜地躺著莺禁,像睡著了一般。 火紅的嫁衣襯著肌膚如雪窄赋。 梳的紋絲不亂的頭發(fā)上哟冬,一...
    開封第一講書人閱讀 49,829評論 1 290
  • 那天,我揣著相機(jī)與錄音忆绰,去河邊找鬼浩峡。 笑死,一個(gè)胖子當(dāng)著我的面吹牛错敢,可吹牛的內(nèi)容都是我干的翰灾。 我是一名探鬼主播,決...
    沈念sama閱讀 38,979評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼预侯!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起峰锁,我...
    開封第一講書人閱讀 37,722評論 0 266
  • 序言:老撾萬榮一對情侶失蹤萎馅,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后虹蒋,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體糜芳,經(jīng)...
    沈念sama閱讀 44,189評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,519評論 2 327
  • 正文 我和宋清朗相戀三年魄衅,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了峭竣。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,654評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡晃虫,死狀恐怖皆撩,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情哲银,我是刑警寧澤扛吞,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布听隐,位于F島的核電站皿哨,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏臼隔。R本人自食惡果不足惜做院,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,940評論 3 313
  • 文/蒙蒙 一盲泛、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧键耕,春花似錦寺滚、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,762評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至棚亩,卻和暖如春蓖议,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背讥蟆。 一陣腳步聲響...
    開封第一講書人閱讀 31,993評論 1 266
  • 我被黑心中介騙來泰國打工勒虾, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人瘸彤。 一個(gè)月前我還...
    沈念sama閱讀 46,382評論 2 360
  • 正文 我出身青樓修然,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子愕宋,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,543評論 2 349

推薦閱讀更多精彩內(nèi)容

  • 在使用單片機(jī)的過程中玻靡,I2C 通信可以說是最被廣泛使用和采納的協(xié)議之一,采用 I2C 協(xié)議可以占用更少的資源中贝,鏈接...
    noparkinghere閱讀 2,156評論 0 8
  • 導(dǎo)語:此為個(gè)人對I2C總線協(xié)議的一點(diǎn)總結(jié)囤捻,如若想深度了解I2C總線協(xié)議可參考相關(guān)文檔 I2C英文權(quán)威手冊 I2C中...
    Ben2Feng閱讀 3,411評論 0 6
  • 1、嵌入式系統(tǒng)的定義 (1)定義:以應(yīng)用為中心邻寿,以計(jì)算機(jī)技術(shù)為基礎(chǔ)蝎土,軟硬件可裁剪,適應(yīng)應(yīng)用系統(tǒng)對功能绣否、可靠性誊涯、成本...
    榮卓然閱讀 1,804評論 0 5
  • ???本文主要介紹嵌入式系統(tǒng)的一些基礎(chǔ)知識(shí),希望對各位有幫助蒜撮。 嵌入式系統(tǒng)基礎(chǔ) 1暴构、嵌入式系統(tǒng)的定義 (1)定義:...
    OpenJetson閱讀 3,297評論 0 13
  • 不是所有的愛都很高調(diào),也不是所以的愛都很驚心動(dòng)魄的換來一個(gè)承諾段磨。
    玻璃之森閱讀 394評論 0 0