接客周·程式設計養生·帶薪休假與菊部養生
餘大師偶爾會跟我探討起光模組測試板介面晶片CH341A不穩定,會導致ATE軟體異常。換一顆新的USB轉I2C介面晶片,剛需,拖久了就成了一種夙願。 困擾了我整整兩個工作日再加一個雙休日的基於MCP2221的USB轉I2C的DLL呼叫問題終於在週一得到破解。我已經用最常用的隱式呼叫DLL的方式,成功呼叫《mcp2221_dll_um_x86.dll》中尚還可用的2個函式,實現了對光模組EEPROM的I2C隨機讀/寫訪問(即指定暫存器偏移量的I2C匯流排操作)。原廠提供的這個V2.2.1 DLL的奇葩之處在於,部分函式比如Mcp2221_GetLastError()在原始碼編譯時就會報錯missing prototype即匯入庫lib檔案中壓根兒就沒有這個函式入口,另外還有部分函式比如Mcp2221_SmbusBlockWrite()和Mcp2221_SmbusBlockRead()總是返回錯誤程式碼但我曾用示波器看過SMB讀時序又不像有問題的樣子,至少下位機該ACK時都正常響應了的。 要理解我對MCP2221晶片的奇葩DLL的破解之道,需要首先從EEPROM的I2C時序說起。和溫度感測器這類從I2C裝置不一樣,EEPROM是有暫存器偏移量概念的。打個比方,從溫度感測器回讀當前取樣的溫度值,那麼我們直接去成都模具園D2棟的迪譜光電隨便找個有問必答的銷售人員問一下就可以,但是要訪問EEPROM的各個暫存器,就像菜地裡的一個蘿蔔一個坑,每個坑位都是順序編號的,哪個序號坑位的蘿蔔有多重,是需要事先指定好坑位的,這個坑位序號,就是暫存器偏移量,即偏離零點的距離,範圍0~255。由於EEPROM暫存器定址是8bit的,這意味著一片菜地(比如AT24C02)可以有2^8即256個蘿蔔(Byte),這一片菜地以A0h作為I2C從裝置寫地址,以A1h作為I2C從裝置讀地址。當然一個菜園(比如AT24C04)可以有2片菜地,第一片菜地以A0h作為寫地址,以A1h作為讀地址,第二片菜地以A2h作為寫地址,以A3h作為讀地址。 讓我們來先看看典型的EEPROM型號為AT24C02的datasheet,對EEPROM的一些I2C專業術語的定義: (……此處省略1800字) 既然能指定坑位號的Mcp2221_Smbusxxx函式不好用,那我們就用不能指定坑位號但幸好還能正常使用的Mcp2221_I2cxxx函式來自己搭建合適的蔬菜大棚!我最開始還不是這樣想的,我想退回到基於2014年的老版本DLL的上位機C#例程《MCP2221DLL_2015_06_17\Unmanaged\Example Code\MCP2221DLL-UM_CSExampleCode》,來嘗試突破。很遺憾,C#我不熟,CVI顯式呼叫DLL我也沒整成功,反而是看到2014年的老版本DLL的SmbReadBlock函式,比SmbWriteBlock函式,多了一個引數是BYTE readRegIndex。我就在想,為啥SMB的block讀函式,就要指定坑位號,而SMB的block寫函式,就可以不指定坑位號呢?當時似乎是靈光乍現,回頭去看page write時序,實際上坑位號和蘿蔔並沒有本質不同,都是前後緊挨著的8bit資料,所以SMB的block寫函式,發出的第一個8bit資料,完全可以當成是坑位號告訴給菜地嘛,所以才可以不像SMB的block讀函式那樣需要明示坑位號。於是乎,Mcp2221_I2cWrite的unsigned char* i2cTxData引數,第一個8bit資料,我就讓它等於坑位號;從第二個8bit到第x+1個8bit,我就給它順序賦值成x個新蘿蔔,這樣一旦執行完一次Mcp2221_I2cWrite函式,就相當於是指定了坑位號再種下了x個新蘿蔔,完美! 再回頭去看Sequential Read時序,需要先寫坑位號再發起立即讀x個老蘿蔔的操作,於是可以先呼叫Mcp2221_I2cWrite函式只發出1個byte當成是坑位號,然後再呼叫Mcp2221_I2cRead函式連續挖出x個老蘿蔔即可。注意這裡的Mcp2221_I2cWrite函式會發出一個STOP結尾,但是標準的讀時序是沒有這個STOP的,不過實踐證實,Re-START前面有沒有這個額外的STOP,下位機都可以正常應對。本來我是準備呼叫Mcp2221_I2cWriteNoStop這個函式來下發不帶額外STOP的坑位號的,但是執行完這個函式SCL就一直拖低,沒法進行下一步操作,就是這個奇葩DLL倒逼著我這個老工程師,連蒙帶猜地採取迂迴戰術才得以成功訪問到EEPROM,一旦想通了I2C時序原理,連線下來的上廁所蹲坑都暢快多了,畢竟這也算是碎片式帶薪休假與菊部養生嘛。
相關文章
- 養生吧,程式設計師!程式設計師
- 程式設計師養生攻略程式設計師
- 程式設計師也要養生程式設計師
- 從程式設計到養生程式設計程式設計
- 大道至簡的養生方法
- 程式設計師也要養生,給DBA和IT同行的一些建議程式設計師
- 「熱話題」33歲程式設計師5小時瀕死體驗,程式設計師養生攻略程式設計師
- 程式設計修養(一) (轉)程式設計
- 程式設計修養(二) (轉)程式設計
- 程式設計修養(三) (轉)程式設計
- 程式設計修養(五) (轉)程式設計
- 程式設計修養(六) (轉)程式設計
- 程式設計修養(四) (轉)程式設計
- 程式設計修養(七) (轉)程式設計
- iOS 程式設計師的自我修養 — 讀《程式設計師的自我修養 連結、裝載與庫》iOS程式設計師
- @程式設計師,再不養生就晚了程式設計師
- 培養程式設計師的人脈程式設計師
- 程式設計師的自我修養程式設計師
- UC Berkeley EECS是如何培養計算機學生的計算機
- 單點養成與多點養成:GBF的多屬性隊伍養成設計分析
- 程式設計師“求包養”攻略揭秘程式設計師
- 程式設計師深夜12點睡覺,領導怒斥:這麼早睡覺,你很會養生啊!程式設計師
- 麻省理工學院是如何培養計算機學生的計算機
- 《程式設計師的自我修養》(三)——庫與執行庫程式設計師
- 程式設計師的職業素養(一)程式設計師
- 如何培養良好的程式設計實踐程式設計
- 如何培養良好的程式設計風格程式設計
- 《程式設計師的職業素養有感》程式設計師
- 程式設計師該有的職業素養程式設計師
- 程式設計師如何提高自我修養(4)程式設計師
- 談談對程式設計師的培養程式設計師
- 程式設計師半夜12點沒加班,領導:你來我公司養生呢?網友:憑什麼?程式設計師
- 程式設計師的自我修養之全棧程式設計師程式設計師全棧
- 程式設計師自我修養之程式設計經驗總結程式設計師
- 養魚出現“浮頭”、死亡?遙控開關的智慧養殖高效、生態、安全的特性
- 一個野生程式設計師的自我修養程式設計師
- 程式設計師的科技道德修養 - idlewords程式設計師
- 淺談程式設計師的數學修養程式設計師